Update ooo320-m1
[ooovba.git] / filter / source / placeware / exporter.cxx
blob2ba6abfc883080a5653e90737d22614d0708e683
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: exporter.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_filter.hxx"
33 #include <com/sun/star/container/XNamed.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
37 #ifndef _COM_SUN_STAR_PRESENTATION_PRESENTATIONPAGE_HPP_
38 #include <com/sun/star/presentation/XPresentationPage.hpp>
39 #endif
40 #include <com/sun/star/container/XIndexAccess.hpp>
41 #include <com/sun/star/document/XFilter.hpp>
42 #include <com/sun/star/text/XText.hpp>
43 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
44 #include <com/sun/star/frame/XModel.hpp>
45 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
46 #include <rtl/ustrbuf.hxx>
47 #include <rtl/string.hxx>
48 #include <osl/diagnose.h>
50 #include <vector>
52 #include "exporter.hxx"
53 #include "Base64Codec.hxx"
54 #include "zip.hxx"
55 #include "tempfile.hxx"
57 using rtl::OUString;
58 using rtl::OString;
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::drawing;
61 using namespace ::com::sun::star::container;
62 using namespace ::com::sun::star::document;
63 using namespace ::com::sun::star::io;
64 using namespace ::com::sun::star::lang;
65 using namespace ::com::sun::star::text;
66 using namespace ::std;
68 using com::sun::star::beans::PropertyValue;
69 using com::sun::star::beans::XPropertySet;
70 using com::sun::star::presentation::XPresentationPage;
71 using com::sun::star::task::XStatusIndicator;
73 // -----------------------------------------------------------------------------
75 PlaceWareExporter::PlaceWareExporter(const Reference< XMultiServiceFactory > &rxMSF)
76 : mxMSF( rxMSF )
80 // -----------------------------------------------------------------------------
82 PlaceWareExporter::~PlaceWareExporter()
86 // -----------------------------------------------------------------------------
87 class PageEntry
89 private:
90 TempFile maTempFile;
91 rtl::OUString maName;
92 rtl::OUString maTitle;
93 rtl::OUString maNotes;
94 rtl::OUString maURL;
96 public:
97 PageEntry();
98 ~PageEntry();
100 OUString getTempURL() { return maTempFile.getFileURL(); }
102 void setName( const rtl::OUString& rName ) { maName = rName; }
103 const rtl::OUString& getName() const { return maName; }
105 void setTitle( const rtl::OUString& rTitle ) { maTitle = rTitle; }
106 const rtl::OUString& getTitle() const { return maTitle; }
108 void setNotes( const rtl::OUString& rNotes ) { maNotes = rNotes; }
109 const rtl::OUString& getNotes() const { return maNotes; }
111 void setURL( const rtl::OUString& rURL ) { maURL = rURL; }
112 const rtl::OUString& getURL() const { return maURL; }
115 PageEntry::PageEntry()
116 : maTempFile( TempFile::createTempFileURL() )
120 PageEntry::~PageEntry()
125 static void encodeFile( osl::File& rSourceFile, Reference< XOutputStream >& xOutputStream ) throw( ::com::sun::star::uno::Exception )
127 if( xOutputStream.is() )
129 sal_uInt64 nTemp( 0 );
131 osl::File::RC nRC = rSourceFile.setPos( osl_Pos_End, 0 );
132 if( osl::File::E_None == nRC )
134 nRC = rSourceFile.getPos( nTemp );
135 if( osl::File::E_None == nRC )
137 nRC = rSourceFile.setPos( osl_Pos_Absolut, 0 );
141 sal_Int32 nLen = static_cast<sal_Int32>(nTemp);
143 if( osl::File::E_None != nRC )
144 throw IOException();
146 sal_Int32 nBufferSize = 3*1024; // !!! buffer size must be a factor of 3 for base64 to work
147 Sequence< sal_Int8 > aInBuffer( nBufferSize < nLen ? nBufferSize : nLen );
148 void* pInBuffer = aInBuffer.getArray();
150 Sequence< sal_Int8 > aOutBuffer;
151 sal_Int32 nRead;
152 while( nLen )
154 nRC = rSourceFile.read( pInBuffer, aInBuffer.getLength(), nTemp );
156 if( (nRC != osl::File::E_None) || (0 == nTemp) )
157 throw IOException();
159 nRead = static_cast<sal_Int32>( nTemp );
161 if( nRead < aInBuffer.getLength() )
163 aInBuffer.realloc( nRead );
164 pInBuffer = aInBuffer.getArray();
167 nLen -= nRead;
169 rtl::OUStringBuffer aStrBuffer;
170 Base64Codec::encodeBase64( aStrBuffer, aInBuffer );
172 sal_Int32 nCount = aStrBuffer.getLength();
174 if( aOutBuffer.getLength() != nCount )
175 aOutBuffer.realloc( nCount );
177 sal_Int8* pBytes = aOutBuffer.getArray();
178 const sal_Unicode* pUnicode = aStrBuffer.getStr();
180 while( nCount-- )
182 // since base64 is always ascii, we can cast safely
183 *pBytes++ = static_cast<sal_Int8>(*pUnicode++);
186 xOutputStream->writeBytes( aOutBuffer );
191 static OString convertString( OUString aInput )
193 OString aRet( aInput.getStr(), aInput.getLength(), RTL_TEXTENCODING_ASCII_US );
194 aRet = aRet.replace( '\r', ' ' );
195 aRet = aRet.replace( '\n', ' ' );
197 return aRet;
200 static void createSlideFile( Reference< XComponent > xDoc, ZipFile& rZipFile, const rtl::OUString& rURL, vector< PageEntry* >& rPageEntries ) throw( ::com::sun::star::uno::Exception )
202 OString aInfo;
204 const OString aNewLine( "\r\n" );
205 OUString aTemp;
207 Reference< XDocumentPropertiesSupplier > xDPS( xDoc, UNO_QUERY );
208 Reference< XDocumentProperties > xDocProps( xDPS->getDocumentProperties() );
210 aTemp = xDocProps->getTitle();
211 if( 0 == aTemp.getLength() )
213 sal_Int32 nPos1 = rURL.lastIndexOf( (sal_Unicode)'/' );
214 if( -1 != nPos1 )
216 sal_Int32 nPos2 = rURL.lastIndexOf( (sal_Unicode)'.' );
217 if( nPos2 > nPos1 )
219 aTemp = rURL.copy( nPos1 + 1, nPos2 - nPos1 - 1 );
221 else
223 aTemp = rURL.copy( nPos1 + 1 );
226 else
228 aTemp = rURL;
232 aInfo += OString( "SlideSetName: " );
233 aInfo += convertString( aTemp );
234 aInfo += aNewLine;
236 aTemp = xDocProps->getAuthor();
238 if( aTemp.getLength() )
240 aInfo += OString( "PresenterName: " );
241 aInfo += convertString( aTemp );
242 aInfo += aNewLine;
245 vector< PageEntry* >::iterator aIter( rPageEntries.begin() );
246 vector< PageEntry* >::iterator aEnd( rPageEntries.end() );
247 while( aIter != aEnd )
249 PageEntry* pEntry = (*aIter++);
251 aInfo += OString( "slide: " );
252 if( pEntry->getTitle().getLength() )
254 aInfo += convertString( pEntry->getTitle() );
256 else
258 aInfo += convertString( pEntry->getName() );
260 aInfo += aNewLine;
262 aInfo += OString( "type: gif");
263 aInfo += aNewLine;
265 aInfo += OString( "url: " );
266 aInfo += convertString( pEntry->getURL() );
267 aInfo += aNewLine;
270 if( pEntry->getNotes().getLength() )
272 aInfo += OString( "notes: " );
273 aInfo += convertString( pEntry->getNotes() );
274 aInfo += aNewLine;
278 TempFile aInfoFile( TempFile::createTempFileURL() );
280 osl::File::RC nRC;
281 sal_uInt64 nTemp;
283 nRC = aInfoFile.open( OpenFlag_Write );
284 if( osl::File::E_None == nRC )
286 nRC = aInfoFile.write( aInfo.getStr(), aInfo.getLength(), nTemp );
287 if( osl::File::E_None == nRC )
289 nRC = aInfoFile.setPos( osl_Pos_Absolut, 0 );
290 if( osl::File::E_None == nRC )
292 nRC = aInfoFile.close();
297 if( (osl::File::E_None != nRC) || !rZipFile.addFile( aInfoFile, OString( RTL_CONSTASCII_STRINGPARAM("slides.txt") ) ))
298 throw IOException();
301 //#define PLACEWARE_DEBUG 1
303 sal_Bool PlaceWareExporter::doExport( Reference< XComponent > xDoc, Reference < XOutputStream > xOutputStream,
304 const rtl::OUString& rURL, Reference < XInterface > /* xHandler */, Reference < XStatusIndicator >& xStatusIndicator )
306 sal_Bool bRet = sal_False;
308 mxGraphicExporter = Reference< XExporter >::query( mxMSF->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.GraphicExportFilter") ) ) );
309 Reference< XDrawPagesSupplier > xDrawPagesSupplier(xDoc, UNO_QUERY);
310 if(!xDrawPagesSupplier.is())
311 return sal_False;
313 Reference< XIndexAccess > xDrawPages( xDrawPagesSupplier->getDrawPages(), UNO_QUERY );
314 if(!xDrawPages.is())
315 return sal_False;
317 if(xStatusIndicator.is())
319 xStatusIndicator->start(OUString( RTL_CONSTASCII_USTRINGPARAM( "PlaceWare:" )),xDrawPages->getCount());
322 Reference< XDrawPage > xDrawPage;
324 osl::File::RC nRC;
326 #ifndef PLACEWARE_DEBUG
327 TempFile aTempFile( TempFile::createTempFileURL() );
328 nRC = aTempFile.open( osl_File_OpenFlag_Write|osl_File_OpenFlag_Read );
329 OUString aURL( aTempFile.getFileURL() );
330 #else
331 OUString aURL( RTL_CONSTASCII_USTRINGPARAM("file:///e:/test.zip") );
332 osl::File::remove( aURL );
333 osl::File aTempFile( aURL );
334 nRC = aTempFile.open( osl_File_OpenFlag_Create|osl_File_OpenFlag_Write|osl_File_OpenFlag_Read );
335 #endif
337 if( osl::File::E_None != nRC )
338 return sal_False;
340 vector< PageEntry* > aPageEntries;
342 // Create new package...
345 ZipFile aZipFile(aTempFile);
347 // export slides as gifs and collect information for slides
349 const sal_Int32 nPageCount = xDrawPages->getCount();
350 sal_Int32 nPage;
352 for( nPage = 0; nPage < nPageCount; nPage++)
354 xDrawPages->getByIndex(nPage) >>= xDrawPage;
356 if( !xDrawPage.is() )
357 continue;
359 PageEntry* pEntry = exportPage( xDrawPage );
360 aPageEntries.push_back( pEntry );
362 OUString aName( RTL_CONSTASCII_USTRINGPARAM("i") );
363 aName += OUString::valueOf( nPage );
364 aName += OUString( RTL_CONSTASCII_USTRINGPARAM(".gif") );
365 pEntry->setURL( aName );
367 if(xStatusIndicator.is())
369 xStatusIndicator->setValue( nPage + 1 );
373 // create the slide.txt file
375 createSlideFile( xDoc, aZipFile, rURL, aPageEntries );
377 // add gifs to zip
378 vector< PageEntry* >::iterator aIter( aPageEntries.begin() );
379 vector< PageEntry* >::iterator aEnd( aPageEntries.end() );
380 while( aIter != aEnd )
382 PageEntry* pEntry = (*aIter++);
384 osl::File aFile(pEntry->getTempURL() );
385 const OUString aTemp( pEntry->getURL() );
387 if( (osl::File::E_None != nRC) || !aZipFile.addFile( aFile, OString( aTemp.getStr(), aTemp.getLength(), RTL_TEXTENCODING_ASCII_US ) ) )
388 throw IOException();
391 if(!aZipFile.close())
392 throw IOException();
394 encodeFile( aTempFile, xOutputStream );
396 bRet = sal_True;
398 catch ( RuntimeException const & )
401 catch ( Exception const & )
405 vector< PageEntry* >::iterator aIter( aPageEntries.begin() );
406 vector< PageEntry* >::iterator aEnd( aPageEntries.end() );
407 while( aIter != aEnd )
409 delete (*aIter++);
412 if( xStatusIndicator.is() )
413 xStatusIndicator->end();
415 return bRet;
418 // -----------------------------------------------------------------------------
420 PageEntry* PlaceWareExporter::exportPage( Reference< XDrawPage >&xDrawPage )
422 Reference< XComponent > xComp( xDrawPage, UNO_QUERY );
424 PageEntry* pEntry = new PageEntry();
426 // get page name
427 Reference< XNamed > xNamed( xDrawPage, UNO_QUERY );
428 if( xNamed.is() )
429 pEntry->setName( xNamed->getName() );
431 // get title text from title presentation shape if available
432 const OUString szTitleTextShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.TitleTextShape") );
433 const OUString szIsEmptyPresObj( RTL_CONSTASCII_USTRINGPARAM("IsEmptyPresentationObject") );
435 sal_Int32 nShapeCount = xDrawPage->getCount();
436 sal_Int32 nShape;
437 for( nShape = 0; nShape < nShapeCount; nShape++ )
439 Reference< XShape > xShape;
440 xDrawPage->getByIndex( nShape ) >>= xShape;
442 if( xShape.is() && xShape->getShapeType() == szTitleTextShape )
444 Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
445 if( xPropSet.is() )
447 sal_Bool bIsEmpty = true;
448 xPropSet->getPropertyValue( szIsEmptyPresObj ) >>= bIsEmpty;
450 if( !bIsEmpty )
452 Reference< XText > xText( xShape, UNO_QUERY );
453 if( xText.is() )
455 pEntry->setTitle( xText->getString() );
459 break;
463 // get notes text if available
464 Reference< XPresentationPage > xPresPage( xDrawPage, UNO_QUERY );
465 if( xPresPage.is() )
467 Reference< XDrawPage > xNotesPage( xPresPage->getNotesPage() );
469 const OUString szNotesShape( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesShape") );
471 nShapeCount = xNotesPage->getCount();
472 for( nShape = 0; nShape < nShapeCount; nShape++ )
474 Reference< XShape > xShape;
475 xNotesPage->getByIndex( nShape ) >>= xShape;
477 if( xShape.is() && (xShape->getShapeType() == szNotesShape) )
479 Reference< XPropertySet > xPropSet( xShape, UNO_QUERY );
480 if( xPropSet.is() )
482 sal_Bool bIsEmpty = true;
483 xPropSet->getPropertyValue( szIsEmptyPresObj ) >>= bIsEmpty;
485 if( !bIsEmpty )
487 Reference< XText > xText( xShape, UNO_QUERY );
488 if( xText.is() )
490 pEntry->setNotes( xText->getString() );
494 break;
499 // create the gif
500 Reference< XFilter > xFilter( mxGraphicExporter, UNO_QUERY );
502 Sequence< PropertyValue > aFilterData( 2 );
503 aFilterData[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Width") );
504 aFilterData[0].Value <<= (sal_Int32)704;
505 aFilterData[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("Translucent") );
506 aFilterData[1].Value <<= (sal_Bool)sal_False;
508 Sequence< PropertyValue > aDescriptor( 3 );
509 aDescriptor[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FilterName") );
510 aDescriptor[0].Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM("GIF") );
511 aDescriptor[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("URL") );
512 aDescriptor[1].Value <<= OUString( pEntry->getTempURL() );
513 aDescriptor[2].Name = OUString( RTL_CONSTASCII_USTRINGPARAM("FilterData") );
514 aDescriptor[2].Value <<= aFilterData;
515 mxGraphicExporter->setSourceDocument( xComp );
516 xFilter->filter( aDescriptor );
518 return pEntry;