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