summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx85
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx11
-rw-r--r--sw/source/filter/ww8/docxexport.cxx41
-rw-r--r--sw/source/filter/ww8/docxexport.hxx7
4 files changed, 144 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 132213138cad..469585492ebc 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -1071,6 +1071,9 @@ void DocxAttributeOutput::StartRunProperties()
assert(!m_postponedDMLDrawing);
m_postponedDMLDrawing = new std::list< PostponedDrawing >;
+
+ assert( !m_postponedOLE );
+ m_postponedOLE = new std::list< PostponedOLE >;
}
void DocxAttributeOutput::InitCollectedRunProperties()
@@ -1326,6 +1329,8 @@ void DocxAttributeOutput::EndRunProperties( const SwRedlineData* pRedlineData )
WritePostponedVMLDrawing();
WritePostponedDMLDrawing();
+ WritePostponedOLE();
+
// merge the properties _before_ the run text (strictly speaking, just
// after the start of the run)
m_pSerializer->mergeTopMarks( sax_fastparser::MERGE_MARKS_PREPEND );
@@ -3306,6 +3311,8 @@ void DocxAttributeOutput::WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rOL
return;
if( WriteOLEMath( pSdrObj, rOLENode, rSize ))
return;
+ if( PostponeOLE( pSdrObj, rOLENode, rSize, pFlyFrmFmt ))
+ return;
// Then we fall back to just export the object as a graphic.
if( m_postponedGraphic == NULL )
FlyFrameGraphic( 0, rSize, pFlyFrmFmt, &rOLENode );
@@ -3467,6 +3474,83 @@ void DocxAttributeOutput::WritePostponedFormControl(const SdrObject* pObject)
}
}
+bool DocxAttributeOutput::PostponeOLE( const SdrObject*, SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt )
+{
+ if( m_postponedVMLDrawing == NULL )
+ return false;
+ m_postponedOLE->push_back( PostponedOLE( &rNode, rSize, pFlyFrmFmt ) );
+ return true;
+}
+
+/*
+ * Write w:object hierarchy for embedded objects after end element of w:rPr tag.
+ */
+void DocxAttributeOutput::WritePostponedOLE()
+{
+ if( m_postponedOLE == NULL )
+ return;
+
+ SAL_INFO( "sw.ww8", OSL_THIS_FUNC );
+
+ for( std::list< PostponedOLE >::iterator it = m_postponedOLE->begin();
+ it != m_postponedOLE->end();
+ ++it )
+ {
+ // write embedded file
+ OString sId = m_rExport.WriteOLENode( *it->object );
+
+ if( sId.isEmpty() )
+ {
+ // the embedded file could not be saved
+ // fallback: save as an image
+ FlyFrameGraphic( 0, it->size, it->frame, it->object );
+ continue;
+ }
+
+ // write preview image
+ const Graphic* pGraphic = const_cast< SwOLENode* >( it->object )->GetGraphic();
+ OUString sImageId = m_rDrawingML.WriteImage( *pGraphic );
+
+ m_pSerializer->startElementNS( XML_w, XML_object, FSEND );
+
+ OStringBuffer sShapeStyle, sShapeId;
+ sShapeStyle.append( "width:" ).append( double( it->size.Width() ) / 20 )
+ .append( "pt;height:" ).append( double( it->size.Height() ) / 20 )
+ .append( "pt" ); //from VMLExport::AddRectangleDimensions(), it does: value/20
+ sShapeId.append( "ole_" ).append( sId );
+
+ // shape definition
+ m_pSerializer->startElementNS( XML_v, XML_shape,
+ XML_id, sShapeId.getStr(),
+ XML_style, sShapeStyle.getStr(),
+ FSNS( XML_o, XML_ole ), "", //compulsory, even if it's empty
+ FSEND );
+
+ // shape filled with the preview image
+ m_pSerializer->singleElementNS( XML_v, XML_imagedata,
+ FSNS( XML_r, XML_id ), OUStringToOString( sImageId, RTL_TEXTENCODING_UTF8 ).getStr(),
+ FSEND );
+
+ m_pSerializer->endElementNS( XML_v, XML_shape );
+
+ // OLE object definition
+ m_pSerializer->singleElementNS( XML_o, XML_OLEObject,
+ XML_Type, "Embed",
+ XML_ProgID,"Excel.Sheet.12", //TODO: should be auto-detected somehow
+ XML_ShapeID, sShapeId.getStr(),
+ XML_DrawAspect, "Content",
+ XML_ObjectID, "_" + OString::number( rand() ),
+ FSNS( XML_r, XML_id ), sId.getStr(),
+ FSEND );
+
+ m_pSerializer->endElementNS( XML_w, XML_object );
+ }
+
+ // clear list of postponed objects
+ delete m_postponedOLE;
+ m_postponedOLE = NULL;
+}
+
/*
* Write w:pict hierarchy end element of w:rPr tag.
*/
@@ -6520,6 +6604,7 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
m_postponedDiagram( NULL ),
m_postponedVMLDrawing(NULL),
m_postponedDMLDrawing(NULL),
+ m_postponedOLE( NULL ),
m_postponedMath( NULL ),
m_postponedChart( NULL ),
pendingPlaceholder( NULL ),
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 30474f17b35c..de98b3c8b64c 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -393,6 +393,7 @@ private:
void WriteOLE2Obj( const SdrObject* pSdrObj, SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt);
bool WriteOLEChart( const SdrObject* pSdrObj, const Size& rSize );
bool WriteOLEMath( const SdrObject* pSdrObj, const SwOLENode& rNode, const Size& rSize );
+ bool PostponeOLE( const SdrObject* pSdrObj, SwOLENode& rNode, const Size& rSize, const SwFlyFrmFmt* pFlyFrmFmt );
/// checks whether the current component is a diagram
bool IsDiagram (const SdrObject* sdrObject);
@@ -668,6 +669,7 @@ private:
void WritePostponedFormControl(const SdrObject* pObject);
void WritePostponedDiagram();
void WritePostponedChart();
+ void WritePostponedOLE();
void WritePostponedVMLDrawing();
void WritePostponedDMLDrawing();
@@ -786,6 +788,15 @@ private:
std::list< PostponedDrawing >* m_postponedVMLDrawing;
std::list< PostponedDrawing >* m_postponedDMLDrawing;
+ struct PostponedOLE
+ {
+ PostponedOLE( SwOLENode* rObject, const Size rSize, const SwFlyFrmFmt* rFrame ) : object( rObject ), size( rSize ), frame( rFrame ) {};
+ SwOLENode* object;
+ const Size size;
+ const SwFlyFrmFmt* frame;
+ };
+ std::list< PostponedOLE >* m_postponedOLE;
+
const SwOLENode* m_postponedMath;
const SdrObject* m_postponedChart;
Size m_postponedChartSize;
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 321e01e6e5ec..41e70834de67 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -66,6 +66,7 @@
#include "ww8par.hxx"
#include "ww8scan.hxx"
#include <oox/token/properties.hxx>
+#include <comphelper/embeddedobjectcontainer.hxx>
#include <comphelper/string.hxx>
#include <rtl/ustrbuf.hxx>
#include <vcl/font.hxx>
@@ -357,6 +358,45 @@ OString DocxExport::OutputChart( uno::Reference< frame::XModel >& xModel, sal_In
return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
}
+OString DocxExport::WriteOLENode( const SwOLENode& rNode )
+{
+ uno::Reference <embed::XEmbeddedObject> xObj( const_cast<SwOLENode&>(rNode).GetOLEObj().GetOleRef() );
+ OUString sId, sMediaType;
+ comphelper::EmbeddedObjectContainer* aContainer = const_cast<SwOLENode&>(rNode).GetOLEObj().GetObject().GetContainer();
+ uno::Reference< io::XInputStream > xInStream = aContainer->GetObjectStream( xObj, &sMediaType );
+
+ OUString sFileName = "embeddings/Microsoft_Excel_Worksheet" + OUString::number( ++m_nOLEObjects ) + ".xlsx";
+ uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream( OUStringBuffer()
+ .appendAscii( "word/" )
+ .append( sFileName )
+ .makeStringAndClear(),
+ sMediaType );
+
+ if( lcl_CopyStream( xInStream, xOutStream ) )
+
+ sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(),
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
+ sFileName, false );
+
+ return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 );
+}
+
+// function copied from embeddedobj/source/msole/oleembed.cxx
+bool DocxExport::lcl_CopyStream( uno::Reference<io::XInputStream> xIn, uno::Reference<io::XOutputStream> xOut )
+{
+ const sal_Int32 nChunkSize = 4096;
+ uno::Sequence< sal_Int8 > aData(nChunkSize);
+ sal_Int32 nTotalRead = 0;
+ sal_Int32 nRead = 0;
+ do
+ {
+ nRead = xIn->readBytes(aData, nChunkSize);
+ nTotalRead += nRead;
+ xOut->writeBytes(aData);
+ } while (nRead == nChunkSize);
+ return nTotalRead != 0;
+}
+
void DocxExport::OutputDML(uno::Reference<drawing::XShape>& xShape)
{
uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY_THROW);
@@ -1319,6 +1359,7 @@ DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCur
m_pSections( NULL ),
m_nHeaders( 0 ),
m_nFooters( 0 ),
+ m_nOLEObjects( 0 ),
m_nHeadersFootersInSection(0),
m_pVMLExport( NULL ),
m_pSdrExport( NULL )
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index d058302d34a3..60779669fae0 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -29,6 +29,7 @@
#include <cstdio>
#include <vector>
#include <boost/optional.hpp>
+#include <ndole.hxx>
class DocxAttributeOutput;
class DocxExportFilter;
@@ -84,6 +85,9 @@ class DocxExport : public MSWordExportBase
/// Footer counter.
sal_Int32 m_nFooters;
+ /// OLE objects counter.
+ sal_Int32 m_nOLEObjects;
+
///Footer and Header counter in Section properties
sal_Int32 m_nHeadersFootersInSection;
@@ -159,6 +163,9 @@ public:
/// Returns the relationd id
OString OutputChart( com::sun::star::uno::Reference< com::sun::star::frame::XModel >& xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr m_pSerializer );
+ OString WriteOLENode( const SwOLENode& rNode );
+ bool lcl_CopyStream( css::uno::Reference< css::io::XInputStream> xIn, css::uno::Reference< css::io::XOutputStream > xOut );
+
/// Writes the shape using drawingML syntax.
void OutputDML( com::sun::star::uno::Reference< com::sun::star::drawing::XShape >& xShape );