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