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

Quelle  vbadocumentproperties.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 "vbadocumentproperties.hxx"
#include <cppuhelper/implbase.hxx>
#include <sal/log.hxx>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/XPropertyContainer.hpp>
#include <ooo/vba/word/WdBuiltInProperty.hpp>
#include <ooo/vba/office/MsoDocProperties.hpp>
#include <comphelper/diagnose_ex.hxx>
#include <memory>
#include "wordvbahelper.hxx"
#include <fesh.hxx>
#include <docsh.hxx>
#include <unotxdoc.hxx>
#include <utility>

using namespace ::ooo::vba;
using namespace css;

/// @throws lang::IllegalArgumentException
static sal_Int8 lcl_toMSOPropType( const uno::Type& aType )
{
    sal_Int16 msoType = office::MsoDocProperties::msoPropertyTypeString;

    switch ( aType.getTypeClass() )
    {
        case uno::TypeClass_BOOLEAN:
            msoType =  office::MsoDocProperties::msoPropertyTypeBoolean;
            break;
        case uno::TypeClass_FLOAT:
            msoType =  office::MsoDocProperties::msoPropertyTypeFloat;
            break;
        case uno::TypeClass_STRUCT: // Assume date
            msoType =  office::MsoDocProperties::msoPropertyTypeDate;
            break;
        case  uno::TypeClass_BYTE:
        case  uno::TypeClass_SHORT:
        case  uno::TypeClass_LONG:
        case  uno::TypeClass_HYPER:
            msoType =  office::MsoDocProperties::msoPropertyTypeNumber;
            break;
        default:
            throw lang::IllegalArgumentException();
    }
    return msoType;
}

namespace {

class PropertGetSetHelper
{
protected:
    rtl::Reference< SwXTextDocument > m_xModel;
    uno::Reference<document::XDocumentProperties> m_xDocProps;
public:
    explicit PropertGetSetHelper( rtl::Reference< SwXTextDocument > xModel ) : m_xModel(std::move( xModel ))
    {
        m_xDocProps.set(m_xModel->getDocumentProperties(), uno::UNO_SET_THROW);
    }
    virtual ~PropertGetSetHelper() {}
    virtual uno::Any getPropertyValue( const OUString& rPropName ) = 0;
    virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) = 0;
    uno::Reference< beans::XPropertySet > getUserDefinedProperties() {
        return uno::Reference<beans::XPropertySet>(
                m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
    }

};

class BuiltinPropertyGetSetHelper : public PropertGetSetHelper
{
public:
    explicit BuiltinPropertyGetSetHelper( const rtl::Reference< SwXTextDocument >& xModel ) :PropertGetSetHelper( xModel )
    {
    }
    virtual uno::Any getPropertyValue( const OUString& rPropName ) override
    {
        if ( rPropName == "EditingDuration" )
        {
            sal_Int32 const nSecs = m_xDocProps->getEditingDuration();
            return uno::Any( nSecs/60 ); // minutes
        }
        else if ("Title" == rPropName)
        {
            return uno::Any(m_xDocProps->getTitle());
        }
        else if ("Subject" == rPropName)
        {
            return uno::Any(m_xDocProps->getSubject());
        }
        else if ("Author" == rPropName)
        {
            return uno::Any(m_xDocProps->getAuthor());
        }
        else if ("Keywords" == rPropName)
        {
            return uno::Any(m_xDocProps->getKeywords());
        }
        else if ("Description" == rPropName)
        {
            return uno::Any(m_xDocProps->getDescription());
        }
        else if ("Template" == rPropName)
        {
            return uno::Any(m_xDocProps->getTemplateName());
        }
        else if ("ModifiedBy" == rPropName)
        {
            return uno::Any(m_xDocProps->getModifiedBy());
        }
        else if ("Generator" == rPropName)
        {
            return uno::Any(m_xDocProps->getGenerator());
        }
        else if ("PrintDate" == rPropName)
        {
            return uno::Any(m_xDocProps->getPrintDate());
        }
        else if ("CreationDate" == rPropName)
        {
            return uno::Any(m_xDocProps->getCreationDate());
        }
        else if ("ModifyDate" == rPropName)
        {
            return uno::Any(m_xDocProps->getModificationDate());
        }
        else if ("AutoloadURL" == rPropName)
        {
            return uno::Any(m_xDocProps->getAutoloadURL());
        }
        else
        {
            // fall back to user-defined properties
            return getUserDefinedProperties()->getPropertyValue(rPropName);
        }
    }
    virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override
    {
        if ("EditingDuration" == rPropName)
        {
            sal_Int32 nMins = 0;
            if (aValue >>= nMins)
            {
                m_xDocProps->setEditingDuration(nMins * 60); // convert minutes
            }
        }
        else if ("Title" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                m_xDocProps->setTitle(str);
            }
        }
        else if ("Subject" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                m_xDocProps->setSubject(str);
            }
        }
        else if ("Author" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                m_xDocProps->setAuthor(str);
            }
        }
        else if ("Keywords" == rPropName)
        {
            uno::Sequence<OUString> keywords;
            if (aValue >>= keywords)
            {
                m_xDocProps->setKeywords(keywords);
            }
        }
        else if ("Description" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                m_xDocProps->setDescription(str);
            }
        }
        else if ("Template" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                m_xDocProps->setTemplateName(str);
            }
        }
        else if ("ModifiedBy" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                m_xDocProps->setModifiedBy(str);
            }
        }
        else if ("Generator" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                return m_xDocProps->setGenerator(str);
            }
        }
        else if ("PrintDate" == rPropName)
        {
            util::DateTime dt;
            if (aValue >>= dt)
            {
                m_xDocProps->setPrintDate(dt);
            }
        }
        else if ("CreationDate" == rPropName)
        {
            util::DateTime dt;
            if (aValue >>= dt)
            {
                m_xDocProps->setCreationDate(dt);
            }
        }
        else if ("ModifyDate" == rPropName)
        {
            util::DateTime dt;
            if (aValue >>= dt)
            {
                m_xDocProps->setModificationDate(dt);
            }
        }
        else if ("AutoloadURL" == rPropName)
        {
            OUString str;
            if (aValue >>= str)
            {
                m_xDocProps->setAutoloadURL(str);
            }
        }
        else
        {
            // fall back to user-defined properties
            getUserDefinedProperties()->setPropertyValue(rPropName, aValue);
        }
    }
};

class CustomPropertyGetSetHelper : public BuiltinPropertyGetSetHelper
{
public:
    explicit CustomPropertyGetSetHelper( const rtl::Reference< SwXTextDocument >& xModel ) :BuiltinPropertyGetSetHelper( xModel )
    {
    }
    virtual uno::Any getPropertyValue( const OUString& rPropName ) override
    {
        return getUserDefinedProperties()->getPropertyValue(rPropName);
    }
    virtual void setPropertyValue(
            const OUString& rPropName, const uno::Any& rValue) override
    {
        return getUserDefinedProperties()->setPropertyValue(rPropName, rValue);
    }
};

class StatisticPropertyGetSetHelper : public PropertGetSetHelper
{
    SwDocShell* mpDocShell;
public:
    explicit StatisticPropertyGetSetHelper( const rtl::Reference< SwXTextDocument >& xModel ) :PropertGetSetHelper( xModel ) , mpDocShell( nullptr )
    {
        mpDocShell = m_xModel->GetDocShell();
    }
    virtual uno::Any getPropertyValue( const OUString& rPropName ) override
    {
        try
        {
            // Characters, ParagraphCount & WordCount are available from
            // the model ( and additionally these also update the statics object )
            return m_xModel->getPropertyValue( rPropName );
        }
        catch (const uno::Exception&)
        {
            TOOLS_WARN_EXCEPTION("sw.vba""");
        }
        uno::Any aReturn;
        if ( rPropName == "LineCount" ) // special processing needed
        {
            if ( mpDocShell )
            {
                if (SwFEShell* pFEShell = mpDocShell->GetFEShell())
                    aReturn <<= pFEShell->GetLineCount();
            }
        }
        else
        {
            uno::Sequence< beans::NamedValue > const stats(
                m_xDocProps->getDocumentStatistics());

            auto pStat = std::find_if(stats.begin(), stats.end(),
                [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; });
            if (pStat == stats.end())
                throw uno::RuntimeException(); // bad Property

            aReturn = pStat->Value;
        }
        return aReturn;
    }

    virtual void setPropertyValue( const OUString& rPropName, const uno::Any& aValue ) override
    {
        uno::Sequence< beans::NamedValue > stats(
                m_xDocProps->getDocumentStatistics());

        auto [begin, end] = asNonConstRange(stats);
        auto pStat = std::find_if(begin, end,
            [&rPropName](const beans::NamedValue& rStat) { return rPropName == rStat.Name; });
        if (pStat != end)
        {
            pStat->Value = aValue;
            m_xDocProps->setDocumentStatistics(stats);
        }
    }
};

class DocPropInfo
{
public:
    OUString msMSODesc;
    OUString msOOOPropName;
    std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;

    static DocPropInfo createDocPropInfo( const OUString& sDesc, const OUString& sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
    {
        DocPropInfo aItem;
        aItem.msMSODesc = sDesc;
        aItem.msOOOPropName = sPropName;
        aItem.mpPropGetSetHelper = rHelper;
        return aItem;
    }

    static DocPropInfo createDocPropInfo( const char* sDesc, const char* sPropName, std::shared_ptr< PropertGetSetHelper > const & rHelper )
    {
        return createDocPropInfo( OUString::createFromAscii( sDesc ), OUString::createFromAscii( sPropName ), rHelper );
    }
    uno::Any getValue()
    {
        if ( mpPropGetSetHelper )
            return mpPropGetSetHelper->getPropertyValue( msOOOPropName );
        return uno::Any();
    }
    void setValue( const uno::Any& rValue )
    {
        if ( mpPropGetSetHelper )
            mpPropGetSetHelper->setPropertyValue( msOOOPropName, rValue );
    }
    uno::Reference< beans::XPropertySet > getUserDefinedProperties()
    {
        uno::Reference< beans::XPropertySet > xProps;
        if ( mpPropGetSetHelper )
            return mpPropGetSetHelper->getUserDefinedProperties();
        return xProps;
    }
};

}

typedef std::unordered_map< sal_Int32, DocPropInfo > MSOIndexToOODocPropInfo;

namespace {

class BuiltInIndexHelper
{
    MSOIndexToOODocPropInfo m_docPropInfoMap;

public:
    explicit BuiltInIndexHelper( const rtl::Reference< SwXTextDocument >& xModel )
    {
        auto aStandardHelper = std::make_shared<BuiltinPropertyGetSetHelper>( xModel );
        auto aUsingStatsHelper = std::make_shared<StatisticPropertyGetSetHelper>( xModel );

        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTitle ] = DocPropInfo::createDocPropInfo( "Title""Title", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySubject ] = DocPropInfo::createDocPropInfo( "Subject""Subject", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAuthor ] = DocPropInfo::createDocPropInfo( "Author""Author", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyKeywords ] = DocPropInfo::createDocPropInfo( "Keywords""Keywords", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyComments ] = DocPropInfo::createDocPropInfo( "Comments""Description", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTemplate ] = DocPropInfo::createDocPropInfo( "Template""Template", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLastAuthor ] = DocPropInfo::createDocPropInfo( "Last author""ModifiedBy", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyRevision ] = DocPropInfo::createDocPropInfo( "Revision number""EditingCycles", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyAppName ] = DocPropInfo::createDocPropInfo( "Application name""Generator", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastPrinted ] = DocPropInfo::createDocPropInfo( "Last print date""PrintDate", aStandardHelper ); // doesn't seem to exist - throw or return nothing ?
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeCreated ] = DocPropInfo::createDocPropInfo( "Creation date""CreationDate", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyTimeLastSaved ] = DocPropInfo::createDocPropInfo( "Last save time""ModifyDate", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyVBATotalEdit ] = DocPropInfo::createDocPropInfo( "Total editing time""EditingDuration", aStandardHelper ); // Not sure if this is correct
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyPages ] = DocPropInfo::createDocPropInfo( "Number of pages""PageCount", aUsingStatsHelper ); // special handling required ?
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyWords ] = DocPropInfo::createDocPropInfo( "Number of words""WordCount", aUsingStatsHelper ); // special handling require ?
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharacters ] = DocPropInfo::createDocPropInfo( "Number of characters""CharacterCount", aUsingStatsHelper ); // special handling required ?
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySecurity ] = DocPropInfo::createDocPropInfo( "Security""", aStandardHelper ); // doesn't seem to exist
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCategory ] = DocPropInfo::createDocPropInfo( "Category""Category", aStandardHelper ); // hacked in
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyFormat ] = DocPropInfo::createDocPropInfo( "Format""", aStandardHelper ); // doesn't seem to exist
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyManager ] = DocPropInfo::createDocPropInfo( "Manager""Manager", aStandardHelper ); // hacked in
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCompany ] = DocPropInfo::createDocPropInfo( "Company""Company", aStandardHelper ); // hacked in
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyBytes ] = DocPropInfo::createDocPropInfo( "Number of bytes""", aStandardHelper ); // doesn't seem to exist - size on disk exists ( for an already saved document ) perhaps it will do ( or we need something else )
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyLines ] = DocPropInfo::createDocPropInfo( "Number of lines""LineCount", aUsingStatsHelper ); // special handling
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyParas ] = DocPropInfo::createDocPropInfo( "Number of paragraphs""ParagraphCount", aUsingStatsHelper ); // special handling
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertySlides ] = DocPropInfo::createDocPropInfo( "Number of slides""" , aStandardHelper ); // doesn't seem to exist
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyNotes ] = DocPropInfo::createDocPropInfo( "Number of notes""", aStandardHelper ); // doesn't seem to exist
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHiddenSlides ] = DocPropInfo::createDocPropInfo("Number of hidden Slides""", aStandardHelper  ); // doesn't seem to exist
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyMMClips ] = DocPropInfo::createDocPropInfo( "Number of multimedia clips""", aStandardHelper ); // doesn't seem to exist
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyHyperlinkBase ] = DocPropInfo::createDocPropInfo( "Hyperlink base""AutoloadURL", aStandardHelper );
        m_docPropInfoMap[ word::WdBuiltInProperty::wdPropertyCharsWSpaces ] = DocPropInfo::createDocPropInfo( "Number of characters (with spaces)""", aStandardHelper ); // doesn't seem to be supported
    }

    MSOIndexToOODocPropInfo& getDocPropInfoMap() { return m_docPropInfoMap; }
};

}

typedef InheritedHelperInterfaceWeakImpl< ooo::vba::XDocumentProperty > SwVbaDocumentProperty_BASE;

namespace {

class SwVbaBuiltInDocumentProperty : public SwVbaDocumentProperty_BASE
{
protected:
    DocPropInfo mPropInfo;
public:
    SwVbaBuiltInDocumentProperty(  const uno::Reference< ov::XHelperInterface >& xParentconst uno::Reference< uno::XComponentContext >& xContext, DocPropInfo  rInfo );
    // XDocumentProperty
    virtual void SAL_CALL Delete(  ) override;
    virtual OUString SAL_CALL getName(  ) override;
    virtual void SAL_CALL setName( const OUString& Name ) override;
    virtual ::sal_Int8 SAL_CALL getType(  ) override;
    virtual void SAL_CALL setType( ::sal_Int8 Type ) override;
    virtual sal_Bool SAL_CALL getLinkToContent(  ) override;
    virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;
    virtual uno::Any SAL_CALL getValue(  ) override;
    virtual void SAL_CALL setValue( const uno::Any& Value ) override;
    virtual OUString SAL_CALL getLinkSource(  ) override;
    virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
    //XDefaultProperty
    virtual OUString SAL_CALL getDefaultPropertyName(  ) override { return u"Value"_ustr; }
    // XHelperInterface
    virtual OUString getServiceImplName() override;
    virtual uno::Sequence<OUString> getServiceNames() override;
};

class SwVbaCustomDocumentProperty : public SwVbaBuiltInDocumentProperty
{
public:

    SwVbaCustomDocumentProperty(  const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo );

    virtual sal_Bool SAL_CALL getLinkToContent(  ) override;
    virtual void SAL_CALL setLinkToContent( sal_Bool LinkToContent ) override;

    virtual OUString SAL_CALL getLinkSource(  ) override;
    virtual void SAL_CALL setLinkSource( const OUString& LinkSource ) override;
    virtual void SAL_CALL Delete(  ) override;
    virtual void SAL_CALL setName( const OUString& Name ) override;
    virtual void SAL_CALL setType( ::sal_Int8 Type ) override;

};

}

SwVbaCustomDocumentProperty::SwVbaCustomDocumentProperty(  const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const DocPropInfo& rInfo ) : SwVbaBuiltInDocumentProperty( xParent, xContext, rInfo )
{
}

sal_Bool
SwVbaCustomDocumentProperty::getLinkToContent(  )
{
    // #FIXME we need to store the link content somewhere
    return false;
}

void
SwVbaCustomDocumentProperty::setLinkToContent( sal_Bool /*bLinkContent*/ )
{
}

OUString
SwVbaCustomDocumentProperty::getLinkSource(  )
{
    // #FIXME we need to store the link content somewhere
    return OUString();
}

void
SwVbaCustomDocumentProperty::setLinkSource( const OUString& /*rsLinkContent*/ )
{
    // #FIXME we need to store the link source somewhere
}

void SAL_CALL
SwVbaCustomDocumentProperty::setName( const OUString& /*Name*/ )
{
    // setName on existing property ?
    // #FIXME
    // do we need to delete existing property and create a new one?
}

void SAL_CALL
SwVbaCustomDocumentProperty::setType( ::sal_Int8 /*Type*/ )
{
    // setType, do we need to do a conversion?
    // #FIXME the underlying value needs to be changed to the new type
}

void SAL_CALL
SwVbaCustomDocumentProperty::Delete(  )
{
    uno::Reference< beans::XPropertyContainer > xContainer(
            mPropInfo.getUserDefinedProperties(), uno::UNO_QUERY_THROW);
    xContainer->removeProperty( getName() );
}

SwVbaBuiltInDocumentProperty::SwVbaBuiltInDocumentProperty( const uno::Reference< ov::XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, DocPropInfo  rInfo ) : SwVbaDocumentProperty_BASE( xParent, xContext ), mPropInfo(std::move( rInfo ))
{
}

void SAL_CALL
SwVbaBuiltInDocumentProperty::Delete(  )
{
    // not valid for Builtin
    throw uno::RuntimeException();
}

OUString SAL_CALL
SwVbaBuiltInDocumentProperty::getName(  )
{
    return mPropInfo.msMSODesc;
}

void SAL_CALL
SwVbaBuiltInDocumentProperty::setName( const OUString& )
{
    // not valid for Builtin
    throw uno::RuntimeException();
}

::sal_Int8 SAL_CALL
SwVbaBuiltInDocumentProperty::getType(  )
{
    return lcl_toMSOPropType( getValue().getValueType() );
}

void SAL_CALL
SwVbaBuiltInDocumentProperty::setType( ::sal_Int8 /*Type*/ )
{
    // not valid for Builtin
    throw uno::RuntimeException();
}

sal_Bool SAL_CALL
SwVbaBuiltInDocumentProperty::getLinkToContent(  )
{
    return false// built-in always false
}

void SAL_CALL
SwVbaBuiltInDocumentProperty::setLinkToContent( sal_Bool /*LinkToContent*/ )
{
    // not valid for Builtin
    throw uno::RuntimeException();
}

uno::Any SAL_CALL
SwVbaBuiltInDocumentProperty::getValue(  )
{
    uno::Any aRet = mPropInfo.getValue();
    if ( !aRet.hasValue() )
        throw uno::RuntimeException();
    return aRet;
}

void SAL_CALL
SwVbaBuiltInDocumentProperty::setValue( const uno::Any& Value )
{
    mPropInfo.setValue( Value );
}

OUString SAL_CALL
SwVbaBuiltInDocumentProperty::getLinkSource(  )
{
    // not valid for Builtin
    throw uno::RuntimeException();
}

void SAL_CALL
SwVbaBuiltInDocumentProperty::setLinkSource( const OUString& /*LinkSource*/ )
{
    // not valid for Builtin
    throw uno::RuntimeException();
}

OUString
SwVbaBuiltInDocumentProperty::getServiceImplName()
{
    return u"SwVbaBuiltinDocumentProperty"_ustr;
}

uno::Sequence<OUString>
SwVbaBuiltInDocumentProperty::getServiceNames()
{
    static uno::Sequence< OUString > const aServiceNames
    {
        u"ooo.vba.word.DocumentProperty"_ustr
    };
    return aServiceNames;
}
typedef ::cppu::WeakImplHelper< css::container::XIndexAccess
        ,css::container::XNameAccess
        ,css::container::XEnumerationAccess
        > PropertiesImpl_BASE;

typedef std::unordered_map< sal_Int32, uno::Reference< XDocumentProperty > > DocProps;

namespace {

class DocPropEnumeration : public ::cppu::WeakImplHelper< css::container::XEnumeration >
{
    DocProps mDocProps;
    DocProps::iterator mIt;
public:

    explicit DocPropEnumeration( DocProps&& rProps ) : mDocProps( std::move(rProps) ), mIt( mDocProps.begin() ) {}
    virtual sal_Bool SAL_CALL hasMoreElements(  ) override
    {
        return mIt != mDocProps.end();
    }
    virtual uno::Any SAL_CALL nextElement(  ) override
    {
        if ( !hasMoreElements() )
            throw container::NoSuchElementException();
        return uno::Any( mIt++->second );
    }
};

}

typedef std::unordered_map< OUString, uno::Reference< XDocumentProperty > > DocPropsByName;

namespace {

class BuiltInPropertiesImpl : public PropertiesImpl_BASE
{
protected:

    rtl::Reference< SwXTextDocument > m_xModel;

    DocProps mDocProps;
    DocPropsByName mNamedDocProps;

    public:
    BuiltInPropertiesImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, rtl::Reference< SwXTextDocument >  xModel ) : m_xModel(std::move( xModel ))
    {
        BuiltInIndexHelper builtIns( m_xModel );
        for ( sal_Int32 index = word::WdBuiltInProperty::wdPropertyTitle; index <= word::WdBuiltInProperty::wdPropertyCharsWSpaces; ++index )
        {
            mDocProps[ index ] = new SwVbaBuiltInDocumentProperty( xParent, xContext, builtIns.getDocPropInfoMap()[ index ] );
            mNamedDocProps[ mDocProps[ index ]->getName() ] = mDocProps[ index ];
        }
    }
// XIndexAccess
    virtual ::sal_Int32 SAL_CALL getCount(  ) override
    {
        return mDocProps.size();
    }
    virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
    {
        // correct the correct by the base class for 1 based indices
        DocProps::iterator it = mDocProps.find( ++Index );
        if ( it == mDocProps.end() )
            throw lang::IndexOutOfBoundsException();
        return uno::Any( it->second  );
    }
    virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
    {
        if ( !hasByName( aName ) )
            throw container::NoSuchElementException();
        DocPropsByName::iterator it = mNamedDocProps.find( aName );
        return uno::Any( it->second );

    }
    virtual uno::Sequence< OUString > SAL_CALL getElementNames(  ) override
    {
        uno::Sequence< OUString > aNames( getCount() );
        OUString* pName = aNames.getArray();
        for (const auto& rEntry : mNamedDocProps)
        {
           *pName = rEntry.first;
           ++pName;
        }
        return aNames;
    }

    virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
    {
        DocPropsByName::iterator it = mNamedDocProps.find( aName );
        if ( it == mNamedDocProps.end() )
            return false;
        return true;
    }
// XElementAccess
    virtual uno::Type SAL_CALL getElementType(  ) override
    {
        return  cppu::UnoType<XDocumentProperty>::get();
    }
    virtual sal_Bool SAL_CALL hasElements(  ) override
    {
        return !mDocProps.empty();
    }
    virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration(  ) override
    {
        return new DocPropEnumeration( std::unordered_map(mDocProps) );
    }
};

}

SwVbaBuiltinDocumentProperties::SwVbaBuiltinDocumentProperties(
    const uno::Reference< XHelperInterface >& xParent,
    const uno::Reference< uno::XComponentContext >& xContext,
    const rtl::Reference< SwXTextDocument >& xModel )
: SwVbaDocumentproperties_BASE( xParent, xContext,  uno::Reference< container::XIndexAccess >( new BuiltInPropertiesImpl( xParent, xContext, xModel ) ) )
{
}

uno::Reference< XDocumentProperty > SAL_CALL
SwVbaBuiltinDocumentProperties::Add( const OUString& /*Name*/, sal_Bool /*LinkToContent*/, ::sal_Int8 /*Type*/, const uno::Any& /*value*/, const uno::Any& /*LinkSource*/ )
{
    throw uno::RuntimeException( u"not supported for Builtin properties"_ustr );
}

// XEnumerationAccess
uno::Type SAL_CALL
SwVbaBuiltinDocumentProperties::getElementType()
{
    return  cppu::UnoType<XDocumentProperty>::get();
}

uno::Reference< container::XEnumeration > SAL_CALL
SwVbaBuiltinDocumentProperties::createEnumeration()
{
    uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW );
    return xEnumAccess->createEnumeration();
}

// ScVbaCollectionBaseImpl
uno::Any
SwVbaBuiltinDocumentProperties::createCollectionObject( const uno::Any& aSource )
{
    // pass through
    return aSource;
}

// XHelperInterface
OUString
SwVbaBuiltinDocumentProperties::getServiceImplName()
{
    return u"SwVbaBuiltinDocumentProperties"_ustr;
}

uno::Sequence<OUString>
SwVbaBuiltinDocumentProperties::getServiceNames()
{
    static uno::Sequence< OUString > const aServiceNames
    {
        u"ooo.vba.word.DocumentProperties"_ustr
    };
    return aServiceNames;
}

namespace {

class CustomPropertiesImpl : public PropertiesImpl_BASE
{
    uno::Reference< XHelperInterface > m_xParent;
    uno::Reference< uno::XComponentContext > m_xContext;
    rtl::Reference< SwXTextDocument > m_xModel;
    uno::Reference< beans::XPropertySet > mxUserDefinedProp;
    std::shared_ptr< PropertGetSetHelper > mpPropGetSetHelper;
public:
    CustomPropertiesImpl( uno::Reference< XHelperInterface > xParent,
                          uno::Reference< uno::XComponentContext > xContext,
                          rtl::Reference< SwXTextDocument >  xModel )
        : m_xParent(std::move( xParent )),
          m_xContext(std::move( xContext )),
          m_xModel(std::move( xModel ))
    {
        // suck in the document( custom ) properties
        mpPropGetSetHelper = std::make_shared<CustomPropertyGetSetHelper>( m_xModel );
        mxUserDefinedProp.set(mpPropGetSetHelper->getUserDefinedProperties(),
                uno::UNO_SET_THROW);
    };
    // XIndexAccess
    virtual ::sal_Int32 SAL_CALL getCount(  ) override
    {
        return mxUserDefinedProp->getPropertySetInfo()->getProperties().getLength();
    }

    virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
    {
        uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
        if ( Index >= aProps.getLength() )
            throw lang::IndexOutOfBoundsException();
        // How to determine type e.g Date? ( com.sun.star.util.DateTime )
        DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aProps[ Index ].Name, aProps[ Index ].Name, mpPropGetSetHelper );
        return uno::Any( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
    }

    virtual uno::Any SAL_CALL getByName( const OUString& aName ) override
    {
        if ( !hasByName( aName ) )
            throw container::NoSuchElementException();

        DocPropInfo aPropInfo = DocPropInfo::createDocPropInfo( aName, aName, mpPropGetSetHelper );
        return uno::Any( uno::Reference< XDocumentProperty >( new SwVbaCustomDocumentProperty( m_xParent, m_xContext, aPropInfo ) ) );
    }

    virtual uno::Sequence< OUString > SAL_CALL getElementNames(  ) override
    {
        const uno::Sequence< beans::Property > aProps = mxUserDefinedProp->getPropertySetInfo()->getProperties();
        uno::Sequence< OUString > aNames( aProps.getLength() );
        std::transform(aProps.begin(), aProps.end(), aNames.getArray(),
            [](const beans::Property& rProp) -> OUString { return rProp.Name; });
        return aNames;
    }

    virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
    {
        SAL_INFO("sw.vba""hasByName(" << aName << ") returns " << mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName ) );
        return mxUserDefinedProp->getPropertySetInfo()->hasPropertyByName( aName );
    }

    // XElementAccess
    virtual uno::Type SAL_CALL getElementType(  ) override
    {
        return  cppu::UnoType<XDocumentProperty>::get();
    }

    virtual sal_Bool SAL_CALL hasElements(  ) override
    {
        return getCount() > 0;
    }

    virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration(  ) override
    {
        // create a map of properties ( the key doesn't matter )
        SAL_INFO("sw.vba""Creating an enumeration");
        sal_Int32 key = 0;
        sal_Int32 nElem =  getCount();
        DocProps simpleDocPropSnapShot;
        for ( ; key < nElem; ++key )
             simpleDocPropSnapShot[ key ].set( getByIndex( key ), uno::UNO_QUERY_THROW );
        SAL_INFO("sw.vba""After creating the enumeration");
        return  new DocPropEnumeration( std::move(simpleDocPropSnapShot) );
    }

    void addProp( const OUString& Name, const uno::Any& Value )
    {
        uno::Reference< beans::XPropertyContainer > xContainer( mxUserDefinedProp, uno::UNO_QUERY_THROW );
        // TODO fixme, perform the necessary Type Value conversions
        xContainer->addProperty( Name, sal_Int16(128), Value );
    }

};

}

SwVbaCustomDocumentProperties::SwVbaCustomDocumentProperties( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const rtl::Reference< SwXTextDocument >& xModel ) : SwVbaBuiltinDocumentProperties( xParent, xContext, xModel )
{
    // replace the m_xIndexAccess implementation ( we need a virtual init )
    m_xIndexAccess.set( new CustomPropertiesImpl( xParent, xContext, xModel ) );
    m_xNameAccess.set( m_xIndexAccess, uno::UNO_QUERY_THROW );
}

uno::Reference< XDocumentProperty > SAL_CALL
SwVbaCustomDocumentProperties::Add( const OUString& Name, sal_Bool LinkToContent, ::sal_Int8 /*Type*/, const uno::Any& Value, const uno::Any& LinkSource )
{
    CustomPropertiesImpl* pCustomProps = dynamic_cast< CustomPropertiesImpl* > ( m_xIndexAccess.get() );
    uno::Reference< XDocumentProperty > xDocProp;
    if ( pCustomProps )
    {
        OUString sLinkSource;
        pCustomProps->addProp( Name, Value );

        xDocProp.set( m_xNameAccess->getByName( Name ), uno::UNO_QUERY_THROW );
        xDocProp->setLinkToContent( LinkToContent );

        if ( LinkSource >>= sLinkSource )
           xDocProp->setLinkSource( sLinkSource );
    }
    return xDocProp;
}

// XHelperInterface
OUString
SwVbaCustomDocumentProperties::getServiceImplName()
{
    return u"SwVbaCustomDocumentProperties"_ustr;
}

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

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

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