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

Quelle  docinf.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/docinf.hxx>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertyContainer.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
#include <com/sun/star/document/XCompatWriterDocProperties.hpp>
#include <com/sun/star/uno/Exception.hpp>
#include <rtl/ustring.hxx>
#include <sal/log.hxx>
#include <tools/debug.hxx>
#include <comphelper/string.hxx>
#include <sot/storage.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/gdimtf.hxx>
#include <vcl/dibtools.hxx>
#include "oleprops.hxx"


// stream names
constexpr OUString STREAM_SUMMARYINFO = u"\005SummaryInformation"_ustr;
constexpr OUString STREAM_DOCSUMMARYINFO = u"\005DocumentSummaryInformation"_ustr;

// usings
using namespace ::com::sun::star;


namespace sfx2 {

ErrCode LoadOlePropertySet(
    const uno::Reference< document::XDocumentProperties>& i_xDocProps,
    SotStorage* i_pStorage )
{
    // *** global properties from stream "005SummaryInformation" ***

    // load the property set
    SfxOlePropertySet aGlobSet;
    ErrCode nGlobError = aGlobSet.LoadPropertySet(i_pStorage,
        STREAM_SUMMARYINFO );

    // global section
    SfxOleSectionRef xGlobSect = aGlobSet.GetSection( SECTION_GLOBAL );
    if( xGlobSect )
    {
        // set supported properties
        OUString aStrValue;
        util::DateTime aDateTime;

        if( xGlobSect->GetStringValue( aStrValue, PROPID_TITLE ) )
            i_xDocProps->setTitle( aStrValue );
        if( xGlobSect->GetStringValue( aStrValue, PROPID_SUBJECT ) )
            i_xDocProps->setSubject( aStrValue );
        if( xGlobSect->GetStringValue( aStrValue, PROPID_KEYWORDS ) ) {
            i_xDocProps->setKeywords(
                ::comphelper::string::convertCommaSeparated(aStrValue) );
        }
        if( xGlobSect->GetStringValue( aStrValue, PROPID_TEMPLATE ) )
            i_xDocProps->setTemplateName( aStrValue );
        if( xGlobSect->GetStringValue( aStrValue, PROPID_COMMENTS ) )
            i_xDocProps->setDescription( aStrValue );

        util::DateTime aInvalid;
        if( xGlobSect->GetStringValue( aStrValue, PROPID_AUTHOR) )
            i_xDocProps->setAuthor( aStrValue );
        else
            i_xDocProps->setAuthor( OUString() );
        if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_CREATED ) )
            i_xDocProps->setCreationDate( aDateTime );
        else
            i_xDocProps->setCreationDate( aInvalid );

        if( xGlobSect->GetStringValue( aStrValue, PROPID_LASTAUTHOR) )
            i_xDocProps->setModifiedBy( aStrValue );
        else
            i_xDocProps->setModifiedBy( OUString() );
        if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_LASTSAVED ) )
            i_xDocProps->setModificationDate( aDateTime );
        else
            i_xDocProps->setModificationDate( aInvalid );

        i_xDocProps->setPrintedBy( OUString() );
        if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_LASTPRINTED ) )
            i_xDocProps->setPrintDate( aDateTime );
        else
            i_xDocProps->setPrintDate( aInvalid );

        if( xGlobSect->GetStringValue( aStrValue, PROPID_REVNUMBER ) )
        {
            sal_Int16 nRevision = static_cast< sal_Int16 >( aStrValue.toInt32() );
            if ( nRevision > 0 )
                i_xDocProps->setEditingCycles( nRevision );
        }

        if( xGlobSect->GetFileTimeValue( aDateTime, PROPID_EDITTIME )
            && !(aDateTime.NanoSeconds == 0 && aDateTime.Seconds == 0
                 && aDateTime.Minutes == 0 && aDateTime.Hours == 0
                 && aDateTime.Day == 0 && aDateTime.Month == 0
                 && aDateTime.Year == 0) )
        {
            assert(aDateTime.Day <= 31);
            // subtract offset 1601-01-01
            aDateTime.Year  -= 1601;
            aDateTime.Month -= 1;
            aDateTime.Day   -= 1;
            try
            {
                i_xDocProps->setEditingDuration(
                    aDateTime.Day     * 60*60*24 +
                    aDateTime.Hours   * 60*60    +
                    aDateTime.Minutes * 60       +
                    aDateTime.Seconds            );
            }
            catch (const lang::IllegalArgumentException &)
            {
                // ignore
            }
        }
    }

    // *** custom properties from stream "005DocumentSummaryInformation" ***

    // load the property set
    SfxOlePropertySet aDocSet;
    ErrCode nDocError = aDocSet.LoadPropertySet(i_pStorage,
        STREAM_DOCSUMMARYINFO );

    // custom properties
    SfxOleSectionRef xCustomSect = aDocSet.GetSection( SECTION_CUSTOM );
    if( xCustomSect )
    {
        uno::Reference < beans::XPropertyContainer > xUserDefined(
            i_xDocProps->getUserDefinedProperties(), uno::UNO_SET_THROW);
        ::std::vector< sal_Int32 > aPropIds;
        xCustomSect->GetPropertyIds( aPropIds );
        forconst auto& rPropId : aPropIds )
        {
            const OUString aPropName = xCustomSect->GetPropertyName( rPropId );
            uno::Any aPropValue = xCustomSect->GetAnyValue( rPropId );
            if( !aPropName.isEmpty() && aPropValue.hasValue() )
            {
                try
                {
                    xUserDefined->addProperty( aPropName,
                        beans::PropertyAttribute::REMOVABLE, aPropValue );
                }
                catch (const uno::Exception&)
                {
                    //ignore
                }
            }
        }
    }

    uno::Reference< document::XCompatWriterDocProperties > xWriterProps( i_xDocProps, uno::UNO_QUERY );
    if ( xWriterProps.is() )
    {
        SfxOleSectionRef xBuiltin = aDocSet.GetSection( SECTION_BUILTIN );
        if ( xBuiltin )
        {
            try
            {
                OUString aStrValue;
                if ( xBuiltin->GetStringValue( aStrValue, PROPID_MANAGER ) )
                    xWriterProps->setManager( aStrValue );
                if ( xBuiltin->GetStringValue( aStrValue, PROPID_CATEGORY ) )
                    xWriterProps->setCategory( aStrValue );
                if ( xBuiltin->GetStringValue( aStrValue, PROPID_COMPANY ) )
                    xWriterProps->setCompany( aStrValue );
            }
            catch (const uno::Exception&)
            {
            }
        }
    }

    // return code
    return (nGlobError != ERRCODE_NONE) ? nGlobError : nDocError;
}

bool SaveOlePropertySet(
    const uno::Reference< document::XDocumentProperties>& i_xDocProps,
    SotStorage* i_pStorage,
    const uno::Sequence<sal_Int8> * i_pThumb,
    const uno::Sequence<sal_Int8> * i_pGuid,
    const uno::Sequence<sal_Int8> * i_pHyperlinks)
{
    // *** global properties into stream "005SummaryInformation" ***

    SfxOlePropertySet aGlobSet;

    // set supported properties
    SfxOleSection& rGlobSect = aGlobSet.AddSection( SECTION_GLOBAL );
    rGlobSect.SetStringValue( PROPID_TITLE,    i_xDocProps->getTitle() );
    rGlobSect.SetStringValue( PROPID_SUBJECT,  i_xDocProps->getSubject() );
    const OUString aStr = ::comphelper::string::convertCommaSeparated(
        i_xDocProps->getKeywords() );
    rGlobSect.SetStringValue( PROPID_KEYWORDS, aStr );
    rGlobSect.SetStringValue( PROPID_TEMPLATE, i_xDocProps->getTemplateName() );
    rGlobSect.SetStringValue( PROPID_COMMENTS, i_xDocProps->getDescription() );
    rGlobSect.SetStringValue( PROPID_AUTHOR,   i_xDocProps->getAuthor() );
    rGlobSect.SetFileTimeValue(PROPID_CREATED, i_xDocProps->getCreationDate());
    rGlobSect.SetStringValue( PROPID_LASTAUTHOR, i_xDocProps->getModifiedBy() );
    rGlobSect.SetFileTimeValue(PROPID_LASTSAVED,
                                i_xDocProps->getModificationDate() );
    // note: apparently PrintedBy is not supported in file format
    rGlobSect.SetFileTimeValue(PROPID_LASTPRINTED, i_xDocProps->getPrintDate());

    sal_Int32 dur = i_xDocProps->getEditingDuration();
    util::DateTime aEditTime;
    // add offset 1601-01-01
    aEditTime.Year    = 1601;
    aEditTime.Month   = 1;
    aEditTime.Day     = 1;
    aEditTime.Hours   = static_cast<sal_Int16>(dur / 3600);
    aEditTime.Minutes = static_cast<sal_Int16>((dur % 3600) / 60);
    aEditTime.Seconds = static_cast<sal_Int16>(dur % 60);
    rGlobSect.SetFileTimeValue( PROPID_EDITTIME, aEditTime );

    rGlobSect.SetStringValue( PROPID_REVNUMBER,
                OUString::number( i_xDocProps->getEditingCycles() ) );
    if ( i_pThumb && i_pThumb->hasElements() )
        rGlobSect.SetThumbnailValue( PROPID_THUMBNAIL, *i_pThumb );

    // save the property set
    ErrCode nGlobError = aGlobSet.SavePropertySet(i_pStorage,
        STREAM_SUMMARYINFO);

    // *** custom properties into stream "005DocumentSummaryInformation" ***

    SfxOlePropertySet aDocSet;

    // set builtin properties
    aDocSet.AddSection( SECTION_BUILTIN );

    // set custom properties
    SfxOleSection& rCustomSect = aDocSet.AddSection( SECTION_CUSTOM );

    // write GUID
    if (i_pGuid) {
        const sal_Int32 nPropId = rCustomSect.GetFreePropertyId();
        rCustomSect.SetBlobValue( nPropId, *i_pGuid );
        rCustomSect.SetPropertyName( nPropId,
            u"_PID_GUID"_ustr );
    }

    // write hyperlinks
    if (i_pHyperlinks) {
        const sal_Int32 nPropId = rCustomSect.GetFreePropertyId();
        rCustomSect.SetBlobValue( nPropId, *i_pHyperlinks );
        rCustomSect.SetPropertyName( nPropId,
            u"_PID_HLINKS"_ustr );
    }

    uno::Reference<beans::XPropertySet> xUserDefinedProps(
        i_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
    uno::Reference<beans::XPropertySetInfo> xPropInfo =
        xUserDefinedProps->getPropertySetInfo();
    DBG_ASSERT(xPropInfo.is(), "UserDefinedProperties Info is null");
    const uno::Sequence<beans::Property> props = xPropInfo->getProperties();
    for (const auto& rProp : props)
    {
        try
        {
            // skip transient properties
            if (~rProp.Attributes & beans::PropertyAttribute::TRANSIENT)
            {
                const OUString name = rProp.Name;
                const sal_Int32 nPropId = rCustomSect.GetFreePropertyId();
                if (rCustomSect.SetAnyValue( nPropId,
                            xUserDefinedProps->getPropertyValue(name))) {
                    rCustomSect.SetPropertyName( nPropId, name );
                }
            }
        }
        catch (const uno::Exception &)
        {
            // may happen with concurrent modification...
            SAL_INFO("sfx""SavePropertySet: exception");
        }
    }

    // save the property set
    ErrCode nDocError = aDocSet.SavePropertySet(i_pStorage,
        STREAM_DOCSUMMARYINFO );

    // return code
    return (nGlobError == ERRCODE_NONE) && (nDocError == ERRCODE_NONE);
}

uno::Sequence<sal_Int8> convertMetaFile(GDIMetaFile const * i_pThumb)
{
    if (i_pThumb) {
        BitmapEx aBitmap;
        SvMemoryStream aStream;
        if (i_pThumb->CreateThumbnail(aBitmap))
        {
            WriteDIB(aBitmap.GetBitmap(), aStream, falsefalse);
            return uno::Sequence<sal_Int8>(static_castconst sal_Int8* >( aStream.GetData() ), aStream.TellEnd());
        }
    }
    return uno::Sequence<sal_Int8>();
}

// namespace sfx2

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

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

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© 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.