diff options
author | Markus Mohrhard <markus.mohrhard@collabora.co.uk> | 2014-03-01 12:44:03 +0100 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2014-03-01 16:23:09 +0100 |
commit | e34870c2396db160c15e3e9bbf3efabf55ee2839 (patch) | |
tree | efcdb1fe313e793ba14999e34eac4d6ade8c596e | |
parent | 6ba394e6119fee2c5424b6c3b5eb3f4276cc2769 (diff) |
support OOXML strict documents in Calc
Change-Id: I277d76aeec28e173d913ccc1506464afe4d09c6d
-rw-r--r-- | include/oox/core/contexthandler.hxx | 1 | ||||
-rw-r--r-- | include/oox/core/filterbase.hxx | 5 | ||||
-rw-r--r-- | include/oox/core/relations.hxx | 11 | ||||
-rw-r--r-- | include/oox/core/xmlfilterbase.hxx | 2 | ||||
-rw-r--r-- | oox/source/core/contexthandler.cxx | 5 | ||||
-rw-r--r-- | oox/source/core/relations.cxx | 37 | ||||
-rw-r--r-- | oox/source/core/xmlfilterbase.cxx | 30 | ||||
-rw-r--r-- | sc/source/filter/oox/excelfilter.cxx | 2 | ||||
-rw-r--r-- | sc/source/filter/oox/workbookfragment.cxx | 17 | ||||
-rw-r--r-- | sc/source/filter/oox/worksheetfragment.cxx | 8 |
10 files changed, 101 insertions, 17 deletions
diff --git a/include/oox/core/contexthandler.hxx b/include/oox/core/contexthandler.hxx index 272927a7c96e..2dda0122e11f 100644 --- a/include/oox/core/contexthandler.hxx +++ b/include/oox/core/contexthandler.hxx @@ -71,6 +71,7 @@ public: OUString getFragmentPathFromRelId( const OUString& rRelId ) const; /** Returns the full fragment path for the first relation of the passed type. */ OUString getFragmentPathFromFirstType( const OUString& rType ) const; + OUString getFragmentPathFromFirstTypeFromOfficeDoc( const OUString& rType ) const; // com.sun.star.xml.sax.XFastContextHandler interface --------------------- diff --git a/include/oox/core/filterbase.hxx b/include/oox/core/filterbase.hxx index 96e488ccc441..45c1ef591132 100644 --- a/include/oox/core/filterbase.hxx +++ b/include/oox/core/filterbase.hxx @@ -20,7 +20,6 @@ #ifndef INCLUDED_OOX_CORE_FILTERBASE_HXX #define INCLUDED_OOX_CORE_FILTERBASE_HXX -#include <memory> #include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/document/XFilter.hpp> @@ -37,6 +36,8 @@ #include <oox/helper/storagebase.hxx> #include <oox/dllapi.h> +#include <boost/scoped_ptr.hpp> + namespace com { namespace sun { namespace star { namespace awt { struct DeviceInfo; } namespace frame { class XFrame; } @@ -283,7 +284,7 @@ private: const ::com::sun::star::uno::Reference< ::com::sun::star::io::XStream >& rxOutStream ) const = 0; private: - ::std::auto_ptr< FilterBaseImpl > mxImpl; + boost::scoped_ptr< FilterBaseImpl > mxImpl; }; // ============================================================================ diff --git a/include/oox/core/relations.hxx b/include/oox/core/relations.hxx index c94e293efafc..05d00adbfeeb 100644 --- a/include/oox/core/relations.hxx +++ b/include/oox/core/relations.hxx @@ -30,11 +30,16 @@ namespace core { // ============================================================================ -/** Expands to an OUString containing an 'officeDocument' relation type created +/** Expands to an OUString containing an 'officeDocument' transitional relation type created from the passed literal(!) ASCII(!) character array. */ #define CREATE_OFFICEDOC_RELATION_TYPE( ascii ) \ ( "http://schemas.openxmlformats.org/officeDocument/2006/relationships/" ascii ) +/** Expands to an OUString containing an 'officeDocument' strict relation type created + from the passed literal(!) ASCII(!) character array. */ +#define CREATE_OFFICEDOC_RELATION_TYPE_STRICT( ascii ) \ + ( "http://purl.oclc.org/ooxml/officeDocument/relationships/" ascii ) + /** Expands to an OUString containing a 'package' relation type created from the passed literal(!) ASCII(!) character array. */ #define CREATE_PACKAGE_RELATION_TYPE( ascii ) \ @@ -74,8 +79,11 @@ public: const Relation* getRelationFromRelId( const OUString& rId ) const; /** Returns the first relation with the passed type. */ const Relation* getRelationFromFirstType( const OUString& rType ) const; + /** Returns the first relation with the passed type. */ + const Relation* getRelationFromFirstTypeFromOfficeDoc( const OUString& rType ) const; /** Finds all relations associated with the passed type. */ RelationsRef getRelationsFromType( const OUString& rType ) const; + RelationsRef getRelationsFromTypeFromOfficeDoc( const OUString& rType ) const; /** Returns the external target of the relation with the passed relation identifier. */ OUString getExternalTargetFromRelId( const OUString& rRelId ) const; @@ -88,6 +96,7 @@ public: OUString getFragmentPathFromRelId( const OUString& rRelId ) const; /** Returns the full fragment path for the first relation of the passed type. */ OUString getFragmentPathFromFirstType( const OUString& rType ) const; + OUString getFragmentPathFromFirstTypeFromOfficeDoc( const OUString& rType ) const; private: OUString maFragmentPath; diff --git a/include/oox/core/xmlfilterbase.hxx b/include/oox/core/xmlfilterbase.hxx index 604f220c4a1d..351910d29926 100644 --- a/include/oox/core/xmlfilterbase.hxx +++ b/include/oox/core/xmlfilterbase.hxx @@ -101,6 +101,8 @@ public: used for fragments referred by the root relations. */ OUString getFragmentPathFromFirstType( const OUString& rType ); + OUString getFragmentPathFromFirstTypeFromOfficeDoc( const OUString& rPart ); + /** Imports a fragment using the passed fragment handler, which contains the full path to the fragment stream. diff --git a/oox/source/core/contexthandler.cxx b/oox/source/core/contexthandler.cxx index 296ed71b9132..806d97503330 100644 --- a/oox/source/core/contexthandler.cxx +++ b/oox/source/core/contexthandler.cxx @@ -77,6 +77,11 @@ OUString ContextHandler::getFragmentPathFromFirstType( const OUString& rType ) c return mxBaseData->mxRelations->getFragmentPathFromFirstType( rType ); } +OUString ContextHandler::getFragmentPathFromFirstTypeFromOfficeDoc( const OUString& rType ) const +{ + return mxBaseData->mxRelations->getFragmentPathFromFirstTypeFromOfficeDoc( rType ); +} + void ContextHandler::implSetLocator( const Reference< XLocator >& rxLocator ) { mxBaseData->mxLocator = rxLocator; diff --git a/oox/source/core/relations.cxx b/oox/source/core/relations.cxx index 5b726a514e06..37425317ca76 100644 --- a/oox/source/core/relations.cxx +++ b/oox/source/core/relations.cxx @@ -43,7 +43,20 @@ OUString lclAppendFileName( const OUString& rPath, const OUString& rFileName ) OUStringBuffer( rPath ).append( '/' ).append( rFileName ).makeStringAndClear(); } -} // namespace +OUString createOfficeDocRelationTypeTransitional(const OUString& rType) +{ + static const OUString aTransitionalBase("http://schemas.openxmlformats.org/officeDocument/2006/relationships/"); + return aTransitionalBase + rType; +} + +OUString createOfficeDocRelationTypeStrict(const OUString& rType) +{ + static const OUString aStrictBase("http://purl.oclc.org/ooxml/officeDocument/relationships/"); + return aStrictBase + rType; +} + +} + @@ -75,6 +88,16 @@ RelationsRef Relations::getRelationsFromType( const OUString& rType ) const return xRelations; } +RelationsRef Relations::getRelationsFromTypeFromOfficeDoc( const OUString& rType ) const +{ + RelationsRef xRelations( new Relations( maFragmentPath ) ); + for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt ) + if( aIt->second.maType.equalsIgnoreAsciiCase( createOfficeDocRelationTypeTransitional(rType) ) || + aIt->second.maType.equalsIgnoreAsciiCase( createOfficeDocRelationTypeStrict(rType) )) + (*xRelations)[ aIt->first ] = aIt->second; + return xRelations; +} + OUString Relations::getExternalTargetFromRelId( const OUString& rRelId ) const { const Relation* pRelation = getRelationFromRelId( rRelId ); @@ -132,7 +155,17 @@ OUString Relations::getFragmentPathFromFirstType( const OUString& rType ) const return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString(); } - +OUString Relations::getFragmentPathFromFirstTypeFromOfficeDoc( const OUString& rType ) const +{ + OUString aTransitionalType(createOfficeDocRelationTypeTransitional(rType)); + const Relation* pRelation = getRelationFromFirstType( aTransitionalType ); + if(!pRelation) + { + OUString aStrictType = createOfficeDocRelationTypeStrict(rType); + pRelation = getRelationFromFirstType( aStrictType ); + } + return pRelation ? getFragmentPathFromRelation( *pRelation ) : OUString(); +} } // namespace core } // namespace oox diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index adbecaa4fdb6..ecf902e52f53 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -233,6 +233,36 @@ OUString XmlFilterBase::getFragmentPathFromFirstType( const OUString& rType ) return importRelations( OUString() )->getFragmentPathFromFirstType( rType ); } +namespace { + +OUString getTransitionalRelationshipOfficeDocType(const OUString& rPart) +{ + static const OUString aBase("http://schemas.openxmlformats.org/officeDocument/2006/relationships/"); + return aBase + rPart; +} + +OUString getStrictRelationshipOfficeDocType(const OUString& rPart) +{ + static const OUString aBase("http://purl.oclc.org/ooxml/officeDocument/relationships/"); + return aBase + rPart; +} + +} + +OUString XmlFilterBase::getFragmentPathFromFirstTypeFromOfficeDoc( const OUString& rPart ) +{ + // importRelations() caches the relations map for subsequence calls + const OUString aTransitionalRelationshipType = getTransitionalRelationshipOfficeDocType(rPart); + OUString aFragment = importRelations( OUString() )->getFragmentPathFromFirstType( aTransitionalRelationshipType ); + if(aFragment.isEmpty()) + { + const OUString aStrictRelationshipType = getStrictRelationshipOfficeDocType(rPart); + aFragment = importRelations( OUString() )->getFragmentPathFromFirstType( aStrictRelationshipType ); + } + + return aFragment; +} + bool XmlFilterBase::importFragment( const rtl::Reference<FragmentHandler>& rxHandler ) { return importFragment(rxHandler, mxImpl->maFastParser); diff --git a/sc/source/filter/oox/excelfilter.cxx b/sc/source/filter/oox/excelfilter.cxx index 0bc886cd1a18..063d5f1bb919 100644 --- a/sc/source/filter/oox/excelfilter.cxx +++ b/sc/source/filter/oox/excelfilter.cxx @@ -101,7 +101,7 @@ bool ExcelFilter::importDocument() throw() this variable (nonpro only). */ //OOX_DUMP_FILE( ::oox::dump::xlsb::Dumper ); - OUString aWorkbookPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "officeDocument" ) ); + OUString aWorkbookPath = getFragmentPathFromFirstTypeFromOfficeDoc( "officeDocument" ); if( aWorkbookPath.isEmpty() ) return false; diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx index 625c5ffee9af..5342fde0401b 100644 --- a/sc/source/filter/oox/workbookfragment.cxx +++ b/sc/source/filter/oox/workbookfragment.cxx @@ -360,26 +360,26 @@ void WorkbookFragment::finalizeImport() ISegmentProgressBarRef xGlobalSegment = getProgressBar().createSegment( PROGRESS_LENGTH_GLOBALS ); // read the theme substream - OUString aThemeFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "theme" ) ); + OUString aThemeFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( "theme" ); if( !aThemeFragmentPath.isEmpty() ) importOoxFragment( new ThemeFragmentHandler( getFilter(), aThemeFragmentPath, getTheme() ) ); xGlobalSegment->setPosition( 0.25 ); // read the styles substream (requires finalized theme buffer) - OUString aStylesFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "styles" ) ); + OUString aStylesFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( "styles" ); if( !aStylesFragmentPath.isEmpty() ) importOoxFragment( new StylesFragment( *this, aStylesFragmentPath ) ); xGlobalSegment->setPosition( 0.5 ); // read the shared string table substream (requires finalized styles buffer) - OUString aSstFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "sharedStrings" ) ); + OUString aSstFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( "sharedStrings" ); if( !aSstFragmentPath.isEmpty() ) if (!importOoxFragment( new SharedStringsFragment( *this, aSstFragmentPath ) )) importOoxFragment(new SharedStringsFragment(*this, aSstFragmentPath.replaceFirst("sharedStrings","SharedStrings"))); xGlobalSegment->setPosition( 0.75 ); // read the connections substream - OUString aConnFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "connections" ) ); + OUString aConnFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( "connections" ); if( !aConnFragmentPath.isEmpty() ) importOoxFragment( new ConnectionsFragment( *this, aConnFragmentPath ) ); xGlobalSegment->setPosition( 1.0 ); @@ -412,14 +412,17 @@ void WorkbookFragment::finalizeImport() // get the sheet type according to the relations type WorksheetType eSheetType = SHEETTYPE_EMPTYSHEET; - if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "worksheet" ) ) + if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "worksheet" ) || + pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE_STRICT( "worksheet" )) eSheetType = SHEETTYPE_WORKSHEET; - else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "chartsheet" ) ) + else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "chartsheet" ) || + pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE_STRICT( "chartsheet" )) eSheetType = SHEETTYPE_CHARTSHEET; else if( (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlMacrosheet" )) || (pRelation->maType == CREATE_MSOFFICE_RELATION_TYPE( "xlIntlMacrosheet" )) ) eSheetType = SHEETTYPE_MACROSHEET; - else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "dialogsheet" ) ) + else if( pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE( "dialogsheet" ) || + pRelation->maType == CREATE_OFFICEDOC_RELATION_TYPE_STRICT(" dialogsheet" )) eSheetType = SHEETTYPE_DIALOGSHEET; OSL_ENSURE( eSheetType != SHEETTYPE_EMPTYSHEET, "WorkbookFragment::finalizeImport - unknown sheet type" ); if( eSheetType != SHEETTYPE_EMPTYSHEET ) diff --git a/sc/source/filter/oox/worksheetfragment.cxx b/sc/source/filter/oox/worksheetfragment.cxx index 81b6411b945b..9ad408a8bf92 100644 --- a/sc/source/filter/oox/worksheetfragment.cxx +++ b/sc/source/filter/oox/worksheetfragment.cxx @@ -203,12 +203,12 @@ WorksheetFragment::WorksheetFragment( const WorksheetHelper& rHelper, const OUSt WorksheetFragmentBase( rHelper, rFragmentPath ) { // import data tables related to this worksheet - RelationsRef xTableRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATION_TYPE( "table" ) ); + RelationsRef xTableRels = getRelations().getRelationsFromTypeFromOfficeDoc( "table" ); for( Relations::const_iterator aIt = xTableRels->begin(), aEnd = xTableRels->end(); aIt != aEnd; ++aIt ) importOoxFragment( new TableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) ); // import comments related to this worksheet - OUString aCommentsFragmentPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "comments" ) ); + OUString aCommentsFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( "comments" ); if( !aCommentsFragmentPath.isEmpty() ) importOoxFragment( new CommentsFragment( *this, aCommentsFragmentPath ) ); } @@ -473,12 +473,12 @@ void WorksheetFragment::initializeImport() initializeWorksheetImport(); // import query table fragments related to this worksheet - RelationsRef xQueryRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATION_TYPE( "queryTable" ) ); + RelationsRef xQueryRels = getRelations().getRelationsFromTypeFromOfficeDoc( "queryTable" ); for( Relations::const_iterator aIt = xQueryRels->begin(), aEnd = xQueryRels->end(); aIt != aEnd; ++aIt ) importOoxFragment( new QueryTableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) ); // import pivot table fragments related to this worksheet - RelationsRef xPivotRels = getRelations().getRelationsFromType( CREATE_OFFICEDOC_RELATION_TYPE( "pivotTable" ) ); + RelationsRef xPivotRels = getRelations().getRelationsFromTypeFromOfficeDoc( "pivotTable" ); for( Relations::const_iterator aIt = xPivotRels->begin(), aEnd = xPivotRels->end(); aIt != aEnd; ++aIt ) importOoxFragment( new PivotTableFragment( *this, getFragmentPathFromRelation( aIt->second ) ) ); } |