Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/sc/source/ui/unoobj/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 27 kB image not shown  

Quelle  textuno.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 <memory>
#include <sal/config.h>
#include <sal/log.hxx>

#include <scitems.hxx>
#include <editeng/eeitem.hxx>
#include <svx/svdpool.hxx>
#include <svx/svdobj.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editobj.hxx>
#include <editeng/flditem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/unoprnms.hxx>
#include <editeng/unofored.hxx>
#include <utility>
#include <vcl/svapp.hxx>

#include <editeng/unoipset.hxx>
#include <textuno.hxx>
#include <fielduno.hxx>
#include <editsrc.hxx>
#include <docsh.hxx>
#include <editutil.hxx>
#include <miscuno.hxx>
#include <cellsuno.hxx>
#include <cellvalue.hxx>
#include <cellform.hxx>
#include <patattr.hxx>
#include <docfunc.hxx>
#include <scmod.hxx>

using namespace com::sun::star;

static const SvxItemPropertySet * lcl_GetHdFtPropertySet()
{
    static const SvxItemPropertySet aHdFtPropertySet_Impl = [] {
        static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
        {
            SVX_UNOEDIT_CHAR_PROPERTIES,
            SVX_UNOEDIT_FONT_PROPERTIES,
            SVX_UNOEDIT_PARA_PROPERTIES,
            SVX_UNOEDIT_NUMBERING_PROPERTY,    // for completeness of service ParagraphProperties
        };

        //  modify PropertyMap to include CONVERT_TWIPS flag for font height
        //  (headers/footers are in twips)

        for (auto & rEntry : aHdFtPropertyMap_Impl)
        {
            if ( ( rEntry.nWID == EE_CHAR_FONTHEIGHT ||
                   rEntry.nWID == EE_CHAR_FONTHEIGHT_CJK ||
                   rEntry.nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
                 rEntry.nMemberId == MID_FONTHEIGHT )
            {
                rEntry.nMemberId |= CONVERT_TWIPS;
            }
        }

        return SvxItemPropertySet(aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool());
    }();
    return &aHdFtPropertySet_Impl;
}

SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, u"ScHeaderFooterContentObj"_ustr, u"com.sun.star.sheet.HeaderFooterContent"_ustr )
SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, u"ScHeaderFooterTextObj"_ustr, u"stardiv.one.Text.Text"_ustr )

ScHeaderFooterContentObj::ScHeaderFooterContentObj()
{
}

ScHeaderFooterContentObj::~ScHeaderFooterContentObj() {}

const EditTextObject* ScHeaderFooterContentObj::GetLeftEditObject() const
{
    return mxLeftText->GetTextObject();
}

const EditTextObject* ScHeaderFooterContentObj::GetCenterEditObject() const
{
    return mxCenterText->GetTextObject();
}

const EditTextObject* ScHeaderFooterContentObj::GetRightEditObject() const
{
    return mxRightText->GetTextObject();
}

// XHeaderFooterContent

uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
{
    SolarMutexGuard aGuard;
    uno::Reference<text::XText> xInt(*mxLeftText, uno::UNO_QUERY);
    return xInt;
}

uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
{
    SolarMutexGuard aGuard;
    uno::Reference<text::XText> xInt(*mxCenterText, uno::UNO_QUERY);
    return xInt;
}

uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
{
    SolarMutexGuard aGuard;
    uno::Reference<text::XText> xInt(*mxRightText, uno::UNO_QUERY);
    return xInt;
}

rtl::Reference<ScHeaderFooterContentObj> ScHeaderFooterContentObj::getImplementation(
                                const uno::Reference<sheet::XHeaderFooterContent>& rObj)
{
    return dynamic_cast<ScHeaderFooterContentObj*>(rObj.get());
}

void ScHeaderFooterContentObj::Init( const EditTextObject* pLeft,
                                                    const EditTextObject* pCenter,
                                                    const EditTextObject* pRight )
{
    mxLeftText = rtl::Reference<ScHeaderFooterTextObj>(new ScHeaderFooterTextObj(this, ScHeaderFooterPart::LEFT, pLeft));
    mxCenterText = rtl::Reference<ScHeaderFooterTextObj>(new ScHeaderFooterTextObj(this, ScHeaderFooterPart::CENTER, pCenter));
    mxRightText = rtl::Reference<ScHeaderFooterTextObj>(new ScHeaderFooterTextObj(this, ScHeaderFooterPart::RIGHT, pRight));
}

ScHeaderFooterTextData::ScHeaderFooterTextData(
    unotools::WeakReference<ScHeaderFooterContentObj> xContent, ScHeaderFooterPart nP, const EditTextObject* pTextObj) :
    mpTextObj(pTextObj ? pTextObj->Clone() : nullptr),
    xContentObj(std::move( xContent )),
    nPart( nP ),
    bDataValid(false)
{
}

ScHeaderFooterTextData::~ScHeaderFooterTextData()
{
    SolarMutexGuard aGuard;     //  needed for EditEngine dtor

    pForwarder.reset();
    pEditEngine.reset();
}

SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
{
    if (!pEditEngine)
    {
        rtl::Reference<SfxItemPool> pEnginePool = EditEngine::CreatePool();
        std::unique_ptr<ScHeaderEditEngine> pHdrEngine(new ScHeaderEditEngine( pEnginePool.get() ));

        pHdrEngine->EnableUndo( false );
        pHdrEngine->SetRefMapMode(MapMode(MapUnit::MapTwip));

        //  default font must be set, independently of document
        ScDocShell* pDocSh(dynamic_cast<ScDocShell*>(SfxObjectShell::Current()));
        std::unique_ptr<CellAttributeHelper> pTmp;
        const ScPatternAttr* pCellAttributeDefault(nullptr);

        if (nullptr != pDocSh)
        {
            // we can use default CellAttribute from ScDocument
            pCellAttributeDefault = &pDocSh->GetDocument().getCellAttributeHelper().getDefaultCellAttribute();
        }
        else
        {
            // no access to ScDocument, use temporary default CellAttributeHelper
            // was: "use global pool from module" which is usually ScMessagePool
            // and gets set in ScTabViewObj::SelectionChanged() by
            // ScFormatShell::ScFormatShell which  calls
            //    SetPool( &pTabViewShell->GetPool() );
            pTmp.reset(new CellAttributeHelper(ScModule::get()->GetPool()));
            pCellAttributeDefault = &pTmp->getDefaultCellAttribute();
        }

        SfxItemSet aDefaults(pHdrEngine->GetEmptyItemSet());
        pCellAttributeDefault->FillEditItemSet(&aDefaults);
        //  FillEditItemSet adjusts font height to 1/100th mm,
        //  but for header/footer twips is needed, as in the PatternAttr:
        aDefaults.Put( pCellAttributeDefault->GetItem(ATTR_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT) );
        aDefaults.Put( pCellAttributeDefault->GetItem(ATTR_CJK_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CJK) ) ;
        aDefaults.Put( pCellAttributeDefault->GetItem(ATTR_CTL_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CTL) );
        pHdrEngine->SetDefaults(std::move(aDefaults));

        ScHeaderFieldData aData;
        ScHeaderFooterTextObj::FillDummyFieldData( aData );
        pHdrEngine->SetData( aData );

        pEditEngine = std::move(pHdrEngine);
        pForwarder.reset( new SvxEditEngineForwarder(*pEditEngine) );
    }

    if (bDataValid)
        return pForwarder.get();

    if (mpTextObj)
        pEditEngine->SetTextCurrentDefaults(*mpTextObj);

    bDataValid = true;
    return pForwarder.get();
}

void ScHeaderFooterTextData::UpdateData()
{
    if (pEditEngine)
    {
        mpTextObj = pEditEngine->CreateTextObject();
    }
}

void ScHeaderFooterTextData::UpdateData(EditEngine& rEditEngine)
{
    mpTextObj = rEditEngine.CreateTextObject();
    bDataValid = false;
}

ScHeaderFooterTextObj::ScHeaderFooterTextObj(
    const unotools::WeakReference<ScHeaderFooterContentObj>& xContent, ScHeaderFooterPart nP, const EditTextObject* pTextObj) :
    aTextData(xContent, nP, pTextObj)
{
    //  ScHeaderFooterTextData acquires rContent
    //  pUnoText is created on demand (getString/setString work without it)
}

void ScHeaderFooterTextObj::CreateUnoText_Impl()
{
    if (!mxUnoText.is())
    {
        //  can't be aggregated because getString/setString is handled here
        ScHeaderFooterEditSource aEditSrc(aTextData);
        mxUnoText.set(new SvxUnoText(&aEditSrc, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>()));
    }
}

ScHeaderFooterTextObj::~ScHeaderFooterTextObj() {}

const EditTextObject* ScHeaderFooterTextObj::GetTextObject() const
{
    return aTextData.GetTextObject();
}

const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
{
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return *mxUnoText;
}

// XText

uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
{
    SolarMutexGuard aGuard;
    return new ScHeaderFooterTextCursor( this );
}

uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
                                    const uno::Reference<text::XTextRange>& aTextPosition )
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return mxUnoText->createTextCursorByRange(aTextPosition);
    //! like ScCellObj::createTextCursorByRange, if SvxUnoTextRange_getReflection available
}

void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData )
{
    OUString aDummy(u"???"_ustr);
    rData.aTitle        = aDummy;
    rData.aLongDocName  = aDummy;
    rData.aShortDocName = aDummy;
    rData.aTabName      = aDummy;
    rData.nPageNo       = 1;
    rData.nTotalPages   = 99;
}

OUString SAL_CALL ScHeaderFooterTextObj::getString()
{
    SolarMutexGuard aGuard;
    OUString aRet;
    const EditTextObject* pData;

    rtl::Reference<ScHeaderFooterContentObj> xContentObj = aTextData.GetContentObj();
    if (!xContentObj.is())
        throw css::uno::RuntimeException(
            u"ScHeaderFooterTextObj::getString: no ContentObj"_ustr);

    switch ( aTextData.GetPart() )
    {
        case ScHeaderFooterPart::LEFT:
            pData = xContentObj->GetLeftEditObject();
        break;
        case ScHeaderFooterPart::CENTER:
            pData = xContentObj->GetCenterEditObject();
        break;
        case ScHeaderFooterPart::RIGHT:
            pData = xContentObj->GetRightEditObject();
        break;
        default:
            SAL_WARN("sc.ui","unexpected enum value of ScHeaderFooterPart");
            pData = nullptr;
    }

    if (pData)
    {
        // for pure text, no font info is needed in pool defaults
        ScHeaderEditEngine aEditEngine( EditEngine::CreatePool().get() );

        ScHeaderFieldData aData;
        FillDummyFieldData( aData );
        aEditEngine.SetData( aData );

        aEditEngine.SetTextCurrentDefaults(*pData);
        aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
    }
    return aRet;
}

void SAL_CALL ScHeaderFooterTextObj::setString( const OUString& aText )
{
    SolarMutexGuard aGuard;

    // for pure text, no font info is needed in pool defaults
    ScHeaderEditEngine aEditEngine(EditEngine::CreatePool().get());
    aEditEngine.SetTextCurrentDefaults( aText );
    aTextData.UpdateData(aEditEngine);
}

void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
                                            const OUString& aString, sal_Bool bAbsorb )
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    mxUnoText->insertString( xRange, aString, bAbsorb );
}

void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
                                            const uno::Reference<text::XTextRange>& xRange,
                                            sal_Int16 nControlCharacter, sal_Bool bAbsorb )
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    mxUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
}

void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
                                            const uno::Reference<text::XTextRange >& xRange,
                                            const uno::Reference<text::XTextContent >& xContent,
                                            sal_Bool bAbsorb )
{
    SolarMutexGuard aGuard;
    if ( xContent.is() && xRange.is() )
    {
        ScEditFieldObj* pHeaderField = dynamic_cast<ScEditFieldObj*>( xContent.get() );

        SvxUnoTextRangeBase* pTextRange =
            comphelper::getFromUnoTunnel<ScHeaderFooterTextCursor>( xRange );

        if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
        {
            SvxEditSource* pEditSource = pTextRange->GetEditSource();
            ESelection aSelection(pTextRange->GetSelection());

            if (!bAbsorb)
            {
                //  don't replace -> append at end
                aSelection.Adjust();
                aSelection.CollapseToEnd();
            }

            SvxFieldItem aItem(pHeaderField->CreateFieldItem());

            SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
            pForwarder->QuickInsertField( aItem, aSelection );
            pEditSource->UpdateData();

            //  new selection: a digit
            aSelection.Adjust();
            aSelection.end.nPara = aSelection.start.nPara;
            aSelection.end.nIndex = aSelection.start.nIndex + 1;

            uno::Reference<text::XTextRange> xTextRange;
            switch ( aTextData.GetPart() )
            {
                case ScHeaderFooterPart::LEFT:
                    xTextRange = aTextData.GetContentObj()->getLeftText();
                break;
                case ScHeaderFooterPart::CENTER:
                    xTextRange = aTextData.GetContentObj()->getCenterText();
                break;
                case ScHeaderFooterPart::RIGHT:
                    xTextRange = aTextData.GetContentObj()->getRightText();
                break;
            }

            pHeaderField->InitDoc(xTextRange, std::make_unique<ScHeaderFooterEditSource>(aTextData), aSelection);

            //  for bAbsorb=FALSE, the new selection must be behind the inserted content
            //  (the xml filter relies on this)
            if (!bAbsorb)
                aSelection.start.nIndex = aSelection.end.nIndex;

            pTextRange->SetSelection( aSelection );

            return;
        }
    }

    if (!mxUnoText.is())
        CreateUnoText_Impl();
    mxUnoText->insertTextContent( xRange, xContent, bAbsorb );
}

void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
                                            const uno::Reference<text::XTextContent>& xContent )
{
    SolarMutexGuard aGuard;
    if ( xContent.is() )
    {
        ScEditFieldObj* pHeaderField = dynamic_cast<ScEditFieldObj*>(xContent.get());
        if ( pHeaderField && pHeaderField->IsInserted() )
        {
            //! check if the field is in this cell
            pHeaderField->DeleteField();
            return;
        }
    }
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    mxUnoText->removeTextContent( xContent );
}

uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText()
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return mxUnoText->getText();
}

uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart()
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return mxUnoText->getStart();
}

uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd()
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return mxUnoText->getEnd();
}

// XTextFieldsSupplier

uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
{
    SolarMutexGuard aGuard;
    // all fields
    return new ScHeaderFieldsObj(aTextData);
}

uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
{
    //  this does not exists in Calc (?)
    return nullptr;
}

// XTextRangeMover

void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
                                        const uno::Reference<text::XTextRange>& xRange,
                                        sal_Int16 nParagraphs )
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    mxUnoText->moveTextRange( xRange, nParagraphs );
}

// XEnumerationAccess

uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return mxUnoText->createEnumeration();
}

// XElementAccess

uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType()
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return mxUnoText->getElementType();
}

sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements()
{
    SolarMutexGuard aGuard;
    if (!mxUnoText.is())
        CreateUnoText_Impl();
    return mxUnoText->hasElements();
}

ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
    SvxUnoTextCursor( rText.GetUnoText() ),
    mxTextObj( &rText )
{
}

ScCellTextCursor::~ScCellTextCursor() noexcept
{
}

// SvxUnoTextCursor methods reimplemented here to return the right objects:

uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText()
{
    return mxTextObj;
}

uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart()
{
    SolarMutexGuard aGuard;

    //! use other object for range than cursor?

    rtl::Reference<ScCellTextCursor> pNew = new ScCellTextCursor( *this );

    ESelection aNewSel(GetSelection());
    aNewSel.CollapseToStart();
    pNew->SetSelection( aNewSel );

    return static_cast<SvxUnoTextRangeBase*>(pNew.get());
}

uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd()
{
    SolarMutexGuard aGuard;

    //! use other object for range than cursor?

    rtl::Reference<ScCellTextCursor> pNew = new ScCellTextCursor( *this );

    ESelection aNewSel(GetSelection());
    aNewSel.CollapseToEnd();
    pNew->SetSelection( aNewSel );

    return static_cast<SvxUnoTextRangeBase*>(pNew.get());
}

// XUnoTunnel

UNO3_GETIMPLEMENTATION2_IMPL(ScCellTextCursor, SvxUnoTextCursor);

ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(rtl::Reference<ScHeaderFooterTextObj> const & rText) :
    SvxUnoTextCursor( rText->GetUnoText() ),
    rTextObj( rText )
{}

ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() noexcept {};

// SvxUnoTextCursor methods reimplemented here to return the right objects:

uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText()
{
    SolarMutexGuard aGuard;
    return rTextObj;
}

uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart()
{
    SolarMutexGuard aGuard;

    //! use other object for range than cursor?

    rtl::Reference<ScHeaderFooterTextCursor> pNew = new ScHeaderFooterTextCursor( *this );

    ESelection aNewSel(GetSelection());
    aNewSel.CollapseToStart();
    pNew->SetSelection( aNewSel );

    return static_cast<SvxUnoTextRangeBase*>(pNew.get());
}

uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd()
{
    SolarMutexGuard aGuard;

    //! use other object for range than cursor?

    rtl::Reference<ScHeaderFooterTextCursor> pNew = new ScHeaderFooterTextCursor( *this );

    ESelection aNewSel(GetSelection());
    aNewSel.CollapseToEnd();
    pNew->SetSelection( aNewSel );

    return static_cast<SvxUnoTextRangeBase*>(pNew.get());
}

// XUnoTunnel

UNO3_GETIMPLEMENTATION2_IMPL(ScHeaderFooterTextCursor, SvxUnoTextCursor);

ScDrawTextCursor::ScDrawTextCursor( uno::Reference<text::XText> xParent,
                                    const SvxUnoTextBase& rText ) :
    SvxUnoTextCursor( rText ),
    xParentText(std::move( xParent ))

{
}

ScDrawTextCursor::~ScDrawTextCursor() noexcept
{
}

// SvxUnoTextCursor methods reimplemented here to return the right objects:

uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText()
{
    SolarMutexGuard aGuard;
    return xParentText;
}

uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart()
{
    SolarMutexGuard aGuard;

    //! use other object for range than cursor?

    rtl::Reference<ScDrawTextCursor> pNew = new ScDrawTextCursor( *this );

    ESelection aNewSel(GetSelection());
    aNewSel.CollapseToStart();
    pNew->SetSelection( aNewSel );

    return static_cast<SvxUnoTextRangeBase*>(pNew.get());
}

uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd()
{
    SolarMutexGuard aGuard;

    //! use other object for range than cursor?

    rtl::Reference<ScDrawTextCursor> pNew = new ScDrawTextCursor( *this );

    ESelection aNewSel(GetSelection());
    aNewSel.CollapseToEnd();
    pNew->SetSelection( aNewSel );

    return static_cast<SvxUnoTextRangeBase*>(pNew.get());
}

// XUnoTunnel

UNO3_GETIMPLEMENTATION2_IMPL(ScDrawTextCursor, SvxUnoTextCursor);

ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
{
    rtl::Reference<SfxItemPool> pEnginePool = EditEngine::CreatePool();
    pEnginePool->SetDefaultMetric( MapUnit::Map100thMM );
    pEditEngine.reset( new ScFieldEditEngine(nullptr, pEnginePool.get(), nullptr, true) );     // TRUE: become owner of pool
    pForwarder.reset( new SvxEditEngineForwarder( *pEditEngine ) );
    pOriginalSource.reset( new ScSimpleEditSource( pForwarder.get() ) );
}

ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
{
    SolarMutexGuard aGuard;     //  needed for EditEngine dtor

    pOriginalSource.reset();
    pForwarder.reset();
    pEditEngine.reset();
}

ScEditEngineTextObj::ScEditEngineTextObj() :
    SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
{
}

ScEditEngineTextObj::~ScEditEngineTextObj() noexcept
{
}

void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
{
    GetEditEngine()->SetTextCurrentDefaults( rTextObject );

    ESelection aSel;
    ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
    SetSelection( aSel );
}

std::unique_ptr<EditTextObject> ScEditEngineTextObj::CreateTextObject()
{
    return GetEditEngine()->CreateTextObject();
}

ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
    pDocShell( pDocSh ),
    aCellPos( rP ),
    bDataValid( false ),
    bInUpdate( false ),
    bDirty( false ),
    bDoUpdate( true )
{
    if (pDocShell)
        pDocShell->GetDocument().AddUnoObject(*this);
}

ScCellTextData::~ScCellTextData()
{
    SolarMutexGuard aGuard;     //  needed for EditEngine dtor

    if (pDocShell)
    {
        pDocShell->GetDocument().RemoveUnoObject(*this);
        pDocShell->GetDocument().DisposeFieldEditEngine(pEditEngine);
    }
    else
        pEditEngine.reset();

    pForwarder.reset();

    pOriginalSource.reset();
}

ScCellEditSource* ScCellTextData::GetOriginalSource()
{
    if (!pOriginalSource)
        pOriginalSource.reset( new ScCellEditSource(pDocShell, aCellPos) );
    return pOriginalSource.get();
}

SvxTextForwarder* ScCellTextData::GetTextForwarder()
{
    if (!pEditEngine)
    {
        if ( pDocShell )
        {
            ScDocument& rDoc = pDocShell->GetDocument();
            pEditEngine = rDoc.CreateFieldEditEngine();
        }
        else
        {
            rtl::Reference<SfxItemPool> pEnginePool = EditEngine::CreatePool();
            pEditEngine.reset( new ScFieldEditEngine(nullptr, pEnginePool.get(), nullptr, true) );
        }
        //  currently, GetPortions doesn't work if UpdateMode is sal_False,
        //  this will be fixed (in EditEngine) by src600
//      pEditEngine->SetUpdateMode( sal_False );
        pEditEngine->EnableUndo( false );
        if (pDocShell)
            pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
        else
            pEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
        pForwarder.reset( new SvxEditEngineForwarder(*pEditEngine) );
    }

    if (bDataValid)
        return pForwarder.get();

    if (pDocShell)
    {
        ScDocument& rDoc = pDocShell->GetDocument();

        SfxItemSet aDefaults(pEditEngine->GetEmptyItemSet());
        ifconst ScPatternAttr* pPattern =
                rDoc.GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
        {
            pPattern->FillEditItemSet(&aDefaults);
            pPattern->FillEditParaItems(&aDefaults); // including alignment etc. (for reading)
        }

        ScRefCellValue aCell(rDoc, aCellPos);
        if (aCell.getType() == CELLTYPE_EDIT)
        {
            const EditTextObject* pObj = aCell.getEditText();
            pEditEngine->SetTextNewDefaults(*pObj, std::move(aDefaults));
        }
        else
        {
            sal_uInt32 nFormat = rDoc.GetNumberFormat(ScRange(aCellPos));
            OUString aText = ScCellFormat::GetInputString(aCell, nFormat, nullptr, rDoc);
            // tdf#157568 check if edit engine already has text
            // If the input string is empty but the edit engine's existing
            // text is not empty, force update of the edit engine's text.
            // Otherwise, the edit engine will still to be set to its
            // existing text.
            // Note: CppunitTest_sc_macros_test testTdf116127 will fail if
            // pEditEngine->SetTextNewDefaults() is passed an empty string
            // and pEditEngine->GetText() is empty string.
            if (!aText.isEmpty() || pEditEngine->HasText())
                pEditEngine->SetTextNewDefaults(aText, std::move(aDefaults));
            else
                pEditEngine->SetDefaults(std::move(aDefaults));
        }
    }

    bDataValid = true;
    return pForwarder.get();
}

void ScCellTextData::UpdateData()
{
    if ( bDoUpdate )
    {
        OSL_ENSURE(pEditEngine != nullptr, "no EditEngine for UpdateData()");
        if ( pDocShell && pEditEngine )
        {
            //  during the own UpdateData call, bDataValid must not be reset,
            //  or things like attributes after the text would be lost
            //  (are not stored in the cell)
            bInUpdate = true;   // prevents bDataValid from being reset
            pDocShell->GetDocFunc().PutData(aCellPos, *pEditEngine, true); // always as text

            bInUpdate = false;
            bDirty = false;
        }
    }
    else
        bDirty = true;
}

void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
    const SfxHintId nId = rHint.GetId();
    if ( nId == SfxHintId::Dying )
    {
        pDocShell = nullptr;                       // invalid now

        pForwarder.reset();
        pEditEngine.reset();     // EditEngine uses document's pool
    }
    else if ( nId == SfxHintId::DataChanged )
    {
        if (!bInUpdate)                         // not for own UpdateData calls
            bDataValid = false;                 // text has to be read from the cell again
    }
}

ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
    ScCellTextData( pDocSh, rP ),
    SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
{
}

ScCellTextObj::~ScCellTextObj() COVERITY_NOEXCEPT_FALSE
{
}

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

Messung V0.5
C=93 H=97 G=94

¤ Dauer der Verarbeitung: 0.12 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.