summaryrefslogtreecommitdiff
path: root/filter/source/placeware/exporter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/placeware/exporter.cxx')
-rw-r--r--filter/source/placeware/exporter.cxx516
1 files changed, 516 insertions, 0 deletions
diff --git a/filter/source/placeware/exporter.cxx b/filter/source/placeware/exporter.cxx
new file mode 100644
index 000000000000..964bc618af5d
--- /dev/null
+++ b/filter/source/placeware/exporter.cxx
@@ -0,0 +1,516 @@
+/*************************************************************************
+ *
+ * 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_filter.hxx"
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#ifndef _COM_SUN_STAR_PRESENTATION_PRESENTATIONPAGE_HPP_
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#endif
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/string.hxx>
+#include <osl/diagnose.h>
+
+#include <vector>
+
+#include "exporter.hxx"
+#include "Base64Codec.hxx"
+#include "zip.hxx"
+#include "tempfile.hxx"
+
+using rtl::OUString;
+using rtl::OString;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::text;
+using namespace ::std;
+
+using com::sun::star::beans::PropertyValue;
+using com::sun::star::beans::XPropertySet;
+using com::sun::star::presentation::XPresentationPage;
+using com::sun::star::task::XStatusIndicator;
+
+// -----------------------------------------------------------------------------
+
+PlaceWareExporter::PlaceWareExporter(const Reference< XMultiServiceFactory > &rxMSF)
+: mxMSF( rxMSF )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+PlaceWareExporter::~PlaceWareExporter()
+{
+}
+
+// -----------------------------------------------------------------------------
+class PageEntry
+{
+private:
+ TempFile maTempFile;
+ rtl::OUString maName;
+ rtl::OUString maTitle;
+ rtl::OUString maNotes;
+ rtl::OUString maURL;
+
+public:
+ PageEntry();
+ ~PageEntry();
+
+ OUString getTempURL() { return maTempFile.getFileURL(); }
+
+ void setName( const rtl::OUString& rName ) { maName = rName; }
+ const rtl::OUString& getName() const { return maName; }
+
+ void setTitle( const rtl::OUString& rTitle ) { maTitle = rTitle; }
+ const rtl::OUString& getTitle() const { return maTitle; }
+
+ void setNotes( const rtl::OUString& rNotes ) { maNotes = rNotes; }
+ const rtl::OUString& getNotes() const { return maNotes; }
+
+ void setURL( const rtl::OUString& rURL ) { maURL = rURL; }
+ const rtl::OUString& getURL() const { return maURL; }
+};
+
+PageEntry::PageEntry()
+: maTempFile( TempFile::createTempFileURL() )
+{
+}
+
+PageEntry::~PageEntry()
+{
+}
+
+
+static void encodeFile( osl::File& rSourceFile, Reference< XOutputStream >& xOutputStream ) throw( ::com::sun::star::uno::Exception )
+{
+ if( xOutputStream.is() )
+ {
+ sal_uInt64 nTemp( 0 );
+
+ osl::File::RC nRC = rSourceFile.setPos( osl_Pos_End, 0 );
+ if( osl::File::E_None == nRC )
+ {
+ nRC = rSourceFile.getPos( nTemp );
+ if( osl::File::E_None == nRC )
+ {
+ nRC = rSourceFile.setPos( osl_Pos_Absolut, 0 );
+ }
+ }
+
+ sal_Int32 nLen = static_cast<sal_Int32>(nTemp);
+
+ if( osl::File::E_None != nRC )
+ throw IOException();
+
+ sal_Int32 nBufferSize = 3*1024; // !!! buffer size must be a factor of 3 for base64 to work
+ Sequence< sal_Int8 > aInBuffer( nBufferSize < nLen ? nBufferSize : nLen );
+ void* pInBuffer = aInBuffer.getArray();
+
+ Sequence< sal_Int8 > aOutBuffer;
+ sal_Int32 nRead;
+ while( nLen )
+ {
+ nRC = rSourceFile.read( pInBuffer, aInBuffer.getLength(), nTemp );
+
+ if( (nRC != osl::File::E_None) || (0 == nTemp) )
+ throw IOException();
+
+ nRead = static_cast<sal_Int32>( nTemp );
+
+ if( nRead < aInBuffer.getLength() )
+ {
+ aInBuffer.realloc( nRead );
+ pInBuffer = aInBuffer.getArray();
+ }
+
+ nLen -= nRead;
+
+ rtl::OUStringBuffer aStrBuffer;
+ Base64Codec::encodeBase64( aStrBuffer, aInBuffer );
+
+ sal_Int32 nCount = aStrBuffer.getLength();
+
+ if( aOutBuffer.getLength() != nCount )
+ aOutBuffer.realloc( nCount );
+
+ sal_Int8* pBytes = aOutBuffer.getArray();
+ const sal_Unicode* pUnicode = aStrBuffer.getStr();
+
+ while( nCount-- )
+ {
+ // since base64 is always ascii, we can cast safely
+ *pBytes++ = static_cast<sal_Int8>(*pUnicode++);
+ }
+
+ xOutputStream->writeBytes( aOutBuffer );
+ }
+ }
+}
+
+static OString convertString( OUString aInput )
+{
+ OString aRet( aInput.getStr(), aInput.getLength(), RTL_TEXTENCODING_ASCII_US );
+ aRet = aRet.replace( '\r', ' ' );
+ aRet = aRet.replace( '\n', ' ' );
+
+ return aRet;
+}
+
+static void createSlideFile( Reference< XComponent > xDoc, ZipFile& rZipFile, const rtl::OUString& rURL, vector< PageEntry* >& rPageEntries ) throw( ::com::sun::star::uno::Exception )
+{
+ OString aInfo;
+
+ const OString aNewLine( "\r\n" );
+ OUString aTemp;
+
+ Reference< XDocumentPropertiesSupplier > xDPS( xDoc, UNO_QUERY );
+ Reference< XDocumentProperties > xDocProps( xDPS->getDocumentProperties() );
+
+ aTemp = xDocProps->getTitle();
+ if( 0 == aTemp.getLength() )
+ {
+ sal_Int32 nPos1 = rURL.lastIndexOf( (sal_Unicode)'/' );
+ if( -1 != nPos1 )
+ {
+ sal_Int32 nPos2 = rURL.lastIndexOf( (sal_Unicode)'.' );
+ if( nPos2 > nPos1 )
+ {
+ aTemp = rURL.copy( nPos1 + 1, nPos2 - nPos1 - 1 );
+ }
+ else
+ {
+ aTemp = rURL.copy( nPos1 + 1 );
+ }
+ }
+ else
+ {
+ aTemp = rURL;
+ }
+ }
+
+ aInfo += OString( "SlideSetName: " );
+ aInfo += convertString( aTemp );
+ aInfo += aNewLine;
+
+ aTemp = xDocProps->getAuthor();
+
+ if( aTemp.getLength() )
+ {
+ aInfo += OString( "PresenterName: " );
+ aInfo += convertString( aTemp );
+ aInfo += aNewLine;
+ }
+
+ vector< PageEntry* >::iterator aIter( rPageEntries.begin() );
+ vector< PageEntry* >::iterator aEnd( rPageEntries.end() );
+ while( aIter != aEnd )
+ {
+ PageEntry* pEntry = (*aIter++);
+
+ aInfo += OString( "slide: " );
+ if( pEntry->getTitle().getLength() )
+ {
+ aInfo += convertString( pEntry->getTitle() );
+ }
+ else
+ {
+ aInfo += convertString( pEntry->getName() );
+ }
+ aInfo += aNewLine;
+
+ aInfo += OString( "type: gif");
+ aInfo += aNewLine;
+
+ aInfo += OString( "url: " );
+ aInfo += convertString( pEntry->getURL() );
+ aInfo += aNewLine;
+
+
+ if( pEntry->getNotes().getLength() )
+ {
+ aInfo += OString( "notes: " );
+ aInfo += convertString( pEntry->getNotes() );
+ aInfo += aNewLine;
+ }
+ }
+
+ TempFile aInfoFile( TempFile::createTempFileURL() );
+
+ osl::File::RC nRC;
+ sal_uInt64 nTemp;
+
+ nRC = aInfoFile.open( OpenFlag_Write );
+ if( osl::File::E_None == nRC )
+ {
+ nRC = aInfoFile.write( aInfo.getStr(), aInfo.getLength(), nTemp );
+ if( osl::File::E_None == nRC )
+ {
+ nRC = aInfoFile.setPos( osl_Pos_Absolut, 0 );
+ if( osl::File::E_None == nRC )
+ {
+ nRC = aInfoFile.close();
+ }
+ }
+ }
+
+ if( (osl::File::E_None != nRC) || !rZipFile.addFile( aInfoFile, OString( RTL_CONSTASCII_STRINGPARAM("slides.txt") ) ))
+ throw IOException();
+}
+
+//#define PLACEWARE_DEBUG 1
+
+sal_Bool PlaceWareExporter::doExport( Reference< XComponent > xDoc, Reference < XOutputStream > xOutputStream,
+ const rtl::OUString& rURL, Reference < XInterface > /* xHandler */, Reference < XStatusIndicator >& xStatusIndicator )
+{
+ sal_Bool bRet = sal_False;
+
+ mxGraphicExporter = Reference< XExporter >::query( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.GraphicExportFilter") ) ) );
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier(xDoc, UNO_QUERY);
+ if(!xDrawPagesSupplier.is())
+ return sal_False;
+
+ Reference< XIndexAccess > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY );
+ if(!xDrawPages.is())
+ return sal_False;
+
+ if(xStatusIndicator.is())
+ {
+ xStatusIndicator->start(OUString( RTL_CONSTASCII_USTRINGPARAM( "PlaceWare:" )),xDrawPages->getCount());
+ }
+
+ Reference< XDrawPage > xDrawPage;
+
+ osl::File::RC nRC;
+
+#ifndef PLACEWARE_DEBUG
+ TempFile aTempFile( TempFile::createTempFileURL() );
+ nRC = aTempFile.open( osl_File_OpenFlag_Write|osl_File_OpenFlag_Read );
+ OUString aURL( aTempFile.getFileURL() );
+#else
+ OUString aURL( RTL_CONSTASCII_USTRINGPARAM("file:///e:/test.zip") );
+ osl::File::remove( aURL );
+ osl::File aTempFile( aURL );
+ nRC = aTempFile.open( osl_File_OpenFlag_Create|osl_File_OpenFlag_Write|osl_File_OpenFlag_Read );
+#endif
+
+ if( osl::File::E_None != nRC )
+ return sal_False;
+
+ vector< PageEntry* > aPageEntries;
+
+ // Create new package...
+ try
+ {
+ ZipFile aZipFile(aTempFile);
+
+ // export slides as gifs and collect information for slides
+
+ const sal_Int32 nPageCount = xDrawPages->getCount();
+ sal_Int32 nPage;
+
+ for( nPage = 0; nPage < nPageCount; nPage++)
+ {
+ xDrawPages->getByIndex(nPage) >>= xDrawPage;
+
+ if( !xDrawPage.is() )
+ continue;
+
+ PageEntry* pEntry = exportPage( xDrawPage );
+ aPageEntries.push_back( pEntry );
+
+ OUString aName( RTL_CONSTASCII_USTRINGPARAM("i") );
+ aName += OUString::valueOf( nPage );
+ aName += OUString( RTL_CONSTASCII_USTRINGPARAM(".gif") );
+ pEntry->setURL( aName );
+
+ if(xStatusIndicator.is())
+ {
+ xStatusIndicator->setValue( nPage + 1 );
+ }
+ }
+
+ // create the slide.txt file
+
+ createSlideFile( xDoc, aZipFile, rURL, aPageEntries );
+
+ // add gifs to zip
+ vector< PageEntry* >::iterator aIter( aPageEntries.begin() );
+ vector< PageEntry* >::iterator aEnd( aPageEntries.end() );
+ while( aIter != aEnd )
+ {
+ PageEntry* pEntry = (*aIter++);
+
+ osl::File aFile(pEntry->getTempURL() );
+ const OUString aTemp( pEntry->getURL() );
+
+ if( (osl::File::E_None != nRC) || !aZipFile.addFile( aFile, OString( aTemp.getStr(), aTemp.getLength(), RTL_TEXTENCODING_ASCII_US ) ) )
+ throw IOException();
+ }
+
+ if(!aZipFile.close())
+ throw IOException();
+
+ encodeFile( aTempFile, xOutputStream );
+
+ bRet = sal_True;
+ }
+ catch ( RuntimeException const & )
+ {
+ }
+ catch ( Exception const & )
+ {
+ }
+
+ vector< PageEntry* >::iterator aIter( aPageEntries.begin() );
+ vector< PageEntry* >::iterator aEnd( aPageEntries.end() );
+ while( aIter != aEnd )
+ {
+ delete (*aIter++);
+ }
+
+ if( xStatusIndicator.is() )
+ xStatusIndicator->end();
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------------
+
+PageEntry* PlaceWareExporter::exportPage( Reference< XDrawPage >&xDrawPage )
+{
+ Reference< XComponent > xComp( xDrawPage, UNO_QUERY );
+
+ PageEntry* pEntry = new PageEntry();
+
+ // get page name
+ Reference< XNamed > xNamed( xDrawPage, UNO_QUERY );
+ if( xNamed.is() )
+ pEntry->setName( xNamed->getName() );
+
+ // get title text from title presentation shape if available
+ const OUString szTitleTextShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.TitleTextShape") );
+ const OUString szIsEmptyPresObj( RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") );
+
+ sal_Int32 nShapeCount = xDrawPage->getCount();
+ sal_Int32 nShape;
+ for( nShape = 0; nShape < nShapeCount; nShape++ )
+ {
+ Reference< XShape > xShape;
+ xDrawPage->getByIndex( nShape ) >>= xShape;
+
+ if( xShape.is() && xShape->getShapeType() == szTitleTextShape )
+ {
+ Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ sal_Bool bIsEmpty = true;
+ xPropSet->getPropertyValue( szIsEmptyPresObj ) >>= bIsEmpty;
+
+ if( !bIsEmpty )
+ {
+ Reference< XText > xText( xShape, UNO_QUERY );
+ if( xText.is() )
+ {
+ pEntry->setTitle( xText->getString() );
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ // get notes text if available
+ Reference< XPresentationPage > xPresPage( xDrawPage, UNO_QUERY );
+ if( xPresPage.is() )
+ {
+ Reference< XDrawPage > xNotesPage( xPresPage->getNotesPage() );
+
+ const OUString szNotesShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesShape") );
+
+ nShapeCount = xNotesPage->getCount();
+ for( nShape = 0; nShape < nShapeCount; nShape++ )
+ {
+ Reference< XShape > xShape;
+ xNotesPage->getByIndex( nShape ) >>= xShape;
+
+ if( xShape.is() && (xShape->getShapeType() == szNotesShape) )
+ {
+ Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
+ if( xPropSet.is() )
+ {
+ sal_Bool bIsEmpty = true;
+ xPropSet->getPropertyValue( szIsEmptyPresObj ) >>= bIsEmpty;
+
+ if( !bIsEmpty )
+ {
+ Reference< XText > xText( xShape, UNO_QUERY );
+ if( xText.is() )
+ {
+ pEntry->setNotes( xText->getString() );
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ // create the gif
+ Reference< XFilter > xFilter( mxGraphicExporter, UNO_QUERY );
+
+ Sequence< PropertyValue > aFilterData( 2 );
+ aFilterData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Width") );
+ aFilterData[0].Value <<= (sal_Int32)704;
+ aFilterData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Translucent") );
+ aFilterData[1].Value <<= (sal_Bool)sal_False;
+
+ Sequence< PropertyValue > aDescriptor( 3 );
+ aDescriptor[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FilterName") );
+ aDescriptor[0].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM("GIF") );
+ aDescriptor[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("URL") );
+ aDescriptor[1].Value <<= OUString( pEntry->getTempURL() );
+ aDescriptor[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FilterData") );
+ aDescriptor[2].Value <<= aFilterData;
+ mxGraphicExporter->setSourceDocument( xComp );
+ xFilter->filter( aDescriptor );
+
+ return pEntry;
+}