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

Quelle  SwXMLTextBlocks1.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 <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <osl/diagnose.h>
#include <svl/macitem.hxx>
#include <svtools/unoevent.hxx>
#include <sfx2/docfile.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <comphelper/fileformat.h>
#include <comphelper/processfactory.hxx>
#include <comphelper/lok.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/xml/sax/InputSource.hpp>
#include <com/sun/star/io/IOException.hpp>
#include <com/sun/star/xml/sax/FastParser.hpp>
#include <com/sun/star/xml/sax/FastToken.hpp>
#include <com/sun/star/xml/sax/Parser.hpp>
#include <com/sun/star/xml/sax/Writer.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <doc.hxx>
#include <docsh.hxx>
#include <shellio.hxx>
#include <SwXMLTextBlocks.hxx>
#include <SwXMLBlockImport.hxx>
#include <SwXMLBlockExport.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <sfx2/event.hxx>
#include <swerror.h>

constexpr OUString XMLN_BLOCKLIST = u"BlockList.xml"_ustr;

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace css::xml::sax;
using namespace xmloff::token;

using ::xmloff::token::XML_BLOCK_LIST;
using ::xmloff::token::XML_UNFORMATTED_TEXT;
using ::xmloff::token::GetXMLToken;

ErrCode SwXMLTextBlocks::GetDoc( sal_uInt16 nIdx )
{
    OUString aFolderName ( GetPackageName ( nIdx ) );

    if (!IsOnlyTextBlock ( nIdx ) )
    {
        try
        {
            m_xRoot = m_xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ );
            m_xMedium = new SfxMedium( m_xRoot, GetBaseURL(), u"writer8"_ustr );
            SwReader aReader( *m_xMedium, aFolderName, m_xDoc.get() );
            ReadXML->SetBlockMode( true );
            aReader.Read( *ReadXML );
            ReadXML->SetBlockMode( false );
            // Ole objects fail to display when inserted into the document, as
            // the ObjectReplacement folder and contents are missing
            OUString sObjReplacements( u"ObjectReplacements"_ustr );
            if ( m_xRoot->hasByName( sObjReplacements ) )
            {
                if (SwDocShell* pShell = m_xDoc->GetDocShell())
                {
                    uno::Reference< document::XStorageBasedDocument > xDocStor( pShell->GetModel(), uno::UNO_QUERY );
                    if (xDocStor)
                    {
                        uno::Reference< embed::XStorage > xStr( xDocStor->getDocumentStorage() );
                        if ( xStr.is() )
                        {
                            m_xRoot->copyElementTo( sObjReplacements, xStr, sObjReplacements );
                            uno::Reference< embed::XTransactedObject > xTrans( xStr, uno::UNO_QUERY );
                            if ( xTrans.is() )
                                xTrans->commit();
                        }
                    }
                }
            }
        }
        catch( uno::Exception& )
        {
        }

        m_xRoot = nullptr;
    }
    else
    {
        OUString aStreamName = aFolderName + ".xml";
        try
        {
            m_xRoot = m_xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ );
            uno::Reference < io::XStream > xStream = m_xRoot->openStreamElement( aStreamName, embed::ElementModes::READ );

            const uno::Reference< uno::XComponentContext >& xContext =
                comphelper::getProcessComponentContext();

            xml::sax::InputSource aParserInput;
            aParserInput.sSystemId = m_aNames[nIdx]->m_aPackageName;

            aParserInput.aInputStream = xStream->getInputStream();

            // get filter
            uno::Reference< xml::sax::XFastDocumentHandler > xFilter = new SwXMLTextBlockImport( xContext, m_aCurrentText, true );
            uno::Reference< xml::sax::XFastTokenHandler > xTokenHandler = new SwXMLTextBlockTokenHandler();

            // connect parser and filter
            uno::Reference< xml::sax::XFastParser > xParser = xml::sax::FastParser::create(xContext);
            xParser->setFastDocumentHandler( xFilter );
            xParser->setTokenHandler( xTokenHandler );

            xParser->registerNamespace( u"http://openoffice.org/2000/text"_ustr, FastToken::NAMESPACE | XML_NAMESPACE_TEXT );
            xParser->registerNamespace( u"http://openoffice.org/2000/office"_ustr, FastToken::NAMESPACE | XML_NAMESPACE_OFFICE );

            // parse
            try
            {
                xParser->parseStream( aParserInput );
            }
            catch( xml::sax::SAXParseException&  )
            {
                // re throw ?
            }
            catch( xml::sax::SAXException&  )
            {
                // re throw ?
            }
            catch( io::IOException& )
            {
                // re throw ?
            }

            m_bInfoChanged = false;
            MakeBlockText(m_aCurrentText);
        }
        catch( uno::Exception& )
        {
        }

        m_xRoot = nullptr;
    }
    return ERRCODE_NONE;
}

// event description for autotext events; this constant should really be
// taken from unocore/unoevents.cxx or ui/unotxt.cxx
const struct SvEventDescription aAutotextEvents[] =
{
    { SvMacroItemId::SwStartInsGlossary,  "OnInsertStart" },
    { SvMacroItemId::SwEndInsGlossary,    "OnInsertDone" },
    { SvMacroItemId::NONE, nullptr }
};

ErrCode SwXMLTextBlocks::GetMacroTable( sal_uInt16 nIdx,
                                      SvxMacroTableDtor& rMacroTable )
{
    // set current auto text
    m_aShort = m_aNames[nIdx]->m_aShort;
    m_aLong = m_aNames[nIdx]->m_aLong;
    m_aPackageName = m_aNames[nIdx]->m_aPackageName;

    // open stream in proper sub-storage
    CloseFile();
    if ( OpenFile() != ERRCODE_NONE )
        return ERR_SWG_READ_ERROR;

    if (comphelper::LibreOfficeKit::isActive())
        return ERR_SWG_READ_ERROR;

    try
    {
        m_xRoot = m_xBlkRoot->openStorageElement( m_aPackageName, embed::ElementModes::READ );
        bool bOasis = SotStorage::GetVersion( m_xRoot ) > SOFFICE_FILEFORMAT_60;

        uno::Reference < io::XStream > xDocStream = m_xRoot->openStreamElement(
            u"atevent.xml"_ustr, embed::ElementModes::READ );
        SAL_INFO("sw""Can't open atevent.xml stream");
        if ( !xDocStream.is() )
            return ERR_SWG_READ_ERROR;

        // prepare ParserInputSource
        xml::sax::InputSource aParserInput;
        aParserInput.sSystemId = m_aName;
        aParserInput.aInputStream = xDocStream->getInputStream();

        // get service factory
        const uno::Reference< uno::XComponentContext >& xContext =
            comphelper::getProcessComponentContext();

        // create descriptor and reference to it. Either
        // both or neither must be kept because of the
        // reference counting!
        rtl::Reference<SvMacroTableEventDescriptor> pDescriptor =
            new SvMacroTableEventDescriptor(aAutotextEvents);
        Sequence<Any> aFilterArguments{ Any(uno::Reference<XNameReplace>(pDescriptor)) };

        // get filter
        OUString sFilterComponent = bOasis
            ? u"com.sun.star.comp.Writer.XMLOasisAutotextEventsImporter"_ustr
            : u"com.sun.star.comp.Writer.XMLAutotextEventsImporter"_ustr;
        uno::Reference< XInterface > xFilterInt =
            xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
                sFilterComponent, aFilterArguments, xContext);


        // parse the stream
        try
        {
            Reference<css::xml::sax::XFastParser> xFastParser(xFilterInt, UNO_QUERY);
            Reference<css::xml::sax::XFastDocumentHandler> xFastDocHandler(xFilterInt, UNO_QUERY);
            if (xFastParser)
            {
                xFastParser->parseStream(aParserInput);
            }
            else if (xFastDocHandler)
            {
                Reference<css::xml::sax::XFastParser> xParser
                    = css::xml::sax::FastParser::create(xContext);
                xParser->setFastDocumentHandler(xFastDocHandler);
                xParser->parseStream(aParserInput);
            }
            else
            {
                Reference<css::xml::sax::XDocumentHandler> xDocHandler(xFilterInt, UNO_QUERY);
                OSL_ENSURE( xDocHandler.is(), "can't instantiate autotext-events filter");
                if ( !xDocHandler.is() )
                    return ERR_SWG_READ_ERROR;
                Reference<css::xml::sax::XParser> xParser = css::xml::sax::Parser::create(xContext);
                xParser->setDocumentHandler(xDocHandler);
                xParser->parseStream(aParserInput);
            }
        }
        catch( xml::sax::SAXParseException& )
        {
            // workaround for #83452#: SetSize doesn't work
            // nRet = ERR_SWG_READ_ERROR;
        }
        catch( xml::sax::SAXException& )
        {
            TOOLS_WARN_EXCEPTION("sw""");
            return ERR_SWG_READ_ERROR;
        }
        catch( io::IOException& )
        {
            TOOLS_WARN_EXCEPTION("sw""");
            return ERR_SWG_READ_ERROR;
        }

        // and finally, copy macro into table
        pDescriptor->copyMacrosIntoTable(rMacroTable);
    }
    catch( uno::Exception& )
    {
        TOOLS_WARN_EXCEPTION("sw""");
        return ERR_SWG_READ_ERROR;
    }

    // success!
    return ERRCODE_NONE;
}

ErrCode SwXMLTextBlocks::GetBlockText( std::u16string_view rShort, OUString& rText )
{
    OUString aFolderName = GeneratePackageName ( rShort );
    OUString aStreamName = aFolderName + ".xml";
    rText.clear();

    try
    {
        bool bTextOnly = true;

        m_xRoot = m_xBlkRoot->openStorageElement( aFolderName, embed::ElementModes::READ );
        if ( !m_xRoot->hasByName( aStreamName ) || !m_xRoot->isStreamElement( aStreamName ) )
        {
            bTextOnly = false;
            aStreamName = "content.xml";
        }

        uno::Reference < io::XStream > xContents = m_xRoot->openStreamElement( aStreamName, embed::ElementModes::READ );
        const uno::Reference< uno::XComponentContext >& xContext =
            comphelper::getProcessComponentContext();

        xml::sax::InputSource aParserInput;
        aParserInput.sSystemId = m_aName;
        aParserInput.aInputStream = xContents->getInputStream();

        // get filter
        uno::Reference< xml::sax::XFastDocumentHandler > xFilter = new SwXMLTextBlockImport( xContext, rText, bTextOnly );
        uno::Reference< xml::sax::XFastTokenHandler > xTokenHandler = new SwXMLTextBlockTokenHandler();

        // connect parser and filter
        uno::Reference< xml::sax::XFastParser > xParser = xml::sax::FastParser::create(xContext);
        xParser->setFastDocumentHandler( xFilter );
        xParser->setTokenHandler( xTokenHandler );

        xParser->registerNamespace( u"urn:oasis:names:tc:opendocument:xmlns:office:1.0"_ustr, FastToken::NAMESPACE | XML_NAMESPACE_OFFICE );
        xParser->registerNamespace( u"urn:oasis:names:tc:opendocument:xmlns:text:1.0"_ustr, FastToken::NAMESPACE | XML_NAMESPACE_TEXT );

        // parse
        try
        {
            xParser->parseStream( aParserInput );
        }
        catch( xml::sax::SAXParseException&  )
        {
            // re throw ?
        }
        catch( xml::sax::SAXException&  )
        {
            // re throw ?
        }
        catch( io::IOException& )
        {
            // re throw ?
        }

        m_xRoot = nullptr;
    }
    catch ( uno::Exception& )
    {
        SAL_WARN("sw""Tried to open non-existent folder or stream: " << aStreamName << " derived from autocorr of: " << OUString(rShort));
    }

    return ERRCODE_NONE;
}

ErrCode SwXMLTextBlocks::PutBlockText( const OUString& rShort,
                                         std::u16string_view rText,  const OUString& rPackageName )
{
    GetIndex ( rShort );
    /*
    if (xBlkRoot->IsContained ( rPackageName ) )
    {
        xBlkRoot->Remove ( rPackageName );
        xBlkRoot->Commit ( );
    }
    */

    OUString aStreamName = rPackageName + ".xml";

    const uno::Reference< uno::XComponentContext >& xContext =
        comphelper::getProcessComponentContext();

    uno::Reference < xml::sax::XWriter > xWriter = xml::sax::Writer::create(xContext);
    ErrCode nRes = ERRCODE_NONE;

    try
    {
    m_xRoot = m_xBlkRoot->openStorageElement( rPackageName, embed::ElementModes::WRITE );
    uno::Reference < io::XStream > xDocStream = m_xRoot->openStreamElement( aStreamName,
                embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );

    uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
    xSet->setPropertyValue(u"MediaType"_ustr, Any(u"text/xml"_ustr) );
    uno::Reference < io::XOutputStream > xOut = xDocStream->getOutputStream();
    xWriter->setOutputStream(xOut);

    rtl::Reference<SwXMLTextBlockExport> xExp( new SwXMLTextBlockExport( xContext, *this, GetXMLToken ( XML_UNFORMATTED_TEXT ), xWriter) );

    xExp->exportDoc( rText );

    uno::Reference < embed::XTransactedObject > xTrans( m_xRoot, uno::UNO_QUERY );
    if ( xTrans.is() )
        xTrans->commit();

    if (! (m_nFlags & SwXmlFlags::NoRootCommit) )
    {
        uno::Reference < embed::XTransactedObject > xTmpTrans( m_xBlkRoot, uno::UNO_QUERY );
        if ( xTmpTrans.is() )
            xTmpTrans->commit();
    }
    }
    catch ( uno::Exception& )
    {
        nRes = ERR_SWG_WRITE_ERROR;
    }

    m_xRoot = nullptr;

    //TODO/LATER: error handling
    /*
    sal_uLong nErr = xBlkRoot->GetError();
    sal_uLong nRes = 0;
    if( nErr == SVSTREAM_DISK_FULL )
        nRes = ERR_W4W_WRITE_FULL;
    else if( nErr != ERRCODE_NONE )
        nRes = ERR_SWG_WRITE_ERROR;
    */

    if( !nRes ) // So that we can access the Doc via GetText & nCur
        MakeBlockText( rText );

    return nRes;
}

void SwXMLTextBlocks::ReadInfo()
{
    const OUString sDocName( XMLN_BLOCKLIST );
    try
    {
        if ( !m_xBlkRoot.is() || !m_xBlkRoot->hasByName( sDocName ) || !m_xBlkRoot->isStreamElement( sDocName ) )
            return;

        const uno::Reference< uno::XComponentContext >& xContext =
                comphelper::getProcessComponentContext();

        xml::sax::InputSource aParserInput;
        aParserInput.sSystemId = sDocName;

        uno::Reference < io::XStream > xDocStream = m_xBlkRoot->openStreamElement( sDocName, embed::ElementModes::READ );
        aParserInput.aInputStream = xDocStream->getInputStream();

        // get filter
        uno::Reference< xml::sax::XFastDocumentHandler > xFilter = new SwXMLBlockListImport( xContext, *this );
        uno::Reference< xml::sax::XFastTokenHandler > xTokenHandler = new SwXMLBlockListTokenHandler();

        // connect parser and filter
        uno::Reference< xml::sax::XFastParser > xParser = xml::sax::FastParser::create(xContext);
        xParser->setFastDocumentHandler( xFilter );
        xParser->registerNamespace( u"http://openoffice.org/2001/block-list"_ustr, FastToken::NAMESPACE | XML_NAMESPACE_BLOCKLIST );
        xParser->setTokenHandler( xTokenHandler );

        // parse
        xParser->parseStream( aParserInput );
    }
    catch ( uno::Exception& )
    {
        TOOLS_WARN_EXCEPTION("sw""when loading " << sDocName);
        // re throw ?
    }
}
void SwXMLTextBlocks::WriteInfo()
{
    if ( !(m_xBlkRoot.is() || ERRCODE_NONE == OpenFile ( false )) )
        return;

    const uno::Reference< uno::XComponentContext >& xContext =
        comphelper::getProcessComponentContext();

    uno::Reference < xml::sax::XWriter > xWriter = xml::sax::Writer::create(xContext);

    /*
    if ( xBlkRoot->IsContained( sDocName) )
    {
        xBlkRoot->Remove ( sDocName );
        xBlkRoot->Commit();
    }
    */


    try
    {
    uno::Reference < io::XStream > xDocStream = m_xBlkRoot->openStreamElement( XMLN_BLOCKLIST,
                embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );

    uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
    xSet->setPropertyValue(u"MediaType"_ustr, Any(u"text/xml"_ustr) );
    uno::Reference < io::XOutputStream > xOut = xDocStream->getOutputStream();
    xWriter->setOutputStream(xOut);

    rtl::Reference<SwXMLBlockListExport> xExp(new SwXMLBlockListExport( xContext, *this, XMLN_BLOCKLIST, xWriter) );

    xExp->exportDoc( XML_BLOCK_LIST );

    uno::Reference < embed::XTransactedObject > xTrans( m_xBlkRoot, uno::UNO_QUERY );
    if ( xTrans.is() )
        xTrans->commit();
    }
    catch ( uno::Exception& )
    {
    }

    m_bInfoChanged = false;
    return;
}

ErrCode SwXMLTextBlocks::SetMacroTable(
    sal_uInt16 nIdx,
    const SvxMacroTableDtor& rMacroTable )
{
    // set current autotext
    m_aShort = m_aNames[nIdx]->m_aShort;
    m_aLong = m_aNames[nIdx]->m_aLong;
    m_aPackageName = m_aNames[nIdx]->m_aPackageName;

    // start XML autotext event export
    ErrCode nRes = ERRCODE_NONE;

    const uno::Reference< uno::XComponentContext >& xContext =
        comphelper::getProcessComponentContext();

    SwDocShell* pShell = m_xDoc->GetDocShell();
    if (!pShell)
        return ERR_SWG_WRITE_ERROR;

    // Get model
    uno::Reference< lang::XComponent > xModelComp = pShell->GetModel();
    OSL_ENSURE( xModelComp.is(), "XMLWriter::Write: got no model" );
    if( !xModelComp.is() )
        return ERR_SWG_WRITE_ERROR;

    // open stream in proper sub-storage
    CloseFile(); // close (it may be open in read-only-mode)
    nRes = OpenFile ( false );

    if ( ERRCODE_NONE == nRes )
    {
        try
        {
            m_xRoot = m_xBlkRoot->openStorageElement( m_aPackageName, embed::ElementModes::WRITE );
            bool bOasis = SotStorage::GetVersion( m_xRoot ) > SOFFICE_FILEFORMAT_60;

            uno::Reference < io::XStream > xDocStream = m_xRoot->openStreamElement( u"atevent.xml"_ustr,
                        embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );

            uno::Reference < beans::XPropertySet > xSet( xDocStream, uno::UNO_QUERY );
            xSet->setPropertyValue(u"MediaType"_ustr, Any(u"text/xml"_ustr) );
            uno::Reference < io::XOutputStream > xOutputStream = xDocStream->getOutputStream();

            // get XML writer
            uno::Reference< xml::sax::XWriter > xSaxWriter =
                xml::sax::Writer::create( xContext );

            // connect XML writer to output stream
            xSaxWriter->setOutputStream( xOutputStream );

            // construct events object
            uno::Reference<XNameAccess> xEvents =
                new SvMacroTableEventDescriptor(rMacroTable,aAutotextEvents);

            // prepare arguments (prepend doc handler to given arguments)
            Sequence<Any> aParams{ Any(xSaxWriter), Any(xEvents) };

            // get filter component
            OUString sFilterComponent = bOasis
                ? u"com.sun.star.comp.Writer.XMLOasisAutotextEventsExporter"_ustr
                : u"com.sun.star.comp.Writer.XMLAutotextEventsExporter"_ustr;
            uno::Reference< document::XExporter > xExporter(
                xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
                    sFilterComponent, aParams, xContext), UNO_QUERY);
            OSL_ENSURE( xExporter.is(),
                    "can't instantiate export filter component" );
            if( xExporter.is() )
            {
                // connect model and filter
                xExporter->setSourceDocument( xModelComp );

                // filter!
                Sequence<beans::PropertyValue> aFilterProps( 0 );
                uno::Reference < document::XFilter > xFilter( xExporter,
                                                         UNO_QUERY );
                xFilter->filter( aFilterProps );
            }
            else
                nRes = ERR_SWG_WRITE_ERROR;

            // finally, commit stream, sub-storage and storage
            uno::Reference < embed::XTransactedObject > xTmpTrans( m_xRoot, uno::UNO_QUERY );
            if ( xTmpTrans.is() )
                xTmpTrans->commit();

            uno::Reference < embed::XTransactedObject > xTrans( m_xBlkRoot, uno::UNO_QUERY );
            if ( xTrans.is() )
                xTrans->commit();

            m_xRoot = nullptr;
        }
        catch ( uno::Exception& )
        {
            nRes = ERR_SWG_WRITE_ERROR;
        }

        CloseFile();
    }
    else
        nRes = ERR_SWG_WRITE_ERROR;

    return nRes;
}

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

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

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