diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /xmlscript/source | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xmlscript/source')
21 files changed, 10296 insertions, 0 deletions
diff --git a/xmlscript/source/inc/misc.hxx b/xmlscript/source/inc/misc.hxx new file mode 100644 index 000000000..d70f6b063 --- /dev/null +++ b/xmlscript/source/inc/misc.hxx @@ -0,0 +1,50 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/uno/Any.hxx> + +namespace xmlscript +{ + +template< typename T > +inline void extract_throw( T * p, css::uno::Any const & a ) +{ + if (! (a >>= *p)) + { + throw css::uno::RuntimeException( + "expected " + cppu::UnoType<T>::get().getTypeName(), + css::uno::Reference< + css::uno::XInterface>() ); + } +} + +template< typename T > +inline T extract_throw( css::uno::Any const & a ) +{ + T v = T(); + extract_throw<T>( &v, a ); + return v; +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/inc/xml_import.hxx b/xmlscript/source/inc/xml_import.hxx new file mode 100644 index 000000000..913634738 --- /dev/null +++ b/xmlscript/source/inc/xml_import.hxx @@ -0,0 +1,44 @@ +/* -*- 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 . + */ +#pragma once + +#include <com/sun/star/xml/input/XRoot.hpp> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> + +namespace xmlscript +{ +// IMPORTING + +/** Creates a document handler to be used for SAX1 parser that can handle + namespaces. Namespace URI are mapped to integer ids for performance. + Implementing the XImporter interface, you will get a startRootElement() + for the root element of your XML document and subsequent + startChildElement() callbacks for each sub element. + Namespaces of tags are identified by their integer value. + + @param xRoot + initial object being called for root context + @return + document handler for parser +*/ +css::uno::Reference<css::xml::sax::XDocumentHandler> +createDocumentHandler(css::uno::Reference<css::xml::input::XRoot> const& xRoot); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xml_helper/xml_byteseq.cxx b/xmlscript/source/xml_helper/xml_byteseq.cxx new file mode 100644 index 000000000..2ae8ecea1 --- /dev/null +++ b/xmlscript/source/xml_helper/xml_byteseq.cxx @@ -0,0 +1,158 @@ +/* -*- 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 <string.h> + +#include <cppuhelper/implbase.hxx> +#include <xmlscript/xml_helper.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> + +using namespace osl; +using namespace com::sun::star; +using namespace com::sun::star::uno; + + +namespace xmlscript +{ + +namespace { + +class BSeqInputStream + : public ::cppu::WeakImplHelper< io::XInputStream > +{ + std::vector<sal_Int8> _seq; + sal_Int32 _nPos; + +public: + explicit BSeqInputStream( std::vector<sal_Int8>&& rSeq ) + : _seq( std::move(rSeq) ) + , _nPos( 0 ) + {} + + // XInputStream + virtual sal_Int32 SAL_CALL readBytes( + Sequence< sal_Int8 > & rData, sal_Int32 nBytesToRead ) override; + virtual sal_Int32 SAL_CALL readSomeBytes( + Sequence< sal_Int8 > & rData, sal_Int32 nMaxBytesToRead ) override; + virtual void SAL_CALL skipBytes( + sal_Int32 nBytesToSkip ) override; + virtual sal_Int32 SAL_CALL available() override; + virtual void SAL_CALL closeInput() override; +}; + +} + +sal_Int32 BSeqInputStream::readBytes( + Sequence< sal_Int8 > & rData, sal_Int32 nBytesToRead ) +{ + nBytesToRead = ((nBytesToRead > static_cast<sal_Int32>(_seq.size()) - _nPos) + ? _seq.size() - _nPos + : nBytesToRead); + + if (rData.getLength() != nBytesToRead) + rData.realloc( nBytesToRead ); + if (nBytesToRead != 0) { + memcpy(rData.getArray(), &_seq[_nPos], nBytesToRead); + } + _nPos += nBytesToRead; + return nBytesToRead; +} + +sal_Int32 BSeqInputStream::readSomeBytes( + Sequence< sal_Int8 > & rData, sal_Int32 nMaxBytesToRead ) +{ + return readBytes( rData, nMaxBytesToRead ); +} + +void BSeqInputStream::skipBytes( + sal_Int32 /*nBytesToSkip*/ ) +{ +} + +sal_Int32 BSeqInputStream::available() +{ + return _seq.size() - _nPos; +} + +void BSeqInputStream::closeInput() +{ +} + +namespace { + +class BSeqOutputStream + : public ::cppu::WeakImplHelper< io::XOutputStream > +{ + std::vector<sal_Int8> * _seq; + +public: + explicit BSeqOutputStream( std::vector<sal_Int8> * seq ) + : _seq( seq ) + {} + + // XOutputStream + virtual void SAL_CALL writeBytes( + Sequence< sal_Int8 > const & rData ) override; + virtual void SAL_CALL flush() override; + virtual void SAL_CALL closeOutput() override; +}; + +} + +void BSeqOutputStream::writeBytes( Sequence< sal_Int8 > const & rData ) +{ + sal_Int32 nPos = _seq->size(); + _seq->resize( nPos + rData.getLength() ); + if (rData.getLength() != 0) { + memcpy( _seq->data() + nPos, + rData.getConstArray(), + rData.getLength() ); + } +} +void BSeqOutputStream::flush() +{ +} + +void BSeqOutputStream::closeOutput() +{ +} + +Reference< io::XInputStream > createInputStream( std::vector<sal_Int8>&& rInData ) +{ + return new BSeqInputStream( std::move(rInData) ); +} + +Reference< io::XInputStream > createInputStream( const sal_Int8* pData, int len ) +{ + std::vector<sal_Int8> rInData(len); + if (len != 0) { + memcpy( rInData.data(), pData, len); + } + return new BSeqInputStream( std::move(rInData) ); +} + +Reference< io::XOutputStream > createOutputStream( std::vector<sal_Int8> * pOutData ) +{ + return new BSeqOutputStream( pOutData ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xml_helper/xml_element.cxx b/xmlscript/source/xml_helper/xml_element.cxx new file mode 100644 index 000000000..2c7c71c58 --- /dev/null +++ b/xmlscript/source/xml_helper/xml_element.cxx @@ -0,0 +1,111 @@ +/* -*- 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 <xmlscript/xml_helper.hxx> +#include <o3tl/safeint.hxx> +#include <osl/diagnose.h> +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> + +using namespace com::sun::star; +using namespace com::sun::star::uno; + +namespace xmlscript +{ + +void XMLElement::addAttribute( OUString const & rAttrName, OUString const & rValue ) +{ + _attrNames.push_back( rAttrName ); + _attrValues.push_back( rValue ); +} + +void XMLElement::addSubElement( Reference< xml::sax::XAttributeList > const & xElem ) +{ + _subElems.push_back( xElem ); +} + +Reference< xml::sax::XAttributeList > const & XMLElement::getSubElement( sal_Int32 nIndex ) +{ + return _subElems[ static_cast<size_t>(nIndex) ]; +} + +void XMLElement::dumpSubElements( Reference< xml::sax::XDocumentHandler > const & xOut ) +{ + for (const Reference<XAttributeList> & _subElem : _subElems) + { + XMLElement * pElem = static_cast< XMLElement * >( _subElem.get() ); + pElem->dump( xOut ); + } +} + +void XMLElement::dump( Reference< xml::sax::XDocumentHandler > const & xOut ) +{ + xOut->ignorableWhitespace( OUString() ); + xOut->startElement( _name, static_cast< xml::sax::XAttributeList * >( this ) ); + // write sub elements + dumpSubElements( xOut ); + xOut->ignorableWhitespace( OUString() ); + xOut->endElement( _name ); +} + +// XAttributeList +sal_Int16 XMLElement::getLength() +{ + return static_cast<sal_Int16>(_attrNames.size()); +} + +OUString XMLElement::getNameByIndex( sal_Int16 nPos ) +{ + OSL_ASSERT( nPos >= 0 && o3tl::make_unsigned(nPos) < _attrNames.size() ); + return _attrNames[ nPos ]; +} + +OUString XMLElement::getTypeByIndex( sal_Int16 nPos ) +{ + OSL_ASSERT( nPos >= 0 && o3tl::make_unsigned(nPos) < _attrNames.size() ); + // xxx todo + return OUString(); +} + +OUString XMLElement::getTypeByName( OUString const & /*rName*/ ) +{ + // xxx todo + return OUString(); +} + +OUString XMLElement::getValueByIndex( sal_Int16 nPos ) +{ + OSL_ASSERT( nPos >= 0 && o3tl::make_unsigned(nPos) < _attrNames.size() ); + return _attrValues[ nPos ]; +} + +OUString XMLElement::getValueByName( OUString const & rName ) +{ + for ( size_t nPos = 0; nPos < _attrNames.size(); ++nPos ) + { + if (_attrNames[ nPos ] == rName) + { + return _attrValues[ nPos ]; + } + } + return OUString(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xml_helper/xml_impctx.cxx b/xmlscript/source/xml_helper/xml_impctx.cxx new file mode 100644 index 000000000..1b4247ba8 --- /dev/null +++ b/xmlscript/source/xml_helper/xml_impctx.cxx @@ -0,0 +1,717 @@ +/* -*- 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 <sal/config.h> + +#include <xml_import.hxx> + +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <com/sun/star/container/NoSuchElementException.hpp> +#include <com/sun/star/xml/input/XAttributes.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <sal/log.hxx> + +#include <memory> +#include <unordered_map> +#include <vector> + +using namespace ::osl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace xmlscript +{ + +const sal_Int32 UID_UNKNOWN = -1; + +typedef std::unordered_map< OUString, sal_Int32 > t_OUString2LongMap; + +namespace { + +struct PrefixEntry +{ + ::std::vector< sal_Int32 > m_Uids; + + PrefixEntry() + { m_Uids.reserve( 4 ); } +}; + +} + +typedef std::unordered_map< + OUString, std::unique_ptr<PrefixEntry> > t_OUString2PrefixMap; + +namespace { + +struct ElementEntry +{ + Reference< xml::input::XElement > m_xElement; + ::std::vector< OUString > m_prefixes; + + ElementEntry() + { m_prefixes.reserve( 2 ); } +}; + +class ExtendedAttributes; + +class MGuard +{ + Mutex * m_pMutex; +public: + explicit MGuard( std::unique_ptr<Mutex> const & pMutex ) + : m_pMutex( pMutex.get() ) + { if (m_pMutex) m_pMutex->acquire(); } + ~MGuard() noexcept + { if (m_pMutex) m_pMutex->release(); } +}; + +class DocumentHandlerImpl : + public ::cppu::WeakImplHelper< xml::sax::XDocumentHandler, + xml::input::XNamespaceMapping, + lang::XInitialization, + css::lang::XServiceInfo > +{ + friend class ExtendedAttributes; + + Reference< xml::input::XRoot > m_xRoot; + + t_OUString2LongMap m_URI2Uid; + sal_Int32 m_uid_count; + + sal_Int32 m_nLastURI_lookup; + OUString m_aLastURI_lookup; + + t_OUString2PrefixMap m_prefixes; + sal_Int32 m_nLastPrefix_lookup; + OUString m_aLastPrefix_lookup; + + std::vector< ElementEntry > m_elements; + sal_Int32 m_nSkipElements; + + std::unique_ptr<Mutex> m_pMutex; + + inline Reference< xml::input::XElement > getCurrentElement() const; + + inline sal_Int32 getUidByURI( OUString const & rURI ); + inline sal_Int32 getUidByPrefix( OUString const & rPrefix ); + + inline void pushPrefix( + OUString const & rPrefix, OUString const & rURI ); + inline void popPrefix( OUString const & rPrefix ); + + inline void getElementName( + OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName ); + +public: + DocumentHandlerImpl( + Reference< xml::input::XRoot > const & xRoot, + bool bSingleThreadedUse ); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( + OUString const & servicename ) override; + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override; + + // XInitialization + virtual void SAL_CALL initialize( + Sequence< Any > const & arguments ) override; + + // XDocumentHandler + virtual void SAL_CALL startDocument() override; + virtual void SAL_CALL endDocument() override; + virtual void SAL_CALL startElement( + OUString const & rQElementName, + Reference< xml::sax::XAttributeList > const & xAttribs ) override; + virtual void SAL_CALL endElement( + OUString const & rQElementName ) override; + virtual void SAL_CALL characters( + OUString const & rChars ) override; + virtual void SAL_CALL ignorableWhitespace( + OUString const & rWhitespaces ) override; + virtual void SAL_CALL processingInstruction( + OUString const & rTarget, OUString const & rData ) override; + virtual void SAL_CALL setDocumentLocator( + Reference< xml::sax::XLocator > const & xLocator ) override; + + // XNamespaceMapping + virtual sal_Int32 SAL_CALL getUidByUri( OUString const & Uri ) override; + virtual OUString SAL_CALL getUriByUid( sal_Int32 Uid ) override; +}; + +} + +constexpr OUStringLiteral g_sXMLNS_PREFIX_UNKNOWN( u"<<< unknown prefix >>>" ); +constexpr OUStringLiteral g_sXMLNS( u"xmlns" ); + + +DocumentHandlerImpl::DocumentHandlerImpl( + Reference< xml::input::XRoot > const & xRoot, + bool bSingleThreadedUse ) + : m_xRoot( xRoot ), + m_uid_count( 0 ), + m_nLastURI_lookup( UID_UNKNOWN ), + m_aLastURI_lookup( "<<< unknown URI >>>" ), + m_nLastPrefix_lookup( UID_UNKNOWN ), + m_aLastPrefix_lookup( "<<< unknown URI >>>" ), + m_nSkipElements( 0 ) +{ + m_elements.reserve( 10 ); + + if (! bSingleThreadedUse) + m_pMutex.reset(new Mutex); +} + +inline Reference< xml::input::XElement > +DocumentHandlerImpl::getCurrentElement() const +{ + MGuard aGuard( m_pMutex ); + if (m_elements.empty()) + return Reference< xml::input::XElement >(); + else + return m_elements.back().m_xElement; +} + +inline sal_Int32 DocumentHandlerImpl::getUidByURI( OUString const & rURI ) +{ + MGuard guard( m_pMutex ); + if (m_nLastURI_lookup == UID_UNKNOWN || m_aLastURI_lookup != rURI) + { + t_OUString2LongMap::const_iterator iFind( m_URI2Uid.find( rURI ) ); + if (iFind != m_URI2Uid.end()) // id found + { + m_nLastURI_lookup = iFind->second; + m_aLastURI_lookup = rURI; + } + else + { + m_nLastURI_lookup = m_uid_count; + ++m_uid_count; + m_URI2Uid[ rURI ] = m_nLastURI_lookup; + m_aLastURI_lookup = rURI; + } + } + return m_nLastURI_lookup; +} + +inline sal_Int32 DocumentHandlerImpl::getUidByPrefix( + OUString const & rPrefix ) +{ + // commonly the last added prefix is used often for several tags... + // good guess + if (m_nLastPrefix_lookup == UID_UNKNOWN || m_aLastPrefix_lookup != rPrefix) + { + t_OUString2PrefixMap::const_iterator iFind( + m_prefixes.find( rPrefix ) ); + if (iFind != m_prefixes.end()) + { + const PrefixEntry & rPrefixEntry = *iFind->second; + SAL_WARN_IF( rPrefixEntry.m_Uids.empty(), "xmlscript.xmlhelper", "rPrefixEntry.m_Uids is empty" ); + m_nLastPrefix_lookup = rPrefixEntry.m_Uids.back(); + m_aLastPrefix_lookup = rPrefix; + } + else + { + m_nLastPrefix_lookup = UID_UNKNOWN; + m_aLastPrefix_lookup = g_sXMLNS_PREFIX_UNKNOWN; + } + } + return m_nLastPrefix_lookup; +} + +inline void DocumentHandlerImpl::pushPrefix( + OUString const & rPrefix, OUString const & rURI ) +{ + // lookup id for URI + sal_Int32 nUid = getUidByURI( rURI ); + + // mark prefix with id + t_OUString2PrefixMap::const_iterator iFind( m_prefixes.find( rPrefix ) ); + if (iFind == m_prefixes.end()) // unused prefix + { + PrefixEntry * pEntry = new PrefixEntry(); + pEntry->m_Uids.push_back( nUid ); // latest id for prefix + m_prefixes[rPrefix].reset(pEntry); + } + else + { + PrefixEntry& rEntry = *iFind->second; + SAL_WARN_IF(rEntry.m_Uids.empty(), "xmlscript.xmlhelper", "pEntry->m_Uids is empty"); + rEntry.m_Uids.push_back(nUid); + } + + m_aLastPrefix_lookup = rPrefix; + m_nLastPrefix_lookup = nUid; +} + +inline void DocumentHandlerImpl::popPrefix( + OUString const & rPrefix ) +{ + t_OUString2PrefixMap::iterator iFind( m_prefixes.find( rPrefix ) ); + if (iFind != m_prefixes.end()) // unused prefix + { + PrefixEntry& rEntry = *iFind->second; + rEntry.m_Uids.pop_back(); // pop last id for prefix + if (rEntry.m_Uids.empty()) // erase prefix key + { + m_prefixes.erase(iFind); + } + } + + m_nLastPrefix_lookup = UID_UNKNOWN; + m_aLastPrefix_lookup = g_sXMLNS_PREFIX_UNKNOWN; +} + +inline void DocumentHandlerImpl::getElementName( + OUString const & rQName, sal_Int32 * pUid, OUString * pLocalName ) +{ + sal_Int32 nColonPos = rQName.indexOf( ':' ); + *pLocalName = (nColonPos >= 0 ? rQName.copy( nColonPos +1 ) : rQName); + *pUid = getUidByPrefix( + nColonPos >= 0 ? rQName.copy( 0, nColonPos ) : OUString() ); +} + +namespace { + +class ExtendedAttributes : + public ::cppu::WeakImplHelper< xml::input::XAttributes > +{ + sal_Int32 const m_nAttributes; + std::unique_ptr<sal_Int32[]> m_pUids; + std::unique_ptr<OUString[]> m_pLocalNames; + std::unique_ptr<OUString[]> m_pQNames; + std::unique_ptr<OUString[]> m_pValues; + +public: + inline ExtendedAttributes( + sal_Int32 nAttributes, + std::unique_ptr<sal_Int32[]> pUids, + std::unique_ptr<OUString[]> pLocalNames, + std::unique_ptr<OUString[]> pQNames, + Reference< xml::sax::XAttributeList > const & xAttributeList ); + + // XAttributes + virtual sal_Int32 SAL_CALL getLength() override; + virtual sal_Int32 SAL_CALL getIndexByQName( + OUString const & rQName ) override; + virtual sal_Int32 SAL_CALL getIndexByUidName( + sal_Int32 nUid, OUString const & rLocalName ) override; + virtual OUString SAL_CALL getQNameByIndex( + sal_Int32 nIndex ) override; + virtual sal_Int32 SAL_CALL getUidByIndex( + sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getLocalNameByIndex( + sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getValueByIndex( + sal_Int32 nIndex ) override; + virtual OUString SAL_CALL getValueByUidName( + sal_Int32 nUid, OUString const & rLocalName ) override; + virtual OUString SAL_CALL getTypeByIndex( + sal_Int32 nIndex ) override; +}; + +} + +inline ExtendedAttributes::ExtendedAttributes( + sal_Int32 nAttributes, + std::unique_ptr<sal_Int32[]> pUids, + std::unique_ptr<OUString[]> pLocalNames, std::unique_ptr<OUString[]> pQNames, + Reference< xml::sax::XAttributeList > const & xAttributeList ) + : m_nAttributes( nAttributes ) + , m_pUids( std::move(pUids) ) + , m_pLocalNames( std::move(pLocalNames) ) + , m_pQNames( std::move(pQNames) ) + , m_pValues( new OUString[ nAttributes ] ) +{ + for ( sal_Int32 nPos = 0; nPos < nAttributes; ++nPos ) + { + m_pValues[ nPos ] = xAttributeList->getValueByIndex( nPos ); + } +} + +// XServiceInfo + +OUString DocumentHandlerImpl::getImplementationName() +{ + return "com.sun.star.comp.xml.input.SaxDocumentHandler"; +} + +sal_Bool DocumentHandlerImpl::supportsService( OUString const & servicename ) +{ + return cppu::supportsService(this, servicename); +} + +Sequence< OUString > DocumentHandlerImpl::getSupportedServiceNames() +{ + return { "com.sun.star.xml.input.SaxDocumentHandler" }; +} + +// XInitialization + +void DocumentHandlerImpl::initialize( + Sequence< Any > const & arguments ) +{ + MGuard guard( m_pMutex ); + Reference< xml::input::XRoot > xRoot; + if (arguments.getLength() != 1 || + !(arguments[ 0 ] >>= xRoot) || + !xRoot.is()) + { + throw RuntimeException( "missing root instance!" ); + } + m_xRoot = xRoot; +} + +// XNamespaceMapping + +sal_Int32 DocumentHandlerImpl::getUidByUri( OUString const & Uri ) +{ + sal_Int32 uid = getUidByURI( Uri ); + SAL_WARN_IF( uid == UID_UNKNOWN, "xmlscript.xmlhelper", "uid UNKNOWN"); + return uid; +} + +OUString DocumentHandlerImpl::getUriByUid( sal_Int32 Uid ) +{ + MGuard guard( m_pMutex ); + for (const auto& rURIUid : m_URI2Uid) + { + if (rURIUid.second == Uid) + return rURIUid.first; + } + throw container::NoSuchElementException( "no such xmlns uid!" , static_cast< OWeakObject * >(this) ); +} + +// XDocumentHandler + +void DocumentHandlerImpl::startDocument() +{ + m_xRoot->startDocument( static_cast< xml::input::XNamespaceMapping * >( this ) ); +} + +void DocumentHandlerImpl::endDocument() +{ + m_xRoot->endDocument(); +} + +void DocumentHandlerImpl::startElement( + OUString const & rQElementName, + Reference< xml::sax::XAttributeList > const & xAttribs ) +{ + Reference< xml::input::XElement > xCurrentElement; + Reference< xml::input::XAttributes > xAttributes; + sal_Int32 nUid; + OUString aLocalName; + ElementEntry elementEntry; + + { // guard start: + MGuard aGuard( m_pMutex ); + // currently skipping elements and waiting for end tags? + if (m_nSkipElements > 0) + { + ++m_nSkipElements; // wait for another end tag + SAL_INFO("xmlscript.xmlhelper", " no context given on createChildElement() => ignoring element \"" << rQElementName << "\" ..."); + return; + } + + sal_Int16 nAttribs = xAttribs->getLength(); + + // save all namespace ids + std::unique_ptr<sal_Int32[]> pUids(new sal_Int32[ nAttribs ]); + std::unique_ptr<OUString[]> pPrefixes(new OUString[ nAttribs ]); + std::unique_ptr<OUString[]> pLocalNames(new OUString[ nAttribs ]); + std::unique_ptr<OUString[]> pQNames(new OUString[ nAttribs ]); + + // first recognize all xmlns attributes + sal_Int16 nPos; + for ( nPos = 0; nPos < nAttribs; ++nPos ) + { + // mark attribute to be collected further + // on with attribute's uid and current prefix + pUids[ nPos ] = 0; // modified + + pQNames[ nPos ] = xAttribs->getNameByIndex( nPos ); + OUString const & rQAttributeName = pQNames[ nPos ]; + + if (rQAttributeName.startsWith( g_sXMLNS )) + { + if (rQAttributeName.getLength() == 5) // set default namespace + { + OUString aDefNamespacePrefix; + pushPrefix( + aDefNamespacePrefix, + xAttribs->getValueByIndex( nPos ) ); + elementEntry.m_prefixes.push_back( aDefNamespacePrefix ); + pUids[ nPos ] = UID_UNKNOWN; + pPrefixes[ nPos ] = g_sXMLNS; + pLocalNames[ nPos ] = aDefNamespacePrefix; + } + else if (':' == rQAttributeName[ 5 ]) // set prefix + { + OUString aPrefix( rQAttributeName.copy( 6 ) ); + pushPrefix( aPrefix, xAttribs->getValueByIndex( nPos ) ); + elementEntry.m_prefixes.push_back( aPrefix ); + pUids[ nPos ] = UID_UNKNOWN; + pPrefixes[ nPos ] = g_sXMLNS; + pLocalNames[ nPos ] = aPrefix; + } + // else just a name starting with xmlns, but no prefix + } + } + + // now read out attribute prefixes (all namespace prefixes have been set) + for ( nPos = 0; nPos < nAttribs; ++nPos ) + { + if (pUids[ nPos ] >= 0) // no xmlns: attribute + { + OUString const & rQAttributeName = pQNames[ nPos ]; + SAL_WARN_IF(rQAttributeName.startsWith( "xmlns:" ), "xmlscript.xmlhelper", "### unexpected xmlns!" ); + + // collect attribute's uid and current prefix + sal_Int32 nColonPos = rQAttributeName.indexOf( ':' ); + if (nColonPos >= 0) + { + pPrefixes[ nPos ] = rQAttributeName.copy( 0, nColonPos ); + pLocalNames[ nPos ] = rQAttributeName.copy( nColonPos +1 ); + } + else + { + pPrefixes[ nPos ].clear(); + pLocalNames[ nPos ] = rQAttributeName; + // leave local names unmodified + } + pUids[ nPos ] = getUidByPrefix( pPrefixes[ nPos ] ); + } + } + pPrefixes.reset(); + // ownership of arrays belongs to attribute list + xAttributes = new ExtendedAttributes(nAttribs, std::move(pUids), std::move(pLocalNames), + std::move(pQNames), xAttribs); + + getElementName( rQElementName, &nUid, &aLocalName ); + + // create new child context and append to list + if (! m_elements.empty()) + xCurrentElement = m_elements.back().m_xElement; + } // :guard end + + if (xCurrentElement.is()) + { + elementEntry.m_xElement = + xCurrentElement->startChildElement( nUid, aLocalName, xAttributes ); + } + else + { + elementEntry.m_xElement = + m_xRoot->startRootElement( nUid, aLocalName, xAttributes ); + } + + { + MGuard aGuard( m_pMutex ); + if (elementEntry.m_xElement.is()) + { + m_elements.push_back( std::move(elementEntry) ); + } + else + { + ++m_nSkipElements; + + // pop prefixes + for (sal_Int32 nPos = elementEntry.m_prefixes.size(); nPos--;) + popPrefix(elementEntry.m_prefixes[nPos]); + + SAL_INFO("xmlscript.xmlhelper", " no context given on createChildElement() => ignoring element \"" << rQElementName << "\" ..."); + } + } +} + +void DocumentHandlerImpl::endElement( + OUString const & rQElementName ) +{ + Reference< xml::input::XElement > xCurrentElement; + { + MGuard aGuard( m_pMutex ); + if (m_nSkipElements) + { + --m_nSkipElements; + SAL_INFO("xmlscript.xmlhelper", "### received endElement() for \"" << rQElementName << "\"."); + return; + } + + // popping context + SAL_WARN_IF( m_elements.empty(), "xmlscript.xmlhelper", "m_elements is empty" ); + ElementEntry& rEntry = m_elements.back(); + xCurrentElement = rEntry.m_xElement; + +#if OSL_DEBUG_LEVEL > 0 + sal_Int32 nUid; + OUString aLocalName; + getElementName( rQElementName, &nUid, &aLocalName ); + SAL_WARN_IF( xCurrentElement->getLocalName() != aLocalName, "xmlscript.xmlhelper", "xCurrentElement->getLocalName() != aLocalName" ); + SAL_WARN_IF( xCurrentElement->getUid() != nUid, "xmlscript.xmlhelper", "xCurrentElement->getUid() != nUid" ); +#endif + + // pop prefixes + for ( sal_Int32 nPos = rEntry.m_prefixes.size(); nPos--; ) + { + popPrefix( rEntry.m_prefixes[ nPos ] ); + } + m_elements.pop_back(); + } + xCurrentElement->endElement(); +} + +void DocumentHandlerImpl::characters( OUString const & rChars ) +{ + Reference< xml::input::XElement > xCurrentElement( getCurrentElement() ); + if (xCurrentElement.is()) + xCurrentElement->characters( rChars ); +} + +void DocumentHandlerImpl::ignorableWhitespace( + OUString const & rWhitespaces ) +{ + Reference< xml::input::XElement > xCurrentElement( getCurrentElement() ); + if (xCurrentElement.is()) + xCurrentElement->ignorableWhitespace( rWhitespaces ); +} + +void DocumentHandlerImpl::processingInstruction( + OUString const & rTarget, OUString const & rData ) +{ + Reference< xml::input::XElement > xCurrentElement( getCurrentElement() ); + if (xCurrentElement.is()) + xCurrentElement->processingInstruction( rTarget, rData ); + else + m_xRoot->processingInstruction( rTarget, rData ); +} + +void DocumentHandlerImpl::setDocumentLocator( + Reference< xml::sax::XLocator > const & xLocator ) +{ + m_xRoot->setDocumentLocator( xLocator ); +} + +// XAttributes + +sal_Int32 ExtendedAttributes::getIndexByQName( OUString const & rQName ) +{ + for ( sal_Int32 nPos = m_nAttributes; nPos--; ) + { + if (m_pQNames[ nPos ] == rQName) + { + return nPos; + } + } + return -1; +} + +sal_Int32 ExtendedAttributes::getLength() +{ + return m_nAttributes; +} + +OUString ExtendedAttributes::getLocalNameByIndex( sal_Int32 nIndex ) +{ + if (nIndex < m_nAttributes) + return m_pLocalNames[ nIndex ]; + else + return OUString(); +} + +OUString ExtendedAttributes::getQNameByIndex( sal_Int32 nIndex ) +{ + if (nIndex < m_nAttributes) + return m_pQNames[ nIndex ]; + else + return OUString(); +} + +OUString ExtendedAttributes::getTypeByIndex( sal_Int32 nIndex ) +{ + SAL_WARN_IF( nIndex >= m_nAttributes , "xmlscript.xmlhelper", "nIndex is bigger then m_nAttributes"); + return OUString(); // unsupported +} + +OUString ExtendedAttributes::getValueByIndex( sal_Int32 nIndex ) +{ + if (nIndex < m_nAttributes) + return m_pValues[ nIndex ]; + else + return OUString(); +} + +sal_Int32 ExtendedAttributes::getIndexByUidName( + sal_Int32 nUid, OUString const & rLocalName ) +{ + for ( sal_Int32 nPos = m_nAttributes; nPos--; ) + { + if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName) + { + return nPos; + } + } + return -1; +} + +sal_Int32 ExtendedAttributes::getUidByIndex( sal_Int32 nIndex ) +{ + if (nIndex < m_nAttributes) + return m_pUids[ nIndex ]; + else + return -1; +} + +OUString ExtendedAttributes::getValueByUidName( + sal_Int32 nUid, OUString const & rLocalName ) +{ + for ( sal_Int32 nPos = m_nAttributes; nPos--; ) + { + if (m_pUids[ nPos ] == nUid && m_pLocalNames[ nPos ] == rLocalName) + { + return m_pValues[ nPos ]; + } + } + return OUString(); +} + +Reference< xml::sax::XDocumentHandler > createDocumentHandler( + Reference< xml::input::XRoot > const & xRoot ) +{ + SAL_WARN_IF( !xRoot.is(), "xmlscript.xmlhelper", "xRoot is NULL" ); + if (xRoot.is()) + { + return new DocumentHandlerImpl(xRoot, true /* mt use */); + } + return Reference< xml::sax::XDocumentHandler >(); +} + +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* +com_sun_star_comp_xml_input_SaxDocumentHandler_get_implementation( + css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const& ) +{ + return cppu::acquire(new xmlscript::DocumentHandlerImpl({}, false /* mt use */)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/common.hxx b/xmlscript/source/xmldlg_imexp/common.hxx new file mode 100644 index 000000000..88b32b0a4 --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/common.hxx @@ -0,0 +1,41 @@ +/* -*- 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 . + */ + +#pragma once + +#include <sal/types.h> + +namespace xmlscript +{ +const sal_Int16 BORDER_NONE = 0; +const sal_Int16 BORDER_3D = 1; +const sal_Int16 BORDER_SIMPLE = 2; +const sal_Int16 BORDER_SIMPLE_COLOR = 3; + +struct StringTriple +{ + char const* first; + char const* second; + char const* third; +}; + +extern StringTriple const* const g_pEventTranslations; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/exp_share.hxx b/xmlscript/source/xmldlg_imexp/exp_share.hxx new file mode 100644 index 000000000..919950c79 --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/exp_share.hxx @@ -0,0 +1,258 @@ +/* -*- 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 . + */ + +#pragma once + +#include <xmlscript/xmldlg_imexp.hxx> +#include <xmlscript/xml_helper.hxx> +#include <osl/diagnose.h> +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertyState.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/awt/FontEmphasisMark.hpp> +#include <com/sun/star/awt/FontRelief.hpp> +#include <memory> +#include <vector> + + +namespace xmlscript +{ + +struct Style +{ + sal_uInt32 _backgroundColor; + sal_uInt32 _textColor; + sal_uInt32 _textLineColor; + sal_Int16 _border; + sal_Int32 _borderColor; + css::awt::FontDescriptor _descr; + sal_uInt16 _fontRelief; + sal_uInt16 _fontEmphasisMark; + sal_uInt32 _fillColor; + sal_Int16 _visualEffect; + + // current highest mask: 0x40 + short _all; + short _set; + + OUString _id; + + explicit Style( short all_ ) + : _backgroundColor(0) + , _textColor(0) + , _textLineColor(0) + , _border(0) + , _borderColor(0) + , _fontRelief(css::awt::FontRelief::NONE) + , _fontEmphasisMark(css::awt::FontEmphasisMark::NONE) + , _fillColor(0) + , _visualEffect(0) + , _all(all_) + , _set(0) + { + } + + css::uno::Reference< css::xml::sax::XAttributeList > createElement(); +}; +class StyleBag +{ + ::std::vector<Style> _styles; + +public: + ~StyleBag() ; + + OUString getStyleId( Style const & rStyle ); + + void dump( css::uno::Reference< css::xml::sax::XExtendedDocumentHandler > + const & xOut ); +}; + +class ElementDescriptor + : public ::xmlscript::XMLElement +{ + css::uno::Reference< css::beans::XPropertySet > _xProps; + css::uno::Reference< css::beans::XPropertyState > _xPropState; + css::uno::Reference< css::frame::XModel > _xDocument; + +public: + ElementDescriptor( + css::uno::Reference< css::beans::XPropertySet > const & xProps, + css::uno::Reference< css::beans::XPropertyState > const & xPropState, + OUString const & name, css::uno::Reference< css::frame::XModel > const & xDocument ) + : XMLElement( name ) + , _xProps( xProps ) + , _xPropState( xPropState ) + , _xDocument( xDocument ) + {} + explicit ElementDescriptor( + OUString const & name ) + : XMLElement( name ) + {} + + template<typename T> + inline void read( + OUString const & propName, OUString const & attrName, + bool forceAttribute = false ); + + template<typename T> + inline bool readProp( T * ret, OUString const & rPropName ); + css::uno::Any readProp( OUString const & rPropName ); + void readScrollableSettings(); + void readDefaults( bool supportPrintable = true, bool supportVisible = true ); + void readStringAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readDoubleAttr( + OUString const & rPropName, OUString const & rAttrName ) + { read<double>( rPropName, rAttrName ); } + void readLongAttr( + OUString const & rPropName, OUString const & rAttrName, + bool forceAttribute = false ) + { read<sal_Int32>( rPropName, rAttrName, forceAttribute ); } + void readHexLongAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readShortAttr( + OUString const & rPropName, OUString const & rAttrName ) + { read<sal_Int32>( rPropName, rAttrName ); } + inline void readBoolAttr( + OUString const & rPropName, OUString const & rAttrName ); + + void readAlignAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readVerticalAlignAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readImageAlignAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readImagePositionAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readDateAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readDateFormatAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readTimeAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readTimeFormatAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readOrientationAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readButtonTypeAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readLineEndFormatAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readSelectionTypeAttr( + OUString const & rPropName, OUString const & rAttrName ); + void readImageScaleModeAttr( + OUString const & rPropName, OUString const & rAttrName ); + + void readDataAwareAttr(OUString const & rAttrName ); + void readImageOrGraphicAttr(OUString const & rAttrName ); + + void addBoolAttr( + OUString const & rAttrName, bool bValue ) + { addAttribute( rAttrName, OUString::boolean(bValue) ); } + void addNumberFormatAttr( + css::uno::Reference< css::beans::XPropertySet > + const & xFormatProperties ); + + void readEvents(); + void readDialogModel( StyleBag * all_styles ); + void readBullitinBoard( StyleBag * all_styles ); + void readMultiPageModel( StyleBag * all_styles ); + void readFrameModel( StyleBag * all_styles ); + void readPageModel( StyleBag * all_styles ); + void readButtonModel( StyleBag * all_styles ); + void readEditModel( StyleBag * all_styles ); + void readCheckBoxModel( StyleBag * all_styles ); + void readRadioButtonModel( StyleBag * all_styles ); + void readComboBoxModel( StyleBag * all_styles ); + void readCurrencyFieldModel( StyleBag * all_styles ); + void readDateFieldModel( StyleBag * all_styles ); + void readFileControlModel( StyleBag * all_styles ); + void readTreeControlModel( StyleBag * all_styles ); + void readFixedTextModel( StyleBag * all_styles ); + void readGroupBoxModel( StyleBag * all_styles ); + void readImageControlModel( StyleBag * all_styles ); + void readListBoxModel( StyleBag * all_styles ); + void readNumericFieldModel( StyleBag * all_styles ); + void readPatternFieldModel( StyleBag * all_styles ); + void readFormattedFieldModel( StyleBag * all_styles ); + void readTimeFieldModel( StyleBag * all_styles ); + void readFixedLineModel( StyleBag * all_styles ); + void readProgressBarModel( StyleBag * all_styles ); + void readScrollBarModel( StyleBag * all_styles ); + void readSpinButtonModel( StyleBag * all_styles ); + void readFixedHyperLinkModel( StyleBag * all_styles ); + void readGridControlModel( StyleBag * all_styles ); +}; + +template<typename T> +inline void ElementDescriptor::read( + OUString const & propName, OUString const & attrName, + bool forceAttribute ) +{ + if (forceAttribute || + css::beans::PropertyState_DEFAULT_VALUE != + _xPropState->getPropertyState( propName )) + { + css::uno::Any a( _xProps->getPropertyValue( propName ) ); + T v = T(); + if (a >>= v) + addAttribute( attrName, OUString::number(v) ); + else + OSL_FAIL( "### unexpected property type!" ); + } +} + +template<> +inline void ElementDescriptor::read<sal_Bool>( + OUString const & propName, OUString const & attrName, + bool forceAttribute ) +{ + if (forceAttribute || + css::beans::PropertyState_DEFAULT_VALUE != + _xPropState->getPropertyState( propName )) + { + css::uno::Any a( _xProps->getPropertyValue( propName ) ); + bool v; + if (a >>= v) + addAttribute( attrName, OUString::boolean(v) ); + else + OSL_FAIL( "### unexpected property type!" ); + } +} + +inline void ElementDescriptor::readBoolAttr( + OUString const & rPropName, OUString const & rAttrName ) +{ + read<sal_Bool>( rPropName, rAttrName ); +} + +template<typename T> +inline bool ElementDescriptor::readProp( + T * ret, OUString const & rPropName ) +{ + _xProps->getPropertyValue( rPropName ) >>= *ret; + return css::beans::PropertyState_DEFAULT_VALUE != + _xPropState->getPropertyState( rPropName ); +} + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/imp_share.hxx b/xmlscript/source/xmldlg_imexp/imp_share.hxx new file mode 100644 index 000000000..12da21724 --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/imp_share.hxx @@ -0,0 +1,1052 @@ +/* -*- 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 . + */ + +#pragma once + +#include <xmlscript/xmldlg_imexp.hxx> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/awt/FontEmphasisMark.hpp> +#include <com/sun/star/awt/FontRelief.hpp> +#include <com/sun/star/xml/input/XRoot.hpp> +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <com/sun/star/container/ElementExistException.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <osl/diagnose.h> +#include <rtl/ref.hxx> +#include <o3tl/string_view.hxx> +#include <memory> +#include <vector> + +namespace xmlscript +{ + +inline sal_Int32 toInt32( OUString const & rStr ) +{ + sal_Int32 nVal; + if (rStr.getLength() > 2 && rStr[ 0 ] == '0' && rStr[ 1 ] == 'x') + nVal = o3tl::toUInt32(rStr.subView( 2 ), 16); + else + nVal = rStr.toInt32(); + return nVal; +} + +inline bool getBoolAttr( + sal_Bool * pRet, OUString const & rAttrName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + sal_Int32 nUid ) +{ + OUString aValue( xAttributes->getValueByUidName( nUid, rAttrName ) ); + if (!aValue.isEmpty()) + { + if ( aValue == "true" ) + { + *pRet = true; + return true; + } + else if ( aValue == "false" ) + { + *pRet = false; + return true; + } + else + { + throw css::xml::sax::SAXException( + rAttrName + ": no boolean value (true|false)!", + css::uno::Reference<css::uno::XInterface>(), css::uno::Any() ); + } + } + return false; +} + +inline bool getStringAttr( + OUString * pRet, OUString const & rAttrName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + sal_Int32 nUid ) +{ + *pRet = xAttributes->getValueByUidName( nUid, rAttrName ); + return (!pRet->isEmpty()); +} + +inline bool getLongAttr( + sal_Int32 * pRet, OUString const & rAttrName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + sal_Int32 nUid ) +{ + OUString aValue( xAttributes->getValueByUidName( nUid, rAttrName ) ); + if (!aValue.isEmpty()) + { + *pRet = toInt32( aValue ); + return true; + } + return false; +} + +class ImportContext; + +struct DialogImport + : public ::cppu::WeakImplHelper< css::xml::input::XRoot > +{ + friend class ImportContext; +private: + css::uno::Reference< css::uno::XComponentContext > _xContext; + css::uno::Reference< css::util::XNumberFormatsSupplier > _xSupplier; + + std::shared_ptr< std::vector< OUString > > _pStyleNames; + std::shared_ptr< std::vector< css::uno::Reference< css::xml::input::XElement > > > _pStyles; + + css::uno::Reference< css::frame::XModel > _xDoc; +public: + css::uno::Reference< css::container::XNameContainer > _xDialogModel; + css::uno::Reference< css::lang::XMultiServiceFactory > _xDialogModelFactory; + + sal_Int32 XMLNS_DIALOGS_UID, XMLNS_SCRIPT_UID; + + bool isEventElement( + sal_Int32 nUid, std::u16string_view rLocalName ) const + { + return ((XMLNS_SCRIPT_UID == nUid && (rLocalName == u"event" || rLocalName == u"listener-event" )) || + (XMLNS_DIALOGS_UID == nUid && rLocalName == u"event" )); + } + + void addStyle( + OUString const & rStyleId, + css::uno::Reference< css::xml::input::XElement > const & xStyle ); + css::uno::Reference< css::xml::input::XElement > getStyle( + std::u16string_view rStyleId ) const; + + css::uno::Reference< css::uno::XComponentContext > + const & getComponentContext() const { return _xContext; } + css::uno::Reference< css::util::XNumberFormatsSupplier > + const & getNumberFormatsSupplier(); + + DialogImport( + css::uno::Reference<css::uno::XComponentContext> const & xContext, + css::uno::Reference<css::container::XNameContainer> + const & xDialogModel, + std::shared_ptr< std::vector< OUString > > const & pStyleNames, + std::shared_ptr< std::vector< css::uno::Reference< css::xml::input::XElement > > > const & pStyles, + css::uno::Reference<css::frame::XModel> const & xDoc ) + : _xContext( xContext ) + , _pStyleNames( pStyleNames ) + , _pStyles( pStyles ) + , _xDoc( xDoc ) + , _xDialogModel( xDialogModel ) + , _xDialogModelFactory( xDialogModel, css::uno::UNO_QUERY_THROW ) + , XMLNS_DIALOGS_UID( 0 ) + , XMLNS_SCRIPT_UID( 0 ) + { OSL_ASSERT( _xDialogModel.is() && _xContext.is() ); } + DialogImport( const DialogImport& rOther ) : + ::cppu::WeakImplHelper< css::xml::input::XRoot >() + , _xContext( rOther._xContext ) + , _xSupplier( rOther._xSupplier ) + , _pStyleNames( rOther._pStyleNames ) + , _pStyles( rOther._pStyles ) + , _xDoc( rOther._xDoc ) + , _xDialogModel( rOther._xDialogModel ) + , _xDialogModelFactory( rOther._xDialogModelFactory ) + , XMLNS_DIALOGS_UID( rOther.XMLNS_DIALOGS_UID ) + , XMLNS_SCRIPT_UID( rOther.XMLNS_SCRIPT_UID ) {} + + virtual ~DialogImport() override; + + const css::uno::Reference< css::frame::XModel >& getDocOwner() const { return _xDoc; } + + // XRoot + virtual void SAL_CALL startDocument( + css::uno::Reference< css::xml::input::XNamespaceMapping > + const & xNamespaceMapping ) override; + virtual void SAL_CALL endDocument() override; + virtual void SAL_CALL processingInstruction( + OUString const & rTarget, OUString const & rData ) override; + virtual void SAL_CALL setDocumentLocator( + css::uno::Reference< css::xml::sax::XLocator > const & xLocator ) override; + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startRootElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; +}; + +class ElementBase + : public ::cppu::WeakImplHelper< css::xml::input::XElement > +{ +protected: + // We deliberately store these as raw pointers, otherwise we get reference cycles between DialogImport and the elements + DialogImport* m_pImport; + ElementBase* m_pParent; +private: + const sal_Int32 _nUid; + const OUString _aLocalName; +protected: + const css::uno::Reference< css::xml::input::XAttributes > _xAttributes; + +public: + ElementBase( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ); + virtual ~ElementBase() override; + + // XElement + virtual css::uno::Reference<css::xml::input::XElement> SAL_CALL getParent() override; + virtual OUString SAL_CALL getLocalName() override; + virtual sal_Int32 SAL_CALL getUid() override; + virtual css::uno::Reference< css::xml::input::XAttributes > + SAL_CALL getAttributes() override; + virtual void SAL_CALL ignorableWhitespace( + OUString const & rWhitespaces ) override; + virtual void SAL_CALL characters( OUString const & rChars ) override; + virtual void SAL_CALL processingInstruction( + OUString const & Target, OUString const & Data ) override; + virtual void SAL_CALL endElement() override; + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; +}; + +class StylesElement + : public ElementBase +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + + StylesElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ElementBase( pImport->XMLNS_DIALOGS_UID, + rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class StyleElement + : public ElementBase +{ + sal_Int32 _backgroundColor; + sal_Int32 _textColor; + sal_Int32 _textLineColor; + sal_Int16 _border; + sal_Int32 _borderColor; + css::awt::FontDescriptor _descr; + sal_Int16 _fontRelief; + sal_Int16 _fontEmphasisMark; + sal_Int32 _fillColor; + sal_Int16 _visualEffect; + + // current highest mask: 0x40 + short _inited, _hasValue; + + void setFontProperties( + css::uno::Reference< css::beans::XPropertySet > const & xProps ) const; + +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + void importTextColorStyle( + css::uno::Reference< css::beans::XPropertySet > const & xProps ); + void importTextLineColorStyle( + css::uno::Reference< css::beans::XPropertySet > const & xProps ); + void importFillColorStyle( + css::uno::Reference< css::beans::XPropertySet > const & xProps ); + void importBackgroundColorStyle( + css::uno::Reference< css::beans::XPropertySet > const & xProps ); + void importFontStyle( + css::uno::Reference< css::beans::XPropertySet > const & xProps ); + void importBorderStyle( + css::uno::Reference< css::beans::XPropertySet > const & xProps ); + void importVisualEffectStyle( + css::uno::Reference< css::beans::XPropertySet > const & xProps ); + + StyleElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ElementBase( pImport->XMLNS_DIALOGS_UID, + rLocalName, xAttributes, pParent, pImport ) + , _backgroundColor(0) + , _textColor(0) + , _textLineColor(0) + , _border(0) + , _borderColor(0) + , _fontRelief( css::awt::FontRelief::NONE ) + , _fontEmphasisMark( css::awt::FontEmphasisMark::NONE ) + , _fillColor(0) + , _visualEffect(0) + , _inited( 0 ) + , _hasValue( 0 ) + { + } +}; + +class MenuPopupElement + : public ElementBase +{ + std::vector< OUString > _itemValues; + std::vector< sal_Int16 > _itemSelected; + bool _allowEmptyItems; +public: + css::uno::Sequence< OUString > getItemValues(); + css::uno::Sequence< sal_Int16 > getSelectedItems(); + + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + + MenuPopupElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport, + bool aAllowEmptyItems) + : ElementBase( pImport->XMLNS_DIALOGS_UID, + rLocalName, xAttributes, pParent, pImport ) + , _allowEmptyItems(aAllowEmptyItems) + {} +}; + +class ControlElement + : public ElementBase +{ + friend class EventElement; + +protected: + sal_Int32 _nBasePosX, _nBasePosY; + + std::vector< css::uno::Reference< css::xml::input::XElement > > _events; + + OUString getControlId( + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + OUString getControlModelName( + OUString const& rDefaultModel, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + css::uno::Reference< css::xml::input::XElement > getStyle( + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); +public: + std::vector<css::uno::Reference< css::xml::input::XElement> >& getEvents() + { return _events; } + + ControlElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ); +}; + +class ImportContext +{ +protected: + DialogImport * const _pImport; + const css::uno::Reference< css::beans::XPropertySet > _xControlModel; + const OUString _aId; + +public: + ImportContext( + DialogImport * pImport, + css::uno::Reference< css::beans::XPropertySet > const & xControlModel_, + OUString const & id ) + : _pImport( pImport ), + _xControlModel( xControlModel_ ), + _aId( id ) + { OSL_ASSERT( _xControlModel.is() ); } + + const css::uno::Reference< css::beans::XPropertySet >& getControlModel() const + { return _xControlModel; } + + void importScollableSettings( css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ); + void importDefaults( + sal_Int32 nBaseX, sal_Int32 nBaseY, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + bool supportPrintable = true ); + void importEvents( + std::vector< css::uno::Reference< css::xml::input::XElement > > + const & rEvents ); + + bool importStringProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importDoubleProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importBooleanProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importShortProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importLongProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importLongProperty( + sal_Int32 nOffset, + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importHexLongProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importAlignProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importVerticalAlignProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importGraphicOrImageProperty(OUString const & rAttrName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ); + bool importImageAlignProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importImagePositionProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importDateProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importDateFormatProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importTimeProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importTimeFormatProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importOrientationProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importButtonTypeProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importLineEndFormatProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importSelectionTypeProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importDataAwareProperty( + OUString const & rPropName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); + bool importImageScaleModeProperty( + OUString const & rPropName, OUString const & rAttrName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ); +}; + +class ControlImportContext : public ImportContext +{ +public: + ControlImportContext( + DialogImport * pImport, + OUString const & rId, OUString const & rControlName ) + : ImportContext( + pImport, + css::uno::Reference< css::beans::XPropertySet >( + pImport->_xDialogModelFactory->createInstance( rControlName ), + css::uno::UNO_QUERY_THROW ), rId ) + {} + ControlImportContext( + DialogImport * pImport, + const css::uno::Reference< css::beans::XPropertySet >& xProps, OUString const & rControlName ) + : ImportContext( + pImport, + xProps, + rControlName ) + {} + + /// @throws css::xml::sax::SAXException + /// @throws css::uno::RuntimeException + void finish() + { + try + { + _pImport->_xDialogModel->insertByName( + _aId, css::uno::Any( + css::uno::Reference<css::awt::XControlModel>::query( + _xControlModel ) ) ); + } + catch(const css::container::ElementExistException &e) + { + throw css::lang::WrappedTargetRuntimeException("", e.Context, css::uno::Any(e)); + } + } +}; + +class WindowElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + WindowElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, nullptr, pImport ) + {} +}; + +class EventElement + : public ElementBase +{ +public: + virtual void SAL_CALL endElement() override; + + EventElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ElementBase( nUid, rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class BulletinBoardElement + : public ControlElement +{ + // we are the owner of this, so have to keep a reference to it + rtl::Reference<DialogImport> mxDialogImport; +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + + BulletinBoardElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ); +}; + +class ButtonElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + ButtonElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class CheckBoxElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + CheckBoxElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class ComboBoxElement + : public ControlElement +{ + css::uno::Reference< css::xml::input::XElement > _popup; +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + ComboBoxElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class MenuListElement + : public ControlElement +{ + css::uno::Reference< css::xml::input::XElement > _popup; +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + MenuListElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class RadioElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + + RadioElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class RadioGroupElement + : public ControlElement +{ + std::vector< css::uno::Reference< css::xml::input::XElement > > _radios; +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + void SAL_CALL endElement() override; + + RadioGroupElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class TitledBoxElement + : public BulletinBoardElement +{ + OUString _label; + std::vector< css::uno::Reference< css::xml::input::XElement > > _radios; +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + TitledBoxElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : BulletinBoardElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class TextElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + TextElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; +class FixedHyperLinkElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + FixedHyperLinkElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class TextFieldElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + TextFieldElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class ImageControlElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + ImageControlElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class FileControlElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + FileControlElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class TreeControlElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + TreeControlElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class CurrencyFieldElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + CurrencyFieldElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class DateFieldElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + DateFieldElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class NumericFieldElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + NumericFieldElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class TimeFieldElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + TimeFieldElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class PatternFieldElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + PatternFieldElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class FormattedFieldElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + FormattedFieldElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class FixedLineElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + FixedLineElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class ScrollBarElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + ScrollBarElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class SpinButtonElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + SpinButtonElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +class MultiPage + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + MultiPage( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + { + m_xContainer.set( m_pImport->_xDialogModelFactory->createInstance( "com.sun.star.awt.UnoMultiPageModel" ), css::uno::UNO_QUERY ); + } +private: + css::uno::Reference< css::container::XNameContainer > m_xContainer; +}; + +class Frame + : public ControlElement +{ + OUString _label; +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + Frame( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +private: + css::uno::Reference< css::container::XNameContainer > m_xContainer; +}; + +class Page + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + Page( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + { + m_xContainer.set( m_pImport->_xDialogModelFactory->createInstance( "com.sun.star.awt.UnoPageModel" ), css::uno::UNO_QUERY ); + } +private: + css::uno::Reference< css::container::XNameContainer > m_xContainer; +}; + +class ProgressBarElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + ProgressBarElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +//============================================================================== +class GridControlElement + : public ControlElement +{ +public: + virtual css::uno::Reference< css::xml::input::XElement > + SAL_CALL startChildElement( + sal_Int32 nUid,::rtl::OUString const & rLocalName, + css::uno::Reference<css::xml::input::XAttributes> const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + GridControlElement(OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_addfunc.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_addfunc.cxx new file mode 100644 index 000000000..be3605de5 --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/xmldlg_addfunc.cxx @@ -0,0 +1,95 @@ +/* -*- 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/io/XInputStreamProvider.hpp> +#include <com/sun/star/xml/sax/Parser.hpp> +#include <com/sun/star/xml/sax/Writer.hpp> + +#include <cppuhelper/implbase.hxx> +#include <xmlscript/xml_helper.hxx> +#include <xmlscript/xmldlg_imexp.hxx> + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::frame; + +namespace xmlscript +{ + +namespace { + +class InputStreamProvider + : public ::cppu::WeakImplHelper< io::XInputStreamProvider > +{ + std::vector<sal_Int8> const _bytes; + +public: + explicit InputStreamProvider( std::vector<sal_Int8>&& rBytes ) + : _bytes( std::move(rBytes) ) + { + } + + // XInputStreamProvider + virtual uno::Reference< io::XInputStream > SAL_CALL createInputStream() override; +}; + +} + +uno::Reference< io::XInputStream > InputStreamProvider::createInputStream() +{ + return ::xmlscript::createInputStream( std::vector(_bytes) ); +} + +uno::Reference< io::XInputStreamProvider > exportDialogModel( + uno::Reference< container::XNameContainer > const & xDialogModel, + uno::Reference< uno::XComponentContext > const & xContext, + uno::Reference< XModel > const & xDocument ) +{ + uno::Reference< xml::sax::XWriter > xWriter = xml::sax::Writer::create(xContext); + + std::vector<sal_Int8> aBytes; + xWriter->setOutputStream( createOutputStream( &aBytes ) ); + + uno::Reference< xml::sax::XExtendedDocumentHandler > xHandler(xWriter, uno::UNO_QUERY_THROW); + exportDialogModel( xHandler, xDialogModel, xDocument ); + + return new InputStreamProvider( std::move(aBytes) ); +} + +void importDialogModel( + uno::Reference< io::XInputStream > const & xInput, + uno::Reference< container::XNameContainer > const & xDialogModel, + uno::Reference< uno::XComponentContext > const & xContext, + uno::Reference< XModel > const & xDocument ) +{ + uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create( xContext ); + + // error handler, entity resolver omitted for this helper function + xParser->setDocumentHandler( importDialogModel( xDialogModel, xContext, xDocument ) ); + + xml::sax::InputSource source; + source.aInputStream = xInput; + source.sSystemId = "virtual file"; + + xParser->parseStream( source ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx new file mode 100644 index 000000000..823df0e9a --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx @@ -0,0 +1,1275 @@ +/* -*- 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 "common.hxx" +#include "exp_share.hxx" +#include <misc.hxx> +#include <xmlscript/xmlns.h> + +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/util/XNumberFormatsSupplier.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <o3tl/any.hxx> +#include <rtl/ref.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace xmlscript +{ + +static bool readBorderProps( + ElementDescriptor * element, Style & style ) +{ + if (element->readProp( &style._border, "Border" )) { + if (style._border == BORDER_SIMPLE /* simple */) + { + if (element->readProp( &style._borderColor, "BorderColor" )) + style._border = BORDER_SIMPLE_COLOR; + } + return true; + } + return false; +} + +static bool readFontProps( ElementDescriptor * element, Style & style ) +{ + bool ret = element->readProp( + &style._descr, "FontDescriptor" ); + ret |= element->readProp( + &style._fontEmphasisMark, "FontEmphasisMark" ); + ret |= element->readProp( + &style._fontRelief, "FontRelief" ); + return ret; +} + +void ElementDescriptor::readMultiPageModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id" , all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readLongAttr( "MultiPageValue", XMLNS_DIALOGS_PREFIX ":value" ); + Any aDecorationAny( _xProps->getPropertyValue( "Decoration" ) ); + bool bDecoration = true; + if ( (aDecorationAny >>= bDecoration) && !bDecoration ) + addAttribute( XMLNS_DIALOGS_PREFIX ":withtabs", "false" ); + + readEvents(); + uno::Reference< container::XNameContainer > xPagesContainer( _xProps, uno::UNO_QUERY ); + if ( xPagesContainer.is() && xPagesContainer->getElementNames().hasElements() ) + { + rtl::Reference<ElementDescriptor> pElem = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":bulletinboard", _xDocument ); + pElem->readBullitinBoard( all_styles ); + addSubElement( pElem ); + } +} + +void ElementDescriptor::readFrameModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x8 | 0x20 ); + + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + OUString aTitle; + + if ( readProp( "Label" ) >>= aTitle) + { + rtl::Reference<ElementDescriptor> title = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":title", _xDocument ); + title->addAttribute( XMLNS_DIALOGS_PREFIX ":value", aTitle ); + addSubElement( title ); + } + uno::Reference< container::XNameContainer > xControlContainer( _xProps, uno::UNO_QUERY ); + if ( xControlContainer.is() && xControlContainer->getElementNames().hasElements() ) + { + rtl::Reference<ElementDescriptor> pElem = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":bulletinboard", _xDocument ); + pElem->readBullitinBoard( all_styles ); + addSubElement( pElem ); + } + readEvents(); +} + +void ElementDescriptor::readPageModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readStringAttr( "Title", XMLNS_DIALOGS_PREFIX ":title" ); + uno::Reference< container::XNameContainer > xControlContainer( _xProps, uno::UNO_QUERY ); + if ( xControlContainer.is() && xControlContainer->getElementNames().hasElements() ) + { + rtl::Reference<ElementDescriptor> pElem = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":bulletinboard", _xDocument ); + pElem->readBullitinBoard( all_styles ); + addSubElement( pElem ); + } + readEvents(); +} + +void ElementDescriptor::readButtonModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "DefaultButton", XMLNS_DIALOGS_PREFIX ":default" ); + readStringAttr( "Label", XMLNS_DIALOGS_PREFIX ":value" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readButtonTypeAttr( "PushButtonType", XMLNS_DIALOGS_PREFIX ":button-type" ); + readImageOrGraphicAttr(XMLNS_DIALOGS_PREFIX ":image-src"); + readImagePositionAttr( "ImagePosition", XMLNS_DIALOGS_PREFIX ":image-position" ); + readImageAlignAttr( "ImageAlign", XMLNS_DIALOGS_PREFIX ":image-align" ); + + if (extract_throw<bool>( _xProps->getPropertyValue( "Repeat" ) )) + readLongAttr( "RepeatDelay", XMLNS_DIALOGS_PREFIX ":repeat", true /* force */ ); + + if (extract_throw<bool>( _xProps->getPropertyValue( "Toggle" ) )) + addAttribute( XMLNS_DIALOGS_PREFIX ":toggled", "1" ); + + readBoolAttr( "FocusOnClick", XMLNS_DIALOGS_PREFIX ":grab-focus" ); + readBoolAttr( "MultiLine",XMLNS_DIALOGS_PREFIX ":multiline" ); + + // State + sal_Int16 nState = 0; + if (readProp( "State" ) >>= nState) + { + switch (nState) + { + case 0: + addAttribute( XMLNS_DIALOGS_PREFIX ":checked", "false" ); + break; + case 1: + addAttribute( XMLNS_DIALOGS_PREFIX ":checked", "true" ); + break; + default: + OSL_FAIL( "### unexpected radio state!" ); + break; + } + } + + readEvents(); +} + +void ElementDescriptor::readCheckBoxModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x8 | 0x20 | 0x40 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (readProp( "VisualEffect" ) >>= aStyle._visualEffect) + aStyle._set |= 0x40; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readStringAttr( "Label", XMLNS_DIALOGS_PREFIX ":value" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readImageOrGraphicAttr(XMLNS_DIALOGS_PREFIX ":image-src"); + readImagePositionAttr( "ImagePosition", XMLNS_DIALOGS_PREFIX ":image-position" ); + readBoolAttr( "MultiLine", XMLNS_DIALOGS_PREFIX ":multiline" ); + + bool bTriState = false; + if ((readProp( "TriState" ) >>= bTriState) && bTriState) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":tristate", "true" ); + } + sal_Int16 nState = 0; + if (_xProps->getPropertyValue( "State" ) >>= nState) + { + switch (nState) + { + case 0: + addAttribute( XMLNS_DIALOGS_PREFIX ":checked", "false" ); + break; + case 1: + addAttribute( XMLNS_DIALOGS_PREFIX ":checked", "true" ); + break; + case 2: // tristate=true exported, checked omitted => don't know! + OSL_ENSURE( bTriState, "### detected tristate value, but TriState is not set!" ); + break; + default: + OSL_FAIL( "### unexpected checkbox state!" ); + break; + } + } + readEvents(); +} + +void ElementDescriptor::readComboBoxModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readStringAttr( "Text", XMLNS_DIALOGS_PREFIX ":value" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readBoolAttr( "Autocomplete", XMLNS_DIALOGS_PREFIX ":autocomplete" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readBoolAttr( "Dropdown", XMLNS_DIALOGS_PREFIX ":spin" ); + readShortAttr( "MaxTextLen", XMLNS_DIALOGS_PREFIX ":maxlength" ); + readShortAttr( "LineCount", XMLNS_DIALOGS_PREFIX ":linecount" ); + // Cell Range, Ref Cell etc. + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":linked-cell" ); + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":source-cell-range" ); + + // string item list + Sequence< OUString > itemValues; + if ((readProp( "StringItemList" ) >>= itemValues) && itemValues.hasElements()) + { + rtl::Reference<ElementDescriptor> popup = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":menupopup", _xDocument ); + + for ( const auto& rItemValue : std::as_const(itemValues) ) + { + rtl::Reference<ElementDescriptor> item = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":menuitem", _xDocument ); + item->addAttribute( XMLNS_DIALOGS_PREFIX ":value", rItemValue ); + popup->addSubElement( item ); + } + + addSubElement( popup ); + } + readEvents(); +} + +void ElementDescriptor::readListBoxModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "MultiSelection", XMLNS_DIALOGS_PREFIX ":multiselection" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "Dropdown", XMLNS_DIALOGS_PREFIX ":spin" ); + readShortAttr( "LineCount", XMLNS_DIALOGS_PREFIX ":linecount" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":linked-cell" ); + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":source-cell-range" ); + // string item list + Sequence< OUString > itemValues; + if ((readProp( "StringItemList" ) >>= itemValues) && itemValues.hasElements()) + { + rtl::Reference<ElementDescriptor> popup = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":menupopup", _xDocument ); + + for ( const auto& rItemValue : std::as_const(itemValues) ) + { + rtl::Reference<ElementDescriptor> item = new ElementDescriptor(_xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":menuitem", _xDocument ); + item->addAttribute( XMLNS_DIALOGS_PREFIX ":value", rItemValue ); + popup->addSubElement( item ); + } + + Sequence< sal_Int16 > selected; + if (readProp( "SelectedItems" ) >>= selected) + { + sal_Int16 const * pSelected = selected.getConstArray(); + for ( sal_Int32 nPos = selected.getLength(); nPos--; ) + { + ElementDescriptor * item = static_cast< ElementDescriptor * >( + popup->getSubElement( pSelected[ nPos ] ).get() ); + item->addAttribute( XMLNS_DIALOGS_PREFIX ":selected", "true" ); + } + } + + addSubElement( popup ); + } + readEvents(); +} + +void ElementDescriptor::readRadioButtonModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x8 | 0x20 | 0x40 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (readProp( "VisualEffect" ) >>= aStyle._visualEffect) + aStyle._set |= 0x40; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id" , all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr("Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readStringAttr( "Label", XMLNS_DIALOGS_PREFIX ":value" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readImageOrGraphicAttr(XMLNS_DIALOGS_PREFIX ":image-src"); + readImagePositionAttr( "ImagePosition", XMLNS_DIALOGS_PREFIX ":image-position" ); + readBoolAttr( "MultiLine", XMLNS_DIALOGS_PREFIX ":multiline" ); + readStringAttr( "GroupName", XMLNS_DIALOGS_PREFIX ":group-name" ); + + sal_Int16 nState = 0; + if (readProp( "State" ) >>= nState) + { + switch (nState) + { + case 0: + addAttribute(XMLNS_DIALOGS_PREFIX ":checked", "false" ); + break; + case 1: + addAttribute( XMLNS_DIALOGS_PREFIX ":checked", "true" ); + break; + default: + OSL_FAIL( "### unexpected radio state!" ); + break; + } + } + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":linked-cell" ); + readEvents(); +} + +void ElementDescriptor::readGroupBoxModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x2 | 0x8 | 0x20 ); + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + + OUString aTitle; + if (readProp( "Label" ) >>= aTitle) + { + rtl::Reference<ElementDescriptor> title = new ElementDescriptor( _xProps, _xPropState, XMLNS_DIALOGS_PREFIX ":title", _xDocument ); + title->addAttribute( XMLNS_DIALOGS_PREFIX ":value", aTitle ); + addSubElement( title ); + } + + readEvents(); +} + +void ElementDescriptor::readFixedTextModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readStringAttr( "Label", XMLNS_DIALOGS_PREFIX ":value" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readBoolAttr( "MultiLine", XMLNS_DIALOGS_PREFIX ":multiline" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "NoLabel", XMLNS_DIALOGS_PREFIX ":nolabel" ); + readEvents(); +} + +void ElementDescriptor::readFixedHyperLinkModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readStringAttr( "Label",XMLNS_DIALOGS_PREFIX ":value" ); + readStringAttr( "URL", XMLNS_DIALOGS_PREFIX ":url" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readBoolAttr( "MultiLine", XMLNS_DIALOGS_PREFIX ":multiline" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "NoLabel", XMLNS_DIALOGS_PREFIX ":nolabel" ); + readEvents(); +} + +void ElementDescriptor::readEditModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readBoolAttr( "HardLineBreaks", XMLNS_DIALOGS_PREFIX ":hard-linebreaks" ); + readBoolAttr( "HScroll", XMLNS_DIALOGS_PREFIX ":hscroll" ); + readBoolAttr( "VScroll", XMLNS_DIALOGS_PREFIX ":vscroll" ); + readShortAttr( "MaxTextLen", XMLNS_DIALOGS_PREFIX ":maxlength" ); + readBoolAttr( "MultiLine", XMLNS_DIALOGS_PREFIX ":multiline" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readStringAttr( "Text", XMLNS_DIALOGS_PREFIX ":value" ); + readLineEndFormatAttr( "LineEndFormat", XMLNS_DIALOGS_PREFIX ":lineend-format" ); + sal_Int16 nEcho = 0; + if (readProp( "EchoChar" ) >>= nEcho) + { + sal_Unicode cEcho = static_cast<sal_Unicode>(nEcho); + addAttribute( XMLNS_DIALOGS_PREFIX ":echochar", OUString( &cEcho, 1 ) ); + } + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":linked-cell" ); + readEvents(); +} + +void ElementDescriptor::readImageControlModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x4 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "ScaleImage", XMLNS_DIALOGS_PREFIX ":scale-image" ); + readImageScaleModeAttr( "ScaleMode", XMLNS_DIALOGS_PREFIX ":scale-mode" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readImageOrGraphicAttr(XMLNS_DIALOGS_PREFIX ":src"); + readEvents(); +} + +void ElementDescriptor::readFileControlModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readStringAttr( "Text", XMLNS_DIALOGS_PREFIX ":value" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readEvents(); +} + +void ElementDescriptor::readTreeControlModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readSelectionTypeAttr( "SelectionType", XMLNS_DIALOGS_PREFIX ":selectiontype" ); + + readBoolAttr( "RootDisplayed", XMLNS_DIALOGS_PREFIX ":rootdisplayed" ); + readBoolAttr( "ShowsHandles", XMLNS_DIALOGS_PREFIX ":showshandles" ); + readBoolAttr( "ShowsRootHandles", XMLNS_DIALOGS_PREFIX ":showsroothandles" ); + readBoolAttr( "Editable", XMLNS_DIALOGS_PREFIX ":editable" ); + readBoolAttr( "InvokesStopNodeEditing", XMLNS_DIALOGS_PREFIX ":invokesstopnodeediting" ); + readLongAttr( "RowHeight", XMLNS_DIALOGS_PREFIX ":rowheight" ); + readEvents(); +} + +void ElementDescriptor::readCurrencyFieldModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readBoolAttr( "StrictFormat", XMLNS_DIALOGS_PREFIX ":strict-format" ); + readStringAttr( "CurrencySymbol", XMLNS_DIALOGS_PREFIX ":currency-symbol" ); + readShortAttr( "DecimalAccuracy", XMLNS_DIALOGS_PREFIX ":decimal-accuracy" ); + readBoolAttr( "ShowThousandsSeparator", XMLNS_DIALOGS_PREFIX ":thousands-separator" ); + readDoubleAttr( "Value", XMLNS_DIALOGS_PREFIX ":value" ); + readDoubleAttr( "ValueMin", XMLNS_DIALOGS_PREFIX ":value-min" ); + readDoubleAttr( "ValueMax", XMLNS_DIALOGS_PREFIX ":value-max" ); + readDoubleAttr( "ValueStep", XMLNS_DIALOGS_PREFIX ":value-step" ); + readBoolAttr( "Spin", XMLNS_DIALOGS_PREFIX ":spin" ); + if (extract_throw<bool>( _xProps->getPropertyValue( "Repeat" ) )) + readLongAttr( "RepeatDelay", XMLNS_DIALOGS_PREFIX ":repeat", true /* force */ ); + readBoolAttr("PrependCurrencySymbol", XMLNS_DIALOGS_PREFIX ":prepend-symbol" ); + readBoolAttr( "EnforceFormat", XMLNS_DIALOGS_PREFIX ":enforce-format" ); + readEvents(); +} + +void ElementDescriptor::readDateFieldModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readBoolAttr( "StrictFormat", XMLNS_DIALOGS_PREFIX ":strict-format" ); + readDateFormatAttr( "DateFormat", XMLNS_DIALOGS_PREFIX ":date-format" ); + readBoolAttr( "DateShowCentury", XMLNS_DIALOGS_PREFIX ":show-century" ); + readDateAttr( "Date", XMLNS_DIALOGS_PREFIX ":value" ); + readDateAttr( "DateMin", XMLNS_DIALOGS_PREFIX ":value-min" ); + readDateAttr( "DateMax", XMLNS_DIALOGS_PREFIX ":value-max" ); + readBoolAttr( "Spin", XMLNS_DIALOGS_PREFIX ":spin" ); + if (extract_throw<bool>( _xProps->getPropertyValue( "Repeat" ) )) + readLongAttr( "RepeatDelay", XMLNS_DIALOGS_PREFIX ":repeat", true /* force */ ); + readBoolAttr( "Dropdown", XMLNS_DIALOGS_PREFIX ":dropdown" ); + readStringAttr( "Text", XMLNS_DIALOGS_PREFIX ":text" ); + readBoolAttr( "EnforceFormat", XMLNS_DIALOGS_PREFIX ":enforce-format" ); + readEvents(); +} + +void ElementDescriptor::readNumericFieldModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readBoolAttr( "StrictFormat", XMLNS_DIALOGS_PREFIX ":strict-format" ); + readShortAttr( "DecimalAccuracy", XMLNS_DIALOGS_PREFIX ":decimal-accuracy" ); + readBoolAttr( "ShowThousandsSeparator", XMLNS_DIALOGS_PREFIX ":thousands-separator" ); + readDoubleAttr( "Value", XMLNS_DIALOGS_PREFIX ":value" ); + readDoubleAttr( "ValueMin", XMLNS_DIALOGS_PREFIX ":value-min" ); + readDoubleAttr( "ValueMax", XMLNS_DIALOGS_PREFIX ":value-max" ); + readDoubleAttr( "ValueStep", XMLNS_DIALOGS_PREFIX ":value-step" ); + readBoolAttr( "Spin", XMLNS_DIALOGS_PREFIX ":spin" ); + if (extract_throw<bool>( _xProps->getPropertyValue( "Repeat" ) )) + readLongAttr( "RepeatDelay", XMLNS_DIALOGS_PREFIX ":repeat", true /* force */ ); + readBoolAttr( "EnforceFormat", XMLNS_DIALOGS_PREFIX ":enforce-format" ); + readEvents(); +} + +void ElementDescriptor::readTimeFieldModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop"); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readBoolAttr( "StrictFormat", XMLNS_DIALOGS_PREFIX ":strict-format" ); + readTimeFormatAttr( "TimeFormat", XMLNS_DIALOGS_PREFIX ":time-format" ); + readTimeAttr( "Time", XMLNS_DIALOGS_PREFIX ":value" ); + readTimeAttr( "TimeMin", XMLNS_DIALOGS_PREFIX ":value-min" ); + readTimeAttr( "TimeMax", XMLNS_DIALOGS_PREFIX ":value-max" ); + readBoolAttr( "Spin", XMLNS_DIALOGS_PREFIX ":spin" ); + if (extract_throw<bool>( _xProps->getPropertyValue( "Repeat" ) )) + readLongAttr( "RepeatDelay", XMLNS_DIALOGS_PREFIX ":repeat", true /* force */ ); + readStringAttr( "Text", XMLNS_DIALOGS_PREFIX ":text" ); + readBoolAttr( "EnforceFormat", XMLNS_DIALOGS_PREFIX ":enforce-format" ); + readEvents(); +} + +void ElementDescriptor::readPatternFieldModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "HideInactiveSelection", XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readBoolAttr( "StrictFormat", XMLNS_DIALOGS_PREFIX ":strict-format" ); + readStringAttr( "Text", XMLNS_DIALOGS_PREFIX ":value" ); + readShortAttr( "MaxTextLen", XMLNS_DIALOGS_PREFIX ":maxlength" ); + readStringAttr( "EditMask", XMLNS_DIALOGS_PREFIX ":edit-mask" ); + readStringAttr( "LiteralMask", XMLNS_DIALOGS_PREFIX ":literal-mask" ); + readEvents(); +} + +void ElementDescriptor::readFormattedFieldModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "ReadOnly", XMLNS_DIALOGS_PREFIX ":readonly" ); + readBoolAttr( "HideInactiveSelection",XMLNS_DIALOGS_PREFIX ":hide-inactive-selection" ); + readBoolAttr( "StrictFormat", XMLNS_DIALOGS_PREFIX ":strict-format" ); + readStringAttr( "Text", XMLNS_DIALOGS_PREFIX ":text" ); + readAlignAttr( "Align", XMLNS_DIALOGS_PREFIX ":align" ); + readShortAttr( "MaxTextLen", XMLNS_DIALOGS_PREFIX ":maxlength" ); + readBoolAttr( "Spin", XMLNS_DIALOGS_PREFIX ":spin" ); + if (extract_throw<bool>( _xProps->getPropertyValue( "Repeat" ) )) + readLongAttr( "RepeatDelay",XMLNS_DIALOGS_PREFIX ":repeat", true /* force */ ); + + Any a( readProp( "EffectiveDefault" ) ); + switch (a.getValueTypeClass()) + { + case TypeClass_DOUBLE: + addAttribute( XMLNS_DIALOGS_PREFIX ":value-default", OUString::number( *o3tl::forceAccess<double>(a) ) ); + break; + case TypeClass_STRING: + addAttribute( XMLNS_DIALOGS_PREFIX ":value-default", *o3tl::forceAccess<OUString>(a) ); + break; + default: + break; + } + readDoubleAttr( "EffectiveMin", XMLNS_DIALOGS_PREFIX ":value-min" ); + readDoubleAttr( "EffectiveMax", XMLNS_DIALOGS_PREFIX ":value-max" ); + readDoubleAttr( "EffectiveValue", XMLNS_DIALOGS_PREFIX ":value" ); + + // format spec + sal_Int32 nKey = 0; + if (readProp( "FormatKey" ) >>= nKey) + { + Reference< util::XNumberFormatsSupplier > xSupplier; + if (readProp( "FormatsSupplier" ) >>= xSupplier) + { + addNumberFormatAttr( + xSupplier->getNumberFormats()->getByKey( nKey ) ); + } + } + readBoolAttr( "TreatAsNumber", XMLNS_DIALOGS_PREFIX ":treat-as-number" ); + readBoolAttr( "EnforceFormat", XMLNS_DIALOGS_PREFIX ":enforce-format" ); + + readEvents(); +} + +void ElementDescriptor::readSpinButtonModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x4 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readOrientationAttr( "Orientation", XMLNS_DIALOGS_PREFIX ":align" ); + readLongAttr( "SpinIncrement", XMLNS_DIALOGS_PREFIX ":increment" ); + readLongAttr( "SpinValue", XMLNS_DIALOGS_PREFIX ":curval" ); + readLongAttr( "SpinValueMax", XMLNS_DIALOGS_PREFIX ":maxval" ); + readLongAttr( "SpinValueMin", XMLNS_DIALOGS_PREFIX ":minval" ); + readLongAttr( "Repeat", XMLNS_DIALOGS_PREFIX ":repeat" ); + readLongAttr( "RepeatDelay", XMLNS_DIALOGS_PREFIX ":repeat-delay" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readHexLongAttr( "SymbolColor", XMLNS_DIALOGS_PREFIX ":symbol-color" ); + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":linked-cell" ); + readEvents(); +} + +void ElementDescriptor::readFixedLineModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x2 | 0x8 | 0x20 ); + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readStringAttr( "Label", XMLNS_DIALOGS_PREFIX ":value" ); + readOrientationAttr( "Orientation", XMLNS_DIALOGS_PREFIX ":align" ); + readEvents(); +} + +void ElementDescriptor::readProgressBarModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x4 | 0x10 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readProp( "FillColor" ) >>= aStyle._descr) + aStyle._set |= 0x10; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readLongAttr( "ProgressValue", XMLNS_DIALOGS_PREFIX ":value" ); + readLongAttr( "ProgressValueMin", XMLNS_DIALOGS_PREFIX ":value-min" ); + readLongAttr( "ProgressValueMax", XMLNS_DIALOGS_PREFIX ":value-max" ); + readEvents(); +} + +void ElementDescriptor::readScrollBarModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x4 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults(); + readOrientationAttr( "Orientation", XMLNS_DIALOGS_PREFIX ":align" ); + readLongAttr( "BlockIncrement", XMLNS_DIALOGS_PREFIX ":pageincrement" ); + readLongAttr( "LineIncrement", XMLNS_DIALOGS_PREFIX ":increment" ); + readLongAttr( "ScrollValue", XMLNS_DIALOGS_PREFIX ":curpos" ); + readLongAttr( "ScrollValueMax", XMLNS_DIALOGS_PREFIX ":maxpos" ); + readLongAttr( "ScrollValueMin", XMLNS_DIALOGS_PREFIX ":minpos" ); + readLongAttr( "VisibleSize", XMLNS_DIALOGS_PREFIX ":visible-size" ); + readLongAttr( "RepeatDelay", XMLNS_DIALOGS_PREFIX ":repeat" ); + readBoolAttr( "Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop" ); + readBoolAttr( "LiveScroll", XMLNS_DIALOGS_PREFIX ":live-scroll" ); + readHexLongAttr( "SymbolColor", XMLNS_DIALOGS_PREFIX ":symbol-color" ); + readDataAwareAttr( XMLNS_DIALOGS_PREFIX ":linked-cell" ); + readEvents(); +} + +void ElementDescriptor::readGridControlModel( StyleBag * all_styles ) +{ + // collect styles + Style aStyle( 0x1 | 0x2 | 0x4 | 0x8 | 0x20 ); + if (readProp("BackgroundColor") >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readBorderProps( this, aStyle )) + aStyle._set |= 0x4; + if (readProp("TextColor") >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp("TextLineColor") >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id",all_styles->getStyleId( aStyle ) ); + } + // collect elements + readDefaults(); + readBoolAttr("Tabstop", XMLNS_DIALOGS_PREFIX ":tabstop"); + readVerticalAlignAttr( "VerticalAlign", XMLNS_DIALOGS_PREFIX ":valign"); + readSelectionTypeAttr( "SelectionModel", XMLNS_DIALOGS_PREFIX ":selectiontype"); + readBoolAttr( "ShowColumnHeader", XMLNS_DIALOGS_PREFIX ":showcolumnheader"); + readBoolAttr( "ShowRowHeader", XMLNS_DIALOGS_PREFIX ":showrowheader"); + readHexLongAttr( "GridLineColor", XMLNS_DIALOGS_PREFIX ":gridline-color"); + readBoolAttr( "UseGridLines", XMLNS_DIALOGS_PREFIX ":usegridlines" ); + readHexLongAttr( "HeaderBackgroundColor", XMLNS_DIALOGS_PREFIX ":headerbackground-color"); + readHexLongAttr( "HeaderTextColor", XMLNS_DIALOGS_PREFIX ":headertext-color"); + readHexLongAttr( "ActiveSelectionBackgroundColor", XMLNS_DIALOGS_PREFIX ":activeselectionbackground-color"); + readHexLongAttr( "ActiveSelectionTextColor", XMLNS_DIALOGS_PREFIX ":activeselectiontext-color"); + readHexLongAttr( "InactiveSelectionBackgroundColor", XMLNS_DIALOGS_PREFIX ":inactiveselectionbackground-color"); + readHexLongAttr( "InactiveSelectionTextColor", XMLNS_DIALOGS_PREFIX ":inactiveselectiontext-color"); + readEvents(); +} + +void ElementDescriptor::readDialogModel( StyleBag * all_styles ) +{ + // collect elements + addAttribute( "xmlns:" XMLNS_DIALOGS_PREFIX, XMLNS_DIALOGS_URI ); + addAttribute( "xmlns:" XMLNS_SCRIPT_PREFIX, XMLNS_SCRIPT_URI ); + + // collect styles + Style aStyle( 0x1 | 0x2 | 0x8 | 0x20 ); + if (readProp( "BackgroundColor" ) >>= aStyle._backgroundColor) + aStyle._set |= 0x1; + if (readProp( "TextColor" ) >>= aStyle._textColor) + aStyle._set |= 0x2; + if (readProp( "TextLineColor" ) >>= aStyle._textLineColor) + aStyle._set |= 0x20; + if (readFontProps( this, aStyle )) + aStyle._set |= 0x8; + if (aStyle._set) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", all_styles->getStyleId( aStyle ) ); + } + + // collect elements + readDefaults( false, false ); + readBoolAttr("Closeable", XMLNS_DIALOGS_PREFIX ":closeable" ); + readBoolAttr( "Moveable", XMLNS_DIALOGS_PREFIX ":moveable" ); + readBoolAttr( "Sizeable", XMLNS_DIALOGS_PREFIX ":resizeable" ); + readStringAttr( "Title", XMLNS_DIALOGS_PREFIX ":title" ); + + readScrollableSettings(); + Any aDecorationAny( _xProps->getPropertyValue( "Decoration" ) ); + bool bDecoration = false; + if ( (aDecorationAny >>= bDecoration) && !bDecoration ) + addAttribute( XMLNS_DIALOGS_PREFIX ":withtitlebar", "false" ); + readImageOrGraphicAttr(XMLNS_DIALOGS_PREFIX ":image-src"); + readEvents(); +} + +void ElementDescriptor::readBullitinBoard( StyleBag * all_styles ) +{ + // collect elements + ::std::vector< rtl::Reference<ElementDescriptor> > all_elements; + // read out all props + Reference< container::XNameContainer > xDialogModel( _xProps, UNO_QUERY ); + if ( !xDialogModel.is() ) + return; // #TODO throw??? + const Sequence< OUString > aElements( xDialogModel->getElementNames() ); + + rtl::Reference<ElementDescriptor> pRadioGroup; + + for ( const auto& rElement : aElements ) + { + Any aControlModel( xDialogModel->getByName( rElement ) ); + Reference< beans::XPropertySet > xProps; + OSL_VERIFY( aControlModel >>= xProps ); + if (! xProps.is()) + continue; + Reference< beans::XPropertyState > xPropState( xProps, UNO_QUERY ); + OSL_ENSURE( xPropState.is(), "no XPropertyState!" ); + if (! xPropState.is()) + continue; + Reference< lang::XServiceInfo > xServiceInfo( xProps, UNO_QUERY ); + OSL_ENSURE( xServiceInfo.is(), "no XServiceInfo!" ); + if (! xServiceInfo.is()) + continue; + + rtl::Reference<ElementDescriptor> pElem; + + // group up radio buttons + if ( xServiceInfo->supportsService( "com.sun.star.awt.UnoControlRadioButtonModel" ) ) + { + if (! pRadioGroup) // open radiogroup + { + pRadioGroup = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":radiogroup", _xDocument ); + all_elements.push_back( pRadioGroup ); + } + + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":radio", _xDocument ); + pElem->readRadioButtonModel( all_styles ); + pRadioGroup->addSubElement( pElem ); + } + else // no radio + { + pRadioGroup = nullptr; // close radiogroup + + if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlButtonModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":button", _xDocument ); + pElem->readButtonModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCheckBoxModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":checkbox", _xDocument ); + pElem->readCheckBoxModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlComboBoxModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":combobox", _xDocument ); + pElem->readComboBoxModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlListBoxModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":menulist", _xDocument ); + pElem->readListBoxModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlGroupBoxModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":titledbox", _xDocument ); + pElem->readGroupBoxModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoMultiPageModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":multipage", _xDocument ); + pElem->readMultiPageModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoFrameModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":frame", _xDocument ); + pElem->readFrameModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoPageModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":page", _xDocument ); + pElem->readPageModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedTextModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":text", _xDocument ); + pElem->readFixedTextModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlEditModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":textfield", _xDocument ); + pElem->readEditModel( all_styles ); + } + // FixedHyperLink + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedHyperlinkModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":linklabel", _xDocument ); + pElem->readFixedHyperLinkModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlImageControlModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":img", _xDocument ); + pElem->readImageControlModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFileControlModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":filecontrol", _xDocument ); + pElem->readFileControlModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.tree.TreeControlModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":treecontrol", _xDocument ); + pElem->readTreeControlModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlCurrencyFieldModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":currencyfield", _xDocument ); + pElem->readCurrencyFieldModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlDateFieldModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":datefield", _xDocument ); + pElem->readDateFieldModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlNumericFieldModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":numericfield", _xDocument ); + pElem->readNumericFieldModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlTimeFieldModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":timefield", _xDocument); + pElem->readTimeFieldModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlPatternFieldModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":patternfield", _xDocument ); + pElem->readPatternFieldModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFormattedFieldModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":formattedfield", _xDocument ); + pElem->readFormattedFieldModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlFixedLineModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":fixedline", _xDocument ); + pElem->readFixedLineModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlScrollBarModel" ) ) + { + pElem = new ElementDescriptor(xProps, xPropState, XMLNS_DIALOGS_PREFIX ":scrollbar", _xDocument ); + pElem->readScrollBarModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlSpinButtonModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":spinbutton", _xDocument ); + pElem->readSpinButtonModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.UnoControlProgressBarModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":progressmeter", _xDocument ); + pElem->readProgressBarModel( all_styles ); + } + else if (xServiceInfo->supportsService( "com.sun.star.awt.grid.UnoControlGridModel" ) ) + { + pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":table", _xDocument ); + pElem->readGridControlModel( all_styles ); + } + + if (pElem) + { + all_elements.push_back( pElem ); + } + else + { + OSL_FAIL( "unknown control type!" ); + continue; + } + } + } + for (const rtl::Reference<ElementDescriptor> & p : all_elements) + { + addSubElement( p ); + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_export.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_export.cxx new file mode 100644 index 000000000..cc561a08d --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/xmldlg_export.cxx @@ -0,0 +1,1419 @@ +/* -*- 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 "common.hxx" +#include "exp_share.hxx" +#include <xmlscript/xmlns.h> + +#include <o3tl/any.hxx> +#include <sal/log.hxx> +#include <tools/diagnose_ex.h> + +#include <com/sun/star/awt/CharSet.hpp> +#include <com/sun/star/awt/FontFamily.hpp> +#include <com/sun/star/awt/FontPitch.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/FontStrikeout.hpp> +#include <com/sun/star/awt/FontType.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/ImagePosition.hpp> +#include <com/sun/star/awt/ImageScaleMode.hpp> +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/awt/PushButtonType.hpp> +#include <com/sun/star/awt/VisualEffect.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/Time.hpp> +#include <tools/date.hxx> +#include <tools/time.hxx> + +#include <com/sun/star/io/XPersistObject.hpp> + +#include <com/sun/star/script/XScriptEventsSupplier.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> + +#include <com/sun/star/style/VerticalAlignment.hpp> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/Locale.hpp> + +#include <com/sun/star/view/SelectionType.hpp> + +#include <com/sun/star/form/binding/XListEntrySink.hpp> +#include <com/sun/star/form/binding/XBindableValue.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> +#include <com/sun/star/document/GraphicStorageHandler.hpp> +#include <com/sun/star/document/XGraphicStorageHandler.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> + +#include <comphelper/processfactory.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <rtl/ref.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace xmlscript +{ + +Reference< xml::sax::XAttributeList > Style::createElement() +{ + rtl::Reference<ElementDescriptor> pStyle = new ElementDescriptor( XMLNS_DIALOGS_PREFIX ":style" ); + + // style-id + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":style-id", _id ); + + // background-color + if (_set & 0x1) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":background-color", "0x" + OUString::number(_backgroundColor,16)); + } + + // text-color + if (_set & 0x2) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":text-color", "0x" + OUString::number(_textColor,16)); + } + + // textline-color + if (_set & 0x20) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":textline-color", "0x" + OUString::number(_textLineColor,16)); + } + + // fill-color + if (_set & 0x10) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":fill-color", "0x" + OUString::number(_fillColor,16)); + } + + // border + if (_set & 0x4) + { + switch (_border) + { + case BORDER_NONE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":border", "none" ); + break; + case BORDER_3D: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":border", "3d" ); + break; + case BORDER_SIMPLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":border", "simple" ); + break; + case BORDER_SIMPLE_COLOR: { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":border", "0x" + OUString::number(_borderColor,16)); + break; + } + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected border value!" ); + break; + } + } + + // visual effect (look) + if (_set & 0x40) + { + switch (_visualEffect) + { + case awt::VisualEffect::NONE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":look", "none" ); + break; + case awt::VisualEffect::LOOK3D: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":look", "3d" ); + break; + case awt::VisualEffect::FLAT: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":look", "simple" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected visual effect value!" ); + break; + } + } + + // font- + if (_set & 0x8) + { + awt::FontDescriptor def_descr; + + // dialog:font-name CDATA #IMPLIED + if (def_descr.Name != _descr.Name) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-name", _descr.Name ); + } + // dialog:font-height %numeric; #IMPLIED + if (def_descr.Height != _descr.Height) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-height", OUString::number( _descr.Height ) ); + } + // dialog:font-width %numeric; #IMPLIED + if (def_descr.Width != _descr.Width) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-width", OUString::number( _descr.Width ) ); + } + // dialog:font-stylename CDATA #IMPLIED + if (def_descr.StyleName != _descr.StyleName) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-stylename", _descr.StyleName ); + } + // dialog:font-family "(decorative|modern|roman|script|swiss|system)" #IMPLIED + if (def_descr.Family != _descr.Family) + { + switch (_descr.Family) + { + case awt::FontFamily::DECORATIVE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-family", "decorative" ); + break; + case awt::FontFamily::MODERN: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-family", "modern" ); + break; + case awt::FontFamily::ROMAN: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-family", "roman" ); + break; + case awt::FontFamily::SCRIPT: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-family", "script" ); + break; + case awt::FontFamily::SWISS: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-family", "swiss" ); + break; + case awt::FontFamily::SYSTEM: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-family", "system" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-family!" ); + break; + } + } + // dialog:font-charset "(ansi|mac|ibmpc_437|ibmpc_850|ibmpc_860|ibmpc_861|ibmpc_863|ibmpc_865|system|symbol)" #IMPLIED + if (def_descr.CharSet != _descr.CharSet) + { + switch (_descr.CharSet) + { + case awt::CharSet::ANSI: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "ansi" ); + break; + case awt::CharSet::MAC: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "mac" ); + break; + case awt::CharSet::IBMPC_437: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "ibmpc_437" ); + break; + case awt::CharSet::IBMPC_850: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "ibmpc_850" ); + break; + case awt::CharSet::IBMPC_860: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "ibmpc_860" ); + break; + case awt::CharSet::IBMPC_861: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "ibmpc_861" ); + break; + case awt::CharSet::IBMPC_863: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "ibmpc_863" ); + break; + case awt::CharSet::IBMPC_865: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "ibmpc_865" ); + break; + case awt::CharSet::SYSTEM: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "system" ); + break; + case awt::CharSet::SYMBOL: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charset", "symbol" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-charset!" ); + break; + } + } + // dialog:font-pitch "(fixed|variable)" #IMPLIED + if (def_descr.Pitch != _descr.Pitch) + { + switch (_descr.Pitch) + { + case awt::FontPitch::FIXED: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-pitch", "fixed" ); + break; + case awt::FontPitch::VARIABLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-pitch", "variable" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-pitch!" ); + break; + } + } + // dialog:font-charwidth CDATA #IMPLIED + if (def_descr.CharacterWidth != _descr.CharacterWidth) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-charwidth", OUString::number( _descr.CharacterWidth ) ); + } + // dialog:font-weight CDATA #IMPLIED + if (def_descr.Weight != _descr.Weight) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-weight", OUString::number( _descr.Weight ) ); + } + // dialog:font-slant "(oblique|italic|reverse_oblique|reverse_italic)" #IMPLIED + if (def_descr.Slant != _descr.Slant) + { + switch (_descr.Slant) + { + case awt::FontSlant_OBLIQUE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-slant", "oblique" ); + break; + case awt::FontSlant_ITALIC: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-slant", "italic" ); + break; + case awt::FontSlant_REVERSE_OBLIQUE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-slant", "reverse_oblique" ); + break; + case awt::FontSlant_REVERSE_ITALIC: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-slant", "reverse_italic" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-slant!" ); + break; + } + } + // dialog:font-underline "(single|double|dotted|dash|longdash|dashdot|dashdotdot|smallwave|wave|doublewave|bold|bolddotted|bolddash|boldlongdash|bolddashdot|bolddashdotdot|boldwave)" #IMPLIED + if (def_descr.Underline != _descr.Underline) + { + switch (_descr.Underline) + { + case awt::FontUnderline::SINGLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "single" ); + break; + case awt::FontUnderline::DOUBLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "double" ); + break; + case awt::FontUnderline::DOTTED: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "dotted" ); + break; + case awt::FontUnderline::DASH: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "dash" ); + break; + case awt::FontUnderline::LONGDASH: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "longdash" ); + break; + case awt::FontUnderline::DASHDOT: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "dashdot" ); + break; + case awt::FontUnderline::DASHDOTDOT: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "dashdotdot" ); + break; + case awt::FontUnderline::SMALLWAVE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "smallwave" ); + break; + case awt::FontUnderline::WAVE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "wave" ); + break; + case awt::FontUnderline::DOUBLEWAVE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "doublewave" ); + break; + case awt::FontUnderline::BOLD: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "bold" ); + break; + case awt::FontUnderline::BOLDDOTTED: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "bolddotted" ); + break; + case awt::FontUnderline::BOLDDASH: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "bolddash" ); + break; + case awt::FontUnderline::BOLDLONGDASH: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "boldlongdash" ); + break; + case awt::FontUnderline::BOLDDASHDOT: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "bolddashdot" ); + break; + case awt::FontUnderline::BOLDDASHDOTDOT: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "bolddashdotdot" ); + break; + case awt::FontUnderline::BOLDWAVE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-underline", "boldwave" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-underline!" ); + break; + } + } + // dialog:font-strikeout "(single|double|bold|slash|x)" #IMPLIED + if (def_descr.Strikeout != _descr.Strikeout) + { + switch (_descr.Strikeout) + { + case awt::FontStrikeout::SINGLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-strikeout", "single" ); + break; + case awt::FontStrikeout::DOUBLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-strikeout", "double" ); + break; + case awt::FontStrikeout::BOLD: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-strikeout", "bold" ); + break; + case awt::FontStrikeout::SLASH: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-strikeout", "slash" ); + break; + case awt::FontStrikeout::X: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-strikeout", "x" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-strikeout!" ); + break; + } + } + // dialog:font-orientation CDATA #IMPLIED + if (def_descr.Orientation != _descr.Orientation) + { + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-orientation", OUString::number( _descr.Orientation ) ); + } + // dialog:font-kerning %boolean; #IMPLIED + if (bool(def_descr.Kerning) != bool(_descr.Kerning)) + { + pStyle->addBoolAttr( XMLNS_DIALOGS_PREFIX ":font-kerning", _descr.Kerning ); + } + // dialog:font-wordlinemode %boolean; #IMPLIED + if (bool(def_descr.WordLineMode) != bool(_descr.WordLineMode)) + { + pStyle->addBoolAttr( XMLNS_DIALOGS_PREFIX ":font-wordlinemode", _descr.WordLineMode ); + } + // dialog:font-type "(raster|device|scalable)" #IMPLIED + if (def_descr.Type != _descr.Type) + { + switch (_descr.Type) + { + case awt::FontType::RASTER: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-type", "raster" ); + break; + case awt::FontType::DEVICE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-type", "device" ); + break; + case awt::FontType::SCALABLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-type", "scalable" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-type!" ); + break; + } + } + + // additional attributes not in FontDescriptor struct + // dialog:font-relief (none|embossed|engraved) #IMPLIED + switch (_fontRelief) + { + case awt::FontRelief::NONE: // don't export default + break; + case awt::FontRelief::EMBOSSED: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-relief", "embossed" ); + break; + case awt::FontRelief::ENGRAVED: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-relief", "engraved" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-relief!" ); + break; + } + // dialog:font-emphasismark (none|dot|circle|disc|accent|above|below) #IMPLIED + switch (_fontEmphasisMark) + { + case awt::FontEmphasisMark::NONE: // don't export default + break; + case awt::FontEmphasisMark::DOT: + pStyle->addAttribute(XMLNS_DIALOGS_PREFIX ":font-emphasismark", "dot" ); + break; + case awt::FontEmphasisMark::CIRCLE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-emphasismark", "circle" ); + break; + case awt::FontEmphasisMark::DISC: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-emphasismark", "disc" ); + break; + case awt::FontEmphasisMark::ACCENT: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-emphasismark", "accent" ); + break; + case awt::FontEmphasisMark::ABOVE: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-emphasismark", "above" ); + break; + case awt::FontEmphasisMark::BELOW: + pStyle->addAttribute( XMLNS_DIALOGS_PREFIX ":font-emphasismark", "below" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected font-emphasismark!" ); + break; + } + } + + return pStyle; +} + +void ElementDescriptor::addNumberFormatAttr( + Reference< beans::XPropertySet > const & xFormatProperties ) +{ + OUString sFormat; + lang::Locale locale; + OSL_VERIFY( xFormatProperties->getPropertyValue( "FormatString" ) >>= sFormat ); + OSL_VERIFY( xFormatProperties->getPropertyValue( "Locale" ) >>= locale ); + + addAttribute(XMLNS_DIALOGS_PREFIX ":format-code", sFormat ); + + // format-locale + LanguageTag aLanguageTag( locale); + OUString aStr; + if (aLanguageTag.isIsoLocale()) + { + // Old style "lll;CC" for compatibility, I really don't know what may + // consume this. + if (aLanguageTag.getCountry().isEmpty()) + aStr = aLanguageTag.getLanguage(); + else + aStr = aLanguageTag.getLanguage() + ";" + aLanguageTag.getCountry(); + } + else + { + aStr = aLanguageTag.getBcp47( false); + } + addAttribute( XMLNS_DIALOGS_PREFIX ":format-locale", aStr ); +} + +Any ElementDescriptor::readProp( OUString const & rPropName ) +{ + if (beans::PropertyState_DEFAULT_VALUE != _xPropState->getPropertyState( rPropName )) + { + return _xProps->getPropertyValue( rPropName ); + } + return Any(); +} + +void ElementDescriptor::readStringAttr( + OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE != + _xPropState->getPropertyState( rPropName )) + { + Any a( _xProps->getPropertyValue( rPropName ) ); + OUString v; + if (a >>= v) + addAttribute( rAttrName, v ); + else + SAL_WARN( "xmlscript.xmldlg", "### unexpected property type!" ); + } +} + +void ElementDescriptor::readHexLongAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE != _xPropState->getPropertyState( rPropName )) + { + Any a( _xProps->getPropertyValue( rPropName ) ); + if (auto n = o3tl::tryAccess<sal_uInt32>(a)) + { + addAttribute( rAttrName, "0x" + OUString::number(*n, 16) ); + } + } +} + +void ElementDescriptor::readDateFormatAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + if (auto n = o3tl::tryAccess<sal_Int16>(a)) + { + switch (*n) + { + case 0: + addAttribute( rAttrName, "system_short" ); + break; + case 1: + addAttribute( rAttrName, "system_short_YY" ); + break; + case 2: + addAttribute( rAttrName, "system_short_YYYY" ); + break; + case 3: + addAttribute( rAttrName, "system_long" ); + break; + case 4: + addAttribute( rAttrName, "short_DDMMYY" ); + break; + case 5: + addAttribute( rAttrName, "short_MMDDYY" ); + break; + case 6: + addAttribute( rAttrName, "short_YYMMDD" ); + break; + case 7: + addAttribute( rAttrName, "short_DDMMYYYY" ); + break; + case 8: + addAttribute( rAttrName, "short_MMDDYYYY" ); + break; + case 9: + addAttribute( rAttrName, "short_YYYYMMDD" ); + break; + case 10: + addAttribute( rAttrName, "short_YYMMDD_DIN5008" ); + break; + case 11: + addAttribute( rAttrName, "short_YYYYMMDD_DIN5008" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected date format!" ); + break; + } + } + else + OSL_FAIL( "### unexpected property type!" ); +} + +void ElementDescriptor::readDateAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + if (a.getValueTypeClass() == TypeClass_STRUCT && a.getValueType() == cppu::UnoType<util::Date>::get()) + { + util::Date aUDate; + if (a >>= aUDate) + { + ::Date aTDate(aUDate); + addAttribute( rAttrName, OUString::number( aTDate.GetDate() ) ); + } + else + OSL_FAIL( "### internal error" ); + } + else + OSL_FAIL( "### unexpected property type!" ); +} + +void ElementDescriptor::readTimeAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + if (a.getValueTypeClass() == TypeClass_STRUCT && a.getValueType() == cppu::UnoType<util::Time>::get()) + { + util::Time aUTime; + if (a >>= aUTime) + { + ::tools::Time aTTime(aUTime); + addAttribute( rAttrName, OUString::number( aTTime.GetTime() / ::tools::Time::nanoPerCenti ) ); + } + else + OSL_FAIL( "### internal error" ); + } + else + OSL_FAIL( "### unexpected property type!" ); +} + +void ElementDescriptor::readTimeFormatAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + if (auto n = o3tl::tryAccess<sal_Int16>(a)) + { + switch (*n) + { + case 0: + addAttribute( rAttrName, "24h_short" ); + break; + case 1: + addAttribute( rAttrName, "24h_long" ); + break; + case 2: + addAttribute( rAttrName, "12h_short" ); + break; + case 3: + addAttribute( rAttrName, "12h_long" ); + break; + case 4: + addAttribute( rAttrName, "Duration_short" ); + break; + case 5: + addAttribute( rAttrName, "Duration_long" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### unexpected time format!" ); + break; + } + } + else + OSL_FAIL( "### unexpected property type!" ); +} + +void ElementDescriptor::readAlignAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + if (auto n = o3tl::tryAccess<sal_Int16>(a)) + { + switch (*n) + { + case 0: + addAttribute( rAttrName, "left" ); + break; + case 1: + addAttribute( rAttrName, "center" ); + break; + case 2: + addAttribute( rAttrName, "right" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal alignment value!" ); + break; + } + } + else + OSL_FAIL( "### unexpected property type!" ); +} + +void ElementDescriptor::readVerticalAlignAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + if (a.getValueTypeClass() == TypeClass_ENUM && a.getValueType() == cppu::UnoType<style::VerticalAlignment>::get()) + { + style::VerticalAlignment eAlign; + a >>= eAlign; + switch (eAlign) + { + case style::VerticalAlignment_TOP: + addAttribute( rAttrName, "top" ); + break; + case style::VerticalAlignment_MIDDLE: + addAttribute( rAttrName, "center" ); + break; + case style::VerticalAlignment_BOTTOM: + addAttribute( rAttrName, "bottom" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal vertical alignment value!" ); + break; + } + } + else + OSL_FAIL( "### unexpected property type!" ); +} + +void ElementDescriptor::readImageOrGraphicAttr(OUString const & rAttrName) +{ + OUString sURL; + if (beans::PropertyState_DEFAULT_VALUE != _xPropState->getPropertyState("Graphic")) + { + uno::Reference<graphic::XGraphic> xGraphic; + _xProps->getPropertyValue("Graphic") >>= xGraphic; + if (xGraphic.is()) + { + Reference< document::XStorageBasedDocument > xDocStorage( _xDocument, UNO_QUERY ); + if ( xDocStorage.is() ) + { + Reference<XComponentContext> xContext = ::comphelper::getProcessComponentContext(); + uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler; + xGraphicStorageHandler.set(document::GraphicStorageHandler::createWithStorage(xContext, xDocStorage->getDocumentStorage())); + if (xGraphicStorageHandler.is()) + { + sURL = xGraphicStorageHandler->saveGraphic(xGraphic); + } + } + } + } + // tdf#130793 Above fails if the dialog is not part of a document. Export the ImageURL then. + if (sURL.isEmpty() + && beans::PropertyState_DEFAULT_VALUE != _xPropState->getPropertyState("ImageURL")) + { + _xProps->getPropertyValue("ImageURL") >>= sURL; + } + if (!sURL.isEmpty()) + addAttribute(rAttrName, sURL); +} + +void ElementDescriptor::readImageAlignAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + if (auto n = o3tl::tryAccess<sal_Int16>(a)) + { + switch (*n) + { + case 0: + addAttribute( rAttrName, "left" ); + break; + case 1: + addAttribute( rAttrName, "top" ); + break; + case 2: + addAttribute( rAttrName, "right" ); + break; + case 3: + addAttribute( rAttrName, "bottom" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal image alignment value!" ); + break; + } + } + else + OSL_FAIL( "### unexpected property type!" ); +} + +void ElementDescriptor::readImagePositionAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + auto n = o3tl::tryAccess<sal_Int16>(a); + if (!n) + return; + + switch (*n) + { + case awt::ImagePosition::LeftTop: + addAttribute( rAttrName, "left-top" ); + break; + case awt::ImagePosition::LeftCenter: + addAttribute( rAttrName, "left-center" ); + break; + case awt::ImagePosition::LeftBottom: + addAttribute( rAttrName, "left-bottom" ); + break; + case awt::ImagePosition::RightTop: + addAttribute( rAttrName, "right-top" ); + break; + case awt::ImagePosition::RightCenter: + addAttribute( rAttrName, "right-center" ); + break; + case awt::ImagePosition::RightBottom: + addAttribute( rAttrName, "right-bottom" ); + break; + case awt::ImagePosition::AboveLeft: + addAttribute( rAttrName, "top-left" ); + break; + case awt::ImagePosition::AboveCenter: + addAttribute( rAttrName, "top-center" ); + break; + case awt::ImagePosition::AboveRight: + addAttribute( rAttrName, "top-right" ); + break; + case awt::ImagePosition::BelowLeft: + addAttribute( rAttrName, "bottom-left" ); + break; + case awt::ImagePosition::BelowCenter: + addAttribute( rAttrName, "bottom-center" ); + break; + case awt::ImagePosition::BelowRight: + addAttribute( rAttrName, "bottom-right" ); + break; + case awt::ImagePosition::Centered: + addAttribute( rAttrName, "center" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal image position value!" ); + break; + } +} + +void ElementDescriptor::readButtonTypeAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + auto n = o3tl::tryAccess<sal_Int16>(a); + if (!n) + return; + + switch (static_cast<awt::PushButtonType>(*n)) + { + case awt::PushButtonType_STANDARD: + addAttribute( rAttrName, "standard" ); + break; + case awt::PushButtonType_OK: + addAttribute( rAttrName, "ok" ); + break; + case awt::PushButtonType_CANCEL: + addAttribute( rAttrName, "cancel" ); + break; + case awt::PushButtonType_HELP: + addAttribute( rAttrName, "help" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal button-type value!" ); + break; + } +} + +void ElementDescriptor::readOrientationAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + auto n = o3tl::tryAccess<sal_Int32>(a); + if (!n) + return; + + switch (*n) + { + case 0: + addAttribute( rAttrName, "horizontal" ); + break; + case 1: + addAttribute( rAttrName, "vertical" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal orientation value!" ); + break; + } +} + +void ElementDescriptor::readLineEndFormatAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any a( _xProps->getPropertyValue( rPropName ) ); + auto n = o3tl::tryAccess<sal_Int16>(a); + if (!n) + return; + + switch (*n) + { + case awt::LineEndFormat::CARRIAGE_RETURN: + addAttribute( rAttrName, "carriage-return" ); + break; + case awt::LineEndFormat::LINE_FEED: + addAttribute( rAttrName, "line-feed" ); + break; + case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: + addAttribute( rAttrName, "carriage-return-line-feed" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal line end format value!" ); + break; + } +} + +void ElementDescriptor::readDataAwareAttr( OUString const & rAttrName ) +{ + Reference< lang::XMultiServiceFactory > xFac; + if ( _xDocument.is() ) + xFac.set( _xDocument, uno::UNO_QUERY ); + + Reference< form::binding::XBindableValue > xBinding( _xProps, UNO_QUERY ); + + if ( xFac.is() && xBinding.is() && rAttrName == XMLNS_DIALOGS_PREFIX ":linked-cell" ) + { + try + { + Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellAddressConversion" ), uno::UNO_QUERY ); + Reference< beans::XPropertySet > xBindable( xBinding->getValueBinding(), UNO_QUERY ); + if ( xBindable.is() ) + { + table::CellAddress aAddress; + xBindable->getPropertyValue( "BoundCell" ) >>= aAddress; + xConvertor->setPropertyValue( "Address", Any( aAddress ) ); + OUString sAddress; + xConvertor->getPropertyValue( "PersistentRepresentation" ) >>= sAddress; + if ( !sAddress.isEmpty() ) + addAttribute( rAttrName, sAddress ); + + SAL_INFO("xmlscript.xmldlg", "*** Bindable value " << sAddress ); + + } + } + catch( uno::Exception& ) + { + } + } + Reference< form::binding::XListEntrySink > xEntrySink( _xProps, UNO_QUERY ); + if ( !(xEntrySink.is() && rAttrName == XMLNS_DIALOGS_PREFIX ":source-cell-range") ) + return; + + Reference< beans::XPropertySet > xListSource( xEntrySink->getListEntrySource(), UNO_QUERY ); + if ( !xListSource.is() ) + return; + + try + { + Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellRangeAddressConversion" ), uno::UNO_QUERY ); + + table::CellRangeAddress aAddress; + xListSource->getPropertyValue( "CellRange" ) >>= aAddress; + + OUString sAddress; + xConvertor->setPropertyValue( "Address", Any( aAddress ) ); + xConvertor->getPropertyValue( "PersistentRepresentation" ) >>= sAddress; + SAL_INFO("xmlscript.xmldlg","**** cell range source list " << sAddress ); + if ( !sAddress.isEmpty() ) + addAttribute( rAttrName, sAddress ); + } + catch( uno::Exception& ) + { + } +} + +void ElementDescriptor::readSelectionTypeAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any aSelectionType ( _xProps->getPropertyValue( rPropName ) ); + + if (aSelectionType.getValueTypeClass() != TypeClass_ENUM || + aSelectionType.getValueType() != cppu::UnoType<view::SelectionType>::get()) + return; + + ::view::SelectionType eSelectionType; + aSelectionType >>= eSelectionType; + + switch (eSelectionType) + { + case ::view::SelectionType_NONE: + addAttribute( rAttrName, "none" ); + break; + case ::view::SelectionType_SINGLE: + addAttribute( rAttrName, "single" ); + break; + case ::view::SelectionType_MULTI: + addAttribute( rAttrName, "multi" ); + break; + case ::view::SelectionType_RANGE: + addAttribute( rAttrName, "range" ); + break; + default: + SAL_WARN( "xmlscript.xmldlg", "### illegal selection type value!" ); + break; + } +} + +void ElementDescriptor::readScrollableSettings() +{ + readLongAttr( "ScrollHeight", + XMLNS_DIALOGS_PREFIX ":scrollheight" ); + readLongAttr( "ScrollWidth", + XMLNS_DIALOGS_PREFIX ":scrollwidth" ); + readLongAttr( "ScrollTop", + XMLNS_DIALOGS_PREFIX ":scrolltop" ); + readLongAttr( "ScrollLeft", + XMLNS_DIALOGS_PREFIX ":scrollleft" ); + readBoolAttr( "HScroll", + XMLNS_DIALOGS_PREFIX ":hscroll" ); + readBoolAttr( "VScroll", + XMLNS_DIALOGS_PREFIX ":vscroll" ); +} + +void ElementDescriptor::readImageScaleModeAttr( OUString const & rPropName, OUString const & rAttrName ) +{ + if (beans::PropertyState_DEFAULT_VALUE == _xPropState->getPropertyState( rPropName )) + return; + + Any aImageScaleMode( _xProps->getPropertyValue( rPropName ) ); + + if (aImageScaleMode.getValueTypeClass() != TypeClass_SHORT) + return; + + sal_Int16 nImageScaleMode = 0; + aImageScaleMode >>= nImageScaleMode; + + switch(nImageScaleMode) + { + case ::awt::ImageScaleMode::NONE: + addAttribute( rAttrName, "none" ); + break; + case ::awt::ImageScaleMode::ISOTROPIC: + addAttribute( rAttrName, "isotropic" ); + break; + case ::awt::ImageScaleMode::ANISOTROPIC: + addAttribute( rAttrName, "anisotropic" ); + break; + default: + OSL_ENSURE( false, "### illegal image scale mode value."); + break; + } +} + +void ElementDescriptor::readDefaults( bool supportPrintable, bool supportVisible ) +{ + Any a( _xProps->getPropertyValue( "Name" ) ); + + // The following is a hack to allow 'form' controls to override the default + // control supported by dialogs. This should work well for both VBA support and + // normal LibreOffice (when normal 'Dialogs' decide to support form control models) + // In the future VBA support might require custom models ( and not the just the form + // variant of a control that we currently use ) In this case the door is still open, + // we just need to define a new way for the 'ServiceName' to be extracted from the + // incoming model. E.g. the use of supporting service + // "com.sun.star.form.FormComponent", 'ServiceName' and XPersistObject + // is only an implementation detail here, in the future some other + // method (perhaps a custom prop) could be used instead. + Reference< lang::XServiceInfo > xSrvInfo( _xProps, UNO_QUERY ); + if ( xSrvInfo.is() && xSrvInfo->supportsService( "com.sun.star.form.FormComponent" ) ) + { + Reference< io::XPersistObject > xPersist( _xProps, UNO_QUERY ); + if ( xPersist.is() ) + { + OUString sCtrlName = xPersist->getServiceName(); + if ( !sCtrlName.isEmpty() ) + addAttribute( XMLNS_DIALOGS_PREFIX ":control-implementation", sCtrlName ); + } + } + addAttribute( XMLNS_DIALOGS_PREFIX ":id", *o3tl::doAccess<OUString>(a) ); + readShortAttr( "TabIndex", XMLNS_DIALOGS_PREFIX ":tab-index" ); + + bool bEnabled = false; + if (_xProps->getPropertyValue( "Enabled" ) >>= bEnabled) + { + if (! bEnabled) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":disabled", "true" ); + } + } + else + { + SAL_WARN( "xmlscript.xmldlg", "unexpected property type for \"Enabled\": not bool!" ); + } + + if (supportVisible) try + { + bool bVisible = true; + if (_xProps->getPropertyValue("EnableVisible" ) >>= bVisible) + { + + // only write out the non default case + if (! bVisible) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":visible", "false" ); + } + } + } + catch( Exception& ) + { + DBG_UNHANDLED_EXCEPTION("xmlscript.xmldlg"); + } + // force writing of pos/size + a = _xProps->getPropertyValue( "PositionX" ); + if (auto n = o3tl::tryAccess<sal_Int32>(a)) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":left", OUString::number(*n) ); + } + a = _xProps->getPropertyValue( "PositionY" ); + if (auto n = o3tl::tryAccess<sal_Int32>(a)) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":top", OUString::number(*n) ); + } + a = _xProps->getPropertyValue( "Width" ); + if (auto n = o3tl::tryAccess<sal_Int32>(a)) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":width", OUString::number(*n) ); + } + a = _xProps->getPropertyValue( "Height" ); + if (auto n = o3tl::tryAccess<sal_Int32>(a)) + { + addAttribute( XMLNS_DIALOGS_PREFIX ":height", OUString::number(*n) ); + } + + if (supportPrintable) + { + readBoolAttr( "Printable", XMLNS_DIALOGS_PREFIX ":printable" ); + } + readLongAttr( "Step", XMLNS_DIALOGS_PREFIX ":page" ); + readStringAttr( "Tag", XMLNS_DIALOGS_PREFIX ":tag" ); + readStringAttr( "HelpText", XMLNS_DIALOGS_PREFIX ":help-text" ); + readStringAttr( "HelpURL", XMLNS_DIALOGS_PREFIX ":help-url" ); +} + +void ElementDescriptor::readEvents() +{ + Reference< script::XScriptEventsSupplier > xSupplier( _xProps, UNO_QUERY ); + if (!xSupplier.is()) + return; + + Reference< container::XNameContainer > xEvents( xSupplier->getEvents() ); + if (!xEvents.is()) + return; + + const Sequence< OUString > aNames( xEvents->getElementNames() ); + for ( const auto& rName : aNames ) + { + script::ScriptEventDescriptor descr; + if (xEvents->getByName( rName ) >>= descr) + { + SAL_WARN_IF( descr.ListenerType.isEmpty() || + descr.EventMethod.isEmpty() || + descr.ScriptCode.isEmpty() || + descr.ScriptType.isEmpty() , "xmlscript.xmldlg", "### invalid event descr!" ); + + OUString aEventName; + + if (descr.AddListenerParam.isEmpty()) + { + // detection of event-name + OString listenerType( OUStringToOString( descr.ListenerType, RTL_TEXTENCODING_ASCII_US ) ); + OString eventMethod( OUStringToOString( descr.EventMethod, RTL_TEXTENCODING_ASCII_US ) ); + StringTriple const * p = g_pEventTranslations; + while (p->first) + { + if (0 == ::rtl_str_compare( p->second, eventMethod.getStr() ) && + 0 == ::rtl_str_compare( p->first, listenerType.getStr() )) + { + aEventName = OUString( p->third, ::rtl_str_getLength( p->third ), RTL_TEXTENCODING_ASCII_US ); + break; + } + ++p; + } + } + + rtl::Reference<ElementDescriptor> pElem; + + if (!aEventName.isEmpty()) // script:event + { + pElem = new ElementDescriptor( XMLNS_SCRIPT_PREFIX ":event" ); + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":event-name", aEventName ); + } + else // script:listener-event + { + pElem = new ElementDescriptor( XMLNS_SCRIPT_PREFIX ":listener-event" ); + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":listener-type", descr.ListenerType ); + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":listener-method", descr.EventMethod ); + + if (!descr.AddListenerParam.isEmpty()) + { + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":listener-param", descr.AddListenerParam ); + } + } + if ( descr.ScriptType == "StarBasic" ) + { + // separate optional location + sal_Int32 nIndex = descr.ScriptCode.indexOf( ':' ); + if (nIndex >= 0) + { + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":location", descr.ScriptCode.copy( 0, nIndex ) ); + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":macro-name", descr.ScriptCode.copy( nIndex +1 ) ); + } + else + { + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":macro-name", descr.ScriptCode ); + } + } + else + { + pElem->addAttribute(XMLNS_SCRIPT_PREFIX ":macro-name", descr.ScriptCode ); + } + + // language + pElem->addAttribute( XMLNS_SCRIPT_PREFIX ":language", descr.ScriptType ); + + addSubElement( pElem ); + } + else + { + SAL_WARN( "xmlscript.xmldlg", "### unexpected event type in container!" ); + } + } +} + +static bool equalFont( Style const & style1, Style const & style2 ) +{ + awt::FontDescriptor const & f1 = style1._descr; + awt::FontDescriptor const & f2 = style2._descr; + return ( + f1.Name == f2.Name && + f1.Height == f2.Height && + f1.Width == f2.Width && + f1.StyleName == f2.StyleName && + f1.Family == f2.Family && + f1.CharSet == f2.CharSet && + f1.Pitch == f2.Pitch && + f1.CharacterWidth == f2.CharacterWidth && + f1.Weight == f2.Weight && + f1.Slant == f2.Slant && + f1.Underline == f2.Underline && + f1.Strikeout == f2.Strikeout && + f1.Orientation == f2.Orientation && + bool(f1.Kerning) == bool(f2.Kerning) && + bool(f1.WordLineMode) == bool(f2.WordLineMode) && + f1.Type == f2.Type && + style1._fontRelief == style2._fontRelief && + style1._fontEmphasisMark == style2._fontEmphasisMark + ); +} + +OUString StyleBag::getStyleId( Style const & rStyle ) +{ + if (! rStyle._set) // nothing set + { + return OUString(); // everything default: no need to export a specific style + } + + // lookup existing style + for (auto & rExistingStyle : _styles) + { + short demanded_defaults = ~rStyle._set & rStyle._all; + // test, if defaults are not set + if ((~rExistingStyle._set & demanded_defaults) == demanded_defaults && + (rStyle._set & (rExistingStyle._all & ~rExistingStyle._set)) == 0) + { + short bset = rStyle._set & rExistingStyle._set; + if ((bset & 0x1) && + rStyle._backgroundColor != rExistingStyle._backgroundColor) + continue; + if ((bset & 0x2) && + rStyle._textColor != rExistingStyle._textColor) + continue; + if ((bset & 0x20) && + rStyle._textLineColor != rExistingStyle._textLineColor) + continue; + if ((bset & 0x10) && + rStyle._fillColor != rExistingStyle._fillColor) + continue; + if ((bset & 0x4) && + (rStyle._border != rExistingStyle._border || + (rStyle._border == BORDER_SIMPLE_COLOR && + rStyle._borderColor != rExistingStyle._borderColor))) + continue; + if ((bset & 0x8) && + !equalFont( rStyle, rExistingStyle )) + continue; + if ((bset & 0x40) && + rStyle._visualEffect != rExistingStyle._visualEffect) + continue; + + // merge in + short bnset = rStyle._set & ~rExistingStyle._set; + if (bnset & 0x1) + rExistingStyle._backgroundColor = rStyle._backgroundColor; + if (bnset & 0x2) + rExistingStyle._textColor = rStyle._textColor; + if (bnset & 0x20) + rExistingStyle._textLineColor = rStyle._textLineColor; + if (bnset & 0x10) + rExistingStyle._fillColor = rStyle._fillColor; + if (bnset & 0x4) { + rExistingStyle._border = rStyle._border; + rExistingStyle._borderColor = rStyle._borderColor; + } + if (bnset & 0x8) { + rExistingStyle._descr = rStyle._descr; + rExistingStyle._fontRelief = rStyle._fontRelief; + rExistingStyle._fontEmphasisMark = rStyle._fontEmphasisMark; + } + if (bnset & 0x40) + rExistingStyle._visualEffect = rStyle._visualEffect; + + rExistingStyle._all |= rStyle._all; + rExistingStyle._set |= rStyle._set; + + return rExistingStyle._id; + } + } + + // no appr style found, append new + Style aNewStyle( rStyle ); + aNewStyle._id = OUString::number( _styles.size() ); + _styles.push_back( aNewStyle ); + return _styles.back()._id; +} + +StyleBag::~StyleBag() +{ +} + +void StyleBag::dump( Reference< xml::sax::XExtendedDocumentHandler > const & xOut ) +{ + if ( _styles.empty()) + return; + + OUString aStylesName( XMLNS_DIALOGS_PREFIX ":styles" ); + xOut->ignorableWhitespace( OUString() ); + xOut->startElement( aStylesName, Reference< xml::sax::XAttributeList >() ); + // export styles + for (auto & _style : _styles) + { + Reference< xml::sax::XAttributeList > xAttr( _style.createElement() ); + static_cast< ElementDescriptor * >( xAttr.get() )->dump( xOut ); + } + xOut->ignorableWhitespace( OUString() ); + xOut->endElement( aStylesName ); +} + +void exportDialogModel( + Reference< xml::sax::XExtendedDocumentHandler > const & xOut, + Reference< container::XNameContainer > const & xDialogModel, + Reference< frame::XModel > const & xDocument ) +{ + StyleBag all_styles; + // window + Reference< beans::XPropertySet > xProps( xDialogModel, UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + Reference< beans::XPropertyState > xPropState( xProps, UNO_QUERY ); + OSL_ASSERT( xPropState.is() ); + + rtl::Reference<ElementDescriptor> pElem = new ElementDescriptor( xProps, xPropState, XMLNS_DIALOGS_PREFIX ":bulletinboard", xDocument ); + pElem->readBullitinBoard( &all_styles ); + + xOut->startDocument(); + + xOut->unknown( + "<!DOCTYPE dlg:window PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\"" + " \"dialog.dtd\">" ); + xOut->ignorableWhitespace( OUString() ); + + OUString aWindowName( XMLNS_DIALOGS_PREFIX ":window" ); + rtl::Reference<ElementDescriptor> pWindow = new ElementDescriptor( xProps, xPropState, aWindowName, xDocument ); + pWindow->readDialogModel( &all_styles ); + xOut->ignorableWhitespace( OUString() ); + xOut->startElement( aWindowName, pWindow ); + // dump out events + pWindow->dumpSubElements( xOut ); + // dump out stylebag + all_styles.dump( xOut ); + + if ( xDialogModel->getElementNames().hasElements() ) + { + // open up bulletinboard + OUString aBBoardName( XMLNS_DIALOGS_PREFIX ":bulletinboard" ); + xOut->ignorableWhitespace( OUString() ); + xOut->startElement( aBBoardName, pElem ); + + pElem->dumpSubElements( xOut ); + // end bulletinboard + xOut->ignorableWhitespace( OUString() ); + xOut->endElement( aBBoardName ); + } + + // end window + xOut->ignorableWhitespace( OUString() ); + xOut->endElement( aWindowName ); + + xOut->endDocument(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx new file mode 100644 index 000000000..bea460715 --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx @@ -0,0 +1,1901 @@ +/* -*- 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 "imp_share.hxx" +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/util/MalformedNumberFormatException.hpp> +#include <com/sun/star/xml/sax/SAXException.hpp> + +#include <cppuhelper/exc_hlp.hxx> +#include <sal/log.hxx> +#include <tools/diagnose_ex.h> +#include <i18nlangtag/languagetag.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace xmlscript +{ + +Reference< xml::input::XElement > Frame::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if ( !m_xContainer.is() ) + m_xContainer.set( m_pImport->_xDialogModelFactory->createInstance( "com.sun.star.awt.UnoFrameModel" ), UNO_QUERY ); + // event + if (m_pImport->isEventElement( nUid, rLocalName )) + { + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); + } + else if ( rLocalName == "bulletinboard" ) + { + // Create new DialogImport for this container + rtl::Reference<DialogImport> pFrameImport = new DialogImport( *m_pImport ); + pFrameImport->_xDialogModel = m_xContainer; + return new BulletinBoardElement( rLocalName, xAttributes, this, pFrameImport.get() ); + } + else if ( rLocalName == "title" ) + { + getStringAttr( &_label, "value", xAttributes, m_pImport->XMLNS_DIALOGS_UID ); + + return new ElementBase( m_pImport->XMLNS_DIALOGS_UID, rLocalName, xAttributes, this, m_pImport ); + } + else + { + SAL_INFO("xmlscript.xmldlg","****** ARGGGGG!!!! **********"); + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } +} + +void Frame::endElement() +{ + if ( !m_xContainer.is() ) + m_xContainer.set( m_pImport->_xDialogModelFactory->createInstance( "com.sun.star.awt.UnoFrameModel" ), UNO_QUERY ); + Reference< beans::XPropertySet > xProps( m_xContainer, UNO_QUERY_THROW ); + // m_pImport is what we need to add to ( e.g. the dialog in this case ) + ControlImportContext ctx( m_pImport, xProps, getControlId( _xAttributes ) ); + + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( 0, 0, _xAttributes ); // inherited from BulletinBoardElement + if (!_label.isEmpty()) + { + xControlModel->setPropertyValue( "Label" , Any( _label ) ); + } + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + + +Reference< xml::input::XElement > MultiPage::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (m_pImport->isEventElement( nUid, rLocalName )) + { + return new EventElement( + nUid, rLocalName, xAttributes, this, m_pImport ); + } + else if ( rLocalName == "bulletinboard" ) + { + // Create new DialogImport for this container + + rtl::Reference<DialogImport> pMultiPageImport = new DialogImport( *m_pImport ); + pMultiPageImport->_xDialogModel = m_xContainer; + return new BulletinBoardElement( rLocalName, xAttributes, this, pMultiPageImport.get() ); + } + else + { + + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } +} + +void MultiPage::endElement() +{ + Reference< beans::XPropertySet > xProps( m_xContainer, UNO_QUERY_THROW ); + // m_pImport is what we need to add to ( e.g. the dialog in this case ) + ControlImportContext ctx( m_pImport, xProps, getControlId( _xAttributes )); + + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + pStyle->importBackgroundColorStyle( xControlModel ); + } + + ctx.importDefaults( 0, 0, _xAttributes ); // inherited from BulletinBoardElement + ctx.importLongProperty("MultiPageValue" , "value", _xAttributes ); + ctx.importBooleanProperty( "Decoration", "withtabs", _xAttributes) ; + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +Reference< xml::input::XElement > Page::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (m_pImport->isEventElement( nUid, rLocalName )) + { + return new EventElement( + nUid, rLocalName, xAttributes, this, m_pImport ); + } + else if ( rLocalName == "bulletinboard" ) + { + + rtl::Reference<DialogImport> pPageImport = new DialogImport( *m_pImport ); + pPageImport->_xDialogModel = m_xContainer; + return new BulletinBoardElement( rLocalName, xAttributes, this, pPageImport.get() ); + } + else + { + + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } +} + +void Page::endElement() +{ + Reference< beans::XPropertySet > xProps( m_xContainer, UNO_QUERY_THROW ); + + ControlImportContext ctx( m_pImport, xProps, getControlId( _xAttributes )); + + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + pStyle->importBackgroundColorStyle( xControlModel ); + } + + ctx.importDefaults( 0, 0, _xAttributes ); // inherited from BulletinBoardElement + ctx.importStringProperty( "Title", "title", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// progressmeter +Reference< xml::input::XElement > ProgressBarElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( + nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void ProgressBarElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlProgressBarModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFillColorStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importLongProperty( "ProgressValue", "value", _xAttributes ); + ctx.importLongProperty( "ProgressValueMin", "value-min", _xAttributes ); + ctx.importLongProperty( "ProgressValueMax", "value-max", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// scrollbar +Reference< xml::input::XElement > ScrollBarElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void ScrollBarElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), getControlModelName( "com.sun.star.awt.UnoControlScrollBarModel" , _xAttributes ) ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importOrientationProperty( "Orientation" , "align", _xAttributes ); + ctx.importLongProperty( "BlockIncrement" , "pageincrement" , _xAttributes ); + ctx.importLongProperty( "LineIncrement" , "increment" , _xAttributes ); + ctx.importLongProperty( "ScrollValue" ,"curpos", _xAttributes ); + ctx.importLongProperty( "ScrollValueMax" , "maxpos" , _xAttributes ); + ctx.importLongProperty( "ScrollValueMin","minpos", _xAttributes ); + ctx.importLongProperty( "VisibleSize", "visible-size", _xAttributes ); + ctx.importLongProperty( "RepeatDelay", "repeat", _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop" , _xAttributes ); + ctx.importBooleanProperty( "LiveScroll", "live-scroll", _xAttributes ); + ctx.importHexLongProperty( "SymbolColor", "symbol-color", _xAttributes ); + + ctx.importDataAwareProperty( "linked-cell" , _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// spinbutton +Reference< xml::input::XElement > SpinButtonElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void SpinButtonElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), getControlModelName( "com.sun.star.awt.UnoControlSpinButtonModel", _xAttributes ) ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importOrientationProperty( "Orientation", "align", _xAttributes ); + ctx.importLongProperty("SpinIncrement", "increment", _xAttributes ); + ctx.importLongProperty("SpinValue", "curval" ,_xAttributes ); + ctx.importLongProperty("SpinValueMax", "maxval", _xAttributes ); + ctx.importLongProperty( "SpinValueMin","minval",_xAttributes ); + ctx.importLongProperty( "Repeat", "repeat", _xAttributes ); + ctx.importLongProperty( "RepeatDelay", "repeat-delay",_xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importHexLongProperty( "SymbolColor", "symbol-color" , _xAttributes ); + ctx.importDataAwareProperty( "linked-cell" , _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// fixedline +Reference< xml::input::XElement > FixedLineElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void FixedLineElement::endElement() +{ + ControlImportContext ctx(m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlFixedLineModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importStringProperty( "Label", "value", _xAttributes ); + ctx.importOrientationProperty( "Orientation", "align", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// patternfield +Reference< xml::input::XElement > PatternFieldElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void PatternFieldElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlPatternFieldModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly" , _xAttributes ); + ctx.importBooleanProperty( "StrictFormat", "strict-format", _xAttributes ); + ctx.importBooleanProperty( "HideInactiveSelection", "hide-inactive-selection", _xAttributes ); + ctx.importStringProperty( "Text", "value", _xAttributes ); + ctx.importShortProperty( "MaxTextLen", "maxlength", _xAttributes ); + ctx.importStringProperty( "EditMask", "edit-mask", _xAttributes ); + ctx.importStringProperty( "LiteralMask", "literal-mask", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// formattedfield +Reference< xml::input::XElement > FormattedFieldElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void FormattedFieldElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlFormattedFieldModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly" , _xAttributes ); + ctx.importBooleanProperty( "StrictFormat", "strict-format" , _xAttributes ); + ctx.importBooleanProperty( "HideInactiveSelection", "hide-inactive-selection", _xAttributes ); + ctx.importAlignProperty( "Align" , "align" , _xAttributes ); + ctx.importDoubleProperty( "EffectiveMin", "value-min" , _xAttributes ); + ctx.importDoubleProperty( "EffectiveMax", "value-max", _xAttributes); + ctx.importDoubleProperty( "EffectiveValue", "value", _xAttributes ); + ctx.importStringProperty( "Text", "text", _xAttributes ); + ctx.importShortProperty( "MaxTextLen", "maxlength", _xAttributes ); + ctx.importBooleanProperty( "Spin", "spin", _xAttributes ); + if (ctx.importLongProperty( "RepeatDelay", "repeat", _xAttributes )) + ctx.getControlModel()->setPropertyValue( "Repeat" , Any(true) ); + + OUString sDefault(_xAttributes->getValueByUidName(m_pImport->XMLNS_DIALOGS_UID, "value-default") ); + if (!sDefault.isEmpty()) + { + double d = sDefault.toDouble(); + if (d != 0.0 || sDefault == "0" || sDefault == "0.0" ) + { + ctx.getControlModel()->setPropertyValue( "EffectiveDefault", Any( d ) ); + } + else // treat as string + { + ctx.getControlModel()->setPropertyValue( "EffectiveDefault", Any( sDefault ) ); + } + } + + // format spec + ctx.getControlModel()->setPropertyValue("FormatsSupplier", Any( m_pImport->getNumberFormatsSupplier() ) ); + + OUString sFormat( _xAttributes->getValueByUidName(m_pImport->XMLNS_DIALOGS_UID, "format-code" ) ); + if (!sFormat.isEmpty()) + { + lang::Locale locale; + + OUString sLocale( _xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID, "format-locale" ) ); + if (!sLocale.isEmpty()) + { + // split locale + // Don't know what may have written what we read here, so parse all + // old style including the trailing ";Variant" if present. + sal_Int32 semi0 = sLocale.indexOf( ';' ); + if (semi0 < 0) // no semi at all, try new BCP47 or just language + { + locale = LanguageTag::convertToLocale( sLocale, false); + } + else + { + sal_Int32 semi1 = sLocale.indexOf( ';', semi0 +1 ); + if (semi1 > semi0) // language;country;variant + { + SAL_WARN( "xmlscript.xmldlg", "format-locale with variant that is ignored: " << sLocale); + locale.Language = sLocale.copy( 0, semi0 ); + locale.Country = sLocale.copy( semi0 +1, semi1 - semi0 -1 ); + // Ignore Variant that no one knows what it would be. + } + else // language;country + { + locale.Language = sLocale.copy( 0, semi0 ); + locale.Country = sLocale.copy( semi0 +1 ); + } + } + } + + try + { + Reference< util::XNumberFormats > xFormats( + m_pImport->getNumberFormatsSupplier()->getNumberFormats() ); + sal_Int32 nKey = xFormats->queryKey( sFormat, locale, true ); + if (-1 == nKey) + { + nKey = xFormats->addNew( sFormat, locale ); + } + ctx.getControlModel()->setPropertyValue("FormatKey", Any( nKey ) ); + } + catch (const util::MalformedNumberFormatException & exc) + { + css::uno::Any anyEx = cppu::getCaughtException(); + SAL_WARN( "xmlscript.xmldlg", exceptionToString(anyEx) ); + // rethrow + throw xml::sax::SAXException( exc.Message, Reference< XInterface >(), anyEx ); + } + } + ctx.importBooleanProperty("TreatAsNumber", "treat-as-number" , _xAttributes ); + ctx.importBooleanProperty("EnforceFormat", "enforce-format", _xAttributes ); + + ctx.importDataAwareProperty( "linked-cell" , _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// timefield +Reference< xml::input::XElement > TimeFieldElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void TimeFieldElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlTimeFieldModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty("Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty("ReadOnly", "readonly", _xAttributes ); + ctx.importBooleanProperty( "StrictFormat", "strict-format", _xAttributes ); + ctx.importBooleanProperty("HideInactiveSelection","hide-inactive-selection", _xAttributes ); + ctx.importTimeFormatProperty( "TimeFormat", "time-format", _xAttributes ); + ctx.importTimeProperty( "Time", "value", _xAttributes ); + ctx.importTimeProperty( "TimeMin", "value-min", _xAttributes ); + ctx.importTimeProperty( "TimeMax", "value-max", _xAttributes ); + ctx.importBooleanProperty( "Spin", "spin", _xAttributes ); + if (ctx.importLongProperty( "RepeatDelay", "repeat", _xAttributes )) + ctx.getControlModel()->setPropertyValue("Repeat", Any(true) ); + ctx.importStringProperty( "Text", "text" , _xAttributes ); + ctx.importBooleanProperty( "EnforceFormat", "enforce-format" , _xAttributes ); + + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// numericfield +Reference< xml::input::XElement > NumericFieldElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void NumericFieldElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlNumericFieldModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importBooleanProperty( "Tabstop","tabstop",_xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly",_xAttributes ); + ctx.importBooleanProperty( "StrictFormat", "strict-format", _xAttributes ); + ctx.importBooleanProperty( "HideInactiveSelection", "hide-inactive-selection", _xAttributes ); + ctx.importShortProperty( "DecimalAccuracy", "decimal-accuracy", _xAttributes ); + ctx.importBooleanProperty( "ShowThousandsSeparator", "thousands-separator", _xAttributes ); + ctx.importDoubleProperty( "Value", "value", _xAttributes ); + ctx.importDoubleProperty( "ValueMin", "value-min", _xAttributes ); + ctx.importDoubleProperty( "ValueMax", "value-max", _xAttributes ); + ctx.importDoubleProperty( "ValueStep", "value-step", _xAttributes ); + ctx.importBooleanProperty( "Spin", "spin", _xAttributes ); + if (ctx.importLongProperty( "RepeatDelay", "repeat", _xAttributes )) + ctx.getControlModel()->setPropertyValue("Repeat", Any(true) ); + ctx.importBooleanProperty( "EnforceFormat", "enforce-format", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// datefield +Reference< xml::input::XElement > DateFieldElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void DateFieldElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlDateFieldModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly", _xAttributes ); + ctx.importBooleanProperty( "StrictFormat", "strict-format", _xAttributes ); + ctx.importBooleanProperty( "HideInactiveSelection", "hide-inactive-selection", _xAttributes ); + ctx.importDateFormatProperty( "DateFormat", "date-format", _xAttributes ); + ctx.importBooleanProperty( "DateShowCentury", "show-century", _xAttributes ); + ctx.importDateProperty( "Date", "value", _xAttributes ); + ctx.importDateProperty( "DateMin", "value-min", _xAttributes ); + ctx.importDateProperty( "DateMax", "value-max", _xAttributes ); + ctx.importBooleanProperty( "Spin", "spin", _xAttributes ); + if (ctx.importLongProperty( "RepeatDelay", "repeat", _xAttributes )) + ctx.getControlModel()->setPropertyValue( "Repeat", Any(true) ); + ctx.importBooleanProperty( "Dropdown", "dropdown", _xAttributes ); + ctx.importStringProperty( "Text", "text", _xAttributes ); + ctx.importBooleanProperty( "EnforceFormat", "enforce-format", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// currencyfield +Reference< xml::input::XElement > CurrencyFieldElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!" , Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void CurrencyFieldElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlCurrencyFieldModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importBooleanProperty("Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly" , _xAttributes ); + ctx.importBooleanProperty( "StrictFormat", "strict-format", _xAttributes ); + ctx.importBooleanProperty( "HideInactiveSelection", "hide-inactive-selection", _xAttributes ); + ctx.importStringProperty( "CurrencySymbol", "currency-symbol", _xAttributes ); + ctx.importShortProperty( "DecimalAccuracy", "decimal-accuracy", _xAttributes ); + ctx.importBooleanProperty( "ShowThousandsSeparator", "thousands-separator", _xAttributes ); + ctx.importDoubleProperty( "Value", "value", _xAttributes ); + ctx.importDoubleProperty( "ValueMin", "value-min", _xAttributes ); + ctx.importDoubleProperty( "ValueMax", "value-max", _xAttributes ); + ctx.importDoubleProperty( "ValueStep", "value-step", _xAttributes ); + ctx.importBooleanProperty( "Spin", "spin", _xAttributes ); + if (ctx.importLongProperty( "RepeatDelay", "repeat", _xAttributes )) + ctx.getControlModel()->setPropertyValue( "Repeat", Any(true) ); + ctx.importBooleanProperty( "PrependCurrencySymbol", "prepend-symbol", _xAttributes ); + ctx.importBooleanProperty( "EnforceFormat", "enforce-format", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// filecontrol +Reference< xml::input::XElement > FileControlElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void FileControlElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlFileControlModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty("HideInactiveSelection","hide-inactive-selection", _xAttributes ); + ctx.importStringProperty( "Text", "value", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// treecontrol +Reference< xml::input::XElement > TreeControlElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void TreeControlElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.tree.TreeControlModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importSelectionTypeProperty( "SelectionType", "selectiontype", _xAttributes ); + ctx.importBooleanProperty( "RootDisplayed", "rootdisplayed", _xAttributes ); + ctx.importBooleanProperty( "ShowsHandles", "showshandles", _xAttributes ); + ctx.importBooleanProperty( "ShowsRootHandles", "showsroothandles" ,_xAttributes ); + ctx.importBooleanProperty( "Editable", "editable", _xAttributes ); + ctx.importBooleanProperty( "RowHeight", "readonly", _xAttributes ); + ctx.importBooleanProperty( "InvokesStopNodeEditing", "invokesstopnodeediting", _xAttributes ); + + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// imagecontrol +Reference< xml::input::XElement > ImageControlElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!" , Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void ImageControlElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlImageControlModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "ScaleImage", "scale-image", _xAttributes ); + ctx.importImageScaleModeProperty( "ScaleMode" , "scale-mode" , _xAttributes ); + ctx.importGraphicOrImageProperty("src" , _xAttributes); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// textfield +Reference< xml::input::XElement > TextElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void TextElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlFixedTextModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importStringProperty( "Label", "value", _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importBooleanProperty( "MultiLine", "multiline" ,_xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "NoLabel", "nolabel", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// FixedHyperLink +Reference< xml::input::XElement > FixedHyperLinkElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!" , Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void FixedHyperLinkElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlFixedHyperlinkModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importStringProperty( "Label", "value", _xAttributes ); + ctx.importStringProperty( "URL", "url", _xAttributes ); + + ctx.importAlignProperty( "Align", "align" ,_xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importBooleanProperty( "MultiLine", "multiline", _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "NoLabel", "nolabel", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// edit +Reference< xml::input::XElement > TextFieldElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void TextFieldElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlEditModel" ); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty("Tabstop", "tabstop", _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importBooleanProperty( "HardLineBreaks", "hard-linebreaks", _xAttributes ); + ctx.importBooleanProperty( "HScroll", "hscroll" ,_xAttributes ); + ctx.importBooleanProperty( "VScroll", "vscroll", _xAttributes ); + ctx.importBooleanProperty("HideInactiveSelection", "hide-inactive-selection", _xAttributes ); + ctx.importShortProperty( "MaxTextLen", "maxlength", _xAttributes ); + ctx.importBooleanProperty( "MultiLine", "multiline", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly", _xAttributes ); + ctx.importStringProperty( "Text", "value", _xAttributes ); + ctx.importLineEndFormatProperty( "LineEndFormat", "lineend-format", _xAttributes ); + OUString aValue; + if (getStringAttr( &aValue, "echochar", _xAttributes, m_pImport->XMLNS_DIALOGS_UID ) && !aValue.isEmpty() ) + { + SAL_WARN_IF( aValue.getLength() != 1, "xmlscript.xmldlg", "### more than one character given for echochar!" ); + sal_Int16 nChar = 0; + if(!aValue.isEmpty()) + { + nChar = static_cast<sal_Int16>(aValue[ 0 ]); + } + xControlModel->setPropertyValue( "EchoChar", Any( nChar ) ); + } + + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// titledbox +Reference< xml::input::XElement > TitledBoxElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (m_pImport->isEventElement( nUid, rLocalName )) + { + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); + } + else if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // title + else if ( rLocalName == "title" ) + { + getStringAttr( &_label, "value", xAttributes, m_pImport->XMLNS_DIALOGS_UID ); + + return new ElementBase( m_pImport->XMLNS_DIALOGS_UID, rLocalName, xAttributes, this, m_pImport ); + } + // radio + else if ( rLocalName == "radio" ) + { + // don't create radios here, => titledbox must be inserted first due to radio grouping, + // possible predecessors! + Reference< xml::input::XElement > xRet( + new RadioElement( rLocalName, xAttributes, this, m_pImport ) ); + _radios.push_back( xRet ); + return xRet; + } + else + { + return BulletinBoardElement::startChildElement( nUid, rLocalName, xAttributes ); + } +} + +void TitledBoxElement::endElement() +{ + { + ControlImportContext ctx(m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlGroupBoxModel" ); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( 0, 0, _xAttributes ); // inherited from BulletinBoardElement + + if (!_label.isEmpty()) + { + xControlModel->setPropertyValue( "Label", Any( _label ) ); + } + + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); + } + + // create radios AFTER group box! + for (Reference<XElement>& xRadio : _radios) + { + Reference< xml::input::XAttributes > xAttributes( xRadio->getAttributes() ); + + ControlImportContext ctx( m_pImport, getControlId( xAttributes ), getControlModelName( "com.sun.star.awt.UnoControlRadioButtonModel", xAttributes ) ); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + pStyle->importVisualEffectStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", xAttributes ); + ctx.importStringProperty( "Label", "value", xAttributes ); + ctx.importAlignProperty( "Align", "align", xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", xAttributes ); + ctx.importGraphicOrImageProperty("image-src" , _xAttributes); + ctx.importImagePositionProperty( "ImagePosition", "image-position", xAttributes ); + ctx.importBooleanProperty( "MultiLine", "multiline", xAttributes ); + ctx.importStringProperty( "GroupName", "group-name", xAttributes ); + + sal_Int16 nVal = 0; + sal_Bool bChecked = false; + if (getBoolAttr( &bChecked, "checked", xAttributes, m_pImport->XMLNS_DIALOGS_UID ) && bChecked) + { + nVal = 1; + } + xControlModel->setPropertyValue( "State", Any( nVal ) ); + ctx.importDataAwareProperty( "linked-cell" , xAttributes ); + ::std::vector< Reference< xml::input::XElement > > & radioEvents = + static_cast< RadioElement * >( xRadio.get() )->getEvents(); + ctx.importEvents( radioEvents ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + radioEvents.clear(); + + ctx.finish(); + } + // avoid ring-reference: + // vector< radio elements > holding radio elements holding this (via _pParent) + _radios.clear(); +} + +// radio +Reference< xml::input::XElement > RadioElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException("expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +// radiogroup +Reference< xml::input::XElement > RadioGroupElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // radio + else if ( rLocalName == "radio" ) + { + // don't create radios here, => titledbox must be inserted first due to radio grouping, + // possible predecessors! + Reference< xml::input::XElement > xRet( + new RadioElement( rLocalName, xAttributes, this, m_pImport ) ); + _radios.push_back( xRet ); + return xRet; + } + else + { + throw xml::sax::SAXException( "expected radio element!", Reference< XInterface >(), Any() ); + } +} +void RadioGroupElement::endElement() +{ + for (Reference<XElement>& xRadio : _radios) + { + Reference< xml::input::XAttributes > xAttributes( + xRadio->getAttributes() ); + + ControlImportContext ctx( m_pImport, getControlId( xAttributes ), getControlModelName( "com.sun.star.awt.UnoControlRadioButtonModel", xAttributes ) ); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + pStyle->importVisualEffectStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, xAttributes ); + ctx.importBooleanProperty("Tabstop", "tabstop", xAttributes ); + ctx.importStringProperty( "Label", "value", xAttributes ); + ctx.importAlignProperty( "Align", "align", xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", xAttributes ); + ctx.importGraphicOrImageProperty("image-src" , _xAttributes); + ctx.importImagePositionProperty( "ImagePosition", "image-position", xAttributes ); + ctx.importBooleanProperty( "MultiLine", "multiline", xAttributes ); + ctx.importStringProperty( "GroupName", "group-name", xAttributes ); + sal_Int16 nVal = 0; + sal_Bool bChecked = false; + if (getBoolAttr( &bChecked, "checked", xAttributes, m_pImport->XMLNS_DIALOGS_UID ) && bChecked) + { + nVal = 1; + } + xControlModel->setPropertyValue( "State", Any( nVal ) ); + + ctx.importDataAwareProperty( "linked-cell", xAttributes ); + + ::std::vector< Reference< xml::input::XElement > > & radioEvents = + static_cast< RadioElement * >( xRadio.get() )->getEvents(); + ctx.importEvents( radioEvents ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + radioEvents.clear(); + + ctx.finish(); + } + // avoid ring-reference: + // vector< radio elements > holding radio elements holding this (via _pParent) + _radios.clear(); +} + +// menupopup +Reference< xml::input::XElement > MenuPopupElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // menuitem + else if ( rLocalName == "menuitem" ) + { + OUString aValue( xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID,"value" ) ); + SAL_WARN_IF( aValue.isEmpty() && !_allowEmptyItems, "xmlscript.xmldlg", "### menuitem has no value?" ); + if ((!aValue.isEmpty()) || _allowEmptyItems) + { + _itemValues.push_back( aValue ); + + OUString aSel( xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID, "selected" ) ); + if (!aSel.isEmpty() && aSel == "true") + { + _itemSelected.push_back( static_cast<sal_Int16>(_itemValues.size()) -1 ); + } + } + return new ElementBase( m_pImport->XMLNS_DIALOGS_UID, rLocalName, xAttributes, this, m_pImport ); + } + else + { + throw xml::sax::SAXException("expected menuitem!" , Reference< XInterface >(), Any() ); + } +} +Sequence< OUString > MenuPopupElement::getItemValues() +{ + Sequence< OUString > aRet( _itemValues.size() ); + OUString * pRet = aRet.getArray(); + for ( size_t nPos = _itemValues.size(); nPos--; ) + { + pRet[ nPos ] = _itemValues[ nPos ]; + } + return aRet; +} +Sequence< sal_Int16 > MenuPopupElement::getSelectedItems() +{ + Sequence< sal_Int16 > aRet( _itemSelected.size() ); + sal_Int16 * pRet = aRet.getArray(); + for ( size_t nPos = _itemSelected.size(); nPos--; ) + { + pRet[ nPos ] = _itemSelected[ nPos ]; + } + return aRet; +} + +// menulist +Reference< xml::input::XElement > MenuListElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (m_pImport->isEventElement( nUid, rLocalName )) + { + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); + } + else if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // menupopup + else if ( rLocalName == "menupopup" ) + { + _popup = new MenuPopupElement( rLocalName, xAttributes, this, m_pImport, false ); + return _popup; + } + else + { + throw xml::sax::SAXException( "expected event or menupopup element!", Reference< XInterface >(), Any() ); + } +} + +void MenuListElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), getControlModelName( "com.sun.star.awt.UnoControlListBoxModel", _xAttributes ) ); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "MultiSelection", "multiselection", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly", _xAttributes ); + ctx.importBooleanProperty( "Dropdown", "spin", _xAttributes ); + ctx.importShortProperty( "LineCount", "linecount", _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + bool bHasLinkedCell = ctx.importDataAwareProperty( "linked-cell" , _xAttributes ); + bool bHasSrcRange = ctx.importDataAwareProperty( "source-cell-range" , _xAttributes ); + if (_popup.is()) + { + MenuPopupElement * p = static_cast< MenuPopupElement * >( _popup.get() ); + if ( !bHasSrcRange ) + xControlModel->setPropertyValue( "StringItemList", Any( p->getItemValues() ) ); + if ( !bHasLinkedCell ) + xControlModel->setPropertyValue( "SelectedItems", Any( p->getSelectedItems() ) ); + + } + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// combobox +Reference< xml::input::XElement > ComboBoxElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (m_pImport->isEventElement( nUid, rLocalName )) + { + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); + } + else if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // menupopup + else if ( rLocalName == "menupopup" ) + { + _popup = new MenuPopupElement( rLocalName, xAttributes, this, m_pImport, true ); + return _popup; + } + else + { + throw xml::sax::SAXException( "expected event or menupopup element!", Reference< XInterface >(), Any() ); + } +} +void ComboBoxElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), getControlModelName( "com.sun.star.awt.UnoControlComboBoxModel", _xAttributes ) ); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importBooleanProperty( "ReadOnly", "readonly", _xAttributes ); + ctx.importBooleanProperty( "Autocomplete", "autocomplete", _xAttributes ); + ctx.importBooleanProperty( "Dropdown", "spin", _xAttributes ); + ctx.importBooleanProperty( "HideInactiveSelection", "hide-inactive-selection", _xAttributes ); + ctx.importShortProperty( "MaxTextLen", "maxlength" ,_xAttributes ); + ctx.importShortProperty( "LineCount", "linecount" ,_xAttributes ); + ctx.importStringProperty( "Text", "value", _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importDataAwareProperty( "linked-cell" , _xAttributes ); + bool bHasSrcRange = ctx.importDataAwareProperty( "source-cell-range" , _xAttributes ); + if (_popup.is() && !bHasSrcRange ) + { + MenuPopupElement * p = static_cast< MenuPopupElement * >( _popup.get() ); + xControlModel->setPropertyValue( "StringItemList", Any( p->getItemValues() ) ); + } + + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// checkbox +Reference< xml::input::XElement > CheckBoxElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void CheckBoxElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlCheckBoxModel" ); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + pStyle->importVisualEffectStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importStringProperty( "Label", "value", _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importGraphicOrImageProperty("image-src" , _xAttributes); + ctx.importImagePositionProperty( "ImagePosition", "image-position", _xAttributes ); + ctx.importBooleanProperty( "MultiLine", "multiline", _xAttributes ); + + sal_Bool bTriState = false; + if (getBoolAttr( &bTriState, "tristate", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + xControlModel->setPropertyValue( "TriState", Any( bTriState ) ); + } + sal_Bool bChecked = false; + if (getBoolAttr( &bChecked, "checked", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + // has "checked" attribute + sal_Int16 nVal = (bChecked ? 1 : 0); + xControlModel->setPropertyValue( "State", Any( nVal ) ); + } + else + { + sal_Int16 nVal = (bTriState ? 2 : 0); // if tristate set, but checked omitted => don't know! + xControlModel->setPropertyValue( "State", Any( nVal ) ); + } + + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// button +Reference< xml::input::XElement > ButtonElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); +} + +void ButtonElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.UnoControlButtonModel" ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + const Reference< beans::XPropertySet >& xControlModel( ctx.getControlModel() ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importStringProperty( "Label", "value", _xAttributes ); + ctx.importAlignProperty( "Align", "align", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importBooleanProperty( "DefaultButton", "default", _xAttributes ); + ctx.importButtonTypeProperty( "PushButtonType", "button-type", _xAttributes ); + ctx.importGraphicOrImageProperty("image-src" , _xAttributes); + ctx.importImagePositionProperty( "ImagePosition", "image-position", _xAttributes ); + ctx.importImageAlignProperty( "ImageAlign", "image-align", _xAttributes ); + if (ctx.importLongProperty( "RepeatDelay", "repeat", _xAttributes )) + ctx.getControlModel()->setPropertyValue( "Repeat", Any(true) ); + sal_Int32 toggled = 0; + if (getLongAttr( &toggled, "toggled", _xAttributes, m_pImport->XMLNS_DIALOGS_UID ) && toggled == 1) + ctx.getControlModel()->setPropertyValue( "Toggle" , Any(true)); + ctx.importBooleanProperty( "FocusOnClick", "grab-focus", _xAttributes ); + ctx.importBooleanProperty( "MultiLine", "multiline", _xAttributes ); + // State + sal_Bool bChecked = false; + if (getBoolAttr( &bChecked, "checked", _xAttributes, m_pImport->XMLNS_DIALOGS_UID ) && bChecked) + { + ctx.getControlModel()->setPropertyValue( "State" , Any( sal_Int16(1) ) ); + } + + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +// bulletinboard +Reference< xml::input::XElement > BulletinBoardElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException("illegal namespace!", Reference< XInterface >(), Any() ); + } + // button + else if ( rLocalName == "button" ) + { + return new ButtonElement( rLocalName, xAttributes, this, m_pImport ); + } + // checkbox + else if ( rLocalName == "checkbox" ) + { + return new CheckBoxElement( rLocalName, xAttributes, this, m_pImport ); + } + // combobox + else if ( rLocalName == "combobox" ) + { + return new ComboBoxElement( rLocalName, xAttributes, this, m_pImport ); + } + // listbox + else if ( rLocalName == "menulist" ) + { + return new MenuListElement( rLocalName, xAttributes, this, m_pImport ); + } + // radiogroup + else if ( rLocalName == "radiogroup" ) + { + return new RadioGroupElement( rLocalName, xAttributes, this, m_pImport ); + } + // titledbox + else if ( rLocalName == "titledbox" ) + { + return new TitledBoxElement( rLocalName, xAttributes, this, m_pImport ); + } + // text + else if ( rLocalName == "text" ) + { + return new TextElement( rLocalName, xAttributes, this, m_pImport ); + } + else if ( rLocalName == "linklabel" ) + { + return new FixedHyperLinkElement( rLocalName, xAttributes, this, m_pImport ); + } + // textfield + else if ( rLocalName == "textfield" ) + { + return new TextFieldElement( rLocalName, xAttributes, this, m_pImport ); + } + // img + else if ( rLocalName == "img" ) + { + return new ImageControlElement( rLocalName, xAttributes, this, m_pImport ); + } + // filecontrol + else if ( rLocalName == "filecontrol" ) + { + return new FileControlElement( rLocalName, xAttributes, this, m_pImport ); + } + // treecontrol + else if ( rLocalName == "treecontrol" ) + { + return new TreeControlElement( rLocalName, xAttributes, this, m_pImport ); + } + // currencyfield + else if ( rLocalName == "currencyfield" ) + { + return new CurrencyFieldElement( rLocalName, xAttributes, this, m_pImport ); + } + // datefield + else if ( rLocalName == "datefield" ) + { + return new DateFieldElement( rLocalName, xAttributes, this, m_pImport ); + } + // datefield + else if ( rLocalName == "numericfield" ) + { + return new NumericFieldElement( rLocalName, xAttributes, this, m_pImport ); + } + // timefield + else if ( rLocalName == "timefield" ) + { + return new TimeFieldElement( rLocalName, xAttributes, this, m_pImport ); + } + // patternfield + else if ( rLocalName == "patternfield" ) + { + return new PatternFieldElement( rLocalName, xAttributes, this, m_pImport ); + } + // formattedfield + else if ( rLocalName == "formattedfield" ) + { + return new FormattedFieldElement( rLocalName, xAttributes, this, m_pImport ); + } + // fixedline + else if ( rLocalName == "fixedline" ) + { + return new FixedLineElement( rLocalName, xAttributes, this, m_pImport ); + } + // scrollbar + else if ( rLocalName == "scrollbar" ) + { + return new ScrollBarElement( rLocalName, xAttributes, this, m_pImport ); + } + // spinbutton + else if ( rLocalName == "spinbutton" ) + { + return new SpinButtonElement( rLocalName, xAttributes, this, m_pImport ); + } + // progressmeter + else if ( rLocalName == "progressmeter" ) + { + return new ProgressBarElement( rLocalName, xAttributes, this, m_pImport ); + } + // table + else if (rLocalName == "table") + { + return new GridControlElement( rLocalName, xAttributes, this, m_pImport ); + } + else if ( rLocalName == "multipage" ) + { + return new MultiPage( rLocalName, xAttributes, this, m_pImport ); + } + else if ( rLocalName == "frame" ) + { + return new Frame( rLocalName, xAttributes, this, m_pImport ); + } + else if ( rLocalName == "page" ) + { + return new Page( rLocalName, xAttributes, this, m_pImport ); + } + // bulletinboard + else if ( rLocalName == "bulletinboard" ) + { + return new BulletinBoardElement( rLocalName, xAttributes, this, m_pImport ); + } + else + { + throw xml::sax::SAXException( "expected styles, bulletinboard or bulletinboard element, not: " + rLocalName, Reference< XInterface >(), Any() ); + } +} + +BulletinBoardElement::BulletinBoardElement( + OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ControlElement( rLocalName, xAttributes, pParent, pImport ), + mxDialogImport(pImport) +{ + OUString aValue( _xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID, "left" ) ); + if (!aValue.isEmpty()) + { + _nBasePosX += toInt32( aValue ); + } + aValue = _xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID, "top" ); + if (!aValue.isEmpty()) + { + _nBasePosY += toInt32( aValue ); + } +} + +// style +Reference< xml::input::XElement > StyleElement::startChildElement( + sal_Int32 /*nUid*/, OUString const & /*rLocalName*/, + Reference< xml::input::XAttributes > const & /*xAttributes*/ ) +{ + throw xml::sax::SAXException( "unexpected sub elements of style!", Reference< XInterface >(), Any() ); +} + +void StyleElement::endElement() +{ + OUString aStyleId( _xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID, "style-id" ) ); + if (aStyleId.isEmpty()) + { + throw xml::sax::SAXException( "missing style-id attribute!", Reference< XInterface >(), Any() ); + } + + m_pImport->addStyle( aStyleId, this ); +} + +// styles +Reference< xml::input::XElement > StylesElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // style + else if ( rLocalName == "style" ) + { + return new StyleElement( rLocalName, xAttributes, this, m_pImport ); + } + else + { + throw xml::sax::SAXException( "expected style element!", Reference< XInterface >(), Any() ); + } +} + +// window +Reference< xml::input::XElement > WindowElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (m_pImport->isEventElement( nUid, rLocalName )) + { + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); + } + else if (m_pImport->XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // styles + else if ( rLocalName == "styles" ) + { + return new StylesElement( rLocalName, xAttributes, this, m_pImport ); + } + // bulletinboard + else if ( rLocalName == "bulletinboard" ) + { + return new BulletinBoardElement( rLocalName, xAttributes, this, m_pImport ); + } + else + { + throw xml::sax::SAXException( "expected styles or bulletinboard element!", Reference< XInterface >(), Any() ); + } +} + +void WindowElement::endElement() +{ + Reference< beans::XPropertySet > xProps( + m_pImport->_xDialogModel, UNO_QUERY_THROW ); + ImportContext ctx( m_pImport, xProps, getControlId( _xAttributes ) ); + + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xProps ); + pStyle->importTextColorStyle( xProps ); + pStyle->importTextLineColorStyle( xProps ); + pStyle->importFontStyle( xProps ); + } + + ctx.importDefaults( 0, 0, _xAttributes, false ); + ctx.importBooleanProperty( "Closeable", "closeable", _xAttributes ); + ctx.importBooleanProperty( "Moveable", "moveable", _xAttributes ); + ctx.importBooleanProperty("Sizeable", "resizeable", _xAttributes ); + ctx.importStringProperty("Title", "title", _xAttributes ); + ctx.importBooleanProperty("Decoration", "withtitlebar", _xAttributes ); + ctx.importGraphicOrImageProperty("image-src" , _xAttributes); + ctx.importScollableSettings( _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); +} + +// table +Reference< xml::input::XElement > GridControlElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + // event + if (!m_pImport->isEventElement( nUid, rLocalName )) + { + throw xml::sax::SAXException( "expected event element!", Reference< XInterface >(), Any() ); + } + + return new EventElement( nUid, rLocalName, xAttributes, this, m_pImport ); + +} + +void GridControlElement::endElement() +{ + ControlImportContext ctx( m_pImport, getControlId( _xAttributes ), "com.sun.star.awt.grid.UnoControlGridModel"); + Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() ); + Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) ); + if (xStyle.is()) + { + StyleElement * pStyle = static_cast< StyleElement * >( xStyle.get () ); + pStyle->importBackgroundColorStyle( xControlModel ); + pStyle->importBorderStyle( xControlModel ); + pStyle->importTextColorStyle( xControlModel ); + pStyle->importTextLineColorStyle( xControlModel ); + pStyle->importFontStyle( xControlModel ); + } + ctx.importDefaults( _nBasePosX, _nBasePosY, _xAttributes ); + ctx.importBooleanProperty( "Tabstop", "tabstop", _xAttributes ); + ctx.importVerticalAlignProperty( "VerticalAlign", "valign", _xAttributes ); + ctx.importSelectionTypeProperty( "SelectionModel", "selectiontype", _xAttributes ); + ctx.importBooleanProperty( "ShowColumnHeader", "showcolumnheader", _xAttributes ); + ctx.importBooleanProperty( "ShowRowHeader", "showrowheader", _xAttributes ); + ctx.importHexLongProperty( "GridLineColor", "gridline-color", _xAttributes ); + ctx.importBooleanProperty( "UseGridLines", "usegridlines", _xAttributes ); + ctx.importHexLongProperty( "HeaderBackgroundColor", "headerbackground-color", _xAttributes ); + ctx.importHexLongProperty( "HeaderTextColor", "headertext-color", _xAttributes ); + ctx.importHexLongProperty( "ActiveSelectionBackgroundColor", "activeselectionbackground-color", _xAttributes ); + ctx.importHexLongProperty( "ActiveSelectionTextColor", "activeselectiontext-color", _xAttributes ); + ctx.importHexLongProperty( "InactiveSelectionBackgroundColor", "inactiveselectionbackground-color", _xAttributes ); + ctx.importHexLongProperty( "InactiveSelectionTextColor", "inactiveselectiontext-color", _xAttributes ); + ctx.importEvents( _events ); + // avoid ring-reference: + // vector< event elements > holding event elements holding this (via _pParent) + _events.clear(); + + ctx.finish(); +} + +//################################################################################################## + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmldlg_imexp/xmldlg_import.cxx b/xmlscript/source/xmldlg_imexp/xmldlg_import.cxx new file mode 100644 index 000000000..5cac12605 --- /dev/null +++ b/xmlscript/source/xmldlg_imexp/xmldlg_import.cxx @@ -0,0 +1,1777 @@ +/* -*- 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 "common.hxx" +#include "imp_share.hxx" +#include <xml_import.hxx> +#include <xmlscript/xmlns.h> + +#include <com/sun/star/awt/CharSet.hpp> +#include <com/sun/star/awt/FontFamily.hpp> +#include <com/sun/star/awt/FontPitch.hpp> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/FontStrikeout.hpp> +#include <com/sun/star/awt/FontType.hpp> +#include <com/sun/star/awt/FontUnderline.hpp> +#include <com/sun/star/awt/ImagePosition.hpp> +#include <com/sun/star/awt/ImageScaleMode.hpp> +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/awt/PushButtonType.hpp> +#include <com/sun/star/awt/VisualEffect.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/util/Date.hpp> +#include <com/sun/star/util/Time.hpp> +#include <sal/log.hxx> +#include <tools/date.hxx> +#include <tools/diagnose_ex.h> +#include <tools/time.hxx> +#include <osl/diagnose.h> + +#include <com/sun/star/script/XScriptEventsSupplier.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> + +#include <com/sun/star/view/SelectionType.hpp> +#include <com/sun/star/form/binding/XBindableValue.hpp> +#include <com/sun/star/form/binding/XValueBinding.hpp> +#include <com/sun/star/form/binding/XListEntrySink.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/table/CellAddress.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include <com/sun/star/document/XGraphicStorageHandler.hpp> +#include <com/sun/star/document/XStorageBasedDocument.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/util/NumberFormatsSupplier.hpp> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; + +namespace xmlscript +{ + +void EventElement::endElement() +{ + static_cast< ControlElement * >( m_pParent )->_events.emplace_back(this ); +} + +ControlElement::ControlElement( + OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : ElementBase( + pImport->XMLNS_DIALOGS_UID, rLocalName, xAttributes, pParent, pImport ) +{ + if (m_pParent) + { + // inherit position + _nBasePosX = static_cast< ControlElement * >( m_pParent )->_nBasePosX; + _nBasePosY = static_cast< ControlElement * >( m_pParent )->_nBasePosY; + } + else + { + _nBasePosX = 0; + _nBasePosY = 0; + } +} + +Reference< xml::input::XElement > ControlElement::getStyle( + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aStyleId( xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID,"style-id" ) ); + if (!aStyleId.isEmpty()) + { + return m_pImport->getStyle( aStyleId ); + } + return Reference< xml::input::XElement >(); +} + +OUString ControlElement::getControlId( + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aId( xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID, "id" ) ); + if (aId.isEmpty()) + { + throw xml::sax::SAXException( "missing id attribute!", Reference< XInterface >(), Any() ); + } + return aId; +} + +OUString ControlElement::getControlModelName( + OUString const& rDefaultModel, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aModel = xAttributes->getValueByUidName( m_pImport->XMLNS_DIALOGS_UID, "control-implementation"); + if (aModel.isEmpty()) + aModel = rDefaultModel; + return aModel; +} + +void StyleElement::importTextColorStyle( + Reference< beans::XPropertySet > const & xProps ) +{ + if ((_inited & 0x2) != 0) + { + if ((_hasValue & 0x2) != 0) + { + xProps->setPropertyValue("TextColor", Any( _textColor ) ); + } + return; + } + _inited |= 0x2; + + if (getLongAttr( &_textColor, "text-color", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _hasValue |= 0x2; + xProps->setPropertyValue( "TextColor", Any( _textColor ) ); + return; + } +} + +void StyleElement::importTextLineColorStyle( + Reference< beans::XPropertySet > const & xProps ) +{ + if ((_inited & 0x20) != 0) + { + if ((_hasValue & 0x20) != 0) + { + xProps->setPropertyValue( "TextLineColor", Any( _textLineColor ) ); + } + return; + } + _inited |= 0x20; + + if (getLongAttr( &_textLineColor, "textline-color", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _hasValue |= 0x20; + xProps->setPropertyValue( "TextLineColor", Any( _textLineColor ) ); + } +} + +void StyleElement::importFillColorStyle( + Reference< beans::XPropertySet > const & xProps ) +{ + if ((_inited & 0x10) != 0) + { + if ((_hasValue & 0x10) != 0) + { + xProps->setPropertyValue( "FillColor", Any( _fillColor ) ); + } + return; + } + _inited |= 0x10; + + if (getLongAttr( &_fillColor, "fill-color", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _hasValue |= 0x10; + xProps->setPropertyValue( "FillColor", Any( _fillColor ) ); + } +} + +void StyleElement::importBackgroundColorStyle( + Reference< beans::XPropertySet > const & xProps ) +{ + if ((_inited & 0x1) != 0) + { + if ((_hasValue & 0x1) != 0) + { + xProps->setPropertyValue( "BackgroundColor", Any( _backgroundColor ) ); + } + return; + } + _inited |= 0x1; + + if (getLongAttr( &_backgroundColor, "background-color", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _hasValue |= 0x1; + xProps->setPropertyValue( "BackgroundColor", Any( _backgroundColor ) ); + } +} + +void StyleElement::importBorderStyle( + Reference< beans::XPropertySet > const & xProps ) +{ + if ((_inited & 0x4) != 0) + { + if ((_hasValue & 0x4) != 0) + { + xProps->setPropertyValue( "Border", Any( _border == BORDER_SIMPLE_COLOR ? BORDER_SIMPLE : _border ) ); + if (_border == BORDER_SIMPLE_COLOR) + xProps->setPropertyValue( "BorderColor", Any(_borderColor) ); + } + return; + } + _inited |= 0x4; + + OUString aValue; + if (!getStringAttr(&aValue, "border", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + return; + + if ( aValue == "none" ) + _border = BORDER_NONE; + else if ( aValue == "3d" ) + _border = BORDER_3D; + else if ( aValue == "simple" ) + _border = BORDER_SIMPLE; + else { + _border = BORDER_SIMPLE_COLOR; + _borderColor = toInt32(aValue); + } + + _hasValue |= 0x4; + importBorderStyle(xProps); // write values +} + +void StyleElement::importVisualEffectStyle( + Reference<beans::XPropertySet> const & xProps ) +{ + if ((_inited & 0x40) != 0) + { + if ((_hasValue & 0x40) != 0) + { + xProps->setPropertyValue( "VisualEffect", Any(_visualEffect) ); + } + return; + } + _inited |= 0x40; + + OUString aValue; + if (!getStringAttr( &aValue, "look", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + return; + + if ( aValue == "none" ) + { + _visualEffect = awt::VisualEffect::NONE; + } + else if ( aValue == "3d" ) + { + _visualEffect = awt::VisualEffect::LOOK3D; + } + else if ( aValue == "simple" ) + { + _visualEffect = awt::VisualEffect::FLAT; + } + else + OSL_ASSERT( false ); + + _hasValue |= 0x40; + xProps->setPropertyValue( "VisualEffect", Any(_visualEffect) ); +} + +void StyleElement::setFontProperties( + Reference< beans::XPropertySet > const & xProps ) const +{ + xProps->setPropertyValue("FontDescriptor", Any( _descr ) ); + xProps->setPropertyValue("FontEmphasisMark", Any( _fontEmphasisMark ) ); + xProps->setPropertyValue("FontRelief", Any( _fontRelief ) ); +} + +void StyleElement::importFontStyle( + Reference< beans::XPropertySet > const & xProps ) +{ + if ((_inited & 0x8) != 0) + { + if ((_hasValue & 0x8) != 0) + { + setFontProperties( xProps ); + } + return; + } + _inited |= 0x8; + + OUString aValue; + bool bFontImport; + + // dialog:font-name CDATA #IMPLIED + bFontImport = getStringAttr( &_descr.Name, "font-name", _xAttributes, m_pImport->XMLNS_DIALOGS_UID ); + + // dialog:font-height %numeric; #IMPLIED + if (getStringAttr( &aValue, "font-height", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _descr.Height = static_cast<sal_Int16>(toInt32( aValue )); + bFontImport = true; + } + // dialog:font-width %numeric; #IMPLIED + if (getStringAttr(&aValue, "font-width", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _descr.Width = static_cast<sal_Int16>(toInt32( aValue )); + bFontImport = true; + } + // dialog:font-stylename CDATA #IMPLIED + bFontImport |= getStringAttr( &_descr.StyleName, "font-stylename", _xAttributes, m_pImport->XMLNS_DIALOGS_UID ); + + // dialog:font-family "(decorative|modern|roman|script|swiss|system)" #IMPLIED + if (getStringAttr(&aValue, "font-family", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "decorative" ) + { + _descr.Family = awt::FontFamily::DECORATIVE; + } + else if ( aValue == "modern" ) + { + _descr.Family = awt::FontFamily::MODERN; + } + else if ( aValue == "roman" ) + { + _descr.Family = awt::FontFamily::ROMAN; + } + else if ( aValue == "script" ) + { + _descr.Family = awt::FontFamily::SCRIPT; + } + else if ( aValue == "swiss" ) + { + _descr.Family = awt::FontFamily::SWISS; + } + else if ( aValue == "system" ) + { + _descr.Family = awt::FontFamily::SYSTEM; + } + else + { + throw xml::sax::SAXException("invalid font-family style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + // dialog:font-charset "(ansi|mac|ibmpc_437|ibmpc_850|ibmpc_860|ibmpc_861|ibmpc_863|ibmpc_865|system|symbol)" #IMPLIED + if (getStringAttr(&aValue, "font-charset", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "ansi" ) + { + _descr.CharSet = awt::CharSet::ANSI; + } + else if ( aValue == "mac" ) + { + _descr.CharSet = awt::CharSet::MAC; + } + else if ( aValue == "ibmpc_437" ) + { + _descr.CharSet = awt::CharSet::IBMPC_437; + } + else if ( aValue == "ibmpc_850" ) + { + _descr.CharSet = awt::CharSet::IBMPC_850; + } + else if ( aValue == "ibmpc_860" ) + { + _descr.CharSet = awt::CharSet::IBMPC_860; + } + else if ( aValue == "ibmpc_861" ) + { + _descr.CharSet = awt::CharSet::IBMPC_861; + } + else if ( aValue == "ibmpc_863" ) + { + _descr.CharSet = awt::CharSet::IBMPC_863; + } + else if ( aValue == "ibmpc_865" ) + { + _descr.CharSet = awt::CharSet::IBMPC_865; + } + else if ( aValue == "system" ) + { + _descr.CharSet = awt::CharSet::SYSTEM; + } + else if ( aValue == "symbol" ) + { + _descr.CharSet = awt::CharSet::SYMBOL; + } + else + { + throw xml::sax::SAXException("invalid font-charset style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + // dialog:font-pitch "(fixed|variable)" #IMPLIED + if (getStringAttr( &aValue, "font-pitch", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "fixed" ) + { + _descr.Pitch = awt::FontPitch::FIXED; + } + else if ( aValue == "variable" ) + { + _descr.Pitch = awt::FontPitch::VARIABLE; + } + else + { + throw xml::sax::SAXException("invalid font-pitch style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + // dialog:font-charwidth CDATA #IMPLIED + if (getStringAttr( &aValue, "font-charwidth", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _descr.CharacterWidth = aValue.toFloat(); + bFontImport = true; + } + // dialog:font-weight CDATA #IMPLIED + if (getStringAttr( &aValue, "font-weight", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _descr.Weight = aValue.toFloat(); + bFontImport = true; + } + + // dialog:font-slant "(oblique|italic|reverse_oblique|reverse_italic)" #IMPLIED + if (getStringAttr( &aValue, "font-slant", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "oblique" ) + { + _descr.Slant = awt::FontSlant_OBLIQUE; + } + else if ( aValue == "italic" ) + { + _descr.Slant = awt::FontSlant_ITALIC; + } + else if ( aValue == "reverse_oblique" ) + { + _descr.Slant = awt::FontSlant_REVERSE_OBLIQUE; + } + else if ( aValue == "reverse_italic" ) + { + _descr.Slant = awt::FontSlant_REVERSE_ITALIC; + } + else + { + throw xml::sax::SAXException("invalid font-slant style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + // dialog:font-underline "(single|double|dotted|dash|longdash|dashdot|dashdotdot|smallwave|wave|doublewave|bold|bolddotted|bolddash|boldlongdash|bolddashdot|bolddashdotdot|boldwave)" #IMPLIED + if (getStringAttr( &aValue, "font-underline", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "single" ) + { + _descr.Underline = awt::FontUnderline::SINGLE; + } + else if ( aValue == "double" ) + { + _descr.Underline = awt::FontUnderline::DOUBLE; + } + else if ( aValue == "dotted" ) + { + _descr.Underline = awt::FontUnderline::DOTTED; + } + else if ( aValue == "dash" ) + { + _descr.Underline = awt::FontUnderline::DASH; + } + else if ( aValue == "longdash" ) + { + _descr.Underline = awt::FontUnderline::LONGDASH; + } + else if ( aValue == "dashdot" ) + { + _descr.Underline = awt::FontUnderline::DASHDOT; + } + else if ( aValue == "dashdotdot" ) + { + _descr.Underline = awt::FontUnderline::DASHDOTDOT; + } + else if ( aValue == "smallwave" ) + { + _descr.Underline = awt::FontUnderline::SMALLWAVE; + } + else if ( aValue == "wave" ) + { + _descr.Underline = awt::FontUnderline::WAVE; + } + else if ( aValue == "doublewave" ) + { + _descr.Underline = awt::FontUnderline::DOUBLEWAVE; + } + else if ( aValue == "bold" ) + { + _descr.Underline = awt::FontUnderline::BOLD; + } + else if ( aValue == "bolddotted" ) + { + _descr.Underline = awt::FontUnderline::BOLDDOTTED; + } + else if ( aValue == "bolddash" ) + { + _descr.Underline = awt::FontUnderline::BOLDDASH; + } + else if ( aValue == "boldlongdash" ) + { + _descr.Underline = awt::FontUnderline::BOLDLONGDASH; + } + else if ( aValue == "bolddashdot" ) + { + _descr.Underline = awt::FontUnderline::BOLDDASHDOT; + } + else if ( aValue == "bolddashdotdot" ) + { + _descr.Underline = awt::FontUnderline::BOLDDASHDOTDOT; + } + else if ( aValue == "boldwave" ) + { + _descr.Underline = awt::FontUnderline::BOLDWAVE; + } + else + { + throw xml::sax::SAXException("invalid font-underline style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + // dialog:font-strikeout "(single|double|bold|slash|x)" #IMPLIED + if (getStringAttr( &aValue, "font-strikeout", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "single" ) + { + _descr.Strikeout = awt::FontStrikeout::SINGLE; + } + else if ( aValue == "double" ) + { + _descr.Strikeout = awt::FontStrikeout::DOUBLE; + } + else if ( aValue == "bold" ) + { + _descr.Strikeout = awt::FontStrikeout::BOLD; + } + else if ( aValue == "slash" ) + { + _descr.Strikeout = awt::FontStrikeout::SLASH; + } + else if ( aValue == "x" ) + { + _descr.Strikeout = awt::FontStrikeout::X; + } + else + { + throw xml::sax::SAXException( "invalid font-strikeout style!" , Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + // dialog:font-orientation CDATA #IMPLIED + if (getStringAttr( &aValue, "font-orientation", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + _descr.Orientation = aValue.toFloat(); + bFontImport = true; + } + // dialog:font-kerning %boolean; #IMPLIED + bFontImport |= getBoolAttr( &_descr.Kerning, "font-kerning", _xAttributes, m_pImport->XMLNS_DIALOGS_UID ); + // dialog:font-wordlinemode %boolean; #IMPLIED + bFontImport |= getBoolAttr( &_descr.WordLineMode,"font-wordlinemode", _xAttributes, m_pImport->XMLNS_DIALOGS_UID ); + + // dialog:font-type "(raster|device|scalable)" #IMPLIED + if (getStringAttr( &aValue, "font-type", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "raster" ) + { + _descr.Type = awt::FontType::RASTER; + } + else if ( aValue == "device" ) + { + _descr.Type = awt::FontType::DEVICE; + } + else if ( aValue == "scalable" ) + { + _descr.Type = awt::FontType::SCALABLE; + } + else + { + throw xml::sax::SAXException( "invalid font-type style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + // additional properties which are not part of the FontDescriptor struct + // dialog:font-relief (none|embossed|engraved) #IMPLIED + if (getStringAttr( &aValue, "font-relief", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "none" ) + { + _fontRelief = awt::FontRelief::NONE; + } + else if ( aValue == "embossed" ) + { + _fontRelief = awt::FontRelief::EMBOSSED; + } + else if ( aValue == "engraved" ) + { + _fontRelief = awt::FontRelief::ENGRAVED; + } + else + { + throw xml::sax::SAXException("invalid font-relief style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + // dialog:font-emphasismark (none|dot|circle|disc|accent|above|below) #IMPLIED + if (getStringAttr(&aValue, "font-emphasismark", _xAttributes, m_pImport->XMLNS_DIALOGS_UID )) + { + if ( aValue == "none" ) + { + _fontEmphasisMark = awt::FontEmphasisMark::NONE; + } + else if ( aValue == "dot" ) + { + _fontEmphasisMark = awt::FontEmphasisMark::DOT; + } + else if ( aValue == "circle" ) + { + _fontEmphasisMark = awt::FontEmphasisMark::CIRCLE; + } + else if ( aValue == "disc" ) + { + _fontEmphasisMark = awt::FontEmphasisMark::DISC; + } + else if ( aValue == "accent" ) + { + _fontEmphasisMark = awt::FontEmphasisMark::ACCENT; + } + else if ( aValue == "above" ) + { + _fontEmphasisMark = awt::FontEmphasisMark::ABOVE; + } + else if ( aValue == "below" ) + { + _fontEmphasisMark = awt::FontEmphasisMark::BELOW; + } + else + { + throw xml::sax::SAXException( "invalid font-emphasismark style!", Reference< XInterface >(), Any() ); + } + bFontImport = true; + } + + if (bFontImport) + { + _hasValue |= 0x8; + setFontProperties( xProps ); + } +} + +bool ImportContext::importStringProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + _xControlModel->setPropertyValue( rPropName, Any( aValue ) ); + return true; + } + return false; +} + +bool ImportContext::importDoubleProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + _xControlModel->setPropertyValue( rPropName, Any( aValue.toDouble() ) ); + return true; + } + return false; +} + +bool ImportContext::importBooleanProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + sal_Bool bBool; + if (getBoolAttr( + &bBool, rAttrName, xAttributes, _pImport->XMLNS_DIALOGS_UID )) + { + _xControlModel->setPropertyValue( rPropName, Any( bBool ) ); + return true; + } + return false; +} + +bool ImportContext::importLongProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + _xControlModel->setPropertyValue( rPropName, Any( toInt32( aValue ) ) ); + return true; + } + return false; +} + +bool ImportContext::importLongProperty( + sal_Int32 nOffset, + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + _xControlModel->setPropertyValue( rPropName, Any( toInt32( aValue ) + nOffset ) ); + return true; + } + return false; +} + +bool ImportContext::importHexLongProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + _xControlModel->setPropertyValue( rPropName, Any( toInt32( aValue ) ) ); + return true; + } + return false; +} + +bool ImportContext::importShortProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + _xControlModel->setPropertyValue( rPropName, Any( static_cast<sal_Int16>(toInt32( aValue )) ) ); + return true; + } + return false; +} + +bool ImportContext::importAlignProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aAlign( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aAlign.isEmpty()) + { + sal_Int16 nAlign; + if ( aAlign == "left" ) + { + nAlign = 0; + } + else if ( aAlign == "center" ) + { + nAlign = 1; + } + else if ( aAlign == "right" ) + { + nAlign = 2; + } + else if ( aAlign == "none" ) + { + nAlign = 0; // default + } + else + { + throw xml::sax::SAXException("invalid align value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nAlign ) ); + return true; + } + return false; +} + +bool ImportContext::importVerticalAlignProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aAlign( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aAlign.isEmpty()) + { + style::VerticalAlignment eAlign; + + if ( aAlign == "top" ) + { + eAlign = style::VerticalAlignment_TOP; + } + else if ( aAlign == "center" ) + { + eAlign = style::VerticalAlignment_MIDDLE; + } + else if ( aAlign == "bottom" ) + { + eAlign = style::VerticalAlignment_BOTTOM; + } + else + { + throw xml::sax::SAXException( "invalid vertical align value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( eAlign ) ); + return true; + } + return false; +} + +bool ImportContext::importGraphicOrImageProperty( + OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString sURL = xAttributes->getValueByUidName( _pImport->XMLNS_DIALOGS_UID, rAttrName ); + if ( !sURL.isEmpty() ) + { + Reference< document::XStorageBasedDocument > xDocStorage( _pImport->getDocOwner(), UNO_QUERY ); + + uno::Reference<graphic::XGraphic> xGraphic; + + uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler; + if ( xDocStorage.is() ) + { + uno::Sequence< Any > aArgs{ Any(xDocStorage->getDocumentStorage()) }; + xGraphicStorageHandler.set( + _pImport->getComponentContext()->getServiceManager()->createInstanceWithArgumentsAndContext( "com.sun.star.comp.Svx.GraphicImportHelper" , aArgs, _pImport->getComponentContext() ), + UNO_QUERY ); + if (xGraphicStorageHandler.is()) + { + try + { + xGraphic = xGraphicStorageHandler->loadGraphic(sURL); + } + catch( const uno::Exception& ) + { + return false; + } + } + } + if (xGraphic.is()) + { + Reference<beans::XPropertySet> xProps = getControlModel(); + if (xProps.is()) + { + xProps->setPropertyValue("Graphic", Any(xGraphic)); + return true; + } + } + else if (!sURL.isEmpty()) + { + // tdf#130793 Above fails if the dialog is not part of a document. + // In this case we need to set the ImageURL. + Reference<beans::XPropertySet> xProps = getControlModel(); + if (xProps.is()) + { + xProps->setPropertyValue("ImageURL", Any(sURL)); + return true; + } + } + } + return false; +} + +bool ImportContext::importDataAwareProperty( + OUString const & rPropName, + Reference<xml::input::XAttributes> const & xAttributes ) +{ + OUString sLinkedCell; + OUString sCellRange; + if ( rPropName == "linked-cell" ) + sLinkedCell = xAttributes->getValueByUidName( _pImport->XMLNS_DIALOGS_UID, rPropName ); + if ( rPropName == "source-cell-range" ) + sCellRange = xAttributes->getValueByUidName( _pImport->XMLNS_DIALOGS_UID, rPropName ); + bool bRes = false; + Reference< lang::XMultiServiceFactory > xFac( _pImport->getDocOwner(), UNO_QUERY ); + if ( xFac.is() && ( !sLinkedCell.isEmpty() || !sCellRange.isEmpty() ) ) + { + // Set up cell link + if ( !sLinkedCell.isEmpty() ) + { + Reference< form::binding::XBindableValue > xBindable( getControlModel(), uno::UNO_QUERY ); + Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellAddressConversion" ), uno::UNO_QUERY ); + if ( xBindable.is() && xConvertor.is() ) + { + table::CellAddress aAddress; + xConvertor->setPropertyValue( "PersistentRepresentation" , uno::Any( sLinkedCell ) ); + xConvertor->getPropertyValue( "Address" ) >>= aAddress; + beans::NamedValue aArg1; + aArg1.Name = "BoundCell"; + aArg1.Value <<= aAddress; + + uno::Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( "com.sun.star.table.CellValueBinding" , { uno::Any(aArg1) }), uno::UNO_QUERY ); + xBindable->setValueBinding( xBinding ); + bRes = true; + } + } + // Set up CellRange + if ( !sCellRange.isEmpty() ) + { + Reference< form::binding::XListEntrySink > xListEntrySink( getControlModel(), uno::UNO_QUERY ); + Reference< beans::XPropertySet > xConvertor( xFac->createInstance( "com.sun.star.table.CellRangeAddressConversion" ), uno::UNO_QUERY ); + if ( xListEntrySink.is() && xConvertor.is() ) + { + table::CellRangeAddress aAddress; + xConvertor->setPropertyValue( "PersistentRepresentation" , uno::Any( sCellRange ) ); + xConvertor->getPropertyValue( "Address" ) >>= aAddress; + beans::NamedValue aArg1; + aArg1.Name = "CellRange"; + aArg1.Value <<= aAddress; + + uno::Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( "com.sun.star.table.CellRangeListSource" , { uno::Any(aArg1) } ), uno::UNO_QUERY ); + xListEntrySink->setListEntrySource( xSource ); + bRes = true; + } + } + } + return bRes; +} + +bool ImportContext::importImageAlignProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aAlign( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aAlign.isEmpty()) + { + sal_Int16 nAlign; + if ( aAlign == "left" ) + { + nAlign = 0; + } + else if ( aAlign == "top" ) + { + nAlign = 1; + } + else if ( aAlign == "right" ) + { + nAlign = 2; + } + else if ( aAlign == "bottom" ) + { + nAlign = 3; + } + else + { + throw xml::sax::SAXException( "invalid image align value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nAlign ) ); + return true; + } + return false; +} + +bool ImportContext::importImagePositionProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aPosition( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aPosition.isEmpty()) + { + sal_Int16 nPosition; + if ( aPosition == "left-top" ) + { + nPosition = awt::ImagePosition::LeftTop; + } + else if ( aPosition == "left-center" ) + { + nPosition = awt::ImagePosition::LeftCenter; + } + else if ( aPosition == "left-bottom" ) + { + nPosition = awt::ImagePosition::LeftBottom; + } + else if ( aPosition == "right-top" ) + { + nPosition = awt::ImagePosition::RightTop; + } + else if ( aPosition == "right-center" ) + { + nPosition = awt::ImagePosition::RightCenter; + } + else if ( aPosition == "right-bottom" ) + { + nPosition = awt::ImagePosition::RightBottom; + } + else if ( aPosition == "top-left" ) + { + nPosition = awt::ImagePosition::AboveLeft; + } + else if ( aPosition == "top-center" ) + { + nPosition = awt::ImagePosition::AboveCenter; + } + else if ( aPosition == "top-right" ) + { + nPosition = awt::ImagePosition::AboveRight; + } + else if ( aPosition == "bottom-left" ) + { + nPosition = awt::ImagePosition::BelowLeft; + } + else if ( aPosition == "bottom-center" ) + { + nPosition = awt::ImagePosition::BelowCenter; + } + else if ( aPosition == "bottom-right" ) + { + nPosition = awt::ImagePosition::BelowRight; + } + else if ( aPosition == "center" ) + { + nPosition = awt::ImagePosition::Centered; + } + else + { + throw xml::sax::SAXException( "invalid image position value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nPosition ) ); + return true; + } + return false; +} + +bool ImportContext::importButtonTypeProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString buttonType( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!buttonType.isEmpty()) + { + awt::PushButtonType nButtonType; + if ( buttonType == "standard" ) + { + nButtonType = awt::PushButtonType_STANDARD; + } + else if ( buttonType == "ok" ) + { + nButtonType = awt::PushButtonType_OK; + } + else if ( buttonType == "cancel" ) + { + nButtonType = awt::PushButtonType_CANCEL; + } + else if ( buttonType == "help" ) + { + nButtonType = awt::PushButtonType_HELP; + } + else + { + throw xml::sax::SAXException( "invalid button-type value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( static_cast<sal_Int16>(nButtonType) ) ); + return true; + } + return false; +} + +bool ImportContext::importDateFormatProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aFormat( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aFormat.isEmpty()) + { + sal_Int16 nFormat; + if ( aFormat == "system_short" ) + { + nFormat = 0; + } + else if ( aFormat == "system_short_YY" ) + { + nFormat = 1; + } + else if ( aFormat == "system_short_YYYY" ) + { + nFormat = 2; + } + else if ( aFormat == "system_long" ) + { + nFormat = 3; + } + else if ( aFormat == "short_DDMMYY" ) + { + nFormat = 4; + } + else if ( aFormat == "short_MMDDYY" ) + { + nFormat = 5; + } + else if ( aFormat == "short_YYMMDD" ) + { + nFormat = 6; + } + else if ( aFormat == "short_DDMMYYYY" ) + { + nFormat = 7; + } + else if ( aFormat == "short_MMDDYYYY" ) + { + nFormat = 8; + } + else if ( aFormat == "short_YYYYMMDD" ) + { + nFormat = 9; + } + else if ( aFormat == "short_YYMMDD_DIN5008" ) + { + nFormat = 10; + } + else if ( aFormat == "short_YYYYMMDD_DIN5008" ) + { + nFormat = 11; + } + else + { + throw xml::sax::SAXException( "invalid date-format value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nFormat ) ); + return true; + } + return false; +} + +bool ImportContext::importTimeProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + ::tools::Time aTTime(toInt32( aValue ) * ::tools::Time::nanoPerCenti); + util::Time aUTime(aTTime.GetUNOTime()); + _xControlModel->setPropertyValue( rPropName, Any( aUTime ) ); + return true; + } + return false; +} + +bool ImportContext::importDateProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aValue( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aValue.isEmpty()) + { + ::Date aTDate(toInt32( aValue )); + util::Date aUDate(aTDate.GetUNODate()); + _xControlModel->setPropertyValue( rPropName, Any( aUDate ) ); + return true; + } + return false; +} + +bool ImportContext::importTimeFormatProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aFormat( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aFormat.isEmpty()) + { + sal_Int16 nFormat; + if ( aFormat == "24h_short" ) + { + nFormat = 0; + } + else if ( aFormat == "24h_long" ) + { + nFormat = 1; + } + else if ( aFormat == "12h_short" ) + { + nFormat = 2; + } + else if ( aFormat == "12h_long" ) + { + nFormat = 3; + } + else if ( aFormat == "Duration_short" ) + { + nFormat = 4; + } + else if ( aFormat == "Duration_long" ) + { + nFormat = 5; + } + else + { + throw xml::sax::SAXException( "invalid time-format value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nFormat ) ); + return true; + } + return false; +} + +bool ImportContext::importOrientationProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aOrient( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aOrient.isEmpty()) + { + sal_Int32 nOrient; + if ( aOrient == "horizontal" ) + { + nOrient = 0; + } + else if ( aOrient == "vertical" ) + { + nOrient = 1; + } + else + { + throw xml::sax::SAXException( "invalid orientation value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nOrient ) ); + return true; + } + return false; +} + +bool ImportContext::importLineEndFormatProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aFormat( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aFormat.isEmpty()) + { + sal_Int16 nFormat; + if ( aFormat == "carriage-return" ) + { + nFormat = awt::LineEndFormat::CARRIAGE_RETURN; + } + else if ( aFormat == "line-feed" ) + { + nFormat = awt::LineEndFormat::LINE_FEED; + } + else if ( aFormat == "carriage-return-line-feed" ) + { + nFormat = awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED; + } + else + { + throw xml::sax::SAXException( "invalid line end format value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nFormat ) ); + return true; + } + return false; +} + +bool ImportContext::importSelectionTypeProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aSelectionType( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aSelectionType.isEmpty()) + { + view::SelectionType eSelectionType; + + if ( aSelectionType == "none" ) + { + eSelectionType = view::SelectionType_NONE; + } + else if ( aSelectionType == "single" ) + { + eSelectionType = view::SelectionType_SINGLE; + } + else if ( aSelectionType == "multi" ) + { + eSelectionType = view::SelectionType_MULTI; + } + else if ( aSelectionType == "range" ) + { + eSelectionType = view::SelectionType_RANGE; + } + else + { + throw xml::sax::SAXException( "invalid selection type value!", Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( eSelectionType ) ); + return true; + } + return false; +} + +bool ImportContext::importImageScaleModeProperty( + OUString const & rPropName, OUString const & rAttrName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + OUString aImageScaleMode( + xAttributes->getValueByUidName( + _pImport->XMLNS_DIALOGS_UID, rAttrName ) ); + if (!aImageScaleMode.isEmpty()) + { + sal_Int16 nImageScaleMode; + + if (aImageScaleMode == "none") + { + nImageScaleMode = awt::ImageScaleMode::NONE; + } + else if (aImageScaleMode == "isotropic") + { + nImageScaleMode = awt::ImageScaleMode::ISOTROPIC; + } + else if (aImageScaleMode == "anisotropic") + { + nImageScaleMode = awt::ImageScaleMode::ANISOTROPIC; + } + else + { + throw xml::sax::SAXException( "invalid scale image mode value!", + Reference< XInterface >(), Any() ); + } + + _xControlModel->setPropertyValue( rPropName, Any( nImageScaleMode ) ); + return true; + } + return false; +} + +StringTriple const s_aEventTranslations[] = +{ + // from xmloff/source/forms/formevents.cxx + // 28.09.2001 tbe added on-adjustmentvaluechange + { "com.sun.star.form.XApproveActionListener", "approveAction", "on-approveaction" }, + { "com.sun.star.awt.XActionListener", "actionPerformed", "on-performaction" }, + { "com.sun.star.form.XChangeListener", "changed", "on-change" }, + { "com.sun.star.awt.XTextListener", "textChanged", "on-textchange" }, + { "com.sun.star.awt.XItemListener", "itemStateChanged", "on-itemstatechange" }, + { "com.sun.star.awt.XFocusListener", "focusGained", "on-focus" }, + { "com.sun.star.awt.XFocusListener", "focusLost", "on-blur" }, + { "com.sun.star.awt.XKeyListener", "keyPressed", "on-keydown" }, + { "com.sun.star.awt.XKeyListener", "keyReleased", "on-keyup" }, + { "com.sun.star.awt.XMouseListener", "mouseEntered", "on-mouseover" }, + { "com.sun.star.awt.XMouseMotionListener", "mouseDragged", "on-mousedrag" }, + { "com.sun.star.awt.XMouseMotionListener", "mouseMoved", "on-mousemove" }, + { "com.sun.star.awt.XMouseListener", "mousePressed", "on-mousedown" }, + { "com.sun.star.awt.XMouseListener", "mouseReleased", "on-mouseup" }, + { "com.sun.star.awt.XMouseListener", "mouseExited", "on-mouseout" }, + { "com.sun.star.form.XResetListener", "approveReset", "on-approvereset" }, + { "com.sun.star.form.XResetListener", "resetted", "on-reset" }, + { "com.sun.star.form.XSubmitListener", "approveSubmit", "on-submit" }, + { "com.sun.star.form.XUpdateListener", "approveUpdate", "on-approveupdate" }, + { "com.sun.star.form.XUpdateListener", "updated", "on-update" }, + { "com.sun.star.form.XLoadListener", "loaded", "on-load" }, + { "com.sun.star.form.XLoadListener", "reloading", "on-startreload" }, + { "com.sun.star.form.XLoadListener", "reloaded", "on-reload" }, + { "com.sun.star.form.XLoadListener", "unloading", "on-startunload" }, + { "com.sun.star.form.XLoadListener", "unloaded", "on-unload" }, + { "com.sun.star.form.XConfirmDeleteListener", "confirmDelete", "on-confirmdelete" }, + { "com.sun.star.sdb.XRowSetApproveListener", "approveRowChange", "on-approverowchange" }, + { "com.sun.star.sdbc.XRowSetListener", "rowChanged", "on-rowchange" }, + { "com.sun.star.sdb.XRowSetApproveListener", "approveCursorMove", "on-approvecursormove" }, + { "com.sun.star.sdbc.XRowSetListener", "cursorMoved", "on-cursormove" }, + { "com.sun.star.form.XDatabaseParameterListener", "approveParameter", "on-supplyparameter" }, + { "com.sun.star.sdb.XSQLErrorListener", "errorOccured", "on-error" }, + { "com.sun.star.awt.XAdjustmentListener", "adjustmentValueChanged", "on-adjustmentvaluechange" }, + { nullptr, nullptr, nullptr } +}; + +StringTriple const * const g_pEventTranslations = s_aEventTranslations; + +void ImportContext::importEvents( + std::vector< Reference< xml::input::XElement > > const & rEvents ) +{ + Reference< script::XScriptEventsSupplier > xSupplier( + _xControlModel, UNO_QUERY ); + if (!xSupplier.is()) + return; + + Reference< container::XNameContainer > xEvents( xSupplier->getEvents() ); + if (!xEvents.is()) + return; + + for (const auto & rEvent : rEvents) + { + script::ScriptEventDescriptor descr; + + EventElement * pEventElement = static_cast< EventElement * >( rEvent.get() ); + sal_Int32 nUid = pEventElement->getUid(); + OUString aLocalName( pEventElement->getLocalName() ); + Reference< xml::input::XAttributes > xAttributes( pEventElement->getAttributes() ); + + // nowadays script events + if (_pImport->XMLNS_SCRIPT_UID == nUid) + { + if (!getStringAttr( &descr.ScriptType, "language" , xAttributes, _pImport->XMLNS_SCRIPT_UID ) || + !getStringAttr( &descr.ScriptCode, "macro-name", xAttributes, _pImport->XMLNS_SCRIPT_UID )) + { + throw xml::sax::SAXException( "missing language or macro-name attribute(s) of event!", Reference< XInterface >(), Any() ); + } + if ( descr.ScriptType == "StarBasic" ) + { + OUString aLocation; + if (getStringAttr( &aLocation, "location", xAttributes, _pImport->XMLNS_SCRIPT_UID )) + { + // prepend location + descr.ScriptCode = aLocation + ":" + descr.ScriptCode; + } + } + else if ( descr.ScriptType == "Script" ) + { + // Check if there is a protocol, if not assume + // this is an early scripting framework url ( without + // the protocol ) and fix it up!! + if ( descr.ScriptCode.indexOf( ':' ) == -1 ) + { + descr.ScriptCode = "vnd.sun.start.script:" + descr.ScriptCode; + } + } + + // script:event element + if ( aLocalName == "event" ) + { + OUString aEventName; + if (! getStringAttr( &aEventName, "event-name", xAttributes, _pImport->XMLNS_SCRIPT_UID )) + { + throw xml::sax::SAXException( "missing event-name attribute!", Reference< XInterface >(), Any() ); + } + + // lookup in table + OString str( OUStringToOString( aEventName, RTL_TEXTENCODING_ASCII_US ) ); + StringTriple const * p = g_pEventTranslations; + while (p->first) + { + if (0 == ::rtl_str_compare( p->third, str.getStr() )) + { + descr.ListenerType = OUString( + p->first, ::rtl_str_getLength( p->first ), + RTL_TEXTENCODING_ASCII_US ); + descr.EventMethod = OUString( + p->second, ::rtl_str_getLength( p->second ), + RTL_TEXTENCODING_ASCII_US ); + break; + } + ++p; + } + + if (! p->first) + { + throw xml::sax::SAXException( "no matching event-name found!", Reference< XInterface >(), Any() ); + } + } + else // script:listener-event element + { + SAL_WARN_IF( aLocalName != "listener-event", "xmlscript.xmldlg", "aLocalName != listener-event" ); + + if (!getStringAttr( &descr.ListenerType, "listener-type" , xAttributes, _pImport->XMLNS_SCRIPT_UID ) || + !getStringAttr( &descr.EventMethod , "listener-method", xAttributes, _pImport->XMLNS_SCRIPT_UID )) + { + throw xml::sax::SAXException("missing listener-type or listener-method attribute(s)!", Reference< XInterface >(), Any() ); + } + // optional listener param + getStringAttr( &descr.AddListenerParam, "listener-param", xAttributes, _pImport->XMLNS_SCRIPT_UID ); + } + } + else // deprecated dlg:event element + { + SAL_WARN_IF( _pImport->XMLNS_DIALOGS_UID != nUid || aLocalName != "event", "xmlscript.xmldlg", "_pImport->XMLNS_DIALOGS_UID != nUid || aLocalName != \"event\"" ); + + if (!getStringAttr( &descr.ListenerType, "listener-type", xAttributes, _pImport->XMLNS_DIALOGS_UID ) || + !getStringAttr( &descr.EventMethod, "event-method", xAttributes, _pImport->XMLNS_DIALOGS_UID )) + { + throw xml::sax::SAXException("missing listener-type or event-method attribute(s)!", Reference< XInterface >(), Any() ); + } + + getStringAttr( &descr.ScriptType, "script-type", xAttributes, _pImport->XMLNS_DIALOGS_UID ); + getStringAttr( &descr.ScriptCode, "script-code", xAttributes, _pImport->XMLNS_DIALOGS_UID ); + getStringAttr( &descr.AddListenerParam, "param", xAttributes, _pImport->XMLNS_DIALOGS_UID ); + } + + xEvents->insertByName( descr.ListenerType + "::" + descr.EventMethod, Any( descr ) ); + } +} +void ImportContext::importScollableSettings( + Reference< xml::input::XAttributes > const & _xAttributes ) +{ + importLongProperty( "ScrollHeight", + "scrollheight", + _xAttributes ); + importLongProperty( "ScrollWidth", + "scrollwidth", + _xAttributes ); + importLongProperty( "ScrollTop", + "scrolltop", + _xAttributes ); + importLongProperty( "ScrollLeft", + "scrollleft", + _xAttributes ); + importBooleanProperty( "HScroll", + "hscroll", + _xAttributes ); + importBooleanProperty( "VScroll", + "vscroll", + _xAttributes ); +} + +void ImportContext::importDefaults( + sal_Int32 nBaseX, sal_Int32 nBaseY, + Reference< xml::input::XAttributes > const & xAttributes, + bool supportPrintable ) +{ + _xControlModel->setPropertyValue( "Name", Any( _aId ) ); + + importShortProperty( "TabIndex", "tab-index", xAttributes ); + + sal_Bool bDisable = false; + if (getBoolAttr( &bDisable,"disabled", xAttributes, _pImport->XMLNS_DIALOGS_UID ) && bDisable) + { + _xControlModel->setPropertyValue( "Enabled", Any( false ) ); + } + + sal_Bool bVisible = true; + if (getBoolAttr( &bVisible, "visible", xAttributes, _pImport->XMLNS_DIALOGS_UID ) && !bVisible) + { + try + { + _xControlModel->setPropertyValue( "EnableVisible", Any( false ) ); + } + catch( Exception& ) + { + DBG_UNHANDLED_EXCEPTION("xmlscript.xmldlg"); + } + } + + if (!importLongProperty( nBaseX, "PositionX", "left", xAttributes ) || + !importLongProperty( nBaseY, "PositionY", "top", xAttributes ) || + !importLongProperty( "Width", "width", xAttributes ) || + !importLongProperty( "Height", "height", xAttributes )) + { + throw xml::sax::SAXException( "missing pos size attribute(s)!", Reference< XInterface >(), Any() ); + } + + if (supportPrintable) + { + importBooleanProperty("Printable", "printable", xAttributes ); + } + + sal_Int32 nLong; + if (! getLongAttr( &nLong, "page", xAttributes, _pImport->XMLNS_DIALOGS_UID )) + { + nLong = 0; + } + _xControlModel->setPropertyValue( "Step", Any( nLong ) ); + + importStringProperty("Tag", "tag", xAttributes ); + importStringProperty( "HelpText", "help-text", xAttributes ); + importStringProperty( "HelpURL", "help-url", xAttributes ); +} + +Reference< xml::input::XElement > ElementBase::getParent() +{ + return static_cast< xml::input::XElement * >( m_pParent ); +} + +OUString ElementBase::getLocalName() +{ + return _aLocalName; +} + +sal_Int32 ElementBase::getUid() +{ + return _nUid; +} + +Reference< xml::input::XAttributes > ElementBase::getAttributes() +{ + return _xAttributes; +} + +void ElementBase::ignorableWhitespace( + OUString const & /*rWhitespaces*/ ) +{ + // not used +} + +void ElementBase::characters( OUString const & /*rChars*/ ) +{ + // not used, all characters ignored +} + +void ElementBase::endElement() +{ +} + +void ElementBase::processingInstruction( + OUString const & /*Target*/, OUString const & /*Data*/ ) +{ +} + +Reference< xml::input::XElement > ElementBase::startChildElement( + sal_Int32 /*nUid*/, OUString const & /*rLocalName*/, + Reference< xml::input::XAttributes > const & /*xAttributes*/ ) +{ + throw xml::sax::SAXException( "unexpected element!", Reference< XInterface >(), Any() ); +} + +ElementBase::ElementBase( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes, + ElementBase * pParent, DialogImport * pImport ) + : m_pImport( pImport ) + , m_pParent( pParent ) + , _nUid( nUid ) + , _aLocalName( rLocalName ) + , _xAttributes( xAttributes ) +{ +} + +ElementBase::~ElementBase() +{ + SAL_INFO("xmlscript.xmldlg", "ElementBase::~ElementBase(): " << _aLocalName ); +} + +// XRoot + +void DialogImport::startDocument( + Reference< xml::input::XNamespaceMapping > const & xNamespaceMapping ) +{ + XMLNS_DIALOGS_UID = xNamespaceMapping->getUidByUri( XMLNS_DIALOGS_URI ); + XMLNS_SCRIPT_UID = xNamespaceMapping->getUidByUri( XMLNS_SCRIPT_URI ); +} + +void DialogImport::endDocument() +{ + // ignored +} + +void DialogImport::processingInstruction( + OUString const & /*rTarget*/, OUString const & /*rData*/ ) +{ + // ignored for now: xxx todo +} + +void DialogImport::setDocumentLocator( + Reference< xml::sax::XLocator > const & /*xLocator*/ ) +{ + // ignored for now: xxx todo +} + +Reference< xml::input::XElement > DialogImport::startRootElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (XMLNS_DIALOGS_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // window + else if ( rLocalName == "window" ) + { + return new WindowElement( rLocalName, xAttributes, this ); + } + else + { + throw xml::sax::SAXException( "illegal root element (expected window) given: " + rLocalName, Reference< XInterface >(), Any() ); + } +} + +DialogImport::~DialogImport() +{ + SAL_INFO("xmlscript.xmldlg", "DialogImport::~DialogImport()." ); +} + +Reference< util::XNumberFormatsSupplier > const & DialogImport::getNumberFormatsSupplier() +{ + if (! _xSupplier.is()) + { + Reference< util::XNumberFormatsSupplier > xSupplier = util::NumberFormatsSupplier::createWithDefaultLocale( getComponentContext() ); + + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! _xSupplier.is()) + { + _xSupplier = xSupplier; + } + } + return _xSupplier; +} + +void DialogImport::addStyle( + OUString const & rStyleId, + Reference< xml::input::XElement > const & xStyle ) +{ + (*_pStyleNames).push_back( rStyleId ); + (*_pStyles).push_back( xStyle ); +} + +Reference< xml::input::XElement > DialogImport::getStyle( + std::u16string_view rStyleId ) const +{ + for ( size_t nPos = 0; nPos < (*_pStyleNames).size(); ++nPos ) + { + if ( (*_pStyleNames)[ nPos ] == rStyleId) + { + return (*_pStyles)[ nPos ]; + } + } + return nullptr; +} + +Reference< xml::sax::XDocumentHandler > importDialogModel( + Reference< container::XNameContainer > const & xDialogModel, + Reference< XComponentContext > const & xContext, + Reference< XModel > const & xDocument ) +{ + // single set of styles and stylenames apply to all containers + auto pStyleNames = std::make_shared<std::vector< OUString >>(); + auto pStyles = std::make_shared<std::vector< css::uno::Reference< css::xml::input::XElement > >>(); + return ::xmlscript::createDocumentHandler( + new DialogImport(xContext, xDialogModel, pStyleNames, pStyles, xDocument)); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmlflat_imexp/xmlbas_export.cxx b/xmlscript/source/xmlflat_imexp/xmlbas_export.cxx new file mode 100644 index 000000000..eefa92eaf --- /dev/null +++ b/xmlscript/source/xmlflat_imexp/xmlbas_export.cxx @@ -0,0 +1,377 @@ +/* -*- 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 <sal/config.h> + +#include "xmlbas_export.hxx" +#include <sal/log.hxx> +#include <xmlscript/xmlns.h> +#include <xmlscript/xml_helper.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/script/XLibraryContainer2.hpp> +#include <com/sun/star/script/XLibraryContainerPassword.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <cppuhelper/supportsservice.hxx> +#include <tools/diagnose_ex.h> +#include <rtl/ref.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; + +namespace xmlscript +{ + // XMLBasicExporterBase + + XMLBasicExporterBase::XMLBasicExporterBase( bool bOasis ) + :m_bOasis( bOasis ) + { + } + + XMLBasicExporterBase::~XMLBasicExporterBase() + { + } + + // XServiceInfo + sal_Bool XMLBasicExporterBase::supportsService( const OUString& rServiceName ) + { + return cppu::supportsService(this, rServiceName); + } + + // XInitialization + + void XMLBasicExporterBase::initialize( const Sequence< Any >& aArguments ) + { + std::scoped_lock aGuard( m_aMutex ); + + if ( aArguments.getLength() != 1 ) + { + throw RuntimeException( "XMLBasicExporterBase::initialize: invalid number of arguments!" ); + } + + aArguments[0] >>= m_xHandler; + + if ( !m_xHandler.is() ) + { + throw RuntimeException( "XMLBasicExporterBase::initialize: invalid argument format!" ); + } + } + + // XExporter + + void XMLBasicExporterBase::setSourceDocument( const Reference< XComponent >& rxDoc ) + { + std::scoped_lock aGuard( m_aMutex ); + + m_xModel.set( rxDoc, UNO_QUERY ); + + if ( !m_xModel.is() ) + { + throw IllegalArgumentException( "XMLBasicExporter::setSourceDocument: no document model!", Reference< XInterface >(), 1 ); + } + } + + // XFilter + +sal_Bool XMLBasicExporterBase::filter( const Sequence< beans::PropertyValue >& /*aDescriptor*/ ) + { + std::scoped_lock aGuard( m_aMutex ); + + bool bReturn = true; + + try + { + if ( m_xHandler.is() ) + { + m_xHandler->startDocument(); + + // ooo/script prefix and URI + OUString aPrefix; + OUString aURI; + if ( m_bOasis ) + { + aPrefix = XMLNS_OOO_PREFIX; + aURI = XMLNS_OOO_URI; + } + else + { + aPrefix = XMLNS_SCRIPT_PREFIX; + aURI = XMLNS_SCRIPT_URI; + } + + // ooo/script:libraries element + OUString aLibContElementName = aPrefix + ":libraries"; + rtl::Reference<XMLElement> pLibContElement = new XMLElement( aLibContElementName ); + + // ooo/script namespace attribute + pLibContElement->addAttribute( "xmlns:" + aPrefix, aURI ); + + // xlink namespace attribute + pLibContElement->addAttribute( "xmlns:" XMLNS_XLINK_PREFIX, XMLNS_XLINK_URI ); + + // <ooo/script:libraries... + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->startElement( aLibContElementName, pLibContElement ); + + Reference< script::XLibraryContainer2 > xLibContainer; + + // try the XEmbeddedScripts interface + Reference< document::XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY ); + if ( xDocumentScripts.is() ) + xLibContainer = xDocumentScripts->getBasicLibraries(); + + if ( !xLibContainer.is() ) + { + // try the "BasicLibraries" property (old-style, for compatibility) + Reference< beans::XPropertySet > xPSet( m_xModel, UNO_QUERY ); + if ( xPSet.is() ) + xPSet->getPropertyValue("BasicLibraries" ) >>= xLibContainer; + } + + SAL_WARN_IF( !xLibContainer.is(), "xmlscript.xmlflat", "XMLBasicExporterBase::filter: nowhere to export to!" ); + + if ( xLibContainer.is() ) + { + const Sequence< OUString > aLibNames = xLibContainer->getElementNames(); + for ( const OUString& rLibName : aLibNames ) + { + if ( xLibContainer->hasByName( rLibName ) ) + { + OUString aTrueStr( "true" ); + + if ( xLibContainer->isLibraryLink( rLibName ) ) + { + // ooo/script:library-linked element + OUString aLibElementName = aPrefix + ":library-linked"; + rtl::Reference<XMLElement> pLibElement = new XMLElement( aLibElementName ); + + // ooo/script:name attribute + pLibElement->addAttribute( aPrefix + ":name", rLibName ); + + OUString aLinkURL( xLibContainer->getLibraryLinkURL( rLibName ) ); + if ( !aLinkURL.isEmpty() ) + { + // xlink:href attribute + pLibElement->addAttribute( XMLNS_XLINK_PREFIX ":href", aLinkURL ); + + // xlink:type attribute + pLibElement->addAttribute( XMLNS_XLINK_PREFIX ":type", "simple" ); + } + + if ( xLibContainer->isLibraryReadOnly( rLibName ) ) + { + // ooo/script:readonly attribute + pLibElement->addAttribute( aPrefix + ":readonly", aTrueStr ); + } + + // <ooo/script:library-linked... + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->startElement( aLibElementName, pLibElement ); + + // ...ooo/script:library-linked> + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->endElement( aLibElementName ); + } + else + { + // ooo/script:library-embedded element + OUString aLibElementName = aPrefix + ":library-embedded"; + rtl::Reference<XMLElement> pLibElement = new XMLElement( aLibElementName ); + + // ooo/script:name attribute + pLibElement->addAttribute( aPrefix + ":name", rLibName ); + + if ( xLibContainer->isLibraryReadOnly( rLibName ) ) + { + // ooo/script:readonly attribute + pLibElement->addAttribute( aPrefix + ":readonly", aTrueStr ); + } + + // TODO: password protected libraries + Reference< script::XLibraryContainerPassword > xPasswd( xLibContainer, UNO_QUERY ); + if ( xPasswd.is() && xPasswd->isLibraryPasswordProtected( rLibName ) ) + continue; + + // <ooo/script:library-embedded... + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->startElement( aLibElementName, pLibElement ); + + if ( !xLibContainer->isLibraryLoaded( rLibName ) ) + xLibContainer->loadLibrary( rLibName ); + + Reference< container::XNameContainer > xLib; + xLibContainer->getByName( rLibName ) >>= xLib; + + if ( xLib.is() ) + { + const Sequence< OUString > aModNames = xLib->getElementNames(); + for ( const OUString& rModName : aModNames ) + { + if ( xLib->hasByName( rModName ) ) + { + // ooo/script:module element + OUString aModElementName = aPrefix + ":module"; + rtl::Reference<XMLElement> pModElement = new XMLElement( aModElementName ); + + // ooo/script:name attribute + pModElement->addAttribute( aPrefix + ":name", rModName ); + + // <ooo/script:module... + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->startElement( aModElementName, pModElement ); + + // ooo/script:source-code element + OUString aSourceElementName = aPrefix + ":source-code"; + rtl::Reference<XMLElement> pSourceElement = new XMLElement( aSourceElementName ); + + // <ooo/script:source-code... + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->startElement( aSourceElementName, pSourceElement ); + + // module data + // TODO: write encrypted data for password protected libraries + OUString aSource; + xLib->getByName( rModName ) >>= aSource; + m_xHandler->characters( aSource ); + + // TODO: <ooo/script:byte-code> + + // ...ooo/script:source-code> + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->endElement( aSourceElementName ); + + // ...ooo/script:module> + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->endElement( aModElementName ); + } + } + } + + // ...ooo/script:library-embedded> + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->endElement( aLibElementName ); + } + } + } + } + + // ...ooo/script:libraries> + m_xHandler->ignorableWhitespace( OUString() ); + m_xHandler->endElement( aLibContElementName ); + + m_xHandler->endDocument(); + } + } + catch ( const container::NoSuchElementException& ) + { + TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "XMLBasicExporterBase::filter" ); + bReturn = false; + } + catch ( const lang::IllegalArgumentException& ) + { + TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "XMLBasicExporterBase::filter" ); + bReturn = false; + } + catch ( const lang::WrappedTargetException& ) + { + TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "XMLBasicExporterBase::filter:" ); + bReturn = false; + } + catch ( const xml::sax::SAXException& ) + { + TOOLS_INFO_EXCEPTION("xmlscript.xmlflat", "XMLBasicExporterBase::filter:" ); + bReturn = false; + } + + return bReturn; + } + + void XMLBasicExporterBase::cancel() + { + // cancel export + } + + // XMLBasicExporter + + XMLBasicExporter::XMLBasicExporter() + :XMLBasicExporterBase( false ) + { + } + + XMLBasicExporter::~XMLBasicExporter() + { + } + + // XServiceInfo + + OUString XMLBasicExporter::getImplementationName( ) + { + return "com.sun.star.comp.xmlscript.XMLBasicExporter"; + } + + Sequence< OUString > XMLBasicExporter::getSupportedServiceNames( ) + { + return { "com.sun.star.document.XMLBasicExporter" }; + } + + // XMLOasisBasicExporter + + XMLOasisBasicExporter::XMLOasisBasicExporter() + :XMLBasicExporterBase( true ) + { + } + + XMLOasisBasicExporter::~XMLOasisBasicExporter() + { + } + + // XServiceInfo + + OUString XMLOasisBasicExporter::getImplementationName( ) + { + return "com.sun.star.comp.xmlscript.XMLOasisBasicExporter"; + } + + Sequence< OUString > XMLOasisBasicExporter::getSupportedServiceNames( ) + { + return { "com.sun.star.document.XMLOasisBasicExporter" }; + } + +} // namespace xmlscript + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_xmlscript_XMLBasicExporter( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + return cppu::acquire(new xmlscript::XMLBasicExporter()); +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * +com_sun_star_comp_xmlscript_XMLOasisBasicExporter( + css::uno::XComponentContext *, + css::uno::Sequence<css::uno::Any> const &) +{ + + return cppu::acquire(new xmlscript::XMLOasisBasicExporter()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmlflat_imexp/xmlbas_export.hxx b/xmlscript/source/xmlflat_imexp/xmlbas_export.hxx new file mode 100644 index 000000000..1ed5e9e5d --- /dev/null +++ b/xmlscript/source/xmlflat_imexp/xmlbas_export.hxx @@ -0,0 +1,92 @@ +/* -*- 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 . + */ + +#pragma once + +#include <com/sun/star/xml/sax/XDocumentHandler.hpp> +#include <com/sun/star/document/XXMLBasicExporter.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <cppuhelper/implbase.hxx> +#include <mutex> + +namespace xmlscript +{ + + + typedef ::cppu::WeakImplHelper< + css::lang::XServiceInfo, + css::lang::XInitialization, + css::document::XXMLBasicExporter > XMLBasicExporterBase_BASE; + + class XMLBasicExporterBase : public XMLBasicExporterBase_BASE + { + private: + std::mutex m_aMutex; + css::uno::Reference< css::xml::sax::XDocumentHandler > m_xHandler; + css::uno::Reference< css::frame::XModel > m_xModel; + bool const m_bOasis; + + public: + explicit XMLBasicExporterBase(bool bOasis); + virtual ~XMLBasicExporterBase() override; + + // XServiceInfo + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override; + + // XInitialization + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override; + + // XExporter + virtual void SAL_CALL setSourceDocument( const css::uno::Reference< css::lang::XComponent >& rxDoc ) override; + + // XFilter + virtual sal_Bool SAL_CALL filter( const css::uno::Sequence< css::beans::PropertyValue >& aDescriptor ) override; + virtual void SAL_CALL cancel() override; + }; + + + class XMLBasicExporter : public XMLBasicExporterBase + { + public: + explicit XMLBasicExporter(); + virtual ~XMLBasicExporter() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + }; + + + class XMLOasisBasicExporter : public XMLBasicExporterBase + { + public: + explicit XMLOasisBasicExporter(); + virtual ~XMLOasisBasicExporter() override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override; + }; + +} // namespace xmlscript + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmllib_imexp/imp_share.hxx b/xmlscript/source/xmllib_imexp/imp_share.hxx new file mode 100644 index 000000000..d9ec1c442 --- /dev/null +++ b/xmlscript/source/xmllib_imexp/imp_share.hxx @@ -0,0 +1,219 @@ +/* -*- 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 . + */ + +#pragma once + +#include <xmlscript/xmllib_imexp.hxx> + +#include <cppuhelper/implbase.hxx> + +#include <com/sun/star/xml/input/XRoot.hpp> +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <rtl/ref.hxx> +#include <o3tl/string_view.hxx> + +#include <vector> + +namespace xmlscript +{ +inline sal_Int32 toInt32( OUString const & rStr ) +{ + sal_Int32 nVal; + if (rStr.getLength() > 2 && rStr[ 0 ] == '0' && rStr[ 1 ] == 'x') + { + nVal = o3tl::toUInt32(rStr.subView( 2 ), 16); + } + else + { + nVal = rStr.toInt32(); + } + return nVal; +} +inline bool getBoolAttr( + bool * pRet, OUString const & rAttrName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, sal_Int32 uid ) +{ + OUString aValue( + xAttributes->getValueByUidName( uid, rAttrName ) ); + if (!aValue.isEmpty()) + { + if ( aValue == "true" ) + { + *pRet = true; + return true; + } + else if ( aValue == "false" ) + { + *pRet = false; + return true; + } + else + { + throw css::xml::sax::SAXException(rAttrName + ": no boolean value (true|false)!", css::uno::Reference< css::uno::XInterface >(), css::uno::Any() ); + } + } + return false; +} + +inline bool getStringAttr( + OUString * pRet, OUString const & rAttrName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, sal_Int32 uid ) +{ + *pRet = xAttributes->getValueByUidName( uid, rAttrName ); + return (!pRet->isEmpty()); +} + +inline bool getLongAttr( + sal_Int32 * pRet, OUString const & rAttrName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + sal_Int32 uid ) +{ + OUString aValue( + xAttributes->getValueByUidName( uid, rAttrName ) ); + if (!aValue.isEmpty()) + { + *pRet = toInt32( aValue ); + return true; + } + return false; +} + +// Library import + +struct LibraryImport + : public ::cppu::WeakImplHelper< css::xml::input::XRoot > +{ + friend class LibrariesElement; + friend class LibraryElement; + + LibDescriptorArray* mpLibArray; + LibDescriptor* const mpLibDesc; // Single library mode + + sal_Int32 XMLNS_LIBRARY_UID; + sal_Int32 XMLNS_XLINK_UID; + +public: + explicit LibraryImport( LibDescriptorArray* pLibArray ) + : mpLibArray(pLibArray) + , mpLibDesc(nullptr) + , XMLNS_LIBRARY_UID(0) + , XMLNS_XLINK_UID(0) + { + } + + // Single library mode + explicit LibraryImport(LibDescriptor* pLibDesc) + : mpLibArray(nullptr) + , mpLibDesc(pLibDesc) + , XMLNS_LIBRARY_UID(0) + , XMLNS_XLINK_UID(0) + { + } + + virtual ~LibraryImport() override; + + // XRoot + virtual void SAL_CALL startDocument( + css::uno::Reference< css::xml::input::XNamespaceMapping > const & xNamespaceMapping ) override; + virtual void SAL_CALL endDocument() override; + virtual void SAL_CALL processingInstruction( + OUString const & rTarget, OUString const & rData ) override; + virtual void SAL_CALL setDocumentLocator( + css::uno::Reference< css::xml::sax::XLocator > const & xLocator ) override; + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL startRootElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ) override; +}; + +class LibElementBase + : public ::cppu::WeakImplHelper< css::xml::input::XElement > +{ +protected: + rtl::Reference<LibraryImport> mxImport; + rtl::Reference<LibElementBase> mxParent; +private: + OUString const _aLocalName; + css::uno::Reference< css::xml::input::XAttributes > _xAttributes; + +public: + LibElementBase( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + LibElementBase * pParent, LibraryImport * pImport ); + virtual ~LibElementBase() override; + + // XElement + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL getParent() override; + virtual OUString SAL_CALL getLocalName() override; + virtual sal_Int32 SAL_CALL getUid() override; + virtual css::uno::Reference< css::xml::input::XAttributes > SAL_CALL getAttributes() override; + virtual void SAL_CALL ignorableWhitespace( + OUString const & rWhitespaces ) override; + virtual void SAL_CALL characters( OUString const & rChars ) override; + virtual void SAL_CALL processingInstruction( + OUString const & rTarget, OUString const & rData ) override; + virtual void SAL_CALL endElement() override; + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ) override; +}; + +class LibrariesElement : public LibElementBase +{ + friend class LibraryElement; + + std::vector< LibDescriptor > mLibDescriptors; + +public: + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + LibrariesElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + LibraryImport * pImport ) + : LibElementBase( rLocalName, xAttributes, nullptr, pImport ) + {} +}; + +class LibraryElement : public LibElementBase +{ + std::vector< OUString > mElements; + +public: + + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ) override; + virtual void SAL_CALL endElement() override; + + LibraryElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + LibElementBase * pParent, LibraryImport * pImport ) + : LibElementBase( rLocalName, xAttributes, pParent, pImport ) + {} +}; + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmllib_imexp/xmllib_export.cxx b/xmlscript/source/xmllib_imexp/xmllib_export.cxx new file mode 100644 index 000000000..00f8045a0 --- /dev/null +++ b/xmlscript/source/xmllib_imexp/xmllib_export.cxx @@ -0,0 +1,135 @@ +/* -*- 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 <rtl/ref.hxx> +#include <xmlscript/xmllib_imexp.hxx> +#include <xmlscript/xml_helper.hxx> +#include <xmlscript/xmlns.h> +#include <com/sun/star/xml/sax/XWriter.hpp> + +using namespace com::sun::star::uno; +using namespace com::sun::star; + +namespace xmlscript +{ + +constexpr OUStringLiteral aTrueStr = u"true"; +constexpr OUStringLiteral aFalseStr = u"false"; + +void +exportLibraryContainer( + Reference< xml::sax::XWriter > const & xOut, + const LibDescriptorArray* pLibArray ) +{ + xOut->startDocument(); + + xOut->unknown( + "<!DOCTYPE library:libraries PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\"" + " \"libraries.dtd\">" ); + xOut->ignorableWhitespace( OUString() ); + + OUString aLibrariesName( XMLNS_LIBRARY_PREFIX ":libraries" ); + rtl::Reference<XMLElement> pLibsElement = new XMLElement( aLibrariesName ); + + pLibsElement->addAttribute( "xmlns:" XMLNS_LIBRARY_PREFIX, XMLNS_LIBRARY_URI ); + pLibsElement->addAttribute( "xmlns:" XMLNS_XLINK_PREFIX, XMLNS_XLINK_URI ); + + xOut->ignorableWhitespace( OUString() ); + xOut->startElement( aLibrariesName, pLibsElement ); + + OUString sTrueStr(aTrueStr); + OUString sFalseStr(aFalseStr); + + int nLibCount = pLibArray->mnLibCount; + for( sal_Int32 i = 0 ; i < nLibCount ; i++ ) + { + LibDescriptor& rLib = pLibArray->mpLibs[i]; + + rtl::Reference<XMLElement> pLibElement(new XMLElement( XMLNS_LIBRARY_PREFIX ":library" )); + + pLibElement->addAttribute( XMLNS_LIBRARY_PREFIX ":name", rLib.aName ); + + if( !rLib.aStorageURL.isEmpty() ) + { + pLibElement->addAttribute( XMLNS_XLINK_PREFIX ":href", rLib.aStorageURL ); + pLibElement->addAttribute( XMLNS_XLINK_PREFIX ":type", "simple" ); + } + + pLibElement->addAttribute( XMLNS_LIBRARY_PREFIX ":link", rLib.bLink ? sTrueStr : sFalseStr ); + + if( rLib.bLink ) + { + pLibElement->addAttribute( XMLNS_LIBRARY_PREFIX ":readonly", rLib.bReadOnly ? sTrueStr : sFalseStr ); + } + + pLibElement->dump( xOut ); + } + + xOut->ignorableWhitespace( OUString() ); + xOut->endElement( aLibrariesName ); + + xOut->endDocument(); +} + +void +exportLibrary( + css::uno::Reference< css::xml::sax::XWriter > const & xOut, + const LibDescriptor& rLib ) +{ + xOut->startDocument(); + + xOut->unknown( + "<!DOCTYPE library:library PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\"" + " \"library.dtd\">" ); + xOut->ignorableWhitespace( OUString() ); + + rtl::Reference<XMLElement> pLibElement = new XMLElement( XMLNS_LIBRARY_PREFIX ":library" ); + + pLibElement->addAttribute( "xmlns:" XMLNS_LIBRARY_PREFIX, XMLNS_LIBRARY_URI ); + + pLibElement->addAttribute( XMLNS_LIBRARY_PREFIX ":name", rLib.aName ); + + OUString sTrueStr(aTrueStr); + OUString sFalseStr(aFalseStr); + + pLibElement->addAttribute( XMLNS_LIBRARY_PREFIX ":readonly", rLib.bReadOnly ? sTrueStr : sFalseStr ); + + pLibElement->addAttribute( XMLNS_LIBRARY_PREFIX ":passwordprotected", rLib.bPasswordProtected ? sTrueStr : sFalseStr ); + + if( rLib.bPreload ) + pLibElement->addAttribute( XMLNS_LIBRARY_PREFIX ":preload", sTrueStr ); + + for( const auto& rElementName : rLib.aElementNames ) + { + rtl::Reference<XMLElement> pElement(new XMLElement( XMLNS_LIBRARY_PREFIX ":element" )); + + pElement->addAttribute( XMLNS_LIBRARY_PREFIX ":name", + rElementName ); + + pLibElement->addSubElement( pElement ); + } + + pLibElement->dump( xOut ); + + xOut->endDocument(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmllib_imexp/xmllib_import.cxx b/xmlscript/source/xmllib_imexp/xmllib_import.cxx new file mode 100644 index 000000000..02c46a65f --- /dev/null +++ b/xmlscript/source/xmllib_imexp/xmllib_import.cxx @@ -0,0 +1,257 @@ +/* -*- 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 <sal/config.h> + +#include <sal/log.hxx> + +#include "imp_share.hxx" +#include <xml_import.hxx> +#include <xmlscript/xmlns.h> + +using namespace css; +using namespace css::uno; + +namespace xmlscript +{ + +Reference< xml::input::XElement > LibElementBase::getParent() +{ + return mxParent; +} + +OUString LibElementBase::getLocalName() +{ + return _aLocalName; +} + +sal_Int32 LibElementBase::getUid() +{ + return mxImport->XMLNS_LIBRARY_UID; +} + +Reference< xml::input::XAttributes > LibElementBase::getAttributes() +{ + return _xAttributes; +} + +void LibElementBase::ignorableWhitespace( + OUString const & /*rWhitespaces*/ ) +{ +} + +void LibElementBase::characters( OUString const & /*rChars*/ ) +{ + // not used, all characters ignored +} + +void LibElementBase::processingInstruction( + OUString const & /*rTarget*/, OUString const & /*rData*/ ) +{ +} + +void LibElementBase::endElement() +{ +} +Reference< xml::input::XElement > LibElementBase::startChildElement( + sal_Int32 /*nUid*/, OUString const & /*rLocalName*/, + Reference< xml::input::XAttributes > const & /*xAttributes*/ ) +{ + throw xml::sax::SAXException("unexpected element!", Reference< XInterface >(), Any() ); +} + +LibElementBase::LibElementBase( + OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes, + LibElementBase * pParent, LibraryImport * pImport ) + : mxImport( pImport ) + , mxParent( pParent ) + , _aLocalName( rLocalName ) + , _xAttributes( xAttributes ) +{ +} + +LibElementBase::~LibElementBase() +{ + SAL_INFO("xmlscript.xmllib", "LibElementBase::~LibElementBase(): " << _aLocalName ); +} + +// XRoot + +void LibraryImport::startDocument( + Reference< xml::input::XNamespaceMapping > const & xNamespaceMapping ) +{ + XMLNS_LIBRARY_UID = xNamespaceMapping->getUidByUri( XMLNS_LIBRARY_URI ); + XMLNS_XLINK_UID = xNamespaceMapping->getUidByUri( XMLNS_XLINK_URI ); +} + +void LibraryImport::endDocument() +{ +} + +void LibraryImport::processingInstruction( + OUString const & /*rTarget*/, OUString const & /*rData*/ ) +{ +} + +void LibraryImport::setDocumentLocator( + Reference< xml::sax::XLocator > const & /*xLocator*/ ) +{ +} + +Reference< xml::input::XElement > LibraryImport::startRootElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (XMLNS_LIBRARY_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + else if ( mpLibArray && rLocalName == "libraries" ) + { + return new LibrariesElement( rLocalName, xAttributes, this ); + } + else if ( mpLibDesc && rLocalName == "library" ) + { + LibDescriptor& aDesc = *mpLibDesc; + aDesc.bLink = aDesc.bReadOnly = aDesc.bPasswordProtected = aDesc.bPreload = false; + + aDesc.aName = xAttributes->getValueByUidName(XMLNS_LIBRARY_UID, "name" ); + getBoolAttr( &aDesc.bReadOnly, "readonly", xAttributes, XMLNS_LIBRARY_UID ); + getBoolAttr( &aDesc.bPasswordProtected, "passwordprotected", xAttributes, XMLNS_LIBRARY_UID ); + getBoolAttr( &aDesc.bPreload, "preload", xAttributes, XMLNS_LIBRARY_UID ); + + return new LibraryElement( rLocalName, xAttributes, nullptr, this ); + } + else + { + throw xml::sax::SAXException( "illegal root element (expected libraries) given: " + rLocalName, Reference< XInterface >(), Any() ); + } +} + +LibraryImport::~LibraryImport() +{ + SAL_INFO("xmlscript.xmllib", "LibraryImport::~LibraryImport()." ); +} + +// libraries +Reference< xml::input::XElement > LibrariesElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (mxImport->XMLNS_LIBRARY_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // library + else if ( rLocalName == "library" ) + { + LibDescriptor aDesc; + aDesc.bLink = aDesc.bReadOnly = aDesc.bPasswordProtected = aDesc.bPreload = false; + + aDesc.aName = xAttributes->getValueByUidName(mxImport->XMLNS_LIBRARY_UID, "name" ); + aDesc.aStorageURL = xAttributes->getValueByUidName( mxImport->XMLNS_XLINK_UID, "href" ); + getBoolAttr(&aDesc.bLink, "link", xAttributes, mxImport->XMLNS_LIBRARY_UID ); + getBoolAttr(&aDesc.bReadOnly, "readonly", xAttributes, mxImport->XMLNS_LIBRARY_UID ); + getBoolAttr(&aDesc.bPasswordProtected, "passwordprotected", xAttributes, mxImport->XMLNS_LIBRARY_UID ); + + mLibDescriptors.push_back( aDesc ); + return new LibraryElement( rLocalName, xAttributes, this, mxImport.get() ); + } + else + { + throw xml::sax::SAXException( "expected styles of bulletinboard element!", Reference< XInterface >(), Any() ); + } +} + +void LibrariesElement::endElement() +{ + sal_Int32 nLibCount = mxImport->mpLibArray->mnLibCount = static_cast<sal_Int32>(mLibDescriptors.size()); + mxImport->mpLibArray->mpLibs.reset( new LibDescriptor[ nLibCount ] ); + + for( sal_Int32 i = 0 ; i < nLibCount ; i++ ) + { + const LibDescriptor& rLib = mLibDescriptors[i]; + mxImport->mpLibArray->mpLibs[i] = rLib; + } +} + +// library +Reference< xml::input::XElement > LibraryElement::startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (mxImport->XMLNS_LIBRARY_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // library + else if ( rLocalName == "element" ) + { + OUString aValue( xAttributes->getValueByUidName(mxImport->XMLNS_LIBRARY_UID, "name" ) ); + if (!aValue.isEmpty()) + mElements.push_back( aValue ); + + return new LibElementBase( rLocalName, xAttributes, this, mxImport.get() ); + } + else + { + throw xml::sax::SAXException( "expected styles or bulletinboard element!", Reference< XInterface >(), Any() ); + } +} + +void LibraryElement::endElement() +{ + sal_Int32 nElementCount = mElements.size(); + Sequence< OUString > aElementNames( nElementCount ); + OUString* pElementNames = aElementNames.getArray(); + for( sal_Int32 i = 0 ; i < nElementCount ; i++ ) + pElementNames[i] = mElements[i]; + + LibDescriptor* pLib = mxImport->mpLibDesc; + if( !pLib ) + pLib = &static_cast< LibrariesElement* >( mxParent.get() )->mLibDescriptors.back(); + pLib->aElementNames = aElementNames; +} + +Reference< css::xml::sax::XDocumentHandler > +importLibraryContainer( LibDescriptorArray* pLibArray ) +{ + return ::xmlscript::createDocumentHandler(new LibraryImport(pLibArray)); +} + +css::uno::Reference< css::xml::sax::XDocumentHandler > +importLibrary( LibDescriptor& rLib ) +{ + return ::xmlscript::createDocumentHandler(new LibraryImport(&rLib)); +} + +LibDescriptorArray::LibDescriptorArray( sal_Int32 nLibCount ) +{ + mnLibCount = nLibCount; + mpLibs.reset( new LibDescriptor[ mnLibCount ] ); +} + +LibDescriptorArray::~LibDescriptorArray() +{ +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmlmod_imexp/imp_share.hxx b/xmlscript/source/xmlmod_imexp/imp_share.hxx new file mode 100644 index 000000000..f914c973b --- /dev/null +++ b/xmlscript/source/xmlmod_imexp/imp_share.hxx @@ -0,0 +1,101 @@ +/* -*- 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 . + */ + +#pragma once + +#include <xmlscript/xmlmod_imexp.hxx> + +#include <cppuhelper/implbase.hxx> +#include <rtl/ustrbuf.hxx> +#include <rtl/ref.hxx> + +#include <com/sun/star/xml/input/XRoot.hpp> + +namespace xmlscript +{ + +// Script module import + +struct ModuleImport + : public ::cppu::WeakImplHelper< css::xml::input::XRoot > +{ + friend class ModuleElement; + + ModuleDescriptor& mrModuleDesc; + + sal_Int32 XMLNS_SCRIPT_UID; + +public: + explicit ModuleImport(ModuleDescriptor& rModuleDesc) + : mrModuleDesc(rModuleDesc) + , XMLNS_SCRIPT_UID(0) + { + } + + virtual ~ModuleImport() override; + + // XRoot + virtual void SAL_CALL startDocument( + css::uno::Reference< css::xml::input::XNamespaceMapping > const & xNamespaceMapping ) override; + virtual void SAL_CALL endDocument() override; + virtual void SAL_CALL processingInstruction( + OUString const & rTarget, OUString const & rData ) override; + virtual void SAL_CALL setDocumentLocator( + css::uno::Reference< css::xml::sax::XLocator > const & xLocator ) override; + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL startRootElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ) override; +}; + +class ModuleElement + : public ::cppu::WeakImplHelper< css::xml::input::XElement > +{ + rtl::Reference<ModuleImport> mxImport; + + OUString const _aLocalName; + css::uno::Reference< css::xml::input::XAttributes > _xAttributes; + OUStringBuffer _strBuffer{512}; + +public: + ModuleElement( + OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes, + ModuleImport * pImport ); + virtual ~ModuleElement() override; + + // XElement + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL getParent() override; + virtual OUString SAL_CALL getLocalName() override; + virtual sal_Int32 SAL_CALL getUid() override; + virtual css::uno::Reference< css::xml::input::XAttributes > SAL_CALL getAttributes() override; + virtual void SAL_CALL ignorableWhitespace( + OUString const & rWhitespaces ) override; + virtual void SAL_CALL characters( OUString const & rChars ) override; + virtual void SAL_CALL processingInstruction( + OUString const & rTarget, OUString const & rData ) override; + virtual void SAL_CALL endElement() override; + virtual css::uno::Reference< css::xml::input::XElement > SAL_CALL startChildElement( + sal_Int32 nUid, OUString const & rLocalName, + css::uno::Reference< css::xml::input::XAttributes > const & xAttributes ) override; +}; + +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmlmod_imexp/xmlmod_export.cxx b/xmlscript/source/xmlmod_imexp/xmlmod_export.cxx new file mode 100644 index 000000000..55b447561 --- /dev/null +++ b/xmlscript/source/xmlmod_imexp/xmlmod_export.cxx @@ -0,0 +1,63 @@ +/* -*- 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 <xmlscript/xmlmod_imexp.hxx> +#include <xmlscript/xml_helper.hxx> +#include <xmlscript/xmlns.h> +#include <com/sun/star/xml/sax/XWriter.hpp> +#include <rtl/ref.hxx> + +using namespace com::sun::star::uno; +using namespace com::sun::star; + +namespace xmlscript +{ + +void +exportScriptModule( + Reference< xml::sax::XWriter > const & xOut, + const ModuleDescriptor& rMod ) +{ + xOut->startDocument(); + + xOut->unknown( + "<!DOCTYPE script:module PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\"" + " \"module.dtd\">"); + xOut->ignorableWhitespace( OUString() ); + + OUString aModuleName( XMLNS_SCRIPT_PREFIX ":module" ); + rtl::Reference<XMLElement> pModElement = new XMLElement( aModuleName ); + + pModElement->addAttribute( "xmlns:" XMLNS_SCRIPT_PREFIX, XMLNS_SCRIPT_URI ); + + pModElement->addAttribute( XMLNS_SCRIPT_PREFIX ":name", rMod.aName ); + pModElement->addAttribute( XMLNS_SCRIPT_PREFIX ":language", rMod.aLanguage ); + if( !rMod.aModuleType.isEmpty() ) + pModElement->addAttribute( XMLNS_SCRIPT_PREFIX ":moduleType", rMod.aModuleType ); + + xOut->ignorableWhitespace( OUString() ); + xOut->startElement( aModuleName, pModElement ); + xOut->characters( rMod.aCode ); + xOut->endElement( aModuleName ); + xOut->endDocument(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmlscript/source/xmlmod_imexp/xmlmod_import.cxx b/xmlscript/source/xmlmod_imexp/xmlmod_import.cxx new file mode 100644 index 000000000..2751d9856 --- /dev/null +++ b/xmlscript/source/xmlmod_imexp/xmlmod_import.cxx @@ -0,0 +1,154 @@ +/* -*- 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 <sal/config.h> + +#include <xmlscript/xmlns.h> +#include <com/sun/star/xml/sax/SAXException.hpp> +#include <sal/log.hxx> + +#include "imp_share.hxx" +#include <xml_import.hxx> + +using namespace css; +using namespace css::uno; + +namespace xmlscript +{ + +Reference< xml::input::XElement > ModuleElement::getParent() +{ + return nullptr; +} +OUString ModuleElement::getLocalName() +{ + return _aLocalName; +} +sal_Int32 ModuleElement::getUid() +{ + return mxImport->XMLNS_SCRIPT_UID; +} +Reference< xml::input::XAttributes > ModuleElement::getAttributes() +{ + return _xAttributes; +} + +void ModuleElement::ignorableWhitespace( + OUString const & /*rWhitespaces*/ ) +{ + // not used +} + +void ModuleElement::characters( OUString const & rChars ) +{ + _strBuffer.append( rChars ); +} + +void ModuleElement::processingInstruction( + OUString const & /*rTarget*/, OUString const & /*rData*/ ) +{ +} + +void ModuleElement::endElement() +{ + mxImport->mrModuleDesc.aCode = _strBuffer.makeStringAndClear(); +} + +Reference< xml::input::XElement > ModuleElement::startChildElement( + sal_Int32 /*nUid*/, OUString const & /*rLocalName*/, + Reference< xml::input::XAttributes > const & /*xAttributes*/ ) +{ + throw xml::sax::SAXException("unexpected element!", Reference< XInterface >(), Any() ); +} + +ModuleElement::ModuleElement( + OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes, + ModuleImport * pImport ) + : mxImport( pImport ) + , _aLocalName( rLocalName ) + , _xAttributes( xAttributes ) +{ +} + +ModuleElement::~ModuleElement() +{ + SAL_INFO("xmlscript.xmlmod", "ModuleElement::~ModuleElement(): " << _aLocalName ); +} + +// XRoot + +void ModuleImport::startDocument( + Reference< xml::input::XNamespaceMapping > const & xNamespaceMapping ) +{ + XMLNS_SCRIPT_UID = xNamespaceMapping->getUidByUri( XMLNS_SCRIPT_URI ); +} + +void ModuleImport::endDocument() +{ + // ignored +} + +void ModuleImport::processingInstruction( + OUString const & /*rTarget*/, OUString const & /*rData*/ ) +{ +} + +void ModuleImport::setDocumentLocator( + Reference< xml::sax::XLocator > const & /*xLocator*/ ) +{ +} + +Reference< xml::input::XElement > ModuleImport::startRootElement( + sal_Int32 nUid, OUString const & rLocalName, + Reference< xml::input::XAttributes > const & xAttributes ) +{ + if (XMLNS_SCRIPT_UID != nUid) + { + throw xml::sax::SAXException( "illegal namespace!", Reference< XInterface >(), Any() ); + } + // window + else if ( rLocalName == "module" ) + { + mrModuleDesc.aName = xAttributes->getValueByUidName( XMLNS_SCRIPT_UID, "name" ); + mrModuleDesc.aLanguage = xAttributes->getValueByUidName( XMLNS_SCRIPT_UID, "language" ); + mrModuleDesc.aModuleType = xAttributes->getValueByUidName( XMLNS_SCRIPT_UID, "moduleType" ); + + return new ModuleElement( rLocalName, xAttributes, this ); + } + else + { + throw xml::sax::SAXException("illegal root element (expected module) given: " + rLocalName, Reference< XInterface >(), Any() ); + } +} + +ModuleImport::~ModuleImport() +{ + SAL_INFO("xmlscript.xmlmod", "ModuleImport::~ModuleImport()." ); +} + +Reference< xml::sax::XDocumentHandler > +importScriptModule( ModuleDescriptor& rMod ) +{ + return ::xmlscript::createDocumentHandler(new ModuleImport(rMod)); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |