summaryrefslogtreecommitdiff
path: root/filter/source/flash/swffilter.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/flash/swffilter.cxx')
-rw-r--r--filter/source/flash/swffilter.cxx526
1 files changed, 526 insertions, 0 deletions
diff --git a/filter/source/flash/swffilter.cxx b/filter/source/flash/swffilter.cxx
new file mode 100644
index 000000000000..03d9d003c30d
--- /dev/null
+++ b/filter/source/flash/swffilter.cxx
@@ -0,0 +1,526 @@
+/*************************************************************************
+ *
+ * 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/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <osl/file.hxx>
+
+#include "swfexporter.hxx"
+
+//#include <stdlib.h>
+//#include <windows.h>
+#include <string.h>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::task;
+
+using ::rtl::OUString;
+using ::rtl::OString;
+using ::com::sun::star::lang::XComponent;
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::io::XOutputStream;
+using ::com::sun::star::container::XIndexAccess;
+using ::osl::FileBase;
+using ::com::sun::star::frame::XModel;
+
+namespace swf {
+
+typedef ::cppu::WeakImplHelper1<com::sun::star::io::XOutputStream> OslOutputStreamWrapper_Base;
+ // needed for some compilers
+class OslOutputStreamWrapper : public OslOutputStreamWrapper_Base
+{
+ osl::File mrFile;
+
+public:
+ OslOutputStreamWrapper(const OUString& sFileName) : mrFile(sFileName)
+ {
+ osl_removeFile(sFileName.pData);
+ mrFile.open(OpenFlag_Create|OpenFlag_Write);
+ }
+
+ // stario::XOutputStream
+ virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL flush( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL closeOutput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
+};
+
+void SAL_CALL OslOutputStreamWrapper::writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& aData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ sal_uInt64 uBytesToWrite = aData.getLength();
+ sal_uInt64 uBytesWritten = 0;
+
+ sal_Int8 const * pBuffer = aData.getConstArray();
+
+ while( uBytesToWrite )
+ {
+ osl::File::RC eRC = mrFile.write( pBuffer, uBytesToWrite, uBytesWritten);
+
+ switch( eRC )
+ {
+ case osl::File::E_INVAL: // the format of the parameters was not valid
+ case osl::File::E_FBIG: // File too large
+
+ case osl::File::E_AGAIN: // Operation would block
+ case osl::File::E_BADF: // Bad file
+ case osl::File::E_FAULT: // Bad address
+ case osl::File::E_INTR: // function call was interrupted
+ case osl::File::E_IO: // I/O error
+ case osl::File::E_NOLCK: // No record locks available
+ case osl::File::E_NOLINK: // Link has been severed
+ case osl::File::E_NOSPC: // No space left on device
+ case osl::File::E_NXIO: // No such device or address
+ throw com::sun::star::io::IOException(); // TODO: Better error handling
+ default: break;
+ }
+
+ uBytesToWrite -= uBytesWritten;
+ pBuffer += uBytesWritten;
+ }
+}
+
+void SAL_CALL OslOutputStreamWrapper::flush( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+}
+
+void SAL_CALL OslOutputStreamWrapper::closeOutput( ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
+{
+ osl::File::RC eRC = mrFile.close();
+
+ switch( eRC )
+ {
+ case osl::File::E_INVAL: // the format of the parameters was not valid
+
+ case osl::File::E_BADF: // Bad file
+ case osl::File::E_INTR: // function call was interrupted
+ case osl::File::E_NOLINK: // Link has been severed
+ case osl::File::E_NOSPC: // No space left on device
+ case osl::File::E_IO: // I/O error
+ throw com::sun::star::io::IOException(); // TODO: Better error handling
+ default: break;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+class FlashExportFilter : public cppu::WeakImplHelper4
+<
+ com::sun::star::document::XFilter,
+ com::sun::star::document::XExporter,
+ com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XServiceInfo
+>
+{
+ Reference< XComponent > mxDoc;
+ Reference< XMultiServiceFactory > mxMSF;
+ Reference< XStatusIndicator> mxStatusIndicator;
+
+ osl::File* mpFile;
+
+public:
+ FlashExportFilter( const Reference< XMultiServiceFactory > &rxMSF);
+
+ // XFilter
+ virtual sal_Bool SAL_CALL filter( const Sequence< PropertyValue >& aDescriptor ) throw(RuntimeException);
+
+ sal_Bool ExportAsMultipleFiles( const Sequence< PropertyValue >& aDescriptor );
+ sal_Bool ExportAsSingleFile( const Sequence< PropertyValue >& aDescriptor );
+
+ virtual void SAL_CALL cancel( ) throw (RuntimeException);
+
+ // XExporter
+ virtual void SAL_CALL setSourceDocument( const Reference< XComponent >& xDoc ) throw(IllegalArgumentException, RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
+};
+
+// -----------------------------------------------------------------------------
+
+FlashExportFilter::FlashExportFilter(const Reference< XMultiServiceFactory > &rxMSF)
+: mxMSF( rxMSF )
+{
+}
+
+
+// -----------------------------------------------------------------------------
+
+OUString exportBackground(FlashExporter &aFlashExporter, Reference< XDrawPage > xDrawPage, OUString sPath, sal_uInt32 nPage, const char* suffix)
+{
+ OUString filename = STR("slide") + VAL(nPage+1) + STR(suffix) + STR(".swf");
+ OUString fullpath = sPath + STR("/") + filename;
+
+ // AS: If suffix is "o" then the last paramter is true (for exporting objects).
+ Reference<XOutputStream> xOutputStreamWrap(*(new OslOutputStreamWrapper(fullpath)), UNO_QUERY);
+ sal_uInt16 nCached = aFlashExporter.exportBackgrounds( xDrawPage, xOutputStreamWrap, sal::static_int_cast<sal_uInt16>( nPage ), *suffix == 'o' );
+ aFlashExporter.Flush();
+ xOutputStreamWrap.clear();
+
+ if (nCached != nPage)
+ {
+ osl_removeFile(fullpath.pData);
+ if ( 0xffff == nCached )
+ return STR("NULL");
+ else
+ return STR("slide") + VAL(nCached+1) + STR(suffix) + STR(".swf");
+ }
+
+ return filename;
+}
+
+template <typename TYPE>
+TYPE findPropertyValue(const Sequence< PropertyValue >& aPropertySequence, const sal_Char* name, TYPE def)
+{
+ TYPE temp = TYPE();
+
+ sal_Int32 nLength = aPropertySequence.getLength();
+ const PropertyValue * pValue = aPropertySequence.getConstArray();
+
+ for ( sal_Int32 i = 0 ; i < nLength; i++)
+ {
+ if ( pValue[i].Name.equalsAsciiL ( name, strlen(name) ) )
+ {
+ pValue[i].Value >>= temp;
+ return temp;
+ }
+ }
+
+ return def;
+}
+
+sal_Bool SAL_CALL FlashExportFilter::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
+ throw (RuntimeException)
+{
+ mxStatusIndicator = findPropertyValue<Reference<XStatusIndicator> >(aDescriptor, "StatusIndicator", mxStatusIndicator);
+
+ Sequence< PropertyValue > aFilterData;
+ aFilterData = findPropertyValue<Sequence< PropertyValue > >(aDescriptor, "FilterData", aFilterData);
+
+ if (findPropertyValue<sal_Bool>(aFilterData, "ExportMultipleFiles", false ))
+ {
+ ExportAsMultipleFiles(aDescriptor);
+ }
+ else
+ {
+ ExportAsSingleFile(aDescriptor);
+ }
+
+ if( mxStatusIndicator.is() )
+ mxStatusIndicator->end();
+
+ return sal_True;
+}
+
+
+// AS: When exporting as multiple files, each background, object layer, and slide gets its own
+// file. Additionally, a file called BackgroundConfig.txt is generated, indicating which
+// background and objects (if any) go with each slide. The files are named slideNb.swf,
+// slideNo.swf, and slideNp.swf, where N is the slide number, and b=background, o=objects, and
+// p=slide contents. Note that under normal circumstances, there will be very few b and o files.
+
+// AS: HACK! Right now, I create a directory as a sibling to the swf file selected in the Export
+// dialog. This directory is called presentation.sxi-swf-files. The name of the swf file selected
+// in the Export dialog has no impact on this. All files created are placed in this directory.
+sal_Bool FlashExportFilter::ExportAsMultipleFiles(const Sequence< PropertyValue >& aDescriptor)
+{
+ Reference< XDrawPagesSupplier > xDrawPagesSupplier(mxDoc, UNO_QUERY);
+ if(!xDrawPagesSupplier.is())
+ return sal_False;
+
+ Reference< XIndexAccess > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY );
+ if(!xDrawPages.is())
+ return sal_False;
+
+ Reference< XDesktop > rDesktop( mxMSF->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY);
+ if (!rDesktop.is())
+ return sal_False;
+
+ Reference< XStorable > xStorable(rDesktop->getCurrentComponent(), UNO_QUERY);
+ if (!xStorable.is())
+ return sal_False;
+
+ Reference< XDrawPage > xDrawPage;
+
+ Reference< XFrame > rFrame = rDesktop->getCurrentFrame();
+ Reference< XDrawView > rDrawView = Reference< XDrawView >( rFrame->getController(), UNO_QUERY );
+
+ Reference< XDrawPage > rCurrentPage = rDrawView->getCurrentPage();
+
+ Sequence< PropertyValue > aFilterData;
+
+ aFilterData = findPropertyValue<Sequence< PropertyValue > >(aDescriptor, "FilterData", aFilterData);
+
+ //AS: Do a bunch of path mangling to figure out where to put the files.
+
+ OUString sOriginalPath = findPropertyValue<OUString>(aDescriptor, "URL", OUString());
+
+ // AS: sPath is the parent directory, where everything else exists (like the sxi,
+ // the -swf-files folder, the -audio files, etc.
+ int lastslash = sOriginalPath.lastIndexOf('/');
+ OUString sPath( sOriginalPath.copy(0, lastslash) );
+
+ OUString sPresentation(xStorable->getLocation());
+
+ lastslash = sPresentation.lastIndexOf('/') + 1;
+ int lastdot = sPresentation.lastIndexOf('.');
+
+ // AS: The name of the presentation, without 3 character extension.
+ OUString sPresentationName = sPresentation.copy(lastslash, lastdot - lastslash);
+
+ OUString fullpath, swfdirpath, backgroundfilename, objectsfilename;
+
+ swfdirpath = sPath + STR("/") + sPresentationName + STR(".sxi-swf-files");
+
+ oslFileError err;
+ err = osl_createDirectory( swfdirpath.pData );
+
+ fullpath = swfdirpath + STR("/backgroundconfig.txt");
+
+ oslFileHandle xBackgroundConfig( 0 );
+
+ // AS: Only export the background config if we're exporting all of the pages, otherwise we'll
+ // screw it up.
+ sal_Bool bExportAll = findPropertyValue<sal_Bool>(aFilterData, "ExportAll", true);
+ if (bExportAll)
+ {
+ osl_removeFile(fullpath.pData);
+ osl_openFile( fullpath.pData, &xBackgroundConfig, osl_File_OpenFlag_Create | osl_File_OpenFlag_Write );
+
+ sal_uInt64 bytesWritten;
+ err = osl_writeFile(xBackgroundConfig, "slides=", strlen("slides="), &bytesWritten);
+ }
+
+ FlashExporter aFlashExporter( mxMSF, findPropertyValue<sal_Int32>(aFilterData, "CompressMode", 75),
+ findPropertyValue<sal_Bool>(aFilterData, "ExportOLEAsJPEG", false));
+
+ const sal_Int32 nPageCount = xDrawPages->getCount();
+ if ( mxStatusIndicator.is() )
+ mxStatusIndicator->start(OUString( RTL_CONSTASCII_USTRINGPARAM( "Saving :" )), nPageCount);
+
+ for(sal_Int32 nPage = 0; nPage < nPageCount; nPage++)
+ {
+ if ( mxStatusIndicator.is() )
+ mxStatusIndicator->setValue( nPage );
+ xDrawPages->getByIndex(nPage) >>= xDrawPage;
+
+ // AS: If we're only exporting the current page, then skip the rest.
+ if (!bExportAll && xDrawPage != rCurrentPage)
+ continue;
+
+ // AS: Export the background, the background objects, and then the slide contents.
+ if (bExportAll || findPropertyValue<sal_Bool>(aFilterData, "ExportBackgrounds", true))
+ {
+ backgroundfilename = exportBackground(aFlashExporter, xDrawPage, swfdirpath, nPage, "b");
+ }
+
+ if (bExportAll || findPropertyValue<sal_Bool>(aFilterData, "ExportBackgroundObjects", true))
+ {
+ objectsfilename = exportBackground(aFlashExporter, xDrawPage, swfdirpath, nPage, "o");
+ }
+
+ if (bExportAll || findPropertyValue<sal_Bool>(aFilterData, "ExportSlideContents", true))
+ {
+ fullpath = swfdirpath + STR("/slide") + VAL(nPage+1) + STR("p.swf");
+
+ Reference<XOutputStream> xOutputStreamWrap(*(new OslOutputStreamWrapper(fullpath)), UNO_QUERY);
+ sal_Bool ret = aFlashExporter.exportSlides( xDrawPage, xOutputStreamWrap, sal::static_int_cast<sal_uInt16>( nPage ) );
+ aFlashExporter.Flush();
+ xOutputStreamWrap.clear();
+
+ if (!ret)
+ osl_removeFile(fullpath.pData);
+ }
+
+ // AS: Write out to the background config what backgrounds and objects this
+ // slide used.
+ if (bExportAll)
+ {
+ OUString temp = backgroundfilename + STR("|") + objectsfilename;
+ OString ASCIItemp(temp.getStr(), temp.getLength(), RTL_TEXTENCODING_ASCII_US);
+
+ sal_uInt64 bytesWritten;
+ osl_writeFile(xBackgroundConfig, ASCIItemp.getStr(), ASCIItemp.getLength(), &bytesWritten);
+
+ if (nPage < nPageCount - 1)
+ osl_writeFile(xBackgroundConfig, "|", 1, &bytesWritten);
+ }
+
+#ifdef AUGUSTUS
+ if (findPropertyValue<sal_Bool>(aFilterData, "ExportSound", true))
+ {
+ fullpath = swfdirpath + STR("/slide") + VAL(nPage+1) + STR("s.swf");
+
+ OUString wavpath = sPath + STR("/") + sPresentationName + STR(".ppt-audio/slide") + VAL(nPage+1) + STR(".wav");
+ FileBase::getSystemPathFromFileURL(wavpath, wavpath);
+ OString sASCIIPath(wavpath.getStr(), wavpath.getLength(), RTL_TEXTENCODING_ASCII_US);
+
+ Reference<XOutputStream> xOutputStreamWrap(*(new OslOutputStreamWrapper(fullpath)), UNO_QUERY);
+ sal_Bool ret = aFlashExporter.exportSound(xOutputStreamWrap, sASCIIPath.getStr());
+ aFlashExporter.Flush();
+ xOutputStreamWrap.clear();
+
+ if (!ret)
+ osl_removeFile(fullpath.pData);
+ }
+#endif // defined AUGUSTUS
+ }
+
+ if (bExportAll)
+ osl_closeFile(xBackgroundConfig);
+
+ return sal_True;
+}
+
+sal_Bool FlashExportFilter::ExportAsSingleFile(const Sequence< PropertyValue >& aDescriptor)
+{
+ Reference < XOutputStream > xOutputStream = findPropertyValue<Reference<XOutputStream> >(aDescriptor, "OutputStream", 0);
+ Sequence< PropertyValue > aFilterData;
+
+ if (!xOutputStream.is() )
+ {
+ OSL_ASSERT ( 0 );
+ return sal_False;
+ }
+
+ FlashExporter aFlashExporter( mxMSF, findPropertyValue<sal_Int32>(aFilterData, "CompressMode", 75),
+ findPropertyValue<sal_Bool>(aFilterData, "ExportOLEAsJPEG", false));
+
+ return aFlashExporter.exportAll( mxDoc, xOutputStream, mxStatusIndicator );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL FlashExportFilter::cancel( )
+ throw (RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+// XExporter
+void SAL_CALL FlashExportFilter::setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc )
+ throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
+{
+ mxDoc = xDoc;
+}
+
+// -----------------------------------------------------------------------------
+
+// XInitialization
+void SAL_CALL FlashExportFilter::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& /* aArguments */ )
+ throw (Exception, RuntimeException)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+OUString FlashExportFilter_getImplementationName ()
+ throw (RuntimeException)
+{
+ return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Impress.FlashExportFilter" ) );
+}
+
+// -----------------------------------------------------------------------------
+
+#define SERVICE_NAME "com.sun.star.document.ExportFilter"
+
+sal_Bool SAL_CALL FlashExportFilter_supportsService( const OUString& ServiceName )
+ throw (RuntimeException)
+{
+ return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
+}
+
+// -----------------------------------------------------------------------------
+
+Sequence< OUString > SAL_CALL FlashExportFilter_getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ Sequence < OUString > aRet(1);
+ OUString* pArray = aRet.getArray();
+ pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
+ return aRet;
+}
+#undef SERVICE_NAME
+
+// -----------------------------------------------------------------------------
+
+Reference< XInterface > SAL_CALL FlashExportFilter_createInstance( const Reference< XMultiServiceFactory > & rSMgr)
+ throw( Exception )
+{
+ return (cppu::OWeakObject*) new FlashExportFilter( rSMgr );
+}
+
+// -----------------------------------------------------------------------------
+
+// XServiceInfo
+OUString SAL_CALL FlashExportFilter::getImplementationName( )
+ throw (RuntimeException)
+{
+ return FlashExportFilter_getImplementationName();
+}
+
+// -----------------------------------------------------------------------------
+
+sal_Bool SAL_CALL FlashExportFilter::supportsService( const OUString& rServiceName )
+ throw (RuntimeException)
+{
+ return FlashExportFilter_supportsService( rServiceName );
+}
+
+// -----------------------------------------------------------------------------
+
+::com::sun::star::uno::Sequence< OUString > SAL_CALL FlashExportFilter::getSupportedServiceNames( )
+ throw (RuntimeException)
+{
+ return FlashExportFilter_getSupportedServiceNames();
+}
+
+// -----------------------------------------------------------------------------
+
+}