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

Quelle  linksrc.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 <sfx2/linksrc.hxx>
#include <sfx2/lnkbase.hxx>
#include <com/sun/star/uno/Any.hxx>

#include <utility>
#include <vcl/timer.hxx>
#include <memory>
#include <vector>
#include <algorithm>


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

namespace sfx2
{

namespace {

class SvLinkSourceTimer : public Timer
{
    SvLinkSource *  pOwner;
    virtual void    Invoke() override;
public:
    explicit SvLinkSourceTimer( SvLinkSource * pOwn );
};

}

SvLinkSourceTimer::SvLinkSourceTimer( SvLinkSource * pOwn )
    : Timer("sfx2 SvLinkSourceTimer"), pOwner( pOwn )
{
}

void SvLinkSourceTimer::Invoke()
{
    // Secure against being destroyed in Handler
    SvLinkSourceRef xHoldAlive( pOwner );
    pOwner->SendDataChanged();
}

static void StartTimer( std::unique_ptr<SvLinkSourceTimer>& pTimer, SvLinkSource * pOwner,
                        sal_uInt64 nTimeout )
{
    if( !pTimer )
    {
        pTimer.reset( new SvLinkSourceTimer( pOwner ) );
        pTimer->SetTimeout( nTimeout );
        pTimer->Start();
    }
}

namespace {

struct SvLinkSource_Entry_Impl
{
    tools::SvRef<SvBaseLink>  xSink;
    OUString                  aDataMimeType;
    sal_uInt16                nAdviseModes;
    bool                      bIsDataSink;

    SvLinkSource_Entry_Impl( SvBaseLink* pLink, OUString aMimeType,
                                sal_uInt16 nAdvMode )
        : xSink( pLink ), aDataMimeType(std::move( aMimeType )),
            nAdviseModes( nAdvMode ), bIsDataSink( true )
    {}

    explicit SvLinkSource_Entry_Impl( SvBaseLink* pLink )
        : xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( false )
    {}
};

class SvLinkSource_Array_Impl
{
friend class SvLinkSource_EntryIter_Impl;
private:
    std::vector<std::unique_ptr<SvLinkSource_Entry_Impl>> mvData;

public:
    SvLinkSource_Array_Impl() {}

    size_t size() const { return mvData.size(); }
    SvLinkSource_Entry_Impl *operator[](size_t idx) const { return mvData[idx].get(); }
    void push_back(SvLinkSource_Entry_Impl* rData) { mvData.emplace_back(rData); }

    void DeleteAndDestroy(SvLinkSource_Entry_Impl const * p)
    {
        auto it = std::find_if(mvData.begin(), mvData.end(),
            [&p](const std::unique_ptr<SvLinkSource_Entry_Impl>& rxData) { return rxData.get() == p; });
        if (it != mvData.end())
            mvData.erase(it);
    }
};

class SvLinkSource_EntryIter_Impl
{
    std::vector<SvLinkSource_Entry_Impl*> aArr;
    const SvLinkSource_Array_Impl& rOrigArr;
    sal_uInt16 nPos;
public:
    explicit SvLinkSource_EntryIter_Impl( const SvLinkSource_Array_Impl& rArr );
    SvLinkSource_Entry_Impl* Curr()
                            { return nPos < aArr.size() ? aArr[ nPos ] : nullptr; }
    SvLinkSource_Entry_Impl* Next();
    bool IsValidCurrValue( SvLinkSource_Entry_Impl const * pEntry );
};

}

SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl(
        const SvLinkSource_Array_Impl& rArr )
    : rOrigArr( rArr ), nPos( 0 )
{
    for (auto const & i : rArr.mvData)
        aArr.push_back(i.get());
}

bool SvLinkSource_EntryIter_Impl::IsValidCurrValue( SvLinkSource_Entry_Impl const * pEntry )
{
    if ( nPos >= aArr.size() )
        return false;
    if (aArr[nPos] != pEntry)
        return false;
    for (auto const & i : rOrigArr.mvData)
        if (i.get() == pEntry)
            return true;
    return false;
}

SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next()
{
    SvLinkSource_Entry_Impl* pRet = nullptr;
    if( nPos + 1 < static_cast<sal_uInt16>(aArr.size()) )
    {
        ++nPos;
        if( rOrigArr.size() == aArr.size() &&
            rOrigArr[ nPos ] == aArr[ nPos ] )
            pRet = aArr[ nPos ];
        else
        {
            // then we must search the current (or the next) in the orig
            do {
                pRet = aArr[ nPos ];
                for (auto const & i : rOrigArr.mvData)
                    if (i.get() == pRet)
                        return pRet;
                pRet = nullptr;
                ++nPos;
            } while( nPos < aArr.size() );

            if( nPos >= aArr.size() )
                pRet = nullptr;
        }
    }
    return pRet;
}

struct SvLinkSource_Impl
{
    SvLinkSource_Array_Impl aArr;
    OUString                aDataMimeType;
    std::unique_ptr<SvLinkSourceTimer>
                            pTimer;
    sal_uInt64              nTimeout;
    css::uno::Reference<css::io::XInputStream>
                            m_xInputStreamToLoadFrom;
    bool                    m_bIsReadOnly;

    SvLinkSource_Impl()
        : nTimeout(3000)
        , m_bIsReadOnly(false)
    {
    }
};

SvLinkSource::SvLinkSource()
     : pImpl( new SvLinkSource_Impl )
{
}

SvLinkSource::~SvLinkSource()
{
}


SvLinkSource::StreamToLoadFrom SvLinkSource::getStreamToLoadFrom()
{
    return StreamToLoadFrom(
        pImpl->m_xInputStreamToLoadFrom,
        pImpl->m_bIsReadOnly);
}

void SvLinkSource::setStreamToLoadFrom(const css::uno::Reference<css::io::XInputStream>& xInputStream, bool bIsReadOnly )
{
    pImpl->m_xInputStreamToLoadFrom = xInputStream;
    pImpl->m_bIsReadOnly = bIsReadOnly;
}

// #i88291#
void SvLinkSource::clearStreamToLoadFrom()
{
    pImpl->m_xInputStreamToLoadFrom.clear();
}

void  SvLinkSource::Closed()
{
    SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
    for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
        if( !p->bIsDataSink )
            p->xSink->Closed();
}

sal_uInt64 SvLinkSource::GetUpdateTimeout() const
{
    return pImpl->nTimeout;
}

void SvLinkSource::SetUpdateTimeout( sal_uInt64 nTimeout )
{
    pImpl->nTimeout = nTimeout;
    if( pImpl->pTimer )
        pImpl->pTimer->SetTimeout( nTimeout );
}

void SvLinkSource::SendDataChanged()
{
    SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
    for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
    {
        if( p->bIsDataSink )
        {
            OUString sDataMimeType( pImpl->aDataMimeType );
            if( sDataMimeType.isEmpty() )
                sDataMimeType = p->aDataMimeType;

            Any aVal;
            if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
                GetData( aVal, sDataMimeType, true ) )
            {
                p->xSink->DataChanged( sDataMimeType, aVal );

                if ( !aIter.IsValidCurrValue( p ) )
                    continue;

                if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
                {
                    pImpl->aArr.DeleteAndDestroy( p );
                }

            }
        }
    }
    pImpl->pTimer.reset();
    pImpl->aDataMimeType.clear();
}

void SvLinkSource::NotifyDataChanged()
{
    if( pImpl->nTimeout )
        StartTimer( pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
    else
    {
        SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
        for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
            if( p->bIsDataSink )
            {
                Any aVal;
                if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
                    GetData( aVal, p->aDataMimeType, true ) )
                {
                    tools::SvRef<sfx2::SvBaseLink> xLink(p->xSink);
                    xLink->DataChanged( p->aDataMimeType, aVal );

                    if ( !aIter.IsValidCurrValue( p ) )
                        continue;

                    if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
                    {
                        pImpl->aArr.DeleteAndDestroy( p );
                    }
                }
            }

        pImpl->pTimer.reset();
    }
}

// notify the sink, the mime type is not
// a selection criterion
void SvLinkSource::DataChanged( const OUString & rMimeType,
                                const css::uno::Any & rVal )
{
    if( pImpl->nTimeout && !rVal.hasValue() )
    {   // only when no data was included
        // fire all data to the sink, independent of the requested format
        pImpl->aDataMimeType = rMimeType;
        StartTimer( pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
    }
    else
    {
        SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
        for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
        {
            if( p->bIsDataSink )
            {
                p->xSink->DataChanged( rMimeType, rVal );

                if ( !aIter.IsValidCurrValue( p ) )
                    continue;

                if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
                {
                    pImpl->aArr.DeleteAndDestroy( p );
                }
            }
        }

        pImpl->pTimer.reset();
    }
}


// only one link is correct
void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const OUString& rMimeType,
                                    sal_uInt16 nAdviseModes )
{
    SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl(
                    pLink, rMimeType, nAdviseModes );
    pImpl->aArr.push_back( pNew );
}

void SvLinkSource::RemoveAllDataAdvise( SvBaseLink const * pLink )
{
    SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
    for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
        if( p->bIsDataSink && p->xSink.get() == pLink )
        {
            pImpl->aArr.DeleteAndDestroy( p );
        }
}

// only one link is correct
void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink )
{
    SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl( pLink );
    pImpl->aArr.push_back( pNew );
}

void SvLinkSource::RemoveConnectAdvise( SvBaseLink const * pLink )
{
    SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
    for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
        if( !p->bIsDataSink && p->xSink.get() == pLink )
        {
            pImpl->aArr.DeleteAndDestroy( p );
        }
}

bool SvLinkSource::HasDataLinks() const
{
    bool bRet = false;
    for( sal_uInt16 n = 0, nEnd = pImpl->aArr.size(); n < nEnd; ++n )
        if( pImpl->aArr[ n ]->bIsDataSink )
        {
            bRet = true;
            break;
        }
    return bRet;
}

// sal_True => waitinmg for data
bool SvLinkSource::IsPending() const
{
    return false;
}

// sal_True => data complete loaded
bool SvLinkSource::IsDataComplete() const
{
    return true;
}

bool SvLinkSource::Connect( SvBaseLink* )
{
    return true;
}

bool SvLinkSource::GetData( css::uno::Any &, const OUString &, bool )
{
    return false;
}

void SvLinkSource::Edit(weld::Window *, SvBaseLink *, const Link<const OUString&, void>&)
{
}

}

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

Messung V0.5
C=94 H=95 G=94

¤ 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.