Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/awt/XControlModel.hpp>
21 : #include <com/sun/star/embed/XClassifiedObject.hpp>
22 : #include <com/sun/star/form/XFormsSupplier.hpp>
23 : #include <com/sun/star/script/ScriptEventDescriptor.hpp>
24 : #include <com/sun/star/script/XEventAttacherManager.hpp>
25 : #include <com/sun/star/beans/XPropertySet.hpp>
26 : #include <com/sun/star/form/XForm.hpp>
27 :
28 : #include <svx/svdpage.hxx>
29 : #include <editeng/outlobj.hxx>
30 : #include <svx/svdotext.hxx>
31 : #include <svx/svdobj.hxx>
32 : #include <svx/svdoole2.hxx>
33 : #include <svx/unoapi.hxx>
34 : #include <svx/fmglob.hxx>
35 : #include <vcl/outdev.hxx>
36 : #include <unotools/tempfile.hxx>
37 : #include <unotools/ucbstreamhelper.hxx>
38 : #include <svx/sdasitm.hxx>
39 : #include <sfx2/docfile.hxx>
40 :
41 : #include <sot/exchange.hxx>
42 : #include "xeescher.hxx"
43 :
44 : #include "global.hxx"
45 : #include "document.hxx"
46 : #include "drwlayer.hxx"
47 : #include "xecontent.hxx"
48 : #include <editeng/flditem.hxx>
49 : #include "userdat.hxx"
50 : #include "xcl97rec.hxx"
51 : #include "xehelper.hxx"
52 : #include "xechart.hxx"
53 : #include "xcl97esc.hxx"
54 : #include <unotools/streamwrap.hxx>
55 : #include <oox/ole/olehelper.hxx>
56 : #include <sfx2/objsh.hxx>
57 :
58 : using ::com::sun::star::uno::Any;
59 : using ::com::sun::star::uno::Exception;
60 : using ::com::sun::star::uno::Reference;
61 : using ::com::sun::star::uno::Sequence;
62 : using ::com::sun::star::uno::UNO_QUERY;
63 : using ::com::sun::star::uno::UNO_QUERY_THROW;
64 : using ::com::sun::star::container::XIndexAccess;
65 : using ::com::sun::star::embed::XClassifiedObject;
66 : using ::com::sun::star::drawing::XShape;
67 : using ::com::sun::star::awt::XControlModel;
68 : using ::com::sun::star::beans::XPropertySet;
69 : using ::com::sun::star::uno::Any;
70 : using ::com::sun::star::form::XForm;
71 : using ::com::sun::star::form::XFormComponent;
72 : using ::com::sun::star::form::XFormsSupplier;
73 : using ::com::sun::star::io::XOutputStream;
74 : using ::com::sun::star::script::ScriptEventDescriptor;
75 : using ::com::sun::star::script::XEventAttacherManager;
76 :
77 72 : XclEscherExGlobal::XclEscherExGlobal( const XclExpRoot& rRoot ) :
78 72 : XclExpRoot( rRoot )
79 : {
80 72 : SetBaseURI( GetMedium().GetBaseURL( true ) );
81 72 : }
82 :
83 21 : SvStream* XclEscherExGlobal::ImplQueryPictureStream()
84 : {
85 21 : mxPicTempFile.reset( new ::utl::TempFile );
86 21 : if( mxPicTempFile->IsValid() )
87 : {
88 21 : mxPicTempFile->EnableKillingFile();
89 21 : mxPicStrm.reset( ::utl::UcbStreamHelper::CreateStream( mxPicTempFile->GetURL(), STREAM_STD_READWRITE ) );
90 21 : mxPicStrm->SetEndian( SvStreamEndian::LITTLE );
91 : }
92 21 : return mxPicStrm.get();
93 : }
94 :
95 72 : XclEscherEx::XclEscherEx( const XclExpRoot& rRoot, XclExpObjectManager& rObjMgr, SvStream& rStrm, const XclEscherEx* pParent ) :
96 72 : EscherEx( pParent ? pParent->mxGlobal : EscherExGlobalRef( new XclEscherExGlobal( rRoot ) ), &rStrm ),
97 : XclExpRoot( rRoot ),
98 : mrObjMgr( rObjMgr ),
99 : pCurrXclObj( NULL ),
100 : pCurrAppData( NULL ),
101 72 : pTheClientData( new XclEscherClientData ),
102 : pAdditionalText( NULL ),
103 : nAdditionalText( 0 ),
104 : mnNextKey( 0 ),
105 216 : mbIsRootDff( pParent == 0 )
106 : {
107 72 : InsertPersistOffset( mnNextKey, 0 );
108 72 : }
109 :
110 216 : XclEscherEx::~XclEscherEx()
111 : {
112 : OSL_ENSURE( !aStack.empty(), "~XclEscherEx: stack not empty" );
113 72 : DeleteCurrAppData();
114 72 : delete pTheClientData;
115 144 : }
116 :
117 219 : sal_uInt32 XclEscherEx::InitNextDffFragment()
118 : {
119 : /* Current value of mnNextKey will be used by caller to refer to the
120 : starting point of the DFF fragment. The key exists already in the
121 : PersistTable (has been inserted by c'tor of previous call of
122 : InitNextDffFragment(), has been updated by UpdateDffFragmentEnd(). */
123 219 : sal_uInt32 nPersistKey = mnNextKey;
124 :
125 : /* Prepare the next key that is used by caller as end point of the DFF
126 : fragment. Will be updated by caller when writing to the DFF stream,
127 : using the UpdateDffFragmentEnd() function. This is needed to find DFF
128 : data written by the SVX base class implementation without interaction,
129 : e.g. the solver container that will be written after the last shape. */
130 219 : ++mnNextKey;
131 219 : InsertPersistOffset( mnNextKey, mpOutStrm->Tell() );
132 :
133 219 : return nPersistKey;
134 : }
135 :
136 280 : void XclEscherEx::UpdateDffFragmentEnd()
137 : {
138 : // update existing fragment key with new stream position
139 280 : ReplacePersistOffset( mnNextKey, mpOutStrm->Tell() );
140 280 : }
141 :
142 231 : sal_uInt32 XclEscherEx::GetDffFragmentPos( sal_uInt32 nFragmentKey )
143 : {
144 : /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
145 : is non-const due to tools/List usage. */
146 231 : return GetPersistOffset( nFragmentKey );
147 : }
148 :
149 51 : sal_uInt32 XclEscherEx::GetDffFragmentSize( sal_uInt32 nFragmentKey )
150 : {
151 : /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
152 : is non-const due to tools/List usage. */
153 51 : return GetDffFragmentPos( nFragmentKey + 1 ) - GetDffFragmentPos( nFragmentKey );
154 : }
155 :
156 129 : bool XclEscherEx::HasPendingDffData()
157 : {
158 : /* TODO: this function is non-const because PersistTable::PtGetOffsetByID()
159 : is non-const due to tools/List usage. */
160 129 : return GetDffFragmentPos( mnNextKey ) < GetStreamPos();
161 : }
162 :
163 26 : XclExpDffAnchorBase* XclEscherEx::CreateDffAnchor( const SdrObject& rSdrObj ) const
164 : {
165 : // the object manager creates the correct anchor type according to context
166 26 : XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor();
167 : // pass the drawing object, that will calculate the anchor position
168 26 : pAnchor->SetSdrObject( rSdrObj );
169 26 : return pAnchor;
170 : }
171 :
172 : namespace {
173 :
174 29 : bool lcl_IsFontwork( const SdrObject* pObj )
175 : {
176 29 : bool bIsFontwork = false;
177 29 : if( pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE )
178 : {
179 10 : const OUString aTextPath = "TextPath";
180 : const SdrCustomShapeGeometryItem& rGeometryItem = static_cast<const SdrCustomShapeGeometryItem&>(
181 10 : pObj->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
182 10 : if( const Any* pAny = rGeometryItem.GetPropertyValueByName( aTextPath, aTextPath ) )
183 0 : *pAny >>= bIsFontwork;
184 : }
185 29 : return bIsFontwork;
186 : }
187 :
188 : } // namespace
189 :
190 58 : EscherExHostAppData* XclEscherEx::StartShape( const Reference< XShape >& rxShape, const Rectangle* pChildAnchor )
191 : {
192 58 : if ( nAdditionalText )
193 0 : nAdditionalText++;
194 58 : bool bInGroup = ( pCurrXclObj != NULL );
195 58 : if ( bInGroup )
196 : { // stacked recursive group object
197 0 : if ( !pCurrAppData->IsStackedGroup() )
198 : { //! UpdateDffFragmentEnd only once
199 0 : pCurrAppData->SetStackedGroup( true );
200 0 : UpdateDffFragmentEnd();
201 : }
202 : }
203 58 : aStack.push( std::make_pair( pCurrXclObj, pCurrAppData ) );
204 58 : pCurrAppData = new XclEscherHostAppData;
205 58 : SdrObject* pObj = GetSdrObjectFromXShape( rxShape );
206 : //added for exporting OCX control
207 58 : sal_Int16 nMsCtlType = 0;
208 58 : if ( !pObj )
209 0 : pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() ); // just what is it?!?
210 : else
211 : {
212 58 : pCurrXclObj = NULL;
213 58 : sal_uInt16 nObjType = pObj->GetObjIdentifier();
214 :
215 58 : if( nObjType == OBJ_OLE2 )
216 : {
217 : // no OLE objects in embedded drawings (chart shapes)
218 26 : if( mbIsRootDff )
219 : {
220 : //! not-const because GetObjRef may load the OLE object
221 26 : Reference < XClassifiedObject > xObj( static_cast<SdrOle2Obj*>(pObj)->GetObjRef(), UNO_QUERY );
222 26 : if ( xObj.is() )
223 : {
224 26 : SvGlobalName aObjClsId( xObj->getClassID() );
225 26 : if ( SotExchange::IsChart( aObjClsId ) )
226 : { // yes, it's a chart diagram
227 26 : mrObjMgr.AddObj( new XclExpChartObj( mrObjMgr, rxShape, pChildAnchor ) );
228 26 : pCurrXclObj = NULL; // no metafile or whatsoever
229 : }
230 : else // metafile and OLE object
231 0 : pCurrXclObj = new XclObjOle( mrObjMgr, *pObj );
232 : }
233 : else // just a metafile
234 0 : pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() );
235 : }
236 : else
237 0 : pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() );
238 : }
239 32 : else if( nObjType == OBJ_UNO )
240 : {
241 : //added for exporting OCX control
242 0 : Reference< XPropertySet > xPropSet( rxShape, UNO_QUERY );
243 0 : Any aAny;
244 : try
245 : {
246 0 : aAny = xPropSet->getPropertyValue("ControlTypeinMSO");
247 0 : aAny >>= nMsCtlType;
248 : }
249 0 : catch(const Exception&)
250 : {
251 : OSL_TRACE("XclEscherEx::StartShape, this control can't get the property ControlTypeinMSO!");
252 : }
253 0 : if( nMsCtlType == 2 ) //OCX Form Control
254 0 : pCurrXclObj = CreateOCXCtrlObj( rxShape, pChildAnchor );
255 : else //TBX Form Control
256 0 : pCurrXclObj = CreateTBXCtrlObj( rxShape, pChildAnchor );
257 0 : if( !pCurrXclObj )
258 0 : pCurrXclObj = new XclObjAny( mrObjMgr, rxShape, GetDocPtr() ); // just a metafile
259 : }
260 32 : else if( !ScDrawLayer::IsNoteCaption( pObj ) )
261 : {
262 : // ignore permanent note shapes
263 : // #i12190# do not ignore callouts (do not filter by object type ID)
264 29 : pCurrXclObj = ShapeInteractionHelper::CreateShapeObj( mrObjMgr, rxShape, GetDocPtr() );
265 29 : ShapeInteractionHelper::PopulateShapeInteractionInfo( mrObjMgr, rxShape, *pCurrAppData );
266 : }
267 : }
268 58 : if ( pCurrXclObj )
269 : {
270 29 : if ( !mrObjMgr.AddObj( pCurrXclObj ) )
271 : { // maximum count reached, object got deleted
272 0 : pCurrXclObj = NULL;
273 : }
274 : else
275 : {
276 29 : pCurrAppData->SetClientData( pTheClientData );
277 29 : if ( nAdditionalText == 0 )
278 : {
279 29 : if ( pObj )
280 : {
281 29 : if ( !bInGroup )
282 : {
283 : /* Create a dummy anchor carrying the flags. Real
284 : coordinates are calculated later in virtual call of
285 : WriteData(EscherEx&,const Rectangle&). */
286 29 : XclExpDffAnchorBase* pAnchor = mrObjMgr.CreateDffAnchor();
287 29 : pAnchor->SetFlags( *pObj );
288 29 : pCurrAppData->SetClientAnchor( pAnchor );
289 : }
290 29 : const SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pObj );
291 29 : if( pTextObj && !lcl_IsFontwork( pTextObj ) && (pObj->GetObjIdentifier() != OBJ_CAPTION) )
292 : {
293 29 : const OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
294 29 : if( pParaObj )
295 : pCurrAppData->SetClientTextbox(
296 9 : new XclEscherClientTextbox( GetRoot(), *pTextObj, pCurrXclObj ) );
297 : }
298 : }
299 : else
300 : {
301 0 : if ( !bInGroup )
302 0 : pCurrAppData->SetClientAnchor( mrObjMgr.CreateDffAnchor() );
303 : }
304 : }
305 0 : else if ( nAdditionalText == 3 )
306 : {
307 0 : if ( pAdditionalText )
308 : {
309 0 : pAdditionalText->SetXclObj( pCurrXclObj );
310 0 : pCurrAppData->SetClientTextbox( pAdditionalText );
311 : }
312 : }
313 : }
314 : }
315 58 : if(pObj)
316 : {
317 : //add for exporting OCX control
318 : //for OCX control import from MS office file,we need keep the id value as MS office file.
319 : //GetOldRoot().pObjRecs->Add( pCurrXclObj ) statement has generated the id value as obj id rule;
320 : //but we trick it here.
321 58 : sal_uInt16 nObjType = pObj->GetObjIdentifier();
322 58 : if( nObjType == OBJ_UNO && pCurrXclObj )
323 : {
324 0 : Reference< XPropertySet > xPropSet( rxShape, UNO_QUERY );
325 0 : Any aAny;
326 : try
327 : {
328 0 : aAny = xPropSet->getPropertyValue("ObjIDinMSO");
329 : }
330 0 : catch(const Exception&)
331 : {
332 : OSL_TRACE("XclEscherEx::StartShape, this control can't get the property ObjIDinMSO!");
333 : }
334 0 : sal_uInt16 nObjIDinMSO = 0xFFFF;
335 0 : aAny >>= nObjIDinMSO;
336 0 : if( nObjIDinMSO != 0xFFFF && nMsCtlType == 2) //OCX
337 : {
338 0 : pCurrXclObj->SetId(nObjIDinMSO);
339 0 : }
340 : }
341 : }
342 58 : if ( !pCurrXclObj )
343 29 : pCurrAppData->SetDontWriteShape( true );
344 58 : return pCurrAppData;
345 : }
346 :
347 58 : void XclEscherEx::EndShape( sal_uInt16 nShapeType, sal_uInt32 nShapeID )
348 : {
349 : // own escher data created? -> never delete such objects
350 58 : bool bOwnEscher = pCurrXclObj && pCurrXclObj->IsOwnEscher();
351 :
352 : // post process the current object - not for objects with own escher data
353 58 : if( pCurrXclObj && !bOwnEscher )
354 : {
355 : // escher data of last shape not written? -> delete it from object list
356 29 : if( nShapeID == 0 )
357 : {
358 0 : XclObj* pLastObj = mrObjMgr.RemoveLastObj();
359 : OSL_ENSURE( pLastObj == pCurrXclObj, "XclEscherEx::EndShape - wrong object" );
360 0 : DELETEZ( pLastObj );
361 0 : pCurrXclObj = 0;
362 : }
363 :
364 29 : if( pCurrXclObj )
365 : {
366 : // set shape type
367 29 : if ( pCurrAppData->IsStackedGroup() )
368 0 : pCurrXclObj->SetEscherShapeTypeGroup();
369 : else
370 : {
371 29 : pCurrXclObj->SetEscherShapeType( nShapeType );
372 29 : UpdateDffFragmentEnd();
373 : }
374 : }
375 : }
376 :
377 : // get next object from stack
378 58 : DeleteCurrAppData();
379 58 : if (aStack.empty())
380 : {
381 0 : pCurrXclObj = NULL;
382 0 : pCurrAppData = NULL;
383 : }
384 : else
385 : {
386 58 : pCurrXclObj = aStack.top().first;
387 58 : pCurrAppData = aStack.top().second;
388 58 : aStack.pop();
389 : }
390 58 : if( nAdditionalText == 3 )
391 0 : nAdditionalText = 0;
392 58 : }
393 :
394 0 : EscherExHostAppData* XclEscherEx::EnterAdditionalTextGroup()
395 : {
396 0 : nAdditionalText = 1;
397 0 : pAdditionalText = static_cast<XclEscherClientTextbox*>( pCurrAppData->GetClientTextbox() );
398 0 : pCurrAppData->SetClientTextbox( NULL );
399 0 : return pCurrAppData;
400 : }
401 :
402 72 : void XclEscherEx::EndDocument()
403 : {
404 72 : if( mbIsRootDff )
405 72 : Flush( static_cast< XclEscherExGlobal& >( *mxGlobal ).GetPictureStream() );
406 :
407 : // seek back DFF stream to prepare saving the MSODRAWING[GROUP] records
408 72 : mpOutStrm->Seek( 0 );
409 72 : }
410 :
411 0 : XclExpOcxControlObj* XclEscherEx::CreateOCXCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor )
412 : {
413 0 : ::std::unique_ptr< XclExpOcxControlObj > xOcxCtrl;
414 :
415 0 : Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
416 0 : if( xCtrlModel.is() )
417 : {
418 : // output stream
419 0 : if( !mxCtlsStrm.Is() )
420 0 : mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
421 0 : if( mxCtlsStrm.Is() )
422 : {
423 0 : OUString aClassName;
424 0 : sal_uInt32 nStrmStart = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() );
425 :
426 : // writes from xCtrlModel into mxCtlsStrm, raw class name returned in aClassName
427 0 : Reference< XOutputStream > xOut( new utl::OSeekableOutputStreamWrapper( *mxCtlsStrm ) );
428 0 : Reference< com::sun::star::frame::XModel > xModel( GetDocShell() ? GetDocShell()->GetModel() : NULL );
429 0 : if( xModel.is() && xOut.is() && oox::ole::MSConvertOCXControls::WriteOCXExcelKludgeStream( xModel, xOut, xCtrlModel, xShape->getSize(), aClassName ) )
430 : {
431 0 : sal_uInt32 nStrmSize = static_cast< sal_uInt32 >( mxCtlsStrm->Tell() - nStrmStart );
432 : // adjust the class name to "Forms.***.1"
433 0 : aClassName = "Forms." + aClassName + ".1";
434 0 : xOcxCtrl.reset( new XclExpOcxControlObj( mrObjMgr, xShape, pChildAnchor, aClassName, nStrmStart, nStrmSize ) );
435 0 : }
436 : }
437 : }
438 0 : return xOcxCtrl.release();
439 : }
440 :
441 0 : XclExpTbxControlObj* XclEscherEx::CreateTBXCtrlObj( Reference< XShape > xShape, const Rectangle* pChildAnchor )
442 : {
443 0 : ::std::unique_ptr< XclExpTbxControlObj > xTbxCtrl( new XclExpTbxControlObj( mrObjMgr, xShape, pChildAnchor ) );
444 0 : if( xTbxCtrl->GetObjType() == EXC_OBJTYPE_UNKNOWN )
445 0 : xTbxCtrl.reset();
446 :
447 0 : if( xTbxCtrl.get() )
448 : {
449 : // find attached macro
450 0 : Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( xShape );
451 0 : ConvertTbxMacro( *xTbxCtrl, xCtrlModel );
452 : }
453 0 : return xTbxCtrl.release();
454 : }
455 :
456 0 : void XclEscherEx::ConvertTbxMacro( XclExpTbxControlObj& rTbxCtrlObj, Reference< XControlModel > xCtrlModel )
457 : {
458 0 : SdrPage* pSdrPage = GetSdrPage( GetCurrScTab() );
459 0 : if( xCtrlModel.is() && GetDocShell() && pSdrPage ) try
460 : {
461 0 : Reference< XFormsSupplier > xFormsSupplier( pSdrPage->getUnoPage(), UNO_QUERY_THROW );
462 0 : Reference< XIndexAccess > xFormsIA( xFormsSupplier->getForms(), UNO_QUERY_THROW );
463 :
464 : // 1) try to find the index of the processed control in the form
465 :
466 0 : Reference< XIndexAccess > xFormIA; // needed in step 2) below
467 0 : sal_Int32 nFoundIdx = -1;
468 :
469 : // search all existing forms in the draw page
470 0 : for( sal_Int32 nFormIdx = 0, nFormCount = xFormsIA->getCount();
471 0 : (nFoundIdx < 0) && (nFormIdx < nFormCount); ++nFormIdx )
472 : {
473 : // get the XIndexAccess interface of the form with index nFormIdx
474 0 : if( xFormIA.set( xFormsIA->getByIndex( nFormIdx ), UNO_QUERY ) )
475 : {
476 : // search all elements (controls) of the current form by index
477 0 : for( sal_Int32 nCtrlIdx = 0, nCtrlCount = xFormIA->getCount();
478 0 : (nFoundIdx < 0) && (nCtrlIdx < nCtrlCount); ++nCtrlIdx )
479 : {
480 : // compare implementation pointers of the control models
481 0 : Reference< XControlModel > xCurrModel( xFormIA->getByIndex( nCtrlIdx ), UNO_QUERY );
482 0 : if( xCtrlModel.get() == xCurrModel.get() )
483 0 : nFoundIdx = nCtrlIdx;
484 0 : }
485 : }
486 : }
487 :
488 : // 2) try to find an attached macro
489 :
490 0 : if( xFormIA.is() && (nFoundIdx >= 0) )
491 : {
492 0 : Reference< XEventAttacherManager > xEventMgr( xFormIA, UNO_QUERY_THROW );
493 : // loop over all events attached to the found control
494 0 : const Sequence< ScriptEventDescriptor > aEventSeq( xEventMgr->getScriptEvents( nFoundIdx ) );
495 0 : bool bFound = false;
496 0 : for( sal_Int32 nEventIdx = 0, nEventCount = aEventSeq.getLength();
497 0 : !bFound && (nEventIdx < nEventCount); ++nEventIdx )
498 : {
499 : // try to set the event data at the Excel control object, returns true on success
500 0 : bFound = rTbxCtrlObj.SetMacroLink( aEventSeq[ nEventIdx ] );
501 0 : }
502 0 : }
503 : }
504 0 : catch( Exception& )
505 : {
506 : }
507 0 : }
508 :
509 130 : void XclEscherEx::DeleteCurrAppData()
510 : {
511 130 : if ( pCurrAppData )
512 : {
513 58 : delete pCurrAppData->GetClientAnchor();
514 : // delete pCurrAppData->GetClientData();
515 58 : delete pCurrAppData->GetClientTextbox();
516 58 : delete pCurrAppData->GetInteractionInfo();
517 58 : delete pCurrAppData;
518 : }
519 130 : }
520 :
521 : // --- class XclEscherClientData -------------------------------------
522 :
523 29 : void XclEscherClientData::WriteData( EscherEx& rEx ) const
524 : { // actual data is in the following OBJ record
525 29 : rEx.AddAtom( 0, ESCHER_ClientData );
526 29 : }
527 :
528 : // --- class XclEscherClientTextbox -------------------------------------
529 :
530 9 : XclEscherClientTextbox::XclEscherClientTextbox( const XclExpRoot& rRoot,
531 : const SdrTextObj& rObj, XclObj* pObj )
532 : :
533 : XclExpRoot( rRoot ),
534 : rTextObj( rObj ),
535 9 : pXclObj( pObj )
536 : {
537 9 : }
538 :
539 9 : void XclEscherClientTextbox::WriteData( EscherEx& /*rEx*/ ) const
540 : {
541 9 : pXclObj->SetText( GetRoot(), rTextObj );
542 9 : }
543 :
544 : XclExpShapeObj*
545 29 : ShapeInteractionHelper::CreateShapeObj( XclExpObjectManager& rObjMgr, const Reference< XShape >& xShape, ScDocument* pDoc )
546 : {
547 29 : return new XclExpShapeObj( rObjMgr, xShape, pDoc );
548 : }
549 :
550 : void
551 29 : ShapeInteractionHelper::PopulateShapeInteractionInfo( XclExpObjectManager& rObjMgr, const Reference< XShape >& xShape, EscherExHostAppData& rHostAppData )
552 : {
553 : try
554 : {
555 29 : SvMemoryStream* pMemStrm = NULL;
556 29 : OUString sHyperLink;
557 58 : OUString sMacro;
558 29 : if ( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( ::GetSdrObjectFromXShape( xShape ) ) )
559 : {
560 3 : sHyperLink = pInfo->GetHlink();
561 3 : sMacro = pInfo->GetMacro();
562 : }
563 29 : if ( !sHyperLink.isEmpty() )
564 : {
565 3 : pMemStrm = new SvMemoryStream();
566 3 : XclExpStream tmpStream( *pMemStrm, rObjMgr.GetRoot() );
567 3 : ScAddress dummyAddress;
568 6 : SvxURLField aUrlField;
569 3 : aUrlField.SetURL( sHyperLink );
570 6 : XclExpHyperlink hExpHlink( rObjMgr.GetRoot(), aUrlField, dummyAddress );
571 6 : hExpHlink.WriteEmbeddedData( tmpStream );
572 : }
573 29 : if ( !sHyperLink.isEmpty() || !sMacro.isEmpty() )
574 32 : rHostAppData.SetInteractionInfo( new InteractionInfo( pMemStrm, true ) );
575 : }
576 0 : catch( Exception& )
577 : {
578 : }
579 59 : }
580 :
581 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|