diff options
Diffstat (limited to 'framework/source/fwe/xml')
-rw-r--r-- | framework/source/fwe/xml/eventsconfiguration.cxx | 165 | ||||
-rw-r--r-- | framework/source/fwe/xml/eventsdocumenthandler.cxx | 553 | ||||
-rw-r--r-- | framework/source/fwe/xml/imagesconfiguration.cxx | 238 | ||||
-rw-r--r-- | framework/source/fwe/xml/imagesdocumenthandler.cxx | 851 | ||||
-rw-r--r-- | framework/source/fwe/xml/menuconfiguration.cxx | 187 | ||||
-rw-r--r-- | framework/source/fwe/xml/menudocumenthandler.cxx | 1022 | ||||
-rw-r--r-- | framework/source/fwe/xml/saxnamespacefilter.cxx | 198 | ||||
-rw-r--r-- | framework/source/fwe/xml/statusbarconfiguration.cxx | 166 | ||||
-rw-r--r-- | framework/source/fwe/xml/statusbardocumenthandler.cxx | 698 | ||||
-rw-r--r-- | framework/source/fwe/xml/toolboxconfiguration.cxx | 156 | ||||
-rw-r--r-- | framework/source/fwe/xml/toolboxdocumenthandler.cxx | 901 | ||||
-rw-r--r-- | framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx | 58 | ||||
-rw-r--r-- | framework/source/fwe/xml/xmlnamespaces.cxx | 191 |
13 files changed, 5384 insertions, 0 deletions
diff --git a/framework/source/fwe/xml/eventsconfiguration.cxx b/framework/source/fwe/xml/eventsconfiguration.cxx new file mode 100644 index 000000000000..873682f60345 --- /dev/null +++ b/framework/source/fwe/xml/eventsconfiguration.cxx @@ -0,0 +1,165 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <framework/eventsconfiguration.hxx> +#include <xml/eventsdocumenthandler.hxx> +#include <services.h> + +#ifndef __FRAMEWORK_XML_SAXNAMESPACEFILTER_HXX_ +#include <xml/saxnamespacefilter.hxx> +#endif + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <unotools/streamwrap.hxx> +#include <tools/debug.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::io; + + +namespace framework +{ + +static Reference< XParser > GetSaxParser( + // #110897# + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + //Reference< XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); + //return Reference< XParser >( xServiceManager->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY); + return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY); +} + +static Reference< XDocumentHandler > GetSaxWriter( + // #110897# + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + //Reference< XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); + //return Reference< XDocumentHandler >( xServiceManager->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ; + return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ; +} + +// #110897# +sal_Bool EventsConfiguration::LoadEventsConfig( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + SvStream& rInStream, EventsConfig& aItems ) +{ + Reference< XParser > xParser( GetSaxParser( xServiceFactory ) ); + Reference< XInputStream > xInputStream( + (::cppu::OWeakObject *)new utl::OInputStreamWrapper( rInStream ), + UNO_QUERY ); + + // connect stream to input stream to the parser + InputSource aInputSource; + + aInputSource.aInputStream = xInputStream; + + // create namespace filter and set events document handler inside to support xml namespaces + Reference< XDocumentHandler > xDocHandler( new OReadEventsDocumentHandler( aItems )); + Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler )); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + try + { + xParser->parseStream( aInputSource ); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch( SAXException& ) + { + return sal_False; + } + catch( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + +// #110897# +sal_Bool EventsConfiguration::StoreEventsConfig( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + SvStream& rOutStream, const EventsConfig& aItems ) +{ + Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) ); + + Reference< XOutputStream > xOutputStream( + (::cppu::OWeakObject *)new utl::OOutputStreamWrapper( rOutStream ), + UNO_QUERY ); + + Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY ); + xDataSource->setOutputStream( xOutputStream ); + + try + { + OWriteEventsDocumentHandler aWriteEventsDocumentHandler( aItems, xWriter ); + aWriteEventsDocumentHandler.WriteEventsDocument(); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch ( SAXException& ) + { + return sal_False; + } + catch ( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + +} + diff --git a/framework/source/fwe/xml/eventsdocumenthandler.cxx b/framework/source/fwe/xml/eventsdocumenthandler.cxx new file mode 100644 index 000000000000..ad21937fcc5d --- /dev/null +++ b/framework/source/fwe/xml/eventsdocumenthandler.cxx @@ -0,0 +1,553 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <framework/fwedllapi.h> +#include <stdio.h> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/resetableguard.hxx> +#include <xml/eventsdocumenthandler.hxx> +#include <macros/debug.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_ +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#endif + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <sal/config.h> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> + +#include <comphelper/attributelist.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::xml::sax; + + +#define XMLNS_EVENT "http://openoffice.org/2001/event" +#define XMLNS_XLINK "http://www.w3.org/1999/xlink" +#define XMLNS_EVENT_PREFIX "event:" +#define XMLNS_XLINK_PREFIX "xlink:" + +#define ATTRIBUTE_XMLNS_EVENT "xmlns:event" +#define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink" + +#define XMLNS_FILTER_SEPARATOR "^" + +#define ELEMENT_EVENTS "events" +#define ELEMENT_EVENT "event" + +#define ATTRIBUTE_LANGUAGE "language" +#define ATTRIBUTE_LIBRARY "library" +#define ATTRIBUTE_NAME "name" +#define ATTRIBUTE_HREF "href" +#define ATTRIBUTE_TYPE "type" +#define ATTRIBUTE_MACRONAME "macro-name" + +#define ELEMENT_NS_EVENTS "event:events" +#define ELEMENT_NS_EVENT "event:event" + +#define ATTRIBUTE_TYPE_CDATA "CDATA" + +#define EVENTS_DOCTYPE "<!DOCTYPE event:events PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"event.dtd\">" + +// Property names for events +#define PROP_EVENT_TYPE "EventType" +#define PROP_LIBRARY "Library" +#define PROP_SCRIPT "Script" +#define PROP_MACRO_NAME "MacroName" +#define STAR_BASIC "StarBasic" +#define JAVA_SCRIPT "JavaScript" + + +namespace framework +{ + +struct EventEntryProperty +{ + OReadEventsDocumentHandler::Event_XML_Namespace nNamespace; + char aEntryName[20]; +}; + +static EventEntryProperty EventEntries[OReadEventsDocumentHandler::EV_XML_ENTRY_COUNT] = +{ + { OReadEventsDocumentHandler::EV_NS_EVENT, ELEMENT_EVENTS }, + { OReadEventsDocumentHandler::EV_NS_EVENT, ELEMENT_EVENT }, + { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_LANGUAGE }, + { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_NAME }, + { OReadEventsDocumentHandler::EV_NS_XLINK, ATTRIBUTE_HREF }, + { OReadEventsDocumentHandler::EV_NS_XLINK, ATTRIBUTE_TYPE }, + { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_MACRONAME }, + { OReadEventsDocumentHandler::EV_NS_EVENT, ATTRIBUTE_LIBRARY } +}; + + +OReadEventsDocumentHandler::OReadEventsDocumentHandler( EventsConfig& aItems ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_aEventItems( aItems ) +{ + ::rtl::OUString aNamespaceEvent( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT )); + ::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )); + ::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR )); + + // create hash map + for ( int i = 0; i < (int)EV_XML_ENTRY_COUNT; i++ ) + { + if ( EventEntries[i].nNamespace == EV_NS_EVENT ) + { + ::rtl::OUString temp( aNamespaceEvent ); + temp += aSeparator; + temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName ); + m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) ); + } + else + { + ::rtl::OUString temp( aNamespaceXLink ); + temp += aSeparator; + temp += ::rtl::OUString::createFromAscii( EventEntries[i].aEntryName ); + m_aEventsMap.insert( EventsHashMap::value_type( temp, (Events_XML_Entry)i ) ); + } + } + + m_bEventsStartFound = sal_False; + m_bEventsEndFound = sal_False; + m_bEventStartFound = sal_False; +} + +OReadEventsDocumentHandler::~OReadEventsDocumentHandler() +{ +} + +// XDocumentHandler +void SAL_CALL OReadEventsDocumentHandler::startDocument(void) +throw ( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadEventsDocumentHandler::endDocument(void) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + if (( m_bEventsStartFound && !m_bEventsEndFound ) || + ( !m_bEventsStartFound && m_bEventsEndFound ) ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'event:events' found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + +void SAL_CALL OReadEventsDocumentHandler::startElement( + const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs ) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName ); + if ( pEventEntry != m_aEventsMap.end() ) + { + switch ( pEventEntry->second ) + { + case EV_ELEMENT_EVENTS: + { + if ( m_bEventsStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:events' cannot be embeded into 'event:events'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bEventsStartFound = sal_True; + } + break; + + case EV_ELEMENT_EVENT: + { + if ( !m_bEventsStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'event:event' must be embeded into element 'event:events'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( m_bEventStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element event:event is not a container!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + ::rtl::OUString aLanguage; + ::rtl::OUString aURL; + ::rtl::OUString aMacroName; + ::rtl::OUString aLibrary; + ::rtl::OUString aEventName; + + m_bEventStartFound = sal_True; + + long nIndex = m_aEventItems.aEventNames.getLength(); + long nPropCount = 2; // every event config entry needs at least 2 properties + Sequence< PropertyValue > aEventProperties( nPropCount ); + + m_aEventItems.aEventNames.realloc( nIndex + 1 ); + + for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ ) + { + pEventEntry = m_aEventsMap.find( xAttribs->getNameByIndex( n ) ); + if ( pEventEntry != m_aEventsMap.end() ) + { + switch ( pEventEntry->second ) + { + case EV_ATTRIBUTE_TYPE: + { + aLanguage = xAttribs->getValueByIndex( n ); + } + break; + + case EV_ATTRIBUTE_NAME: + { + aEventName = xAttribs->getValueByIndex( n ); + } + break; + + case XL_ATTRIBUTE_HREF: + { + aURL = xAttribs->getValueByIndex( n ); + } + break; + + case EV_ATTRIBUTE_MACRONAME: + { + aMacroName = xAttribs->getValueByIndex( n ); + } + break; + + case EV_ATTRIBUTE_LIBRARY: + { + aLibrary = xAttribs->getValueByIndex( n ); + } + break; + + default: + break; // nothing to do + } + } + } // for + + ::rtl::OUString aRequiredAttributeName; + if ( aLanguage.getLength() == 0 ) + aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE )); + else if ( aEventName.getLength() == 0 ) + aRequiredAttributeName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME )); + + // check for missing attribute values + if ( aRequiredAttributeName.getLength() > 0 ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute ")); + aErrorMessage += aRequiredAttributeName; + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " must have a value!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + Any a; + + // set properties + a <<= aLanguage; + aEventProperties[0].Value <<= a; + aEventProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_EVENT_TYPE )); + + a <<= aMacroName; + aEventProperties[1].Value <<= a; + aEventProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_MACRO_NAME )); + + if ( aLibrary.getLength() > 0 ) + { + ++nPropCount; + aEventProperties.realloc( nPropCount ); + a <<= aLibrary; + aEventProperties[nPropCount-1].Value <<= a; + aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_LIBRARY )); + } + + if ( aURL.getLength() > 0 ) + { + ++nPropCount; + aEventProperties.realloc( nPropCount ); + a <<= aURL; + aEventProperties[nPropCount-1].Value <<= a; + aEventProperties[nPropCount-1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PROP_SCRIPT )); + } + + // set event name + m_aEventItems.aEventNames[ nIndex ] = aEventName; + + m_aEventItems.aEventsProperties.realloc( nIndex + 1 ); + a <<= aEventProperties; + m_aEventItems.aEventsProperties[ nIndex ] = a; + } + break; + + default: + break; + } + } +} + +void SAL_CALL OReadEventsDocumentHandler::endElement(const ::rtl::OUString& aName) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + EventsHashMap::const_iterator pEventEntry = m_aEventsMap.find( aName ); + if ( pEventEntry != m_aEventsMap.end() ) + { + switch ( pEventEntry->second ) + { + case EV_ELEMENT_EVENTS: + { + if ( !m_bEventsStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:events' found, but no start element" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bEventsStartFound = sal_False; + } + break; + + case EV_ELEMENT_EVENT: + { + if ( !m_bEventStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'event:event' found, but no start element" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bEventStartFound = sal_False; + } + break; + + default: + break; // impossible case + } + } +} + +void SAL_CALL OReadEventsDocumentHandler::characters(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadEventsDocumentHandler::ignorableWhitespace(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadEventsDocumentHandler::processingInstruction( + const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadEventsDocumentHandler::setDocumentLocator( + const Reference< XLocator > &xLocator) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xLocator = xLocator; +} + +::rtl::OUString OReadEventsDocumentHandler::getErrorLineString() +{ + ResetableGuard aGuard( m_aLock ); + + char buffer[32]; + + if ( m_xLocator.is() ) + { + snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>(m_xLocator->getLineNumber() )); + return ::rtl::OUString::createFromAscii( buffer ); + } + else + return ::rtl::OUString(); +} + + +//_________________________________________________________________________________________________________________ +// OWriteEventsDocumentHandler +//_________________________________________________________________________________________________________________ + +OWriteEventsDocumentHandler::OWriteEventsDocumentHandler( + const EventsConfig& aItems, + Reference< XDocumentHandler > rWriteDocumentHandler ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_aItems( aItems ), + m_xWriteDocumentHandler( rWriteDocumentHandler ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY ); + m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); + m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX )); + m_aXMLEventNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT_PREFIX )); +} + +OWriteEventsDocumentHandler::~OWriteEventsDocumentHandler() +{ +} + +void OWriteEventsDocumentHandler::WriteEventsDocument() throw +( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xWriteDocumentHandler->startDocument(); + + // write DOCTYPE line! + Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY ); + if ( xExtendedDocHandler.is() ) + { + xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( EVENTS_DOCTYPE )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + } + + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_EVENT )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_EVENT )) ); + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) ); + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )), pList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + Sequence< PropertyValue > aEventProperties; + + for ( int i = 0; i < m_aItems.aEventNames.getLength(); i++ ) + { + if ( m_aItems.aEventsProperties[i] >>= aEventProperties ) + WriteEvent( m_aItems.aEventNames[i], aEventProperties ); + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENTS )) ); + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endDocument(); +} + +//_________________________________________________________________________________________________________________ +// protected member functions +//_________________________________________________________________________________________________________________ + +void OWriteEventsDocumentHandler::WriteEvent( const ::rtl::OUString& aEventName, const Sequence< PropertyValue >& aPropertyValues ) throw +( SAXException, RuntimeException ) +{ + if ( aPropertyValues.getLength() > 0 ) + { + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + if ( m_aAttributeURL.getLength() == 0 ) + { + m_aAttributeURL = m_aXMLXlinkNS; + m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )); + m_aAttributeLinkType = m_aXMLXlinkNS; + m_aAttributeLinkType += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE )); + m_aAttributeLanguage = m_aXMLEventNS; + m_aAttributeLanguage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LANGUAGE )); + m_aAttributeMacroName = m_aXMLEventNS; + m_aAttributeMacroName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MACRONAME )); + m_aAttributeLibrary = m_aXMLEventNS; + m_aAttributeLibrary += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_LIBRARY )); + m_aAttributeName = m_aXMLEventNS; + m_aAttributeName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NAME )); + } + + pList->AddAttribute( m_aAttributeName, m_aAttributeType, aEventName ); + + sal_Bool bURLSet = sal_False; + ::rtl::OUString aValue; + ::rtl::OUString aName; + + // save attributes + for ( int i = 0; i < aPropertyValues.getLength(); i++ ) + { + aPropertyValues[i].Value >>= aValue; + if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_EVENT_TYPE ))) + pList->AddAttribute( m_aAttributeLanguage, m_aAttributeType, aValue ); + else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_MACRO_NAME )) && + aValue.getLength() > 0 ) + pList->AddAttribute( m_aAttributeMacroName, m_aAttributeType, aValue ); + else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_LIBRARY )) && + aValue.getLength() > 0 ) + pList->AddAttribute( m_aAttributeLibrary, m_aAttributeType, aValue ); + else if ( aPropertyValues[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( PROP_SCRIPT ))) + { + pList->AddAttribute( m_aAttributeURL, m_aAttributeType, aValue ); + bURLSet = sal_True; + } + } + + if ( bURLSet ) + pList->AddAttribute( m_aAttributeLinkType, m_aAttributeType, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "simple" )) ); + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )), xList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EVENT )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + } +} + +} // namespace framework + diff --git a/framework/source/fwe/xml/imagesconfiguration.cxx b/framework/source/fwe/xml/imagesconfiguration.cxx new file mode 100644 index 000000000000..d561a76d5995 --- /dev/null +++ b/framework/source/fwe/xml/imagesconfiguration.cxx @@ -0,0 +1,238 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <framework/imagesconfiguration.hxx> +#include <services.h> + +#ifndef __FRAMEWORK_CLASSES_IMAGESDOCUMENTHANDLER_HXX_ +#include <xml/imagesdocumenthandler.hxx> +#endif +#include <xml/saxnamespacefilter.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <unotools/streamwrap.hxx> +#include <tools/debug.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::io; + + +namespace framework +{ + +SV_IMPL_PTRARR( ImageItemListDescriptor, ImageItemDescriptorPtr ); +SV_IMPL_PTRARR( ExternalImageItemListDescriptor, ExternalImageItemDescriptorPtr ); +SV_IMPL_PTRARR( ImageListDescriptor, ImageListItemDescriptorPtr ); + +static Reference< XParser > GetSaxParser( + // #110897# + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + //Reference< XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); + //return Reference< XParser >( xServiceManager->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY); + return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY); +} + +static Reference< XDocumentHandler > GetSaxWriter( + // #110897# + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + //Reference< XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); + //return Reference< XDocumentHandler >( xServiceManager->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ; + return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ; +} + +// #110897# +sal_Bool ImagesConfiguration::LoadImages( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + SvStream& rInStream, ImageListsDescriptor& aItems ) +{ + Reference< XParser > xParser( GetSaxParser( xServiceFactory ) ); + Reference< XInputStream > xInputStream( + (::cppu::OWeakObject *)new utl::OInputStreamWrapper( rInStream ), + UNO_QUERY ); + + // connect stream to input stream to the parser + InputSource aInputSource; + + aInputSource.aInputStream = xInputStream; + + // create namespace filter and set document handler inside to support xml namespaces + Reference< XDocumentHandler > xDocHandler( new OReadImagesDocumentHandler( aItems )); + Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler )); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + try + { + xParser->parseStream( aInputSource ); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch( SAXException& ) + { + return sal_False; + } + catch( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + + +// #110897# +sal_Bool ImagesConfiguration::StoreImages( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + SvStream& rOutStream, const ImageListsDescriptor& aItems ) +{ + Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) ); + + Reference< XOutputStream > xOutputStream( + (::cppu::OWeakObject *)new utl::OOutputStreamWrapper( rOutStream ), + UNO_QUERY ); + + Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY ); + xDataSource->setOutputStream( xOutputStream ); + + try + { + OWriteImagesDocumentHandler aWriteImagesDocumentHandler( aItems, xWriter ); + aWriteImagesDocumentHandler.WriteImagesDocument(); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch ( SAXException& ) + { + return sal_False; + } + catch ( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + +sal_Bool ImagesConfiguration::LoadImages( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rInputStream, + ImageListsDescriptor& rItems ) +{ + Reference< XParser > xParser( GetSaxParser( xServiceFactory ) ); + + // connect stream to input stream to the parser + InputSource aInputSource; + + aInputSource.aInputStream = rInputStream; + + // create namespace filter and set document handler inside to support xml namespaces + Reference< XDocumentHandler > xDocHandler( new OReadImagesDocumentHandler( rItems )); + Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler )); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + try + { + xParser->parseStream( aInputSource ); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch( SAXException& ) + { + return sal_False; + } + catch( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + +sal_Bool ImagesConfiguration::StoreImages( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rOutputStream, + const ImageListsDescriptor& rItems ) +{ + Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) ); + + Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY ); + xDataSource->setOutputStream( rOutputStream ); + + try + { + OWriteImagesDocumentHandler aWriteImagesDocumentHandler( rItems, xWriter ); + aWriteImagesDocumentHandler.WriteImagesDocument(); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch ( SAXException& ) + { + return sal_False; + } + catch ( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + +} + diff --git a/framework/source/fwe/xml/imagesdocumenthandler.cxx b/framework/source/fwe/xml/imagesdocumenthandler.cxx new file mode 100644 index 000000000000..cdf20958332a --- /dev/null +++ b/framework/source/fwe/xml/imagesdocumenthandler.cxx @@ -0,0 +1,851 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <stdio.h> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/resetableguard.hxx> +#include <xml/imagesdocumenthandler.hxx> +#include <macros/debug.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_ +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#endif + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/attributelist.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +#define ELEMENT_IMAGECONTAINER "imagescontainer" +#define ELEMENT_IMAGES "images" +#define ELEMENT_ENTRY "entry" +#define ELEMENT_EXTERNALIMAGES "externalimages" +#define ELEMENT_EXTERNALENTRY "externalentry" + +#define ELEMENT_NS_IMAGESCONTAINER "image:imagescontainer" +#define ELEMENT_NS_IMAGES "image:images" +#define ELEMENT_NS_ENTRY "image:entry" +#define ELEMENT_NS_EXTERNALIMAGES "image:externalimages" +#define ELEMENT_NS_EXTERNALENTRY "image:externalentry" + +#define ATTRIBUTE_HREF "href" +#define ATTRIBUTE_MASKCOLOR "maskcolor" +#define ATTRIBUTE_COMMAND "command" +#define ATTRIBUTE_BITMAPINDEX "bitmap-index" +#define ATTRIBUTE_MASKURL "maskurl" +#define ATTRIBUTE_MASKMODE "maskmode" +#define ATTRIBUTE_HIGHCONTRASTURL "highcontrasturl" +#define ATTRIBUTE_HIGHCONTRASTMASKURL "highcontrastmaskurl" +#define ATTRIBUTE_TYPE_CDATA "CDATA" + +#define ATTRIBUTE_MASKMODE_BITMAP "maskbitmap" +#define ATTRIBUTE_MASKMODE_COLOR "maskcolor" + +#define ATTRIBUTE_XMLNS_IMAGE "xmlns:image" +#define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink" + +#define ATTRIBUTE_XLINK_TYPE "xlink:type" +#define ATTRIBUTE_XLINK_TYPE_VALUE "simple" + +#define XMLNS_IMAGE "http://openoffice.org/2001/image" +#define XMLNS_XLINK "http://www.w3.org/1999/xlink" +#define XMLNS_IMAGE_PREFIX "image:" +#define XMLNS_XLINK_PREFIX "xlink:" + +#define XMLNS_FILTER_SEPARATOR "^" + +#define IMAGES_DOCTYPE "<!DOCTYPE image:imagecontainer PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"image.dtd\">" + +namespace framework +{ + +struct ImageXMLEntryProperty +{ + OReadImagesDocumentHandler::Image_XML_Namespace nNamespace; + char aEntryName[20]; +}; + +ImageXMLEntryProperty ImagesEntries[OReadImagesDocumentHandler::IMG_XML_ENTRY_COUNT] = +{ + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_IMAGECONTAINER }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_IMAGES }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_ENTRY }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_EXTERNALIMAGES }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ELEMENT_EXTERNALENTRY }, + { OReadImagesDocumentHandler::IMG_NS_XLINK, ATTRIBUTE_HREF }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKCOLOR }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_COMMAND }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_BITMAPINDEX }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKURL }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_MASKMODE }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTURL }, + { OReadImagesDocumentHandler::IMG_NS_IMAGE, ATTRIBUTE_HIGHCONTRASTMASKURL } +}; + + +OReadImagesDocumentHandler::OReadImagesDocumentHandler( ImageListsDescriptor& aItems ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_aImageList( aItems ), + m_pImages( 0 ), + m_pExternalImages( 0 ) +{ + m_aImageList.pImageList = NULL; + m_aImageList.pExternalImageList = NULL; + + m_nHashMaskModeBitmap = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_BITMAP )).hashCode(); + m_nHashMaskModeColor = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_COLOR )).hashCode(); + + // create hash map to speed up lookup + for ( int i = 0; i < (int)IMG_XML_ENTRY_COUNT; i++ ) + { + ::rtl::OUStringBuffer temp( 20 ); + + if ( ImagesEntries[i].nNamespace == IMG_NS_IMAGE ) + temp.appendAscii( XMLNS_IMAGE ); + else + temp.appendAscii( XMLNS_XLINK ); + + temp.appendAscii( XMLNS_FILTER_SEPARATOR ); + temp.appendAscii( ImagesEntries[i].aEntryName ); + m_aImageMap.insert( ImageHashMap::value_type( temp.makeStringAndClear(), (Image_XML_Entry)i ) ); + } + + // reset states + m_bImageContainerStartFound = sal_False; + m_bImageContainerEndFound = sal_False; + m_bImagesStartFound = sal_False; + m_bImagesEndFound = sal_False; + m_bImageStartFound = sal_False; + m_bExternalImagesStartFound = sal_False; + m_bExternalImagesEndFound = sal_False; + m_bExternalImageStartFound = sal_False; +} + +OReadImagesDocumentHandler::~OReadImagesDocumentHandler() +{ +} + +// XDocumentHandler +void SAL_CALL OReadImagesDocumentHandler::startDocument(void) +throw ( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadImagesDocumentHandler::endDocument(void) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + if (( m_bImageContainerStartFound && !m_bImageContainerEndFound ) || + ( !m_bImageContainerStartFound && m_bImageContainerEndFound ) ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'image:imagecontainer' found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + +void SAL_CALL OReadImagesDocumentHandler::startElement( + const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs ) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ; + if ( pImageEntry != m_aImageMap.end() ) + { + switch ( pImageEntry->second ) + { + case IMG_ELEMENT_IMAGECONTAINER: + { + // image:imagecontainer element (container element for all further image elements) + if ( m_bImageContainerStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:imagecontainer' cannot be embeded into 'image:imagecontainer'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bImageContainerStartFound = sal_True; + } + break; + + case IMG_ELEMENT_IMAGES: + { + if ( !m_bImageContainerStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' must be embeded into element 'image:imagecontainer'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( m_bImagesStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:images' cannot be embeded into 'image:images'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( !m_aImageList.pImageList ) + m_aImageList.pImageList = new ImageListDescriptor; + + m_bImagesStartFound = sal_True; + m_pImages = new ImageListItemDescriptor; + + for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ ) + { + pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) ); + if ( pImageEntry != m_aImageMap.end() ) + { + switch ( pImageEntry->second ) + { + case IMG_ATTRIBUTE_HREF: + { + m_pImages->aURL = xAttribs->getValueByIndex( n ); + } + break; + + case IMG_ATTRIBUTE_MASKCOLOR: + { + ::rtl::OUString aColor = xAttribs->getValueByIndex( n ); + + if ( aColor.getLength() > 0 ) + { + if ( aColor.getStr()[0] == '#' ) + { + // the color value is given as #rrggbb and used the hexadecimal system!! + sal_uInt32 nColor = aColor.copy( 1 ).toInt32( 16 ); + + m_pImages->aMaskColor = Color( COLORDATA_RGB( nColor ) ); + } + } + } + break; + + case IMG_ATTRIBUTE_MASKURL: + { + m_pImages->aMaskURL = xAttribs->getValueByIndex( n ); + } + break; + + case IMG_ATTRIBUTE_MASKMODE: + { + sal_Int32 nHashCode = xAttribs->getValueByIndex( n ).hashCode(); + if ( nHashCode == m_nHashMaskModeBitmap ) + m_pImages->nMaskMode = ImageMaskMode_Bitmap; + else if ( nHashCode == m_nHashMaskModeColor ) + m_pImages->nMaskMode = ImageMaskMode_Color; + else + { + delete m_pImages; + m_pImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute image:maskmode must be 'maskcolor' or 'maskbitmap'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + break; + + case IMG_ATTRIBUTE_HIGHCONTRASTURL: + { + m_pImages->aHighContrastURL = xAttribs->getValueByIndex( n ); + } + break; + + case IMG_ATTRIBUTE_HIGHCONTRASTMASKURL: + { + m_pImages->aHighContrastMaskURL = xAttribs->getValueByIndex( n ); + } + break; + + default: + break; + } + } + } // for + + if ( m_pImages->aURL.Len() == 0 ) + { + delete m_pImages; + m_pImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute xlink:href must have a value!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + break; + + case IMG_ELEMENT_ENTRY: + { + // Check that image:entry is embeded into image:images! + if ( !m_bImagesStartFound ) + { + delete m_pImages; + m_pImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:entry' must be embeded into element 'image:images'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( !m_pImages->pImageItemList ) + m_pImages->pImageItemList = new ImageItemListDescriptor; + + m_bImageStartFound = sal_True; + + // Create new image item descriptor + ImageItemDescriptor* pItem = new ImageItemDescriptor; + pItem->nIndex = -1; + + // Read attributes for this image definition + for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ ) + { + pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) ); + if ( pImageEntry != m_aImageMap.end() ) + { + switch ( pImageEntry->second ) + { + case IMG_ATTRIBUTE_COMMAND: + { + pItem->aCommandURL = xAttribs->getValueByIndex( n ); + } + break; + + case IMG_ATTRIBUTE_BITMAPINDEX: + { + pItem->nIndex = xAttribs->getValueByIndex( n ).toInt32(); + } + break; + + default: + break; + } + } + } + + // Check required attribute "bitmap-index" + if ( pItem->nIndex < 0 ) + { + delete pItem; + delete m_pImages; + m_pImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:bitmap-index' must have a value >= 0!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + // Check required attribute "command" + if ( pItem->aCommandURL.Len() == 0 ) + { + delete pItem; + delete m_pImages; + m_pImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( m_pImages ) + m_pImages->pImageItemList->Insert( pItem, m_pImages->pImageItemList->Count() ); + } + break; + + case IMG_ELEMENT_EXTERNALIMAGES: + { + // Check that image:externalimages is embeded into image:imagecontainer + if ( !m_bImageContainerStartFound ) + { + delete m_pImages; + m_pImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' must be embeded into element 'image:imagecontainer'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + // Check that image:externalentry is NOT embeded into image:externalentry + if ( m_bExternalImagesStartFound ) + { + delete m_pImages; + m_pImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalimages' cannot be embeded into 'image:externalimages'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + // Create unique external image container + m_bExternalImagesStartFound = sal_True; + m_pExternalImages = new ExternalImageItemListDescriptor; + } + break; + + case IMG_ELEMENT_EXTERNALENTRY: + { + if ( !m_bExternalImagesStartFound ) + { + delete m_pImages; + delete m_pExternalImages; + m_pImages = NULL; + m_pExternalImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' must be embeded into 'image:externalimages'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( m_bExternalImageStartFound ) + { + delete m_pImages; + delete m_pExternalImages; + m_pImages = NULL; + m_pExternalImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'image:externalentry' cannot be embeded into 'image:externalentry'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bExternalImageStartFound = sal_True; + + ExternalImageItemDescriptor* pItem = new ExternalImageItemDescriptor; + + // Read attributes for this external image definition + for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ ) + { + pImageEntry = m_aImageMap.find( xAttribs->getNameByIndex( n ) ); + if ( pImageEntry != m_aImageMap.end() ) + { + switch ( pImageEntry->second ) + { + case IMG_ATTRIBUTE_COMMAND: + { + pItem->aCommandURL = xAttribs->getValueByIndex( n ); + } + break; + + case IMG_ATTRIBUTE_HREF: + { + pItem->aURL = xAttribs->getValueByIndex( n ); + } + break; + + default: + break; + } + } + } + + // Check required attribute "command" + if ( pItem->aCommandURL.Len() == 0 ) + { + delete pItem; + delete m_pImages; + delete m_pExternalImages; + m_pImages = NULL; + m_pExternalImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'image:command' must have a value!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + // Check required attribute "href" + if ( pItem->aURL.Len() == 0 ) + { + delete pItem; + delete m_pImages; + delete m_pExternalImages; + m_pImages = NULL; + m_pExternalImages = NULL; + + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute 'xlink:href' must have a value!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( m_pExternalImages ) + m_pExternalImages->Insert( pItem, m_pExternalImages->Count() ); + } + break; + + default: + break; + } + } +} + +void SAL_CALL OReadImagesDocumentHandler::endElement(const ::rtl::OUString& aName) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + ImageHashMap::const_iterator pImageEntry = m_aImageMap.find( aName ) ; + if ( pImageEntry != m_aImageMap.end() ) + { + switch ( pImageEntry->second ) + { + case IMG_ELEMENT_IMAGECONTAINER: + { + m_bImageContainerEndFound = sal_True; + } + break; + + case IMG_ELEMENT_IMAGES: + { + if ( m_pImages ) + { + if ( m_aImageList.pImageList ) + m_aImageList.pImageList->Insert( m_pImages, m_aImageList.pImageList->Count() ); + m_pImages = NULL; + } + m_bImagesStartFound = sal_False; + } + break; + + case IMG_ELEMENT_ENTRY: + { + m_bImageStartFound = sal_False; + } + break; + + case IMG_ELEMENT_EXTERNALIMAGES: + { + if ( m_pExternalImages && !m_aImageList.pExternalImageList ) + { + if ( !m_aImageList.pExternalImageList ) + m_aImageList.pExternalImageList = m_pExternalImages; + } + + m_bExternalImagesStartFound = sal_False; + m_pExternalImages = NULL; + } + break; + + case IMG_ELEMENT_EXTERNALENTRY: + { + m_bExternalImageStartFound = sal_False; + } + break; + + default: + break; + } + } +} + +void SAL_CALL OReadImagesDocumentHandler::characters(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadImagesDocumentHandler::ignorableWhitespace(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadImagesDocumentHandler::processingInstruction( + const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadImagesDocumentHandler::setDocumentLocator( + const Reference< XLocator > &xLocator) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xLocator = xLocator; +} + +::rtl::OUString OReadImagesDocumentHandler::getErrorLineString() +{ + ResetableGuard aGuard( m_aLock ); + + char buffer[32]; + + if ( m_xLocator.is() ) + { + snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() )); + return ::rtl::OUString::createFromAscii( buffer ); + } + else + return ::rtl::OUString(); +} + + +//_________________________________________________________________________________________________________________ +// OWriteImagesDocumentHandler +//_________________________________________________________________________________________________________________ + +OWriteImagesDocumentHandler::OWriteImagesDocumentHandler( + const ImageListsDescriptor& aItems, + Reference< XDocumentHandler > rWriteDocumentHandler ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_aImageListsItems( aItems ), + m_xWriteDocumentHandler( rWriteDocumentHandler ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY ); + m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); + m_aXMLImageNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE_PREFIX )); + m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX )); + m_aAttributeXlinkType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE )); + m_aAttributeValueSimple = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XLINK_TYPE_VALUE )); +} + +OWriteImagesDocumentHandler::~OWriteImagesDocumentHandler() +{ +} + +void OWriteImagesDocumentHandler::WriteImagesDocument() throw +( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xWriteDocumentHandler->startDocument(); + + // write DOCTYPE line! + Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY ); + if ( xExtendedDocHandler.is() ) + { + xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMAGES_DOCTYPE )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + } + + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_IMAGE )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_IMAGE )) ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) ); + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )), pList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + if ( m_aImageListsItems.pImageList ) + { + ImageListDescriptor* pImageList = m_aImageListsItems.pImageList; + + for ( sal_uInt16 i = 0; i < m_aImageListsItems.pImageList->Count(); i++ ) + { + const ImageListItemDescriptor* pImageItems = (*pImageList)[i]; + WriteImageList( pImageItems ); + } + } + + if ( m_aImageListsItems.pExternalImageList ) + { + WriteExternalImageList( m_aImageListsItems.pExternalImageList ); + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGESCONTAINER )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endDocument(); +} + +//_________________________________________________________________________________________________________________ +// protected member functions +//_________________________________________________________________________________________________________________ + +void OWriteImagesDocumentHandler::WriteImageList( const ImageListItemDescriptor* pImageList ) throw +( SAXException, RuntimeException ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + // save required attributes + pList->AddAttribute( m_aAttributeXlinkType, + m_aAttributeType, + m_aAttributeValueSimple ); + + pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )), + m_aAttributeType, + pImageList->aURL ); + + if ( pImageList->nMaskMode == ImageMaskMode_Bitmap ) + { + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_BITMAP )) ); + + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKURL )), + m_aAttributeType, + pImageList->aMaskURL ); + + if ( pImageList->aHighContrastMaskURL.Len() > 0 ) + { + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTMASKURL )), + m_aAttributeType, + pImageList->aHighContrastMaskURL ); + } + } + else + { + ::rtl::OUStringBuffer aColorStrBuffer( 8 ); + sal_Int64 nValue = pImageList->aMaskColor.GetRGBColor(); + + aColorStrBuffer.appendAscii( "#" ); + aColorStrBuffer.append( ::rtl::OUString::valueOf( nValue, 16 )); + + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKCOLOR )), + m_aAttributeType, + aColorStrBuffer.makeStringAndClear() ); + + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_MASKMODE_COLOR )) ); + } + + if ( pImageList->aHighContrastURL.Len() > 0 ) + { + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HIGHCONTRASTURL )), + m_aAttributeType, + pImageList->aHighContrastURL ); + } + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )), xList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + ImageItemListDescriptor* pImageItemList = pImageList->pImageItemList; + if ( pImageItemList ) + { + for ( sal_uInt16 i = 0; i < pImageItemList->Count(); i++ ) + WriteImage( (*pImageItemList)[i] ); + } + + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_IMAGES )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); +} + +void OWriteImagesDocumentHandler::WriteImage( const ImageItemDescriptor* pImage ) throw +( SAXException, RuntimeException ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BITMAPINDEX )), + m_aAttributeType, + ::rtl::OUString::valueOf( (sal_Int32)pImage->nIndex ) ); + + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )), + m_aAttributeType, + pImage->aCommandURL ); + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )), xList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_ENTRY )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); +} + +void OWriteImagesDocumentHandler::WriteExternalImageList( const ExternalImageItemListDescriptor* pExternalImageList ) throw +( SAXException, RuntimeException ) +{ + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )), m_xEmptyList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + for ( sal_uInt16 i = 0; i < pExternalImageList->Count(); i++ ) + { + ExternalImageItemDescriptor* pItem = (*pExternalImageList)[i]; + WriteExternalImage( pItem ); + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALIMAGES )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); +} + +void OWriteImagesDocumentHandler::WriteExternalImage( const ExternalImageItemDescriptor* pExternalImage ) throw +( SAXException, RuntimeException ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + // save required attributes + pList->AddAttribute( m_aAttributeXlinkType, + m_aAttributeType, + m_aAttributeValueSimple ); + + if ( pExternalImage->aURL.Len() > 0 ) + { + pList->AddAttribute( m_aXMLXlinkNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HREF )), + m_aAttributeType, + pExternalImage->aURL ); + } + + if ( pExternalImage->aCommandURL.Len() > 0 ) + { + pList->AddAttribute( m_aXMLImageNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_COMMAND )), + m_aAttributeType, + pExternalImage->aCommandURL ); + } + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )), xList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_EXTERNALENTRY )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); +} + +} // namespace framework + + + + diff --git a/framework/source/fwe/xml/menuconfiguration.cxx b/framework/source/fwe/xml/menuconfiguration.cxx new file mode 100644 index 000000000000..8a6d2cd1bafd --- /dev/null +++ b/framework/source/fwe/xml/menuconfiguration.cxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <framework/menuconfiguration.hxx> + +#ifndef __FRAMEWORK_CLASSES_BMKMENU_HXX_ +#include <framework/bmkmenu.hxx> +#endif +#include <framework/addonmenu.hxx> +#include <xml/menudocumenthandler.hxx> +#include <xml/saxnamespacefilter.hxx> +#include <services.h> + +#ifndef _FRAMEWORK_UIELEMENT_ROOTITEMCONTAINER_HXX_ +#include <uielement/rootitemcontainer.hxx> +#endif + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/frame/XFrame.hpp> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::io; + +namespace framework +{ + +sal_Bool MenuConfiguration::IsPickListItemId( sal_uInt16 nId ) +{ + return (( START_ITEMID_PICKLIST <= nId ) && ( nId <= END_ITEMID_PICKLIST )); +} + +sal_Bool MenuConfiguration::IsWindowListItemId( sal_uInt16 nId ) +{ + return (( START_ITEMID_WINDOWLIST <= nId ) && ( nId <= END_ITEMID_WINDOWLIST )); +} + + +MenuConfiguration::MenuConfiguration( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager ) +: m_rxServiceManager( rServiceManager ) +{ +} + + +MenuConfiguration::~MenuConfiguration() +{ +} + + +Reference< XIndexAccess > MenuConfiguration::CreateMenuBarConfigurationFromXML( + Reference< XInputStream >& rInputStream ) +throw ( WrappedTargetException ) +{ + Reference< XParser > xParser( m_rxServiceManager->createInstance(SERVICENAME_SAXPARSER),UNO_QUERY); + + // connect stream to input stream to the parser + InputSource aInputSource; + + aInputSource.aInputStream = rInputStream; + + + // create menu bar + Reference< XIndexContainer > xItemContainer( static_cast< cppu::OWeakObject *>( new RootItemContainer()), UNO_QUERY ); + + // create namespace filter and set menudocument handler inside to support xml namespaces + + // #110897# Reference< XDocumentHandler > xDocHandler( new OReadMenuDocumentHandler( xItemContainer )); + Reference< XDocumentHandler > xDocHandler( new OReadMenuDocumentHandler( m_rxServiceManager, xItemContainer )); + + Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler )); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + try + { + xParser->parseStream( aInputSource ); + return Reference< XIndexAccess >( xItemContainer, UNO_QUERY ); + } + catch ( RuntimeException& e ) + { + throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() ); + } + catch( SAXException& e ) + { + SAXException aWrappedSAXException; + + if ( !( e.WrappedException >>= aWrappedSAXException )) + throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() ); + else + throw WrappedTargetException( aWrappedSAXException.Message, Reference< XInterface >(), Any() ); + } + catch( ::com::sun::star::io::IOException& e ) + { + throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() ); + } +} + +PopupMenu* MenuConfiguration::CreateBookmarkMenu( + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, + const ::rtl::OUString& aURL ) +throw ( ::com::sun::star::lang::WrappedTargetException ) +{ + if ( aURL == BOOKMARK_NEWMENU ) + return new BmkMenu( rFrame, BmkMenu::BMK_NEWMENU ); + else if ( aURL == BOOKMARK_WIZARDMENU ) + return new BmkMenu( rFrame, BmkMenu::BMK_WIZARDMENU ); + else + return NULL; +} + +void MenuConfiguration::StoreMenuBarConfigurationToXML( + Reference< XIndexAccess >& rMenuBarConfiguration, + Reference< XOutputStream >& rOutputStream ) +throw ( WrappedTargetException ) +{ + Reference< XDocumentHandler > xWriter; + + xWriter = Reference< XDocumentHandler >( m_rxServiceManager->createInstance( + SERVICENAME_SAXWRITER), UNO_QUERY) ; + + Reference< XActiveDataSource> xDataSource( xWriter , UNO_QUERY ); + xDataSource->setOutputStream( rOutputStream ); + + try + { + OWriteMenuDocumentHandler aWriteMenuDocumentHandler( rMenuBarConfiguration, xWriter ); + aWriteMenuDocumentHandler.WriteMenuDocument(); + } + catch ( RuntimeException& e ) + { + throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() ); + } + catch ( SAXException& e ) + { + throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() ); + } + catch ( ::com::sun::star::io::IOException& e ) + { + throw WrappedTargetException( e.Message, Reference< XInterface >(), Any() ); + } +} + +} + diff --git a/framework/source/fwe/xml/menudocumenthandler.cxx b/framework/source/fwe/xml/menudocumenthandler.cxx new file mode 100644 index 000000000000..26ec3bf09372 --- /dev/null +++ b/framework/source/fwe/xml/menudocumenthandler.cxx @@ -0,0 +1,1022 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <stdio.h> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <xml/menudocumenthandler.hxx> +#include <framework/menuconfiguration.hxx> +#include <framework/addonmenu.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#include <com/sun/star/lang/XSingleComponentFactory.hpp> +#include <com/sun/star/ui/ItemType.hpp> +#include <com/sun/star/ui/ItemStyle.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <comphelper/processfactory.hxx> +#include <rtl/logfile.hxx> +#include <comphelper/attributelist.hxx> + +//_________________________________________________________________________________________________________________ +// defines +//_________________________________________________________________________________________________________________ + +#define XMLNS_MENU "http://openoffice.org/2001/menu" +#define XMLNS_PREFIX "menu:" + +#define ELEMENT_MENUBAR "http://openoffice.org/2001/menu^menubar" +#define ELEMENT_MENU "http://openoffice.org/2001/menu^menu" +#define ELEMENT_MENUPOPUP "http://openoffice.org/2001/menu^menupopup" +#define ELEMENT_MENUITEM "http://openoffice.org/2001/menu^menuitem" +#define ELEMENT_MENUSEPARATOR "http://openoffice.org/2001/menu^menuseparator" + +#define ELEMENT_NS_MENUBAR "menu:menubar" +#define ELEMENT_NS_MENU "menu:menu" +#define ELEMENT_NS_MENUPOPUP "menu:menupopup" +#define ELEMENT_NS_MENUITEM "menu:menuitem" +#define ELEMENT_NS_MENUSEPARATOR "menu:menuseparator" + +#define ATTRIBUTE_ID "http://openoffice.org/2001/menu^id" +#define ATTRIBUTE_LABEL "http://openoffice.org/2001/menu^label" +#define ATTRIBUTE_HELPID "http://openoffice.org/2001/menu^helpid" +#define ATTRIBUTE_LINEBREAK "http://openoffice.org/2001/menu^linebreak" +#define ATTRIBUTE_STYLE "http://openoffice.org/2001/menu^style" + +#define ATTRIBUTE_NS_ID "menu:id" +#define ATTRIBUTE_NS_LABEL "menu:label" +#define ATTRIBUTE_NS_HELPID "menu:helpid" +#define ATTRIBUTE_NS_LINEBREAK "menu:linebreak" +#define ATTRIBUTE_NS_STYLE "menu:style" + +#define ATTRIBUTE_XMLNS_MENU "xmlns:menu" + +#define ATTRIBUTE_TYPE_CDATA "CDATA" + +#define MENUBAR_DOCTYPE "<!DOCTYPE menu:menubar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"menubar.dtd\">" + +#define ATTRIBUTE_ITEMSTYLE_TEXT "text" +#define ATTRIBUTE_ITEMSTYLE_IMAGE "image" +#define ATTRIBUTE_ITEMSTYLE_RADIO "radio" + +// Property names of a menu/menu item ItemDescriptor +static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; +static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; +static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer"; +static const char ITEM_DESCRIPTOR_LABEL[] = "Label"; +static const char ITEM_DESCRIPTOR_TYPE[] = "Type"; +static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; + +// special popup menus (filled during runtime) must be saved as an empty popup menu or menuitem!!! +static const sal_Int32 CMD_PROTOCOL_SIZE = 5; +static const char CMD_PROTOCOL[] = ".uno:"; +static const char ADDDIRECT_CMD[] = ".uno:AddDirect" ; +static const char AUTOPILOTMENU_CMD[] = ".uno:AutoPilotMenu" ; +static const char FILEMENU_CMD[] = ".uno:Picklist" ; +static const char WINDOWMENU_CMD[] = ".uno:WindowList" ; + +//_________________________________________________________________________________________________________________ +// using namespaces +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::ui; + +namespace framework +{ + +struct MenuStyleItem +{ + sal_Int16 nBit; + const char* attrName; +}; + +MenuStyleItem MenuItemStyles[ ] = { + { ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE }, + { ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT }, + { ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO } +}; + + +sal_Int32 nMenuStyleItemEntries = sizeof( MenuItemStyles ) / sizeof( MenuItemStyles[ 0 ] ); + +static void ExtractMenuParameters( const Sequence< PropertyValue > rProp, + ::rtl::OUString& rCommandURL, + ::rtl::OUString& rLabel, + ::rtl::OUString& rHelpURL, + Reference< XIndexAccess >& rSubMenu, + sal_Int16& rType, + sal_Int16& rStyle ) +{ + for ( sal_Int32 i = 0; i < rProp.getLength(); i++ ) + { + if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL )) + { + rProp[i].Value >>= rCommandURL; + rCommandURL = rCommandURL.intern(); + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL )) + { + rProp[i].Value >>= rHelpURL; + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_CONTAINER )) + { + rProp[i].Value >>= rSubMenu; + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL )) + { + rProp[i].Value >>= rLabel; + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE )) + { + rProp[i].Value >>= rType; + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE )) + { + rProp[i].Value >>= rStyle; + } + } +} + + +// ----------------------------------------------------------------------------- +// Base class implementation + +ReadMenuDocumentHandlerBase::ReadMenuDocumentHandlerBase() : + m_xLocator( 0 ), + m_xReader( 0 ), + m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )), + m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )), + m_aContainer( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_CONTAINER )), + m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )), + m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL )), + m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE )) +{ +} + +ReadMenuDocumentHandlerBase::~ReadMenuDocumentHandlerBase() +{ +} + +void SAL_CALL ReadMenuDocumentHandlerBase::ignorableWhitespace( + const ::rtl::OUString& ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL ReadMenuDocumentHandlerBase::processingInstruction( + const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL ReadMenuDocumentHandlerBase::setDocumentLocator( + const Reference< XLocator > &xLocator) +throw( SAXException, RuntimeException ) +{ + m_xLocator = xLocator; +} + +::rtl::OUString ReadMenuDocumentHandlerBase::getErrorLineString() +{ + char buffer[32]; + + if ( m_xLocator.is() ) + { + snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() )); + return ::rtl::OUString::createFromAscii( buffer ); + } + else + return ::rtl::OUString(); +} + +void ReadMenuDocumentHandlerBase::initPropertyCommon( + Sequence< PropertyValue > &rProps, const rtl::OUString &rCommandURL, + const rtl::OUString &rHelpId, const rtl::OUString &rLabel, sal_Int16 nItemStyleBits ) +{ + rProps[0].Name = m_aCommandURL; + rProps[1].Name = m_aHelpURL; + rProps[2].Name = m_aContainer; + rProps[3].Name = m_aLabel; + rProps[4].Name = m_aStyle; + rProps[5].Name = m_aType; + + // Common values + rProps[0].Value <<= rCommandURL.intern(); + rProps[1].Value <<= rHelpId; + rProps[2].Value <<= Reference< XIndexContainer >(); + rProps[3].Value <<= rLabel; + rProps[4].Value <<= nItemStyleBits; + rProps[5].Value <<= ::com::sun::star::ui::ItemType::DEFAULT; +} + +// ----------------------------------------------------------------------------- + +OReadMenuDocumentHandler::OReadMenuDocumentHandler( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + const Reference< XIndexContainer >& rMenuBarContainer ) +: m_nElementDepth( 0 ), + m_bMenuBarMode( sal_False ), + m_xMenuBarContainer( rMenuBarContainer ), + m_xContainerFactory( rMenuBarContainer, UNO_QUERY ), + mxServiceFactory(xServiceFactory) +{ +} + +// #110897# +const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuDocumentHandler::getServiceFactory() +{ + // #110897# + return mxServiceFactory; +} + +OReadMenuDocumentHandler::~OReadMenuDocumentHandler() +{ +} + + +void SAL_CALL OReadMenuDocumentHandler::startDocument(void) + throw ( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuDocumentHandler::endDocument(void) + throw( SAXException, RuntimeException ) +{ + if ( m_nElementDepth > 0 ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A closing element is missing!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + + +void SAL_CALL OReadMenuDocumentHandler::startElement( + const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList ) +throw( SAXException, RuntimeException ) +{ + if ( m_bMenuBarMode ) + { + ++m_nElementDepth; + m_xReader->startElement( aName, xAttrList ); + } + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR ))) + { + ++m_nElementDepth; + m_bMenuBarMode = sal_True; + + // #110897# m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( m_xMenuBarContainer, m_xContainerFactory )); + m_xReader = Reference< XDocumentHandler >( new OReadMenuBarHandler( getServiceFactory(), m_xMenuBarContainer, m_xContainerFactory )); + + m_xReader->startDocument(); + } +} + + +void SAL_CALL OReadMenuDocumentHandler::characters(const rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuDocumentHandler::endElement( const ::rtl::OUString& aName ) + throw( SAXException, RuntimeException ) +{ + if ( m_bMenuBarMode ) + { + --m_nElementDepth; + m_xReader->endElement( aName ); + if ( 0 == m_nElementDepth ) + { + m_xReader->endDocument(); + m_xReader = Reference< XDocumentHandler >(); + m_bMenuBarMode = sal_False; + if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUBAR ))) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menubar expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + } +} + + +// ----------------------------------------------------------------------------- + + +// #110897# +OReadMenuBarHandler::OReadMenuBarHandler( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + const Reference< XIndexContainer >& rMenuBarContainer, + const Reference< XSingleComponentFactory >& rFactory ) +: m_nElementDepth( 0 ), + m_bMenuMode( sal_False ), + m_xMenuBarContainer( rMenuBarContainer ), + m_xContainerFactory( rFactory ), + mxServiceFactory( xServiceFactory ) +{ +} + +// #110897# +const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& OReadMenuBarHandler::getServiceFactory() +{ + // #110897# + return mxServiceFactory; +} + +OReadMenuBarHandler::~OReadMenuBarHandler() +{ +} + + +void SAL_CALL OReadMenuBarHandler::startDocument(void) + throw ( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuBarHandler::endDocument(void) + throw( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuBarHandler::startElement( + const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList ) +throw( SAXException, RuntimeException ) +{ + if ( m_bMenuMode ) + { + ++m_nElementDepth; + m_xReader->startElement( rName, xAttrList ); + } + else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) + { + ++m_nElementDepth; + + ::rtl::OUString aHelpId; + ::rtl::OUString aCommandId; + ::rtl::OUString aLabel; + sal_Int16 nItemBits(0); + + m_bMenuMode = sal_True; + + // Container must be factory to create sub container + Reference< XComponentContext > xComponentContext; + Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY ); + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= + xComponentContext; + + Reference< XIndexContainer > xSubItemContainer; + if ( m_xContainerFactory.is() ) + xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( xComponentContext ), UNO_QUERY ); + + if ( xSubItemContainer.is() ) + { + // read attributes for menu + for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) + { + ::rtl::OUString aName = xAttrList->getNameByIndex( i ); + ::rtl::OUString aValue = xAttrList->getValueByIndex( i ); + if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID ))) + aCommandId = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL ))) + aLabel = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID ))) + aHelpId = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE ))) + { + ::rtl::OUString aTemp( aValue ); + sal_Int32 nIndex = 0; + do + { + ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex ); + if ( aToken.getLength() > 0 ) + { + if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT; + else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::ICON; + else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK; + } + } + while ( nIndex >= 0 ); + } + } + + if ( aCommandId.getLength() > 0 ) + { + Sequence< PropertyValue > aSubMenuProp( 6 ); + initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits ); + aSubMenuProp[2].Value <<= xSubItemContainer; + + m_xMenuBarContainer->insertByIndex( m_xMenuBarContainer->getCount(), makeAny( aSubMenuProp ) ); + } + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory )); + m_xReader->startDocument(); + } + } + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "element menu expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + + +void SAL_CALL OReadMenuBarHandler::characters(const rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + + +void OReadMenuBarHandler::endElement( const ::rtl::OUString& aName ) + throw( SAXException, RuntimeException ) +{ + if ( m_bMenuMode ) + { + --m_nElementDepth; + if ( 0 == m_nElementDepth ) + { + m_xReader->endDocument(); + m_xReader = Reference< XDocumentHandler >(); + m_bMenuMode = sal_False; + if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + else + m_xReader->endElement( aName ); + } +} + + +// ----------------------------------------------------------------------------- + + +OReadMenuHandler::OReadMenuHandler( + const Reference< XIndexContainer >& rMenuContainer, + const Reference< XSingleComponentFactory >& rFactory ) : + m_nElementDepth( 0 ), + m_bMenuPopupMode( sal_False ), + m_xMenuContainer( rMenuContainer ), + m_xContainerFactory( rFactory ) +{ +} + + +OReadMenuHandler::~OReadMenuHandler() +{ +} + + +void SAL_CALL OReadMenuHandler::startDocument(void) + throw ( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuHandler::endDocument(void) + throw( SAXException, RuntimeException) +{ +} + + +void SAL_CALL OReadMenuHandler::startElement( + const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttrList ) +throw( SAXException, RuntimeException ) +{ + if ( m_bMenuPopupMode ) + { + ++m_nElementDepth; + m_xReader->startElement( aName, xAttrList ); + } + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP ))) + { + ++m_nElementDepth; + m_bMenuPopupMode = sal_True; + m_xReader = Reference< XDocumentHandler >( new OReadMenuPopupHandler( m_xMenuContainer, m_xContainerFactory )); + m_xReader->startDocument(); + } + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + + +void SAL_CALL OReadMenuHandler::characters(const rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuHandler::endElement( const ::rtl::OUString& aName ) + throw( SAXException, RuntimeException ) +{ + if ( m_bMenuPopupMode ) + { + --m_nElementDepth; + if ( 0 == m_nElementDepth ) + { + m_xReader->endDocument(); + m_xReader = Reference< XDocumentHandler >(); + m_bMenuPopupMode = sal_False; + if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUPOPUP ))) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menupopup expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + else + m_xReader->endElement( aName ); + } +} + + +// ----------------------------------------------------------------------------- + + +OReadMenuPopupHandler::OReadMenuPopupHandler( + const Reference< XIndexContainer >& rMenuContainer, + const Reference< XSingleComponentFactory >& rFactory ) : + m_nElementDepth( 0 ), + m_bMenuMode( sal_False ), + m_xMenuContainer( rMenuContainer ), + m_xContainerFactory( rFactory ), + m_nNextElementExpected( ELEM_CLOSE_NONE ) +{ +} + + +OReadMenuPopupHandler::~OReadMenuPopupHandler() +{ +} + + +void SAL_CALL OReadMenuPopupHandler::startDocument(void) + throw ( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuPopupHandler::endDocument(void) + throw( SAXException, RuntimeException) +{ +} + +void SAL_CALL OReadMenuPopupHandler::startElement( + const ::rtl::OUString& rName, const Reference< XAttributeList > &xAttrList ) +throw( SAXException, RuntimeException ) +{ + ++m_nElementDepth; + + if ( m_bMenuMode ) + m_xReader->startElement( rName, xAttrList ); + else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) + { + ::rtl::OUString aHelpId; + ::rtl::OUString aCommandId; + ::rtl::OUString aLabel; + sal_Int16 nItemBits(0); + + m_bMenuMode = sal_True; + + // Container must be factory to create sub container + if ( !m_xComponentContext.is() ) + { + const Reference< XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), UNO_QUERY_THROW ); + m_xComponentContext.set(xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), UNO_QUERY_THROW ); + } + + Reference< XIndexContainer > xSubItemContainer; + if ( m_xContainerFactory.is() ) + xSubItemContainer = Reference< XIndexContainer >( m_xContainerFactory->createInstanceWithContext( m_xComponentContext ), UNO_QUERY ); + + // read attributes for menu + for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) + { + ::rtl::OUString aName = xAttrList->getNameByIndex( i ); + ::rtl::OUString aValue = xAttrList->getValueByIndex( i ); + if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID ))) + aCommandId = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL ))) + aLabel = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID ))) + aHelpId = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE ))) + { + ::rtl::OUString aTemp( aValue ); + sal_Int32 nIndex = 0; + do + { + ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex ); + if ( aToken.getLength() > 0 ) + { + if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT; + else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::ICON; + else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK; + } + } + while ( nIndex >= 0 ); + } + + } + + if ( aCommandId.getLength() > 0 ) + { + Sequence< PropertyValue > aSubMenuProp( 6 ); + initPropertyCommon( aSubMenuProp, aCommandId, aHelpId, aLabel, nItemBits ); + aSubMenuProp[2].Value <<= xSubItemContainer; + + m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aSubMenuProp ) ); + } + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "attribute id for element menu required!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_xReader = Reference< XDocumentHandler >( new OReadMenuHandler( xSubItemContainer, m_xContainerFactory )); + m_xReader->startDocument(); + } + else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM ))) + { + ::rtl::OUString aHelpId; + ::rtl::OUString aCommandId; + ::rtl::OUString aLabel; + sal_Int16 nItemBits(0); + // read attributes for menu item + for ( sal_Int16 i=0; i< xAttrList->getLength(); i++ ) + { + ::rtl::OUString aName = xAttrList->getNameByIndex( i ); + ::rtl::OUString aValue = xAttrList->getValueByIndex( i ); + if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ID ))) + aCommandId = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_LABEL ))) + aLabel = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_HELPID ))) + aHelpId = aValue; + else if ( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE ))) + { + ::rtl::OUString aTemp( aValue ); + sal_Int32 nIndex = 0; + do + { + ::rtl::OUString aToken = aTemp.getToken( 0, '+', nIndex ); + if ( aToken.getLength() > 0 ) + { + if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_TEXT ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT; + else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_IMAGE ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::ICON; + else if ( aToken.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ITEMSTYLE_RADIO ) ) ) + nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK; + } + } + while ( nIndex >= 0 ); + } + + } + + if ( aCommandId.getLength() > 0 ) + { + Sequence< PropertyValue > aMenuItem( 6 ); + initPropertyCommon( aMenuItem, aCommandId, aHelpId, aLabel, nItemBits ); + aMenuItem[2].Value <<= Reference< XIndexContainer >(); + + m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuItem ) ); + } + + m_nNextElementExpected = ELEM_CLOSE_MENUITEM; + } + else if ( rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR ))) + { + Sequence< PropertyValue > aMenuSeparator( 1 ); + aMenuSeparator[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )); + aMenuSeparator[0].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE; + + m_xMenuContainer->insertByIndex( m_xMenuContainer->getCount(), makeAny( aMenuSeparator ) ); + + m_nNextElementExpected = ELEM_CLOSE_MENUSEPARATOR; + } + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "unknown element found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + + +void SAL_CALL OReadMenuPopupHandler::characters(const rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + + +void SAL_CALL OReadMenuPopupHandler::endElement( const ::rtl::OUString& aName ) + throw( SAXException, RuntimeException ) +{ + --m_nElementDepth; + if ( m_bMenuMode ) + { + if ( 0 == m_nElementDepth ) + { + m_xReader->endDocument(); + m_xReader = Reference< XDocumentHandler >(); + m_bMenuMode = sal_False; + if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENU ))) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menu expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + else + m_xReader->endElement( aName ); + } + else + { + if ( m_nNextElementExpected == ELEM_CLOSE_MENUITEM ) + { + if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUITEM ))) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuitem expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + else if ( m_nNextElementExpected == ELEM_CLOSE_MENUSEPARATOR ) + { + if ( !aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ELEMENT_MENUSEPARATOR ))) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "closing element menuseparator expected!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + + m_nNextElementExpected = ELEM_CLOSE_NONE; + } +} + + +// --------------------------------- Write XML --------------------------------- + + +OWriteMenuDocumentHandler::OWriteMenuDocumentHandler( + const Reference< XIndexAccess >& rMenuBarContainer, + const Reference< XDocumentHandler >& rDocumentHandler ) : + m_xMenuBarContainer( rMenuBarContainer ), + m_xWriteDocumentHandler( rDocumentHandler ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY ); + m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); +} + + +OWriteMenuDocumentHandler::~OWriteMenuDocumentHandler() +{ +} + + +void OWriteMenuDocumentHandler::WriteMenuDocument() +throw ( SAXException, RuntimeException ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > rList( (XAttributeList *) pList , UNO_QUERY ); + + m_xWriteDocumentHandler->startDocument(); + + // write DOCTYPE line! + Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY ); + if ( xExtendedDocHandler.is() ) + { + xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( MENUBAR_DOCTYPE )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + } + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_MENU )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_MENU )) ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "menubar" )) ); + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )), pList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + WriteMenu( m_xMenuBarContainer ); + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUBAR )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endDocument(); +} + + +void OWriteMenuDocumentHandler::WriteMenu( const Reference< XIndexAccess >& rMenuContainer ) +throw ( SAXException, RuntimeException ) +{ + sal_Int32 nItemCount = rMenuContainer->getCount(); + sal_Bool bSeparator = sal_False; + Any aAny; + + for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ ) + { + Sequence< PropertyValue > aProps; + aAny = rMenuContainer->getByIndex( nItemPos ); + if ( aAny >>= aProps ) + { + ::rtl::OUString aCommandURL; + ::rtl::OUString aLabel; + ::rtl::OUString aHelpURL; + sal_Int16 nType( ::com::sun::star::ui::ItemType::DEFAULT ); + sal_Int16 nItemBits( 0 ); + Reference< XIndexAccess > xSubMenu; + + ExtractMenuParameters( aProps, aCommandURL, aLabel, aHelpURL, xSubMenu, nType, nItemBits ); + if ( xSubMenu.is() ) + { + if ( aCommandURL.equalsAscii( ADDDIRECT_CMD ) || + aCommandURL.equalsAscii( AUTOPILOTMENU_CMD )) + { + WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits ); + bSeparator = sal_False; + } + else if (( aCommandURL.getLength() > 0 ) && !AddonPopupMenu::IsCommandURLPrefix ( aCommandURL )) + { + ::comphelper::AttributeList* pListMenu = new ::comphelper::AttributeList; + Reference< XAttributeList > xListMenu( (XAttributeList *)pListMenu , UNO_QUERY ); + + pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )), + m_aAttributeType, + aCommandURL ); + + if ( !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL ))) + pListMenu->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )), + m_aAttributeType, + aLabel ); + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )), xListMenu ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )), m_xEmptyList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + WriteMenu( xSubMenu ); + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUPOPUP )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENU )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + bSeparator = sal_False; + } + } + else + { + if ( nType == ::com::sun::star::ui::ItemType::DEFAULT ) + { + if ( aCommandURL.getLength() > 0 ) + { + bSeparator = sal_False; + WriteMenuItem( aCommandURL, aLabel, aHelpURL, nItemBits ); + } + } + else if ( !bSeparator ) + { + // Don't write two separators together + WriteMenuSeparator(); + bSeparator = sal_True; + } + } + } + } +} + + +void OWriteMenuDocumentHandler::WriteMenuItem( const ::rtl::OUString& aCommandURL, const ::rtl::OUString& aLabel, const ::rtl::OUString& aHelpURL, sal_Int16 nStyle ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_ID )), + m_aAttributeType, + aCommandURL ); + + if ( aHelpURL.getLength() > 0 ) + { + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_HELPID )), + m_aAttributeType, + aHelpURL ); + } + + if (( aLabel.getLength() > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL ))) + { + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_LABEL )), + m_aAttributeType, + aLabel ); + } + if (( nStyle > 0 ) && !( aCommandURL.copy( CMD_PROTOCOL_SIZE ).equalsAscii( CMD_PROTOCOL ))) + { + rtl::OUString aValue; + MenuStyleItem* pStyle = MenuItemStyles; + + for ( sal_Int32 nIndex = 0; nIndex < nMenuStyleItemEntries; ++nIndex, ++pStyle ) + { + if ( nStyle & pStyle->nBit ) + { + if ( aValue.getLength() ) + aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("+") ) ); + aValue += rtl::OUString::createFromAscii( pStyle->attrName ); + } + } + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_NS_STYLE )), + m_aAttributeType, + aValue ); + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )), xList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUITEM )) ); +} + + +void OWriteMenuDocumentHandler::WriteMenuSeparator() +{ + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )), m_xEmptyList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_MENUSEPARATOR )) ); +} + +} // namespace framework + diff --git a/framework/source/fwe/xml/saxnamespacefilter.cxx b/framework/source/fwe/xml/saxnamespacefilter.cxx new file mode 100644 index 000000000000..a92c58547e06 --- /dev/null +++ b/framework/source/fwe/xml/saxnamespacefilter.cxx @@ -0,0 +1,198 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble + with solaris headers ... +*/ +#include <vector> + +#include <stdio.h> + +#include <xml/saxnamespacefilter.hxx> + +#include <comphelper/attributelist.hxx> + +#include <vcl/svapp.hxx> +#include <rtl/logfile.hxx> + +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::uno; + +const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" )); +const ::rtl::OUString aXMLAttributeType( RTL_CONSTASCII_USTRINGPARAM( "CDATA" )); + +namespace framework{ + + +SaxNamespaceFilter::SaxNamespaceFilter( Reference< XDocumentHandler >& rSax1DocumentHandler ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_xLocator( 0 ), + xDocumentHandler( rSax1DocumentHandler ), + m_nDepth( 0 ) +{ +} + +SaxNamespaceFilter::~SaxNamespaceFilter() +{ +} + +// XDocumentHandler +void SAL_CALL SaxNamespaceFilter::startDocument(void) + throw ( SAXException, RuntimeException ) +{ +} + +void SAL_CALL SaxNamespaceFilter::endDocument(void) + throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL SaxNamespaceFilter::startElement( + const rtl::OUString& rName, const Reference< XAttributeList > &xAttribs ) + throw( SAXException, RuntimeException ) +{ + XMLNamespaces aXMLNamespaces; + if ( !m_aNamespaceStack.empty() ) + aXMLNamespaces = m_aNamespaceStack.top(); + + ::comphelper::AttributeList* pNewList = new ::comphelper::AttributeList(); + + // examine all namespaces for this level + ::std::vector< sal_Int16 > aAttributeIndexes; + { + for ( sal_Int16 i=0; i< xAttribs->getLength(); i++ ) + { + ::rtl::OUString aName = xAttribs->getNameByIndex( i ); + if ( aName.compareTo( aXMLAttributeNamespace, aXMLAttributeNamespace.getLength() ) == 0 ) + aXMLNamespaces.addNamespace( aName, xAttribs->getValueByIndex( i )); + else + aAttributeIndexes.push_back( i ); + } + } + + // current namespaces for this level + m_aNamespaceStack.push( aXMLNamespaces ); + + try + { + // apply namespaces to all remaing attributes + for ( ::std::vector< sal_Int16 >::const_iterator i( + aAttributeIndexes.begin()); + i != aAttributeIndexes.end(); ++i ) + { + ::rtl::OUString aAttributeName = xAttribs->getNameByIndex( *i ); + ::rtl::OUString aValue = xAttribs->getValueByIndex( *i ); + ::rtl::OUString aNamespaceAttributeName = aXMLNamespaces.applyNSToAttributeName( aAttributeName ); + pNewList->AddAttribute( aNamespaceAttributeName, aXMLAttributeType, aValue ); + } + } + catch ( SAXException& e ) + { + e.Message = ::rtl::OUString( getErrorLineString() + e.Message ); + throw e; + } + + ::rtl::OUString aNamespaceElementName; + + try + { + aNamespaceElementName = aXMLNamespaces.applyNSToElementName( rName ); + } + catch ( SAXException& e ) + { + e.Message = ::rtl::OUString( getErrorLineString() + e.Message ); + throw e; + } + + xDocumentHandler->startElement( aNamespaceElementName, pNewList ); +} + +void SAL_CALL SaxNamespaceFilter::endElement(const rtl::OUString& aName) + throw( SAXException, RuntimeException ) +{ + XMLNamespaces& aXMLNamespaces = m_aNamespaceStack.top(); + ::rtl::OUString aNamespaceElementName; + + try + { + aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName ); + } + catch ( SAXException& e ) + { + e.Message = ::rtl::OUString( getErrorLineString() + e.Message ); + throw e; + } + + xDocumentHandler->endElement( aNamespaceElementName ); + m_aNamespaceStack.pop(); +} + +void SAL_CALL SaxNamespaceFilter::characters(const rtl::OUString& aChars) + throw( SAXException, RuntimeException ) +{ + xDocumentHandler->characters( aChars ); +} + +void SAL_CALL SaxNamespaceFilter::ignorableWhitespace(const rtl::OUString& aWhitespaces) + throw( SAXException, RuntimeException ) +{ + xDocumentHandler->ignorableWhitespace( aWhitespaces ); +} + +void SAL_CALL SaxNamespaceFilter::processingInstruction( + const rtl::OUString& aTarget, const rtl::OUString& aData) + throw( SAXException, RuntimeException ) +{ + xDocumentHandler->processingInstruction( aTarget, aData ); +} + +void SAL_CALL SaxNamespaceFilter::setDocumentLocator( + const Reference< XLocator > &xLocator) + throw( SAXException, RuntimeException ) +{ + m_xLocator = xLocator; + xDocumentHandler->setDocumentLocator( xLocator ); +} + +::rtl::OUString SaxNamespaceFilter::getErrorLineString() +{ + char buffer[32]; + + if ( m_xLocator.is() ) + { + snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() )); + return ::rtl::OUString::createFromAscii( buffer ); + } + else + return ::rtl::OUString(); +} + +} // namespace + diff --git a/framework/source/fwe/xml/statusbarconfiguration.cxx b/framework/source/fwe/xml/statusbarconfiguration.cxx new file mode 100644 index 000000000000..0d79ef8fd461 --- /dev/null +++ b/framework/source/fwe/xml/statusbarconfiguration.cxx @@ -0,0 +1,166 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <framework/statusbarconfiguration.hxx> +#include <xml/statusbardocumenthandler.hxx> +#include <xml/saxnamespacefilter.hxx> +#include <services.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <unotools/streamwrap.hxx> +#include <tools/debug.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::container; + + +namespace framework +{ + +SV_IMPL_PTRARR( StatusBarDescriptor, StatusBarItemDescriptorPtr); + +static Reference< XParser > GetSaxParser( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY); +} + +static Reference< XDocumentHandler > GetSaxWriter( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ; +} + +sal_Bool StatusBarConfiguration::LoadStatusBar( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&, + SvStream&, StatusBarDescriptor& ) +{ + // obsolete - only support linkage of binary filters! + return sal_True; +} + +sal_Bool StatusBarConfiguration::StoreStatusBar( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&, + SvStream&, const StatusBarDescriptor& ) +{ + // obsolete - only support linkage of binary filters! + return sal_True; +} + +sal_Bool StatusBarConfiguration::LoadStatusBar( + const Reference< XMultiServiceFactory >& xServiceFactory, + const Reference< XInputStream >& xInputStream, + const Reference< XIndexContainer >& rStatusbarConfiguration ) +{ + Reference< XParser > xParser( GetSaxParser( xServiceFactory ) ); + + // connect stream to input stream to the parser + InputSource aInputSource; + aInputSource.aInputStream = xInputStream; + + // create namespace filter and set menudocument handler inside to support xml namespaces + Reference< XDocumentHandler > xDocHandler( new OReadStatusBarDocumentHandler( rStatusbarConfiguration )); + Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler )); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + try + { + xParser->parseStream( aInputSource ); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch( SAXException& ) + { + return sal_False; + } + catch( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + +sal_Bool StatusBarConfiguration::StoreStatusBar( + const Reference< XMultiServiceFactory >& xServiceFactory, + const Reference< XOutputStream >& xOutputStream, + const Reference< XIndexAccess >& rStatusbarConfiguration ) +{ + Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) ); + Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY ); + xDataSource->setOutputStream( xOutputStream ); + + try + { + OWriteStatusBarDocumentHandler aWriteStatusBarDocumentHandler( rStatusbarConfiguration, xWriter ); + aWriteStatusBarDocumentHandler.WriteStatusBarDocument(); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch ( SAXException& ) + { + return sal_False; + } + catch ( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} +} + diff --git a/framework/source/fwe/xml/statusbardocumenthandler.cxx b/framework/source/fwe/xml/statusbardocumenthandler.cxx new file mode 100644 index 000000000000..3d8d4bfc7c9a --- /dev/null +++ b/framework/source/fwe/xml/statusbardocumenthandler.cxx @@ -0,0 +1,698 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <stdio.h> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/resetableguard.hxx> +#include <xml/statusbardocumenthandler.hxx> +#include <macros/debug.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_ +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#endif +#include <com/sun/star/ui/ItemStyle.hpp> +#include <com/sun/star/ui/ItemType.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> +#include <vcl/status.hxx> + +#include <comphelper/attributelist.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::ui; +using namespace ::com::sun::star::container; + +#define XMLNS_STATUSBAR "http://openoffice.org/2001/statusbar" +#define XMLNS_XLINK "http://www.w3.org/1999/xlink" +#define XMLNS_STATUSBAR_PREFIX "statusbar:" +#define XMLNS_XLINK_PREFIX "xlink:" + +#define XMLNS_FILTER_SEPARATOR "^" + +#define ELEMENT_STATUSBAR "statusbar" +#define ELEMENT_STATUSBARITEM "statusbaritem" + +#define ATTRIBUTE_ALIGN "align" +#define ATTRIBUTE_STYLE "style" +#define ATTRIBUTE_URL "href" +#define ATTRIBUTE_WIDTH "width" +#define ATTRIBUTE_OFFSET "offset" +#define ATTRIBUTE_AUTOSIZE "autosize" +#define ATTRIBUTE_OWNERDRAW "ownerdraw" +#define ATTRIBUTE_HELPURL "helpid" + +#define ELEMENT_NS_STATUSBAR "statusbar:statusbar" +#define ELEMENT_NS_STATUSBARITEM "statusbar:statusbaritem" + +#define ATTRIBUTE_XMLNS_STATUSBAR "xmlns:statusbar" +#define ATTRIBUTE_XMLNS_XLINK "xmlns:xlink" + +#define ATTRIBUTE_TYPE_CDATA "CDATA" + +#define ATTRIBUTE_BOOLEAN_TRUE "true" +#define ATTRIBUTE_BOOLEAN_FALSE "false" + +#define ATTRIBUTE_ALIGN_LEFT "left" +#define ATTRIBUTE_ALIGN_RIGHT "right" +#define ATTRIBUTE_ALIGN_CENTER "center" + +#define ATTRIBUTE_STYLE_IN "in" +#define ATTRIBUTE_STYLE_OUT "out" +#define ATTRIBUTE_STYLE_FLAT "flat" + +#define STATUSBAR_DOCTYPE "<!DOCTYPE statusbar:statusbar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"statusbar.dtd\">" + +namespace framework +{ + +// Property names of a menu/menu item ItemDescriptor +static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; +static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; +static const char ITEM_DESCRIPTOR_OFFSET[] = "Offset"; +static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; +static const char ITEM_DESCRIPTOR_WIDTH[] = "Width"; +static const char ITEM_DESCRIPTOR_TYPE[] = "Type"; + +static void ExtractStatusbarItemParameters( + const Sequence< PropertyValue > rProp, + ::rtl::OUString& rCommandURL, + ::rtl::OUString& rHelpURL, + sal_Int16& rOffset, + sal_Int16& rStyle, + sal_Int16& rWidth ) +{ + for ( sal_Int32 i = 0; i < rProp.getLength(); i++ ) + { + if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL )) + { + rProp[i].Value >>= rCommandURL; + rCommandURL = rCommandURL.intern(); + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL )) + { + rProp[i].Value >>= rHelpURL; + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_OFFSET )) + { + rProp[i].Value >>= rOffset; + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE )) + { + rProp[i].Value >>= rStyle; + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH )) + { + rProp[i].Value >>= rWidth; + } + } +} + +struct StatusBarEntryProperty +{ + OReadStatusBarDocumentHandler::StatusBar_XML_Namespace nNamespace; + char aEntryName[20]; +}; + +StatusBarEntryProperty StatusBarEntries[OReadStatusBarDocumentHandler::SB_XML_ENTRY_COUNT] = +{ + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ELEMENT_STATUSBAR }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ELEMENT_STATUSBARITEM }, + { OReadStatusBarDocumentHandler::SB_NS_XLINK, ATTRIBUTE_URL }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_ALIGN }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_STYLE }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_AUTOSIZE }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_OWNERDRAW }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_WIDTH }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_OFFSET }, + { OReadStatusBarDocumentHandler::SB_NS_STATUSBAR, ATTRIBUTE_HELPURL } +}; + + +OReadStatusBarDocumentHandler::OReadStatusBarDocumentHandler( + const Reference< XIndexContainer >& rStatusBarItems ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_aStatusBarItems( rStatusBarItems ) +{ + ::rtl::OUString aNamespaceStatusBar( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR )); + ::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )); + ::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR )); + + // create hash map + for ( int i = 0; i < (int)SB_XML_ENTRY_COUNT; i++ ) + { + if ( StatusBarEntries[i].nNamespace == SB_NS_STATUSBAR ) + { + ::rtl::OUString temp( aNamespaceStatusBar ); + temp += aSeparator; + temp += ::rtl::OUString::createFromAscii( StatusBarEntries[i].aEntryName ); + m_aStatusBarMap.insert( StatusBarHashMap::value_type( temp, (StatusBar_XML_Entry)i ) ); + } + else + { + ::rtl::OUString temp( aNamespaceXLink ); + temp += aSeparator; + temp += ::rtl::OUString::createFromAscii( StatusBarEntries[i].aEntryName ); + m_aStatusBarMap.insert( StatusBarHashMap::value_type( temp, (StatusBar_XML_Entry)i ) ); + } + } + + m_bStatusBarStartFound = sal_False; + m_bStatusBarEndFound = sal_False; + m_bStatusBarItemStartFound = sal_False; +} + +OReadStatusBarDocumentHandler::~OReadStatusBarDocumentHandler() +{ +} + +// XDocumentHandler +void SAL_CALL OReadStatusBarDocumentHandler::startDocument(void) +throw ( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadStatusBarDocumentHandler::endDocument(void) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + if (( m_bStatusBarStartFound && !m_bStatusBarEndFound ) || + ( !m_bStatusBarStartFound && m_bStatusBarEndFound ) ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'statusbar' found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + +void SAL_CALL OReadStatusBarDocumentHandler::startElement( + const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs ) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + StatusBarHashMap::const_iterator pStatusBarEntry = m_aStatusBarMap.find( aName ) ; + if ( pStatusBarEntry != m_aStatusBarMap.end() ) + { + switch ( pStatusBarEntry->second ) + { + case SB_ELEMENT_STATUSBAR: + { + if ( m_bStatusBarStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'statusbar:statusbar' cannot be embeded into 'statusbar:statusbar'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bStatusBarStartFound = sal_True; + } + break; + + case SB_ELEMENT_STATUSBARITEM: + { + if ( !m_bStatusBarStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'statusbar:statusbaritem' must be embeded into element 'statusbar:statusbar'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( m_bStatusBarItemStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element statusbar:statusbaritem is not a container!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + ::rtl::OUString aCommandURL; + ::rtl::OUString aHelpURL; + sal_Int16 nItemBits( ItemStyle::ALIGN_CENTER|ItemStyle::DRAW_IN3D ); + sal_Int16 nWidth( 0 ); + sal_Int16 nOffset( STATUSBAR_OFFSET ); + sal_Bool bCommandURL( sal_False ); + + m_bStatusBarItemStartFound = sal_True; + for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ ) + { + pStatusBarEntry = m_aStatusBarMap.find( xAttribs->getNameByIndex( n ) ); + if ( pStatusBarEntry != m_aStatusBarMap.end() ) + { + switch ( pStatusBarEntry->second ) + { + case SB_ATTRIBUTE_URL: + { + bCommandURL = sal_True; + aCommandURL = xAttribs->getValueByIndex( n ); + } + break; + + case SB_ATTRIBUTE_ALIGN: + { + if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_LEFT )) ) + { + nItemBits |= ItemStyle::ALIGN_LEFT; + nItemBits &= ~ItemStyle::ALIGN_CENTER; + } + else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_CENTER )) ) + { + nItemBits |= ItemStyle::ALIGN_CENTER; + nItemBits &= ~ItemStyle::ALIGN_LEFT; + } + else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_ALIGN_RIGHT )) ) + { + nItemBits |= ItemStyle::ALIGN_RIGHT; + } + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:align must have one value of 'left','right' or 'center'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + break; + + case SB_ATTRIBUTE_STYLE: + { + if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_IN )) ) + { + nItemBits |= ItemStyle::DRAW_IN3D; + nItemBits &= ~ItemStyle::DRAW_OUT3D; + } + else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_OUT )) ) + { + nItemBits |= ItemStyle::DRAW_OUT3D; + nItemBits &= ~ItemStyle::DRAW_IN3D; + } + else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_STYLE_FLAT )) ) + { + nItemBits |= ItemStyle::DRAW_FLAT; + } + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:autosize must have value 'true' or 'false'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + break; + + case SB_ATTRIBUTE_AUTOSIZE: + { + if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) ) + nItemBits |= ItemStyle::AUTO_SIZE; + else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) ) + nItemBits &= ~ItemStyle::AUTO_SIZE; + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:autosize must have value 'true' or 'false'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + break; + + case SB_ATTRIBUTE_OWNERDRAW: + { + if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) ) + nItemBits |= ItemStyle::OWNER_DRAW; + else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) ) + nItemBits &= ~ItemStyle::OWNER_DRAW; + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute statusbar:ownerdraw must have value 'true' or 'false'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + break; + + case SB_ATTRIBUTE_WIDTH: + { + nWidth = (sal_Int16)(xAttribs->getValueByIndex( n ).toInt32()); + } + break; + + case SB_ATTRIBUTE_OFFSET: + { + nOffset = (sal_Int16)(xAttribs->getValueByIndex( n ).toInt32()); + } + break; + + case SB_ATTRIBUTE_HELPURL: + { + aHelpURL = xAttribs->getValueByIndex( n ); + } + break; + + default: + break; + } + } + } // for + + if ( !bCommandURL ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute statusbar:url must have a value!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + else + { + Sequence< PropertyValue > aStatusbarItemProp( 6 ); + aStatusbarItemProp[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL )); + aStatusbarItemProp[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )); + aStatusbarItemProp[2].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_OFFSET )); + aStatusbarItemProp[3].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE )); + aStatusbarItemProp[4].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_WIDTH )); + aStatusbarItemProp[5].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )); + + aStatusbarItemProp[0].Value <<= aCommandURL; + aStatusbarItemProp[1].Value <<= aHelpURL; + aStatusbarItemProp[2].Value <<= nOffset; + aStatusbarItemProp[3].Value <<= nItemBits; + aStatusbarItemProp[4].Value <<= nWidth; + aStatusbarItemProp[5].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT ); + + m_aStatusBarItems->insertByIndex( m_aStatusBarItems->getCount(), makeAny( aStatusbarItemProp ) ); + } + } + break; + + default: + break; + } + } +} + +void SAL_CALL OReadStatusBarDocumentHandler::endElement(const ::rtl::OUString& aName) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + StatusBarHashMap::const_iterator pStatusBarEntry = m_aStatusBarMap.find( aName ) ; + if ( pStatusBarEntry != m_aStatusBarMap.end() ) + { + switch ( pStatusBarEntry->second ) + { + case SB_ELEMENT_STATUSBAR: + { + if ( !m_bStatusBarStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'statusbar' found, but no start element 'statusbar'" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bStatusBarStartFound = sal_False; + } + break; + + case SB_ELEMENT_STATUSBARITEM: + { + if ( !m_bStatusBarItemStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'statusbar:statusbaritem' found, but no start element 'statusbar:statusbaritem'" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bStatusBarItemStartFound = sal_False; + } + break; + + default: + break; + } + } +} + +void SAL_CALL OReadStatusBarDocumentHandler::characters(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadStatusBarDocumentHandler::ignorableWhitespace(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadStatusBarDocumentHandler::processingInstruction( + const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadStatusBarDocumentHandler::setDocumentLocator( + const Reference< XLocator > &xLocator) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xLocator = xLocator; +} + +::rtl::OUString OReadStatusBarDocumentHandler::getErrorLineString() +{ + ResetableGuard aGuard( m_aLock ); + + char buffer[32]; + + if ( m_xLocator.is() ) + { + snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() )); + return ::rtl::OUString::createFromAscii( buffer ); + } + else + return ::rtl::OUString(); +} + + +//_________________________________________________________________________________________________________________ +// OWriteStatusBarDocumentHandler +//_________________________________________________________________________________________________________________ + +OWriteStatusBarDocumentHandler::OWriteStatusBarDocumentHandler( + const Reference< XIndexAccess >& aStatusBarItems, + const Reference< XDocumentHandler >& rWriteDocumentHandler ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_aStatusBarItems( aStatusBarItems ), + m_xWriteDocumentHandler( rWriteDocumentHandler ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY ); + m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); + m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX )); + m_aXMLStatusBarNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR_PREFIX )); +} + +OWriteStatusBarDocumentHandler::~OWriteStatusBarDocumentHandler() +{ +} + +void OWriteStatusBarDocumentHandler::WriteStatusBarDocument() throw +( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xWriteDocumentHandler->startDocument(); + + // write DOCTYPE line! + Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY ); + if ( xExtendedDocHandler.is() ) + { + xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STATUSBAR_DOCTYPE )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + } + + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_STATUSBAR )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_STATUSBAR )) ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) ); + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBAR )), pList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + sal_Int32 nItemCount = m_aStatusBarItems->getCount(); + Any aAny; + + for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ ) + { + Sequence< PropertyValue > aProps; + aAny = m_aStatusBarItems->getByIndex( nItemPos ); + if ( aAny >>= aProps ) + { + ::rtl::OUString aCommandURL; + ::rtl::OUString aHelpURL; + sal_Int16 nStyle( ItemStyle::ALIGN_CENTER|ItemStyle::DRAW_IN3D ); + sal_Int16 nWidth( 0 ); + sal_Int16 nOffset( STATUSBAR_OFFSET ); + + ExtractStatusbarItemParameters( + aProps, + aCommandURL, + aHelpURL, + nOffset, + nStyle, + nWidth ); + + if ( aCommandURL.getLength() > 0 ) + WriteStatusBarItem( aCommandURL, aHelpURL, nOffset, nStyle, nWidth ); + } + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBAR )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endDocument(); +} + +//_________________________________________________________________________________________________________________ +// protected member functions +//_________________________________________________________________________________________________________________ + +void OWriteStatusBarDocumentHandler::WriteStatusBarItem( + const rtl::OUString& rCommandURL, + const rtl::OUString& /*rHelpURL*/, + sal_Int16 nOffset, + sal_Int16 nStyle, + sal_Int16 nWidth ) +throw ( SAXException, RuntimeException ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + if ( m_aAttributeURL.getLength() == 0 ) + { + m_aAttributeURL = m_aXMLXlinkNS; + m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL )); + } + + // save required attribute (URL) + pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL ); + + // alignment + if ( nStyle & ItemStyle::ALIGN_RIGHT ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_RIGHT )) ); + } + else if ( nStyle & ItemStyle::ALIGN_CENTER ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_CENTER )) ); + } + else + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ALIGN_LEFT )) ); + } + + // style ( SIB_IN is default ) + if ( nStyle & ItemStyle::DRAW_FLAT ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE_FLAT )) ); + } + else if ( nStyle & ItemStyle::DRAW_OUT3D ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_STYLE_OUT )) ); + } + + // autosize (default sal_False) + if ( nStyle & ItemStyle::AUTO_SIZE ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_AUTOSIZE )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) ); + } + + // ownerdraw (default sal_False) + if ( nStyle & ItemStyle::OWNER_DRAW ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_OWNERDRAW )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) ); + } + + // width (default 0) + if ( nWidth > 0 ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )), + m_aAttributeType, + ::rtl::OUString::valueOf( (sal_Int32)nWidth ) ); + } + + // offset (default STATUSBAR_OFFSET) + if ( nOffset != STATUSBAR_OFFSET ) + { + pList->AddAttribute( m_aXMLStatusBarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_OFFSET )), + m_aAttributeType, + ::rtl::OUString::valueOf( (sal_Int32)nOffset ) ); + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBARITEM )), xList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_STATUSBARITEM )) ); +} + +} // namespace framework + diff --git a/framework/source/fwe/xml/toolboxconfiguration.cxx b/framework/source/fwe/xml/toolboxconfiguration.cxx new file mode 100644 index 000000000000..994354a7e1a8 --- /dev/null +++ b/framework/source/fwe/xml/toolboxconfiguration.cxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <framework/toolboxconfiguration.hxx> +#include <xml/toolboxdocumenthandler.hxx> +#include <xml/saxnamespacefilter.hxx> +#include <services.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/xml/sax/XParser.hpp> +#include <com/sun/star/io/XActiveDataSource.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#ifndef _UNOTOOLS_PROCESSFACTORY_HXX +#include <comphelper/processfactory.hxx> +#endif +#include <unotools/streamwrap.hxx> +#include <tools/debug.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::container; + + +namespace framework +{ + +static Reference< XParser > GetSaxParser( + // #110897# + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + return Reference< XParser >( xServiceFactory->createInstance( SERVICENAME_SAXPARSER), UNO_QUERY); +} + +static Reference< XDocumentHandler > GetSaxWriter( + // #110897# + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory + ) +{ + return Reference< XDocumentHandler >( xServiceFactory->createInstance( SERVICENAME_SAXWRITER), UNO_QUERY) ; +} + +// #110897# +sal_Bool ToolBoxConfiguration::LoadToolBox( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& rInputStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >& rToolbarConfiguration ) +{ + Reference< XParser > xParser( GetSaxParser( xServiceFactory ) ); + + // connect stream to input stream to the parser + InputSource aInputSource; + + aInputSource.aInputStream = rInputStream; + + // create namespace filter and set menudocument handler inside to support xml namespaces + Reference< XDocumentHandler > xDocHandler( new OReadToolBoxDocumentHandler( rToolbarConfiguration )); + Reference< XDocumentHandler > xFilter( new SaxNamespaceFilter( xDocHandler )); + + // connect parser and filter + xParser->setDocumentHandler( xFilter ); + + try + { + xParser->parseStream( aInputSource ); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch( SAXException& ) + { + return sal_False; + } + catch( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + + +// #110897# +sal_Bool ToolBoxConfiguration::StoreToolBox( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& rOutputStream, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& rToolbarConfiguration ) +{ + Reference< XDocumentHandler > xWriter( GetSaxWriter( xServiceFactory ) ); + + Reference< ::com::sun::star::io::XActiveDataSource> xDataSource( xWriter , UNO_QUERY ); + xDataSource->setOutputStream( rOutputStream ); + + try + { + OWriteToolBoxDocumentHandler aWriteToolBoxDocumentHandler( rToolbarConfiguration, xWriter ); + aWriteToolBoxDocumentHandler.WriteToolBoxDocument(); + return sal_True; + } + catch ( RuntimeException& ) + { + return sal_False; + } + catch ( SAXException& ) + { + return sal_False; + } + catch ( ::com::sun::star::io::IOException& ) + { + return sal_False; + } +} + +} + diff --git a/framework/source/fwe/xml/toolboxdocumenthandler.cxx b/framework/source/fwe/xml/toolboxdocumenthandler.cxx new file mode 100644 index 000000000000..b41f50339343 --- /dev/null +++ b/framework/source/fwe/xml/toolboxdocumenthandler.cxx @@ -0,0 +1,901 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <stdio.h> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/resetableguard.hxx> +#include <xml/toolboxdocumenthandler.hxx> +#include <macros/debug.hxx> +#include <xml/toolboxconfigurationdefines.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#include <com/sun/star/ui/ItemType.hpp> +#include <com/sun/star/ui/ItemStyle.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <sal/config.h> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <rtl/ustrbuf.hxx> + +#include <comphelper/attributelist.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::xml::sax; + + +#define TOOLBAR_DOCTYPE "<!DOCTYPE toolbar:toolbar PUBLIC \"-//OpenOffice.org//DTD OfficeDocument 1.0//EN\" \"toolbar.dtd\">" + +namespace framework +{ + +// Property names of a menu/menu item ItemDescriptor +static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL"; +static const char ITEM_DESCRIPTOR_HELPURL[] = "HelpURL"; +static const char ITEM_DESCRIPTOR_TOOLTIP[] = "Tooltip"; +static const char ITEM_DESCRIPTOR_LABEL[] = "Label"; +static const char ITEM_DESCRIPTOR_TYPE[] = "Type"; +static const char ITEM_DESCRIPTOR_STYLE[] = "Style"; +static const char ITEM_DESCRIPTOR_VISIBLE[] = "IsVisible"; +static const char ITEM_DESCRIPTOR_WIDTH[] = "Width"; + +static void ExtractToolbarParameters( const Sequence< PropertyValue > rProp, + ::rtl::OUString& rCommandURL, + ::rtl::OUString& rLabel, + ::rtl::OUString& rHelpURL, + ::rtl::OUString& rTooltip, + sal_Int16& rStyle, + sal_Int16& rWidth, + sal_Bool& rVisible, + sal_Int16& rType ) +{ + for ( sal_Int32 i = 0; i < rProp.getLength(); i++ ) + { + if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_COMMANDURL )) + { + rProp[i].Value >>= rCommandURL; + rCommandURL = rCommandURL.intern(); + } + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_HELPURL )) + rProp[i].Value >>= rHelpURL; + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TOOLTIP )) + rProp[i].Value >>= rTooltip; + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_LABEL )) + rProp[i].Value >>= rLabel; + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_TYPE )) + rProp[i].Value >>= rType; + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_VISIBLE )) + rProp[i].Value >>= rVisible; + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_WIDTH )) + rProp[i].Value >>= rWidth; + else if ( rProp[i].Name.equalsAscii( ITEM_DESCRIPTOR_STYLE )) + rProp[i].Value >>= rStyle; + } +} + +struct ToolboxStyleItem +{ + sal_Int16 nBit; + const char* attrName; +}; + +ToolboxStyleItem Styles[ ] = { + { ::com::sun::star::ui::ItemStyle::RADIO_CHECK, ATTRIBUTE_ITEMSTYLE_RADIO }, + { ::com::sun::star::ui::ItemStyle::ALIGN_LEFT, ATTRIBUTE_ITEMSTYLE_LEFT }, + { ::com::sun::star::ui::ItemStyle::AUTO_SIZE, ATTRIBUTE_ITEMSTYLE_AUTO }, + { ::com::sun::star::ui::ItemStyle::REPEAT, ATTRIBUTE_ITEMSTYLE_REPEAT }, + { ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY, ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY }, + { ::com::sun::star::ui::ItemStyle::DROP_DOWN, ATTRIBUTE_ITEMSTYLE_DROPDOWN }, + { ::com::sun::star::ui::ItemStyle::ICON, ATTRIBUTE_ITEMSTYLE_IMAGE }, + { ::com::sun::star::ui::ItemStyle::TEXT, ATTRIBUTE_ITEMSTYLE_TEXT }, +}; + +sal_Int32 nStyleItemEntries = sizeof( Styles ) / sizeof( Styles[ 0 ] ); + +struct ToolBarEntryProperty +{ + OReadToolBoxDocumentHandler::ToolBox_XML_Namespace nNamespace; + char aEntryName[20]; +}; + +ToolBarEntryProperty ToolBoxEntries[OReadToolBoxDocumentHandler::TB_XML_ENTRY_COUNT] = +{ + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBAR }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARITEM }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARSPACE }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARBREAK }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ELEMENT_TOOLBARSEPARATOR }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_TEXT }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_BITMAP }, + { OReadToolBoxDocumentHandler::TB_NS_XLINK, ATTRIBUTE_URL }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_ITEMBITS }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_VISIBLE }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_WIDTH }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_USER }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_HELPID }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_ITEMSTYLE }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_UINAME }, + { OReadToolBoxDocumentHandler::TB_NS_TOOLBAR, ATTRIBUTE_TOOLTIP }, +}; + +OReadToolBoxDocumentHandler::OReadToolBoxDocumentHandler( const Reference< XIndexContainer >& rItemContainer ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_rItemContainer( rItemContainer ), + m_aType( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TYPE )), + m_aLabel( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_LABEL )), + m_aStyle( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_STYLE )), + m_aHelpURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_HELPURL )), + m_aTooltip( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_TOOLTIP )), + m_aIsVisible( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_VISIBLE )), + m_aCommandURL( RTL_CONSTASCII_USTRINGPARAM( ITEM_DESCRIPTOR_COMMANDURL )) + { + ::rtl::OUString aNamespaceToolBar( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR )); + ::rtl::OUString aNamespaceXLink( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )); + ::rtl::OUString aSeparator( RTL_CONSTASCII_USTRINGPARAM( XMLNS_FILTER_SEPARATOR )); + + // create hash map + for ( int i = 0; i < (int)TB_XML_ENTRY_COUNT; i++ ) + { + if ( ToolBoxEntries[i].nNamespace == TB_NS_TOOLBAR ) + { + ::rtl::OUString temp( aNamespaceToolBar ); + temp += aSeparator; + temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName ); + m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) ); + } + else + { + ::rtl::OUString temp( aNamespaceXLink ); + temp += aSeparator; + temp += ::rtl::OUString::createFromAscii( ToolBoxEntries[i].aEntryName ); + m_aToolBoxMap.insert( ToolBoxHashMap::value_type( temp, (ToolBox_XML_Entry)i ) ); + } + } + + // pre-calculate a hash code for all style strings to speed up xml read process + m_nHashCode_Style_Radio = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_RADIO ).hashCode(); + m_nHashCode_Style_Auto = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_AUTO ).hashCode(); + m_nHashCode_Style_Left = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_LEFT ).hashCode(); + m_nHashCode_Style_AutoSize = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_AUTOSIZE ).hashCode(); + m_nHashCode_Style_DropDown = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_DROPDOWN ).hashCode(); + m_nHashCode_Style_Repeat = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_REPEAT ).hashCode(); + m_nHashCode_Style_DropDownOnly = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_DROPDOWNONLY ).hashCode(); + m_nHashCode_Style_Text = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_TEXT ).hashCode(); + m_nHashCode_Style_Image = ::rtl::OUString::createFromAscii( ATTRIBUTE_ITEMSTYLE_IMAGE ).hashCode(); + + m_bToolBarStartFound = sal_False; + m_bToolBarEndFound = sal_False; + m_bToolBarItemStartFound = sal_False; + m_bToolBarSpaceStartFound = sal_False; + m_bToolBarBreakStartFound = sal_False; + m_bToolBarSeparatorStartFound = sal_False; +} + +OReadToolBoxDocumentHandler::~OReadToolBoxDocumentHandler() +{ +} + +// XDocumentHandler +void SAL_CALL OReadToolBoxDocumentHandler::startDocument(void) +throw ( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadToolBoxDocumentHandler::endDocument(void) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + if (( m_bToolBarStartFound && !m_bToolBarEndFound ) || + ( !m_bToolBarStartFound && m_bToolBarEndFound ) ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No matching start or end element 'toolbar' found!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } +} + +void SAL_CALL OReadToolBoxDocumentHandler::startElement( + const ::rtl::OUString& aName, const Reference< XAttributeList > &xAttribs ) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ; + if ( pToolBoxEntry != m_aToolBoxMap.end() ) + { + switch ( pToolBoxEntry->second ) + { + case TB_ELEMENT_TOOLBAR: + { + if ( m_bToolBarStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbar' cannot be embeded into 'toolbar:toolbar'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + else + { + // Check if we have a UI name set in our XML file + ::rtl::OUString aUIName; + for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ ) + { + pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) ); + if ( pToolBoxEntry != m_aToolBoxMap.end() ) + { + switch ( pToolBoxEntry->second ) + { + case TB_ATTRIBUTE_UINAME: + aUIName = xAttribs->getValueByIndex( n ); + break; + default: + break; + } + } + } + + if ( aUIName.getLength() > 0 ) + { + // Try to set UI name as a container property + Reference< XPropertySet > xPropSet( m_rItemContainer, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" )), makeAny( aUIName ) ); + } + catch ( UnknownPropertyException& ) + { + } + } + } + } + + m_bToolBarStartFound = sal_True; + } + break; + + case TB_ELEMENT_TOOLBARITEM: + { + if ( !m_bToolBarStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element 'toolbar:toolbaritem' must be embeded into element 'toolbar:toolbar'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( m_bToolBarSeparatorStartFound || + m_bToolBarBreakStartFound || + m_bToolBarSpaceStartFound || + m_bToolBarItemStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbaritem is not a container!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + ::rtl::OUString aAttribute; + sal_Bool bAttributeURL = sal_False; + + m_bToolBarItemStartFound = sal_True; + ::rtl::OUString aLabel; + ::rtl::OUString aCommandURL; + ::rtl::OUString aHelpURL; + ::rtl::OUString aTooltip; + ::rtl::OUString aBitmapName; + sal_uInt16 nItemBits( 0 ); + sal_uInt16 nWidth( 0 ); + sal_uInt16 nUserDef( 0 ); + sal_Bool bVisible( sal_True ); + + for ( sal_Int16 n = 0; n < xAttribs->getLength(); n++ ) + { + pToolBoxEntry = m_aToolBoxMap.find( xAttribs->getNameByIndex( n ) ); + if ( pToolBoxEntry != m_aToolBoxMap.end() ) + { + switch ( pToolBoxEntry->second ) + { + case TB_ATTRIBUTE_TEXT: + { + aLabel = xAttribs->getValueByIndex( n ); + } + break; + + case TB_ATTRIBUTE_BITMAP: + { + aBitmapName = xAttribs->getValueByIndex( n ); + } + break; + + case TB_ATTRIBUTE_URL: + { + bAttributeURL = sal_True; + aCommandURL = xAttribs->getValueByIndex( n ).intern(); + } + break; + + case TB_ATTRIBUTE_ITEMBITS: + { + nItemBits = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32()); + } + break; + + case TB_ATTRIBUTE_VISIBLE: + { + if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_TRUE )) ) + bVisible = sal_True; + else if ( xAttribs->getValueByIndex( n ).equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) ) + bVisible = sal_False; + else + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Attribute toolbar:visible must have value 'true' or 'false'!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + break; + + case TB_ATTRIBUTE_WIDTH: + { + nWidth = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32()); + } + break; + + case TB_ATTRIBUTE_USER: + { + nUserDef = (sal_uInt16)(xAttribs->getValueByIndex( n ).toInt32()); + } + break; + + case TB_ATTRIBUTE_HELPID: + { + aHelpURL = xAttribs->getValueByIndex( n ); + } + break; + + case TB_ATTRIBUTE_TOOLTIP: + { + aTooltip = xAttribs->getValueByIndex( n ); + } + break; + + case TB_ATTRIBUTE_STYLE: + { + // read space seperated item style list + ::rtl::OUString aTemp = xAttribs->getValueByIndex( n ); + sal_Int32 nIndex = 0; + + do + { + ::rtl::OUString aToken = aTemp.getToken( 0, ' ', nIndex ); + if ( aToken.getLength() > 0 ) + { + sal_Int32 nHashCode = aToken.hashCode(); + if ( nHashCode == m_nHashCode_Style_Radio ) + nItemBits |= ::com::sun::star::ui::ItemStyle::RADIO_CHECK; + else if ( nHashCode == m_nHashCode_Style_Left ) + nItemBits |= ::com::sun::star::ui::ItemStyle::ALIGN_LEFT; + else if ( nHashCode == m_nHashCode_Style_AutoSize ) + nItemBits |= ::com::sun::star::ui::ItemStyle::AUTO_SIZE; + else if ( nHashCode == m_nHashCode_Style_DropDown ) + nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN; + else if ( nHashCode == m_nHashCode_Style_Repeat ) + nItemBits |= ::com::sun::star::ui::ItemStyle::REPEAT; + else if ( nHashCode == m_nHashCode_Style_DropDownOnly ) + nItemBits |= ::com::sun::star::ui::ItemStyle::DROPDOWN_ONLY; + else if ( nHashCode == m_nHashCode_Style_DropDown ) + nItemBits |= ::com::sun::star::ui::ItemStyle::DROP_DOWN; + else if ( nHashCode == m_nHashCode_Style_Text ) + nItemBits |= ::com::sun::star::ui::ItemStyle::TEXT; + else if ( nHashCode == m_nHashCode_Style_Image ) + nItemBits |= ::com::sun::star::ui::ItemStyle::ICON; + } + } + while ( nIndex >= 0 ); + } + break; + + default: + break; + } + } + } // for + + if ( !bAttributeURL ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Required attribute toolbar:url must have a value!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + if ( aCommandURL.getLength() > 0 ) + { + Sequence< PropertyValue > aToolbarItemProp( 7 ); + aToolbarItemProp[0].Name = m_aCommandURL; + aToolbarItemProp[1].Name = m_aHelpURL; + aToolbarItemProp[2].Name = m_aLabel; + aToolbarItemProp[3].Name = m_aType; + aToolbarItemProp[4].Name = m_aStyle; + aToolbarItemProp[5].Name = m_aIsVisible; + aToolbarItemProp[6].Name = m_aTooltip; + + aToolbarItemProp[0].Value <<= aCommandURL; + aToolbarItemProp[1].Value <<= aHelpURL; + aToolbarItemProp[2].Value <<= aLabel; + aToolbarItemProp[3].Value = makeAny( ::com::sun::star::ui::ItemType::DEFAULT ); + aToolbarItemProp[4].Value <<= nItemBits; + aToolbarItemProp[5].Value <<= bVisible; + aToolbarItemProp[6].Value <<= aTooltip; + + m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) ); + } + } + break; + + case TB_ELEMENT_TOOLBARSPACE: + { + if ( m_bToolBarSeparatorStartFound || + m_bToolBarBreakStartFound || + m_bToolBarSpaceStartFound || + m_bToolBarItemStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarspace is not a container!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarSpaceStartFound = sal_True; + + Sequence< PropertyValue > aToolbarItemProp( 2 ); + aToolbarItemProp[0].Name = m_aCommandURL; + aToolbarItemProp[1].Name = m_aType; + + aToolbarItemProp[0].Value <<= rtl::OUString(); + aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_SPACE; + + m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) ); + } + break; + + case TB_ELEMENT_TOOLBARBREAK: + { + if ( m_bToolBarSeparatorStartFound || + m_bToolBarBreakStartFound || + m_bToolBarSpaceStartFound || + m_bToolBarItemStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarbreak is not a container!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarBreakStartFound = sal_True; + + Sequence< PropertyValue > aToolbarItemProp( 2 ); + aToolbarItemProp[0].Name = m_aCommandURL; + aToolbarItemProp[1].Name = m_aType; + + aToolbarItemProp[0].Value <<= rtl::OUString(); + aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK; + + m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) ); + } + break; + + case TB_ELEMENT_TOOLBARSEPARATOR: + { + if ( m_bToolBarSeparatorStartFound || + m_bToolBarBreakStartFound || + m_bToolBarSpaceStartFound || + m_bToolBarItemStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Element toolbar:toolbarseparator is not a container!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarSeparatorStartFound = sal_True; + + Sequence< PropertyValue > aToolbarItemProp( 2 ); + aToolbarItemProp[0].Name = m_aCommandURL; + aToolbarItemProp[1].Name = m_aType; + + aToolbarItemProp[0].Value <<= rtl::OUString(); + aToolbarItemProp[1].Value <<= ::com::sun::star::ui::ItemType::SEPARATOR_LINE; + + m_rItemContainer->insertByIndex( m_rItemContainer->getCount(), makeAny( aToolbarItemProp ) ); + } + break; + + default: + break; + } + } +} + +void SAL_CALL OReadToolBoxDocumentHandler::endElement(const ::rtl::OUString& aName) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + ToolBoxHashMap::const_iterator pToolBoxEntry = m_aToolBoxMap.find( aName ) ; + if ( pToolBoxEntry != m_aToolBoxMap.end() ) + { + switch ( pToolBoxEntry->second ) + { + case TB_ELEMENT_TOOLBAR: + { + if ( !m_bToolBarStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar' found, but no start element 'toolbar'" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarStartFound = sal_False; + } + break; + + case TB_ELEMENT_TOOLBARITEM: + { + if ( !m_bToolBarItemStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbaritem' found, but no start element 'toolbar:toolbaritem'" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarItemStartFound = sal_False; + } + break; + + case TB_ELEMENT_TOOLBARBREAK: + { + if ( !m_bToolBarBreakStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarbreak' found, but no start element 'toolbar:toolbarbreak'" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarBreakStartFound = sal_False; + } + break; + + case TB_ELEMENT_TOOLBARSPACE: + { + if ( !m_bToolBarSpaceStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarspace' found, but no start element 'toolbar:toolbarspace'" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarSpaceStartFound = sal_False; + } + break; + + case TB_ELEMENT_TOOLBARSEPARATOR: + { + if ( !m_bToolBarSeparatorStartFound ) + { + ::rtl::OUString aErrorMessage = getErrorLineString(); + aErrorMessage += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "End element 'toolbar:toolbarseparator' found, but no start element 'toolbar:toolbarseparator'" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + + m_bToolBarSeparatorStartFound = sal_False; + } + break; + + default: + break; + } + } +} + +void SAL_CALL OReadToolBoxDocumentHandler::characters(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadToolBoxDocumentHandler::ignorableWhitespace(const ::rtl::OUString&) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadToolBoxDocumentHandler::processingInstruction( + const ::rtl::OUString& /*aTarget*/, const ::rtl::OUString& /*aData*/ ) +throw( SAXException, RuntimeException ) +{ +} + +void SAL_CALL OReadToolBoxDocumentHandler::setDocumentLocator( + const Reference< XLocator > &xLocator) +throw( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xLocator = xLocator; +} + +::rtl::OUString OReadToolBoxDocumentHandler::getErrorLineString() +{ + ResetableGuard aGuard( m_aLock ); + + char buffer[32]; + + if ( m_xLocator.is() ) + { + snprintf( buffer, sizeof(buffer), "Line: %ld - ", static_cast<long>( m_xLocator->getLineNumber() )); + return ::rtl::OUString::createFromAscii( buffer ); + } + else + return ::rtl::OUString(); +} + + +//_________________________________________________________________________________________________________________ +// OWriteToolBoxDocumentHandler +//_________________________________________________________________________________________________________________ + +OWriteToolBoxDocumentHandler::OWriteToolBoxDocumentHandler( + const Reference< XIndexAccess >& rItemAccess, + Reference< XDocumentHandler >& rWriteDocumentHandler ) : + ThreadHelpBase( &Application::GetSolarMutex() ), + m_xWriteDocumentHandler( rWriteDocumentHandler ), + m_rItemAccess( rItemAccess ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + m_xEmptyList = Reference< XAttributeList >( (XAttributeList *) pList, UNO_QUERY ); + m_aAttributeType = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TYPE_CDATA )); + m_aXMLXlinkNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK_PREFIX )); + m_aXMLToolbarNS = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR_PREFIX )); +} + +OWriteToolBoxDocumentHandler::~OWriteToolBoxDocumentHandler() +{ +} + +void OWriteToolBoxDocumentHandler::WriteToolBoxDocument() throw +( SAXException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + m_xWriteDocumentHandler->startDocument(); + + // write DOCTYPE line! + Reference< XExtendedDocumentHandler > xExtendedDocHandler( m_xWriteDocumentHandler, UNO_QUERY ); + if ( xExtendedDocHandler.is() ) + { + xExtendedDocHandler->unknown( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( TOOLBAR_DOCTYPE )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + } + + ::rtl::OUString aUIName; + Reference< XPropertySet > xPropSet( m_rItemAccess, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName; + } + catch ( UnknownPropertyException& ) + { + } + } + + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_TOOLBAR )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_TOOLBAR )) ); + + pList->AddAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_XMLNS_XLINK )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_XLINK )) ); + + if ( aUIName.getLength() > 0 ) + pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_UINAME )), + m_aAttributeType, + aUIName ); + + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )), pList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + + sal_Int32 nItemCount = m_rItemAccess->getCount(); + Any aAny; + + for ( sal_Int32 nItemPos = 0; nItemPos < nItemCount; nItemPos++ ) + { + Sequence< PropertyValue > aProps; + aAny = m_rItemAccess->getByIndex( nItemPos ); + if ( aAny >>= aProps ) + { + ::rtl::OUString aCommandURL; + ::rtl::OUString aLabel; + ::rtl::OUString aHelpURL; + ::rtl::OUString aTooltip; + sal_Bool bVisible( sal_True ); + sal_Int16 nType( ::com::sun::star::ui::ItemType::DEFAULT ); + sal_Int16 nWidth( 0 ); + sal_Int16 nStyle( 0 ); + + ExtractToolbarParameters( aProps, aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible, nType ); + if ( nType == ::com::sun::star::ui::ItemType::DEFAULT ) + WriteToolBoxItem( aCommandURL, aLabel, aHelpURL, aTooltip, nStyle, nWidth, bVisible ); + else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_SPACE ) + WriteToolBoxSpace(); + else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINE ) + WriteToolBoxSeparator(); + else if ( nType == ::com::sun::star::ui::ItemType::SEPARATOR_LINEBREAK ) + WriteToolBoxBreak(); + } + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBAR )) ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endDocument(); +} + +//_________________________________________________________________________________________________________________ +// protected member functions +//_________________________________________________________________________________________________________________ + +void OWriteToolBoxDocumentHandler::WriteToolBoxItem( + const ::rtl::OUString& rCommandURL, + const ::rtl::OUString& rLabel, + const ::rtl::OUString& rHelpURL, + const ::rtl::OUString& rTooltip, + sal_Int16 nStyle, + sal_Int16 nWidth, + sal_Bool bVisible ) +throw ( SAXException, RuntimeException ) +{ + ::comphelper::AttributeList* pList = new ::comphelper::AttributeList; + Reference< XAttributeList > xList( (XAttributeList *) pList , UNO_QUERY ); + + if ( m_aAttributeURL.getLength() == 0 ) + { + m_aAttributeURL = m_aXMLXlinkNS; + m_aAttributeURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_URL )); + } + + // save required attribute (URL) + pList->AddAttribute( m_aAttributeURL, m_aAttributeType, rCommandURL ); + + if ( rLabel.getLength() > 0 ) + { + pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TEXT )), + m_aAttributeType, + rLabel ); + } + + if ( bVisible == sal_False ) + { + pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_VISIBLE )), + m_aAttributeType, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_BOOLEAN_FALSE )) ); + } + + if ( rHelpURL.getLength() > 0 ) + { + pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_HELPID )), + m_aAttributeType, + rHelpURL ); + } + + if ( rTooltip.getLength() > 0 ) + { + pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_TOOLTIP )), + m_aAttributeType, + rTooltip ); + } + + if ( nStyle > 0 ) + { + rtl::OUString aValue; + ToolboxStyleItem* pStyle = Styles; + + for ( sal_Int32 nIndex = 0; nIndex < nStyleItemEntries; ++nIndex, ++pStyle ) + { + if ( nStyle & pStyle->nBit ) + { + if ( aValue.getLength() ) + aValue = aValue.concat( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(" ") ) ); + aValue += rtl::OUString::createFromAscii( pStyle->attrName ); + } + } + pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_ITEMSTYLE )), + m_aAttributeType, + aValue ); + } + + if ( nWidth > 0 ) + { + pList->AddAttribute( m_aXMLToolbarNS + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ATTRIBUTE_WIDTH )), + m_aAttributeType, + ::rtl::OUString::valueOf( sal_Int32( nWidth )) ); + } + + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )), xList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARITEM )) ); +} + +void OWriteToolBoxDocumentHandler::WriteToolBoxSpace() throw +( SAXException, RuntimeException ) +{ + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )), m_xEmptyList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSPACE )) ); +} + +void OWriteToolBoxDocumentHandler::WriteToolBoxBreak() throw +( SAXException, RuntimeException ) +{ + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )), m_xEmptyList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARBREAK )) ); +} + +void OWriteToolBoxDocumentHandler::WriteToolBoxSeparator() throw +( SAXException, RuntimeException ) +{ + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->startElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )), m_xEmptyList ); + m_xWriteDocumentHandler->ignorableWhitespace( ::rtl::OUString() ); + m_xWriteDocumentHandler->endElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ELEMENT_NS_TOOLBARSEPARATOR )) ); +} + +} // namespace framework + diff --git a/framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx b/framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx new file mode 100644 index 000000000000..645750dc3f51 --- /dev/null +++ b/framework/source/fwe/xml/toolboxlayoutdocumenthandler.cxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <stdio.h> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/resetableguard.hxx> +#include <xml/toolboxlayoutdocumenthandler.hxx> +#include <macros/debug.hxx> +#include <xml/toolboxconfigurationdefines.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#ifndef __COM_SUN_STAR_XML_SAX_XEXTENDEDDOCUMENTHANDLER_HPP_ +#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp> +#endif + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ diff --git a/framework/source/fwe/xml/xmlnamespaces.cxx b/framework/source/fwe/xml/xmlnamespaces.cxx new file mode 100644 index 000000000000..fbaf51613d15 --- /dev/null +++ b/framework/source/fwe/xml/xmlnamespaces.cxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <xml/xmlnamespaces.hxx> + +using namespace ::com::sun::star::xml::sax; +using namespace ::com::sun::star::uno; + +const ::rtl::OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" )); + +namespace framework +{ + +XMLNamespaces::XMLNamespaces() +{ +} + +XMLNamespaces::XMLNamespaces( const XMLNamespaces& aXMLNamespaces ) +{ + m_aDefaultNamespace = aXMLNamespaces.m_aDefaultNamespace; + m_aNamespaceMap = aXMLNamespaces.m_aNamespaceMap; +} + +XMLNamespaces::~XMLNamespaces() +{ +} + +void XMLNamespaces::addNamespace( const ::rtl::OUString& aName, const ::rtl::OUString& aValue ) throw( SAXException ) +{ + NamespaceMap::iterator p; + ::rtl::OUString aNamespaceName( aName ); + sal_Int32 nXMLNamespaceLength = aXMLAttributeNamespace.getLength(); + + // delete preceding "xmlns" + if ( aNamespaceName.compareTo( aXMLAttributeNamespace, nXMLNamespaceLength ) == 0 ) + { + if ( aNamespaceName.getLength() == nXMLNamespaceLength ) + { + aNamespaceName = ::rtl::OUString(); + } + else if ( aNamespaceName.getLength() >= nXMLNamespaceLength+2 ) + { + aNamespaceName = aNamespaceName.copy( nXMLNamespaceLength+1 ); + } + else + { + // a xml namespace without name is not allowed (e.g. "xmlns:" ) + ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "A xml namespace without name is not allowed!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + + if ( aValue.getLength() == 0 && aNamespaceName.getLength() > 0 ) + { + // namespace should be reseted - as xml draft states this is only allowed + // for the default namespace - check and throw exception if check fails + ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Clearing xml namespace only allowed for default namespace!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + else + { + if ( aNamespaceName.getLength() == 0 ) + m_aDefaultNamespace = aValue; + else + { + p = m_aNamespaceMap.find( aNamespaceName ); + if ( p != m_aNamespaceMap.end() ) + { + // replace current namespace definition + m_aNamespaceMap.erase( p ); + m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue )); + } + else + { + m_aNamespaceMap.insert( NamespaceMap::value_type( aNamespaceName, aValue )); + } + } + } +} + +::rtl::OUString XMLNamespaces::applyNSToAttributeName( const ::rtl::OUString& aName ) const throw( SAXException ) +{ + // xml draft: there is no default namespace for attributes! + + int index; + if (( index = aName.indexOf( ':' )) > 0 ) + { + if ( aName.getLength() > index+1 ) + { + ::rtl::OUString aAttributeName = getNamespaceValue( aName.copy( 0, index ) ); + aAttributeName += ::rtl::OUString::createFromAscii( "^" ); + aAttributeName += aName.copy( index+1 ); + return aAttributeName; + } + else + { + // attribute with namespace but without name "namespace:" is not allowed!! + ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + + return aName; +} + +::rtl::OUString XMLNamespaces::applyNSToElementName( const ::rtl::OUString& aName ) const throw( SAXException ) +{ + // xml draft: element names can have a default namespace + + int index = aName.indexOf( ':' ); + ::rtl::OUString aNamespace; + ::rtl::OUString aElementName = aName; + + if ( index > 0 ) + aNamespace = getNamespaceValue( aName.copy( 0, index ) ); + else + aNamespace = m_aDefaultNamespace; + + if ( aNamespace.getLength() > 0 ) + { + aElementName = aNamespace; + aElementName += ::rtl::OUString::createFromAscii( "^" ); + } + else + return aName; + + if ( index > 0 ) + { + if ( aName.getLength() > index+1 ) + aElementName += aName.copy( index+1 ); + else + { + // attribute with namespace but without a name is not allowed (e.g. "cfg:" ) + ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "Attribute has no name only preceding namespace!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } + else + aElementName += aName; + + return aElementName; +} + +::rtl::OUString XMLNamespaces::getNamespaceValue( const ::rtl::OUString& aNamespace ) const throw( SAXException ) +{ + if ( aNamespace.getLength() == 0 ) + return m_aDefaultNamespace; + else + { + NamespaceMap::const_iterator p; + p = m_aNamespaceMap.find( aNamespace ); + if ( p != m_aNamespaceMap.end() ) + return p->second; + else + { + // namespace not defined => throw exception! + ::rtl::OUString aErrorMessage( RTL_CONSTASCII_USTRINGPARAM( "XML namespace used but not defined!" )); + throw SAXException( aErrorMessage, Reference< XInterface >(), Any() ); + } + } +} + +} + |