Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/source/core/unocore/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 18 kB image not shown  

Quelle  unoflatpara.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <unobaseclass.hxx>
#include <unocrsrhelper.hxx>
#include <unoflatpara.hxx>

#include <o3tl/safeint.hxx>
#include <utility>
#include <vcl/svapp.hxx>
#include <com/sun/star/text/TextMarkupType.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <unotextmarkup.hxx>
#include <ndtxt.hxx>
#include <doc.hxx>
#include <IDocumentLayoutAccess.hxx>
#include <IDocumentStylePoolAccess.hxx>
#include <viewsh.hxx>
#include <viewimp.hxx>
#include <breakit.hxx>
#include <pam.hxx>
#include <unotextrange.hxx>
#include <pagefrm.hxx>
#include <cntfrm.hxx>
#include <txtfrm.hxx>
#include <rootfrm.hxx>
#include <poolfmt.hxx>
#include <pagedesc.hxx>
#include <GrammarContact.hxx>
#include <viewopt.hxx>
#include <comphelper/servicehelper.hxx>
#include <comphelper/propertysetinfo.hxx>
#include <comphelper/sequence.hxx>
#include <sal/log.hxx>

#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/text/XTextRange.hpp>

using namespace ::com::sun::star;

namespace SwUnoCursorHelper {

uno::Reference<text::XFlatParagraphIterator>
CreateFlatParagraphIterator(SwDoc & rDoc, sal_Int32 const nTextMarkupType,
        bool const bAutomatic)
{
    return new SwXFlatParagraphIterator(rDoc, nTextMarkupType, bAutomatic);
}

}

SwXFlatParagraph::SwXFlatParagraph( SwTextNode& rTextNode, OUString aExpandText, const ModelToViewHelper& rMap )
    : SwXFlatParagraph_Base(& rTextNode, rMap)
    , maExpandText(std::move(aExpandText))
    , maOrigText(rTextNode.GetText())
{
}

SwXFlatParagraph::~SwXFlatParagraph()
{
}


// XPropertySet
uno::Reference< beans::XPropertySetInfo > SAL_CALL
SwXFlatParagraph::getPropertySetInfo()
{
    static const comphelper::PropertyMapEntry s_Entries[] = {
        { u"FieldPositions"_ustr, -1, ::cppu::UnoType<uno::Sequence<sal_Int32>>::get(), beans::PropertyAttribute::READONLY, 0 },
        { u"FootnotePositions"_ustr, -1, ::cppu::UnoType<uno::Sequence<sal_Int32>>::get(), beans::PropertyAttribute::READONLY, 0 },
        { u"SortedTextId"_ustr, -1, ::cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
        { u"DocumentElementsCount"_ustr, -1, ::cppu::UnoType<sal_Int32>::get(), beans::PropertyAttribute::READONLY, 0 },
    };
    return new comphelper::PropertySetInfo(s_Entries);
}

void SAL_CALL
SwXFlatParagraph::setPropertyValue(const OUString&, const uno::Any&)
{
    throw lang::IllegalArgumentException(u"no values can be set"_ustr,
            getXWeak(), 0);
}

uno::Any SAL_CALL
SwXFlatParagraph::getPropertyValue(const OUString& rPropertyName)
{
    SolarMutexGuard g;

    if (rPropertyName == "FieldPositions")
    {
        return uno::Any( comphelper::containerToSequence( GetConversionMap().getFieldPositions() ) );
    }
    else if (rPropertyName == "FootnotePositions")
    {
        return uno::Any( comphelper::containerToSequence( GetConversionMap().getFootnotePositions() ) );
    }
    else if (rPropertyName == "SortedTextId")
    {
        SwTextNode const*const pCurrentNode = GetTextNode();
        sal_Int32 nIndex = -1;
        if ( pCurrentNode )
            nIndex = pCurrentNode->GetIndex().get();
        return uno::Any( nIndex );
    }
    else if (rPropertyName == "DocumentElementsCount")
    {
        SwTextNode const*const pCurrentNode = GetTextNode();
        sal_Int32 nCount = -1;
        if ( pCurrentNode )
            nCount = pCurrentNode->GetDoc().GetNodes().Count().get();
        return uno::Any( nCount );
    }
    return uno::Any();
}

void SAL_CALL
SwXFlatParagraph::addPropertyChangeListener(
        const OUString& /*rPropertyName*/,
        const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
{
    SAL_WARN("sw.uno",
        "SwXFlatParagraph::addPropertyChangeListener(): not implemented");
}

void SAL_CALL
SwXFlatParagraph::removePropertyChangeListener(
        const OUString& /*rPropertyName*/,
        const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
{
    SAL_WARN("sw.uno",
        "SwXFlatParagraph::removePropertyChangeListener(): not implemented");
}

void SAL_CALL
SwXFlatParagraph::addVetoableChangeListener(
        const OUString& /*rPropertyName*/,
        const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
{
    SAL_WARN("sw.uno",
        "SwXFlatParagraph::addVetoableChangeListener(): not implemented");
}

void SAL_CALL
SwXFlatParagraph::removeVetoableChangeListener(
        const OUString& /*rPropertyName*/,
        const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
{
    SAL_WARN("sw.uno",
        "SwXFlatParagraph::removeVetoableChangeListener(): not implemented");
}


css::uno::Reference< css::container::XStringKeyMap > SAL_CALL SwXFlatParagraph::getMarkupInfoContainer()
{
    return SwXTextMarkup::getMarkupInfoContainer();
}

void SAL_CALL SwXFlatParagraph::commitTextRangeMarkup(::sal_Int32 nType, const OUString & aIdentifier, const uno::Reference< text::XTextRange> & xRange,
                                                      const css::uno::Reference< css::container::XStringKeyMap > & xMarkupInfoContainer)
{
    SolarMutexGuard aGuard;
    SwXTextMarkup::commitTextRangeMarkup( nType, aIdentifier, xRange,  xMarkupInfoContainer );
}

void SAL_CALL SwXFlatParagraph::commitStringMarkup(::sal_Int32 nType, const OUString &&nbsp;rIdentifier, ::sal_Int32 nStart, ::sal_Int32 nLength, const css::uno::Reference< css::container::XStringKeyMap > & rxMarkupInfoContainer)
{
    SolarMutexGuard aGuard;
    SwXTextMarkup::commitStringMarkup( nType, rIdentifier, nStart, nLength,  rxMarkupInfoContainer );
}

// text::XFlatParagraph:
OUString SAL_CALL SwXFlatParagraph::getText()
{
    return maExpandText;
}

// text::XFlatParagraph:
void SAL_CALL SwXFlatParagraph::setChecked( ::sal_Int32 nType, sal_Bool bVal )
{
    SolarMutexGuard aGuard;

    if (!GetTextNode())
        return;

    if ( text::TextMarkupType::SPELLCHECK == nType )
    {
        GetTextNode()->SetWrongDirty(
            bVal ? sw::WrongState::DONE : sw::WrongState::TODO);
    }
    else if ( text::TextMarkupType::SMARTTAG == nType )
        GetTextNode()->SetSmartTagDirty( !bVal );
    else if( text::TextMarkupType::PROOFREADING == nType )
    {
        GetTextNode()->SetGrammarCheckDirty( !bVal );
        if( bVal )
            sw::finishGrammarCheckFor(*GetTextNode());
    }
}

// text::XFlatParagraph:
sal_Bool SAL_CALL SwXFlatParagraph::isChecked( ::sal_Int32 nType )
{
    SolarMutexGuard aGuard;
    if (GetTextNode())
    {
        if ( text::TextMarkupType::SPELLCHECK == nType )
            return !GetTextNode()->IsWrongDirty();
        else if ( text::TextMarkupType::PROOFREADING == nType )
            return !GetTextNode()->IsGrammarCheckDirty();
        else if ( text::TextMarkupType::SMARTTAG == nType )
            return !GetTextNode()->IsSmartTagDirty();
    }

    return true;
}

// text::XFlatParagraph:
sal_Bool SAL_CALL SwXFlatParagraph::isModified()
{
    SolarMutexGuard aGuard;
    return !GetTextNode() || GetTextNode()->GetText() != maOrigText;
}

// text::XFlatParagraph:
lang::Locale SAL_CALL SwXFlatParagraph::getLanguageOfText(::sal_Int32 nPos, ::sal_Int32 nLen)
{
    SolarMutexGuard aGuard;
    if (!GetTextNode())
        return LanguageTag::convertToLocale( LANGUAGE_NONE );

    const lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetTextNode()->GetLang(nPos, nLen) ) );
    return aLocale;
}

// text::XFlatParagraph:
lang::Locale SAL_CALL SwXFlatParagraph::getPrimaryLanguageOfText(::sal_Int32 nPos, ::sal_Int32 nLen)
{
    SolarMutexGuard aGuard;

    if (!GetTextNode())
        return LanguageTag::convertToLocale( LANGUAGE_NONE );

    const lang::Locale aLocale( SW_BREAKITER()->GetLocale( GetTextNode()->GetLang(nPos, nLen) ) );
    return aLocale;
}

// text::XFlatParagraph:
void SAL_CALL SwXFlatParagraph::changeText(::sal_Int32 nPos, ::sal_Int32 nLen, const OUString & aNewText, const css::uno::Sequence< css::beans::PropertyValue > & aAttributes)
{
    SolarMutexGuard aGuard;

    if (!GetTextNode())
        return;

    SwTextNode *const pOldTextNode = GetTextNode();

    if (nPos < 0 || pOldTextNode->Len() < nPos || nLen < 0 || o3tl::make_unsigned(pOldTextNode->Len()) < static_cast<sal_uInt32>(nPos) + nLen)
    {
        throw lang::IllegalArgumentException();
    }

    SwPaM aPaM( *GetTextNode(), nPos, *GetTextNode(), nPos+nLen );

    UnoActionContext aAction( &GetTextNode()->GetDoc() );

    const rtl::Reference<SwXTextRange> xRange =
        SwXTextRange::CreateXTextRange(
            GetTextNode()->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
    if ( xRange.is() )
    {
        for ( const auto& rAttribute : aAttributes )
            xRange->setPropertyValue( rAttribute.Name, rAttribute.Value );
    }

    IDocumentContentOperations& rIDCO = pOldTextNode->getIDocumentContentOperations();
    rIDCO.ReplaceRange( aPaM, aNewText, false );

    ClearTextNode(); // TODO: is this really needed?
}

// text::XFlatParagraph:
void SAL_CALL SwXFlatParagraph::changeAttributes(::sal_Int32 nPos, ::sal_Int32 nLen, const css::uno::Sequence< css::beans::PropertyValue > & aAttributes)
{
    SolarMutexGuard aGuard;

    if (!GetTextNode())
        return;

    if (nPos < 0 || GetTextNode()->Len() < nPos || nLen < 0 || o3tl::make_unsigned(GetTextNode()->Len()) < static_cast<sal_uInt32>(nPos) + nLen)
    {
        throw lang::IllegalArgumentException();
    }

    SwPaM aPaM( *GetTextNode(), nPos, *GetTextNode(), nPos+nLen );

    UnoActionContext aAction( &GetTextNode()->GetDoc() );

    const rtl::Reference<SwXTextRange> xRange =
        SwXTextRange::CreateXTextRange(
            GetTextNode()->GetDoc(), *aPaM.GetPoint(), aPaM.GetMark() );
    if ( xRange.is() )
    {
        for ( const auto& rAttribute : aAttributes )
            xRange->setPropertyValue( rAttribute.Name, rAttribute.Value );
    }

    ClearTextNode(); // TODO: is this really needed?
}

// text::XFlatParagraph:
css::uno::Sequence< ::sal_Int32 > SAL_CALL SwXFlatParagraph::getLanguagePortions()
{
    return css::uno::Sequence< ::sal_Int32>();
}

SwXFlatParagraphIterator::SwXFlatParagraphIterator( SwDoc& rDoc, sal_Int32 nTypebool bAutomatic )
    : mpDoc( &rDoc ),
      mnType( nType ),
      mbAutomatic( bAutomatic ),
      mnCurrentNode( 0 ),
      mnEndNode( rDoc.GetNodes().Count() )
{
    //mnStartNode = mnCurrentNode = get node from current cursor TODO!

    // register as listener and get notified when document is closed
    StartListening(mpDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_STANDARD )->GetNotifier());
}

SwXFlatParagraphIterator::~SwXFlatParagraphIterator()
{
    SolarMutexGuard aGuard;
    EndListeningAll();
}

void SwXFlatParagraphIterator::Notify( const SfxHint& rHint )
{
    if(rHint.GetId() == SfxHintId::Dying)
    {
        SolarMutexGuard aGuard;
        mpDoc = nullptr;
    }
}

uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getFirstPara()
{
    return getNextPara();   // TODO
}

uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getNextPara()
{
    SolarMutexGuard aGuard;

    if (!mpDoc)
        return nullptr;

    SwTextNode* pRet = nullptr;
    if ( mbAutomatic )
    {
        SwViewShell* pViewShell = mpDoc->getIDocumentLayoutAccess().GetCurrentViewShell();

        SwPageFrame* pCurrentPage = pViewShell ? pViewShell->Imp()->GetFirstVisPage(pViewShell->GetOut()) : nullptr;
        SwPageFrame* pStartPage = pCurrentPage;
        SwPageFrame* pStopPage = nullptr;

        while ( pCurrentPage && pCurrentPage != pStopPage )
        {
            if (mnType != text::TextMarkupType::SPELLCHECK || pCurrentPage->IsInvalidSpelling() )
            {
                // this method is supposed to return an empty paragraph in case Online Checking is disabled
                if ( ( mnType == text::TextMarkupType::PROOFREADING || mnType == text::TextMarkupType::SPELLCHECK )
                    && !pViewShell->GetViewOptions()->IsOnlineSpell() )
                    return nullptr;

                // search for invalid content:
                SwContentFrame* pCnt = pCurrentPage->ContainsContent();

                while( pCnt && pCurrentPage->IsAnLower( pCnt ) )
                {
                    if (pCnt->IsTextFrame())
                    {
                        SwTextFrame const*const pText(static_cast<SwTextFrame const*>(pCnt));
                        if (sw::MergedPara const*const pMergedPara = pText->GetMergedPara()
            )
                        {
                            SwTextNode * pTextNode(nullptr);
                            for (auto const& e : pMergedPara->extents)
                            {
                                if (e.pNode != pTextNode)
                                {
                                    pTextNode = e.pNode;
                                    if ((mnType == text::TextMarkupType::SPELLCHECK
                                            && pTextNode->IsWrongDirty()) ||
                                        (mnType == text::TextMarkupType::PROOFREADING
                                             && pTextNode->IsGrammarCheckDirty()))
                                    {
                                        pRet = pTextNode;
                                        break;
                                    }
                                }
                            }
                        }
                        else
                        {
                            SwTextNode const*const pTextNode(pText->GetTextNodeFirst());
                            if ((mnType == text::TextMarkupType::SPELLCHECK
                                    && pTextNode->IsWrongDirty()) ||
                                (mnType == text::TextMarkupType::PROOFREADING
                                     && pTextNode->IsGrammarCheckDirty()))

                            {
                                pRet = const_cast<SwTextNode*>(pTextNode);
                            }
                        }

                        if (pRet)
                        {
                            break;
                        }
                    }

                    pCnt = pCnt->GetNextContentFrame();
                }
            }

            if ( pRet )
                break;

            // if there is no invalid text node on the current page,
            // we validate the page
            pCurrentPage->ValidateSpelling();

            // proceed with next page, wrap at end of document if required:
            pCurrentPage = static_cast<SwPageFrame*>(pCurrentPage->GetNext());

            if ( !pCurrentPage && !pStopPage )
            {
                pStopPage = pStartPage;
                pCurrentPage = static_cast<SwPageFrame*>(pViewShell->GetLayout()->Lower());
            }
        }
    }
    else    // non-automatic checking
    {
        const SwNodes& rNodes = mpDoc->GetNodes();
        const SwNodeOffset nMaxNodes = rNodes.Count();

        while ( mnCurrentNode < mnEndNode && mnCurrentNode < nMaxNodes )
        {
            SwNode* pNd = rNodes[ mnCurrentNode ];

            ++mnCurrentNode;

            pRet = pNd->GetTextNode();
            if ( pRet )
                break;

            if ( mnCurrentNode == mnEndNode )
            {
                mnCurrentNode = SwNodeOffset(0);
                mnEndNode = SwNodeOffset(0);
            }
        }
    }

    if ( !pRet )
        return nullptr;

    // Expand the string:
    const ModelToViewHelper aConversionMap(*pRet, mpDoc->getIDocumentLayoutAccess().GetCurrentLayout());
    const OUString& aExpandText = aConversionMap.getViewText();

    return new SwXFlatParagraph( *pRet, aExpandText, aConversionMap );
}

uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getLastPara()
{
    return getNextPara();
}

uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaAfter(const uno::Reference< text::XFlatParagraph > & xPara)
{
    SolarMutexGuard aGuard;

    if (!mpDoc)
        return nullptr;

    SwXFlatParagraph* const pFlatParagraph(dynamic_cast<SwXFlatParagraph*>(xPara.get()));
    SAL_WARN_IF(!pFlatParagraph, "sw.core""invalid argument");
    if ( !pFlatParagraph )
        return nullptr;

    SwTextNode const*const pCurrentNode = pFlatParagraph->GetTextNode();

    if ( !pCurrentNode )
        return nullptr;

    SwTextNode* pNextTextNode = nullptr;
    const SwNodes& rNodes = pCurrentNode->GetDoc().GetNodes();

    for( SwNodeOffset nCurrentNode = pCurrentNode->GetIndex() + 1; nCurrentNode < rNodes.Count(); ++nCurrentNode )
    {
        SwNode* pNd = rNodes[ nCurrentNode ];
        pNextTextNode = pNd->GetTextNode();
        if ( pNextTextNode )
            break;
    }

    if ( !pNextTextNode )
        return nullptr;

    // Expand the string:
    const ModelToViewHelper aConversionMap(*pNextTextNode, mpDoc->getIDocumentLayoutAccess().GetCurrentLayout());
    const OUString& aExpandText = aConversionMap.getViewText();

    return new SwXFlatParagraph( *pNextTextNode, aExpandText, aConversionMap );
}

uno::Reference< text::XFlatParagraph > SwXFlatParagraphIterator::getParaBefore(const uno::Reference< text::XFlatParagraph > & xPara )
{
    SolarMutexGuard aGuard;

    if (!mpDoc)
        return nullptr;

    SwXFlatParagraph* const pFlatParagraph(dynamic_cast<SwXFlatParagraph*>(xPara.get()));
    SAL_WARN_IF(!pFlatParagraph, "sw.core""invalid argument");
    if ( !pFlatParagraph )
        return nullptr;

    SwTextNode const*const pCurrentNode = pFlatParagraph->GetTextNode();

    if ( !pCurrentNode )
        return nullptr;

    SwTextNode* pPrevTextNode = nullptr;
    const SwNodes& rNodes = pCurrentNode->GetDoc().GetNodes();

    for( SwNodeOffset nCurrentNode = pCurrentNode->GetIndex() - 1; nCurrentNode > SwNodeOffset(0); --nCurrentNode )
    {
        SwNode* pNd = rNodes[ nCurrentNode ];
        pPrevTextNode = pNd->GetTextNode();
        if ( pPrevTextNode )
            break;
    }

    if ( !pPrevTextNode )
        return nullptr;

    // Expand the string:
    const ModelToViewHelper aConversionMap(*pPrevTextNode, mpDoc->getIDocumentLayoutAccess().GetCurrentLayout());
    const OUString& aExpandText = aConversionMap.getViewText();

    return new SwXFlatParagraph( *pPrevTextNode, aExpandText, aConversionMap );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=96 H=97 G=96

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.