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 <comphelper/storagehelper.hxx>
21 : #include <comphelper/processfactory.hxx>
22 : #include <com/sun/star/embed/EmbedStates.hpp>
23 : #include <com/sun/star/embed/EmbeddedObjectCreator.hpp>
24 : #include <com/sun/star/embed/OOoEmbeddedObjectFactory.hpp>
25 : #include <com/sun/star/embed/XLinkCreator.hpp>
26 : #include <com/sun/star/embed/XEmbeddedObject.hpp>
27 : #include <com/sun/star/embed/XVisualObject.hpp>
28 : #include <com/sun/star/embed/Aspects.hpp>
29 : #include <com/sun/star/task/XInteractionHandler.hpp>
30 : #include <rtl/ustrbuf.hxx>
31 : #include <comphelper/classids.hxx>
32 : #include <com/sun/star/lang/XUnoTunnel.hpp>
33 : #include <xmloff/prstylei.hxx>
34 : #include <xmloff/maptype.hxx>
35 : #include <xmloff/xmlprmap.hxx>
36 : #include <xmloff/txtprmap.hxx>
37 : #include <xmloff/i18nmap.hxx>
38 : #include "unocrsr.hxx"
39 : #include "TextCursorHelper.hxx"
40 : #include "unoframe.hxx"
41 : #include "doc.hxx"
42 : #include "unocoll.hxx"
43 : #include <fmtfsize.hxx>
44 : #include <fmtanchr.hxx>
45 : #include <fmtcntnt.hxx>
46 : #include "xmlimp.hxx"
47 : #include "xmltbli.hxx"
48 : #include "xmltexti.hxx"
49 : #include "XMLRedlineImportHelper.hxx"
50 : #include <xmloff/XMLFilterServiceNames.h>
51 : #include <SwAppletImpl.hxx>
52 : #include <ndole.hxx>
53 : #include <docsh.hxx>
54 : #include <sfx2/docfile.hxx>
55 : #include <switerator.hxx>
56 :
57 : // for locking SolarMutex: svapp + mutex
58 : #include <vcl/svapp.hxx>
59 : #include <osl/mutex.hxx>
60 :
61 : #include <toolkit/helper/vclunohelper.hxx>
62 : #include <svtools/embedhlp.hxx>
63 : #include <svl/urihelper.hxx>
64 :
65 : using namespace ::com::sun::star;
66 : using namespace ::com::sun::star::uno;
67 : using namespace ::com::sun::star::lang;
68 : using namespace ::com::sun::star::text;
69 : using namespace ::com::sun::star::frame;
70 : using namespace ::com::sun::star::beans;
71 : using namespace xml::sax;
72 :
73 : struct XMLServiceMapEntry_Impl
74 : {
75 : const sal_Char *sFilterService;
76 : sal_Int32 nFilterServiceLen;
77 :
78 : sal_uInt32 n1;
79 : sal_uInt16 n2, n3;
80 : sal_uInt8 n4, n5, n6, n7, n8, n9, n10, n11;
81 : };
82 :
83 : #define SERVICE_MAP_ENTRY( app, s ) \
84 : { XML_IMPORT_FILTER_##app, sizeof(XML_IMPORT_FILTER_##app)-1, \
85 : SO3_##s##_CLASSID }
86 :
87 : const XMLServiceMapEntry_Impl aServiceMap[] =
88 : {
89 : SERVICE_MAP_ENTRY( WRITER, SW ),
90 : SERVICE_MAP_ENTRY( CALC, SC ),
91 : SERVICE_MAP_ENTRY( DRAW, SDRAW ),
92 : SERVICE_MAP_ENTRY( IMPRESS, SIMPRESS ),
93 : SERVICE_MAP_ENTRY( CHART, SCH ),
94 : SERVICE_MAP_ENTRY( MATH, SM ),
95 : { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
96 : };
97 24 : static void lcl_putHeightAndWidth ( SfxItemSet &rItemSet,
98 : sal_Int32 nHeight, sal_Int32 nWidth,
99 : long *pTwipHeight=0, long *pTwipWidth=0 )
100 : {
101 24 : if( nWidth > 0 && nHeight > 0 )
102 : {
103 24 : nWidth = MM100_TO_TWIP( nWidth );
104 24 : if( nWidth < MINFLY )
105 0 : nWidth = MINFLY;
106 24 : nHeight = MM100_TO_TWIP( nHeight );
107 24 : if( nHeight < MINFLY )
108 0 : nHeight = MINFLY;
109 24 : rItemSet.Put( SwFmtFrmSize( ATT_FIX_SIZE, nWidth, nHeight ) );
110 : }
111 :
112 24 : SwFmtAnchor aAnchor( FLY_AT_CHAR );
113 24 : rItemSet.Put( aAnchor );
114 :
115 24 : if( pTwipWidth )
116 24 : *pTwipWidth = nWidth;
117 24 : if( pTwipHeight )
118 24 : *pTwipHeight = nHeight;
119 24 : }
120 :
121 19 : static void lcl_setObjectVisualArea( const uno::Reference< embed::XEmbeddedObject >& xObj,
122 : sal_Int64 nAspect,
123 : const Size& aVisSize,
124 : const MapUnit& aUnit )
125 : {
126 19 : if( xObj.is() && nAspect != embed::Aspects::MSOLE_ICON )
127 : {
128 : // convert the visual area to the objects units
129 19 : MapUnit aObjUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
130 19 : Size aObjVisSize = OutputDevice::LogicToLogic( aVisSize, aUnit, aObjUnit );
131 19 : awt::Size aSz;
132 19 : aSz.Width = aObjVisSize.Width();
133 19 : aSz.Height = aObjVisSize.Height();
134 :
135 : try
136 : {
137 19 : xObj->setVisualAreaSize( nAspect, aSz );
138 : }
139 0 : catch( uno::Exception& )
140 : {
141 : OSL_FAIL( "Couldn't set visual area of the object!\n" );
142 : }
143 : }
144 19 : }
145 :
146 493 : SwXMLTextImportHelper::SwXMLTextImportHelper(
147 : const uno::Reference < XModel>& rModel,
148 : SvXMLImport& rImport,
149 : const uno::Reference<XPropertySet> & rInfoSet,
150 : bool bInsertM, bool bStylesOnlyM, bool _bProgress,
151 : bool bBlockM, bool bOrganizerM,
152 : sal_Bool /*bPreserveRedlineMode*/ ) :
153 : XMLTextImportHelper( rModel, rImport, bInsertM, bStylesOnlyM, _bProgress,
154 : bBlockM, bOrganizerM ),
155 493 : pRedlineHelper( NULL )
156 : {
157 493 : uno::Reference<XPropertySet> xDocPropSet( rModel, UNO_QUERY );
158 : pRedlineHelper = new XMLRedlineImportHelper(
159 493 : bInsertM || bBlockM, xDocPropSet, rInfoSet );
160 493 : }
161 :
162 1479 : SwXMLTextImportHelper::~SwXMLTextImportHelper()
163 : {
164 : // the redline helper destructor sets properties on the document
165 : // and may through an exception while doing so... catch this
166 : try
167 : {
168 493 : delete pRedlineHelper;
169 : }
170 : catch ( const RuntimeException& )
171 : {
172 : // ignore
173 : }
174 986 : }
175 :
176 37 : SvXMLImportContext *SwXMLTextImportHelper::CreateTableChildContext(
177 : SvXMLImport& rImport,
178 : sal_uInt16 nPrefix, const OUString& rLocalName,
179 : const uno::Reference< XAttributeList > & xAttrList )
180 : {
181 : return new SwXMLTableContext(
182 37 : (SwXMLImport&)rImport, nPrefix, rLocalName, xAttrList );
183 : }
184 :
185 28 : bool SwXMLTextImportHelper::IsInHeaderFooter() const
186 : {
187 : uno::Reference<XUnoTunnel> xCrsrTunnel(
188 28 : ((SwXMLTextImportHelper *)this)->GetCursor(), UNO_QUERY );
189 : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
190 : OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
191 28 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
192 : OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
193 28 : SwDoc *pDoc = pTxtCrsr ? pTxtCrsr->GetDoc() : NULL;
194 :
195 28 : return pDoc && pDoc->IsInHeaderFooter( pTxtCrsr->GetPaM()->GetPoint()->nNode );
196 : }
197 :
198 24 : static SwOLENode *lcl_GetOLENode( const SwFrmFmt *pFrmFmt )
199 : {
200 24 : SwOLENode *pOLENd = 0;
201 24 : if( pFrmFmt )
202 : {
203 24 : const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
204 24 : const SwNodeIndex *pNdIdx = rCntnt.GetCntntIdx();
205 24 : pOLENd = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetOLENode();
206 : }
207 : OSL_ENSURE( pOLENd, "Where is the OLE node" );
208 24 : return pOLENd;
209 : }
210 :
211 24 : uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertOLEObject(
212 : SvXMLImport& rImport,
213 : const OUString& rHRef,
214 : const OUString& rStyleName,
215 : const OUString& rTblName,
216 : sal_Int32 nWidth, sal_Int32 nHeight )
217 : {
218 : // this method will modify the document directly -> lock SolarMutex
219 24 : SolarMutexGuard aGuard;
220 :
221 24 : uno::Reference < XPropertySet > xPropSet;
222 :
223 24 : sal_Int32 nPos = rHRef.indexOf( ':' );
224 24 : if( -1 == nPos )
225 0 : return xPropSet;
226 :
227 48 : OUString aObjName( rHRef.copy( nPos+1) );
228 :
229 24 : if( aObjName.isEmpty() )
230 0 : return xPropSet;
231 :
232 48 : uno::Reference<XUnoTunnel> xCrsrTunnel( GetCursor(), UNO_QUERY );
233 : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
234 : OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
235 24 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
236 : OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
237 24 : SwDoc *pDoc = SwImport::GetDocFromXMLImport( rImport );
238 :
239 24 : SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
240 48 : RES_FRMATR_END );
241 24 : Size aTwipSize( 0, 0 );
242 24 : Rectangle aVisArea( 0, 0, nWidth, nHeight );
243 : lcl_putHeightAndWidth( aItemSet, nHeight, nWidth,
244 24 : &aTwipSize.Height(), &aTwipSize.Width() );
245 :
246 24 : SwFrmFmt *pFrmFmt = 0;
247 24 : SwOLENode *pOLENd = 0;
248 24 : if( rHRef.copy( 0, nPos ) == "vnd.sun.star.ServiceName" )
249 : {
250 16 : bool bInsert = false;
251 16 : SvGlobalName aClassName;
252 16 : const XMLServiceMapEntry_Impl *pEntry = aServiceMap;
253 64 : while( pEntry->sFilterService )
254 : {
255 48 : if( aObjName.equalsAsciiL( pEntry->sFilterService,
256 48 : pEntry->nFilterServiceLen ) )
257 : {
258 32 : aClassName = SvGlobalName( pEntry->n1, pEntry->n2,
259 : pEntry->n3, pEntry->n4,
260 : pEntry->n5, pEntry->n6,
261 : pEntry->n7, pEntry->n8,
262 : pEntry->n9, pEntry->n10,
263 16 : pEntry->n11 );
264 16 : bInsert = true;
265 16 : break;
266 : }
267 32 : pEntry++;
268 : }
269 :
270 16 : if( bInsert )
271 : {
272 16 : uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
273 : try
274 : {
275 : // create object with desired ClassId
276 16 : sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
277 16 : OUString aName("DummyName");
278 32 : uno::Sequence < sal_Int8 > aClass( aClassName.GetByteSequence() );
279 32 : uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
280 : uno::Reference < embed::XEmbeddedObject > xObj =
281 16 : uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitNew(
282 : aClass, OUString(), xStorage, aName,
283 32 : uno::Sequence < beans::PropertyValue >() ), uno::UNO_QUERY );
284 16 : if ( xObj.is() )
285 : {
286 : //TODO/LATER: is it enough to only set the VisAreaSize?
287 16 : lcl_setObjectVisualArea( xObj, nAspect, aTwipSize, MAP_TWIP );
288 : }
289 :
290 16 : pFrmFmt = pDoc->Insert( *pTxtCrsr->GetPaM(),
291 : ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ),
292 : &aItemSet,
293 : NULL,
294 32 : NULL );
295 16 : pOLENd = lcl_GetOLENode( pFrmFmt );
296 16 : if( pOLENd )
297 32 : aObjName = pOLENd->GetOLEObj().GetCurrentPersistName();
298 : }
299 0 : catch ( uno::Exception& )
300 : {
301 16 : }
302 16 : }
303 : }
304 : else
305 : {
306 : // check whether an object with this name already exists in the document
307 8 : OUString aName;
308 16 : SwIterator<SwCntntNode,SwFmtColl> aIter( *pDoc->GetDfltGrfFmtColl() );
309 15 : for( SwCntntNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
310 : {
311 7 : SwOLENode* pExistingOLENd = pNd->GetOLENode();
312 7 : if( pExistingOLENd )
313 : {
314 6 : OUString aExistingName = pExistingOLENd->GetOLEObj().GetCurrentPersistName();
315 6 : if ( aExistingName.equals( aObjName ) )
316 : {
317 : OSL_FAIL( "The document contains duplicate object references, means it is partially broken, please let developers know how this document was generated!\n" );
318 :
319 0 : OUString aTmpName = pDoc->GetPersist()->GetEmbeddedObjectContainer().CreateUniqueObjectName();
320 : try
321 : {
322 0 : pDoc->GetPersist()->GetStorage()->copyElementTo( aObjName,
323 : pDoc->GetPersist()->GetStorage(),
324 0 : aTmpName );
325 0 : aName = aTmpName;
326 : }
327 0 : catch ( uno::Exception& )
328 : {
329 : OSL_FAIL( "Couldn't create a copy of the object!\n" );
330 : }
331 :
332 0 : break;
333 6 : }
334 : }
335 : }
336 :
337 8 : if ( aName.isEmpty() )
338 8 : aName = aObjName;
339 :
340 : // the correct aspect will be set later
341 : // TODO/LATER: Actually it should be set here
342 8 : if( pTxtCrsr )
343 : {
344 8 : pFrmFmt = pDoc->InsertOLE( *pTxtCrsr->GetPaM(), aName, embed::Aspects::MSOLE_CONTENT, &aItemSet, NULL, NULL );
345 8 : pOLENd = lcl_GetOLENode( pFrmFmt );
346 : }
347 16 : aObjName = aName;
348 : }
349 :
350 24 : if( !pFrmFmt )
351 0 : return xPropSet;
352 :
353 24 : if( IsInsertMode() )
354 : {
355 16 : if( !pOLENd )
356 0 : pOLENd = lcl_GetOLENode( pFrmFmt );
357 16 : if( pOLENd )
358 16 : pOLENd->SetOLESizeInvalid( sal_True );
359 : }
360 :
361 24 : SwXFrame *pXFrame = SwXFrames::GetObject( *pFrmFmt, FLYCNTTYPE_OLE );
362 24 : xPropSet = pXFrame;
363 24 : if( pDoc->GetDrawModel() )
364 : SwXFrame::GetOrCreateSdrObject(
365 24 : static_cast<SwFlyFrmFmt*>( pXFrame->GetFrmFmt() ) ); // req for z-order
366 24 : if( !rTblName.isEmpty() )
367 : {
368 0 : const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
369 0 : const SwNodeIndex *pNdIdx = rCntnt.GetCntntIdx();
370 0 : SwOLENode *pOLENode = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetOLENode();
371 : OSL_ENSURE( pOLENode, "Where is the OLE node" );
372 :
373 0 : OUStringBuffer aBuffer( rTblName.getLength() );
374 0 : bool bQuoted = false;
375 0 : bool bEscape = false;
376 0 : bool bError = false;
377 0 : for( sal_Int32 i=0; i < rTblName.getLength(); i++ )
378 : {
379 0 : bool bEndOfNameFound = false;
380 0 : sal_Unicode c = rTblName[i];
381 0 : switch( c )
382 : {
383 : case '\'':
384 0 : if( bEscape )
385 : {
386 0 : aBuffer.append( c );
387 0 : bEscape = false;
388 : }
389 0 : else if( bQuoted )
390 : {
391 0 : bEndOfNameFound = true;
392 : }
393 0 : else if( 0 == i )
394 : {
395 0 : bQuoted = true;
396 : }
397 : else
398 : {
399 0 : bError = true;
400 : }
401 0 : break;
402 : case '\\':
403 0 : if( bEscape )
404 : {
405 0 : aBuffer.append( c );
406 0 : bEscape = false;
407 : }
408 : else
409 : {
410 0 : bEscape = true;
411 : }
412 0 : break;
413 : case ' ':
414 : case '.':
415 0 : if( !bQuoted )
416 : {
417 0 : bEndOfNameFound = true;
418 : }
419 : else
420 : {
421 0 : aBuffer.append( c );
422 0 : bEscape = false;
423 : }
424 0 : break;
425 : default:
426 : {
427 0 : aBuffer.append( c );
428 0 : bEscape = false;
429 : }
430 0 : break;
431 : }
432 0 : if( bError || bEndOfNameFound )
433 : break;
434 : }
435 0 : if( !bError )
436 : {
437 0 : OUString sTblName( aBuffer.makeStringAndClear() );
438 0 : pOLENode->SetChartTblName( GetRenameMap().Get( XML_TEXT_RENAME_TYPE_TABLE, sTblName ) );
439 0 : }
440 : }
441 :
442 24 : sal_Int64 nDrawAspect = 0;
443 24 : const XMLPropStyleContext *pStyle = 0;
444 24 : bool bHasSizeProps = false;
445 24 : if( !rStyleName.isEmpty() )
446 : {
447 24 : pStyle = FindAutoFrameStyle( rStyleName );
448 24 : if( pStyle )
449 : {
450 : UniReference < SvXMLImportPropertyMapper > xImpPrMap =
451 24 : pStyle->GetStyles()
452 24 : ->GetImportPropertyMapper(pStyle->GetFamily());
453 : OSL_ENSURE( xImpPrMap.is(), "Where is the import prop mapper?" );
454 24 : if( xImpPrMap.is() )
455 : {
456 : UniReference<XMLPropertySetMapper> rPropMapper =
457 24 : xImpPrMap->getPropertySetMapper();
458 :
459 24 : sal_Int32 nCount = pStyle->GetProperties().size();
460 231 : for( sal_Int32 i=0; i < nCount; i++ )
461 : {
462 207 : const XMLPropertyState& rProp = pStyle->GetProperties()[i];
463 207 : sal_Int32 nIdx = rProp.mnIndex;
464 207 : if( -1 == nIdx )
465 31 : continue;
466 :
467 176 : switch( rPropMapper->GetEntryContextId(nIdx) )
468 : {
469 : case CTF_OLE_VIS_AREA_LEFT:
470 : {
471 0 : sal_Int32 nVal = 0;
472 0 : rProp.maValue >>= nVal;
473 0 : aVisArea.setX( nVal );
474 : }
475 0 : break;
476 : case CTF_OLE_VIS_AREA_TOP:
477 : {
478 3 : sal_Int32 nVal = 0;
479 3 : rProp.maValue >>= nVal;
480 3 : aVisArea.setY( nVal );
481 : }
482 3 : break;
483 : case CTF_OLE_VIS_AREA_WIDTH:
484 : {
485 3 : sal_Int32 nVal = 0;
486 3 : rProp.maValue >>= nVal;
487 3 : aVisArea.setWidth( nVal );
488 3 : bHasSizeProps = true;
489 : }
490 3 : break;
491 : case CTF_OLE_VIS_AREA_HEIGHT:
492 : {
493 3 : sal_Int32 nVal = 0;
494 3 : rProp.maValue >>= nVal;
495 3 : aVisArea.setHeight( nVal );
496 3 : bHasSizeProps = true;
497 : }
498 3 : break;
499 : case CTF_OLE_DRAW_ASPECT:
500 : {
501 24 : rProp.maValue >>= nDrawAspect;
502 :
503 24 : if ( !nDrawAspect )
504 0 : nDrawAspect = embed::Aspects::MSOLE_CONTENT;
505 :
506 24 : if ( pOLENd )
507 24 : pOLENd->GetOLEObj().GetObject().SetViewAspect( nDrawAspect );
508 : }
509 24 : break;
510 : }
511 24 : }
512 24 : }
513 : }
514 : }
515 :
516 24 : if ( bHasSizeProps )
517 : {
518 : uno::Reference < embed::XEmbeddedObject > xObj =
519 3 : pDoc->GetPersist()->GetEmbeddedObjectContainer().GetEmbeddedObject( aObjName );
520 3 : if( xObj.is() )
521 : lcl_setObjectVisualArea( xObj, ( nDrawAspect ? nDrawAspect : embed::Aspects::MSOLE_CONTENT ),
522 3 : aVisArea.GetSize(), MAP_100TH_MM );
523 : }
524 :
525 48 : return xPropSet;
526 : }
527 :
528 0 : uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertOOoLink(
529 : SvXMLImport& rImport,
530 : const OUString& rHRef,
531 : const OUString& /*rStyleName*/,
532 : const OUString& /*rTblName*/,
533 : sal_Int32 nWidth, sal_Int32 nHeight )
534 : {
535 : // this method will modify the document directly -> lock SolarMutex
536 0 : SolarMutexGuard aGuard;
537 :
538 0 : uno::Reference < XPropertySet > xPropSet;
539 :
540 0 : uno::Reference<XUnoTunnel> xCrsrTunnel( GetCursor(), UNO_QUERY );
541 : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
542 : OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
543 0 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
544 : OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
545 0 : SwDoc *pDoc = SwImport::GetDocFromXMLImport( rImport );
546 :
547 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
548 0 : RES_FRMATR_END );
549 0 : Size aTwipSize( 0, 0 );
550 : lcl_putHeightAndWidth( aItemSet, nHeight, nWidth,
551 0 : &aTwipSize.Height(), &aTwipSize.Width() );
552 :
553 : // We'll need a (valid) URL. If we don't have do not insert the link and return early.
554 : // Copy URL into URL oject on the way.
555 0 : INetURLObject aURLObj;
556 0 : bool bValidURL = !rHRef.isEmpty() &&
557 : aURLObj.SetURL( URIHelper::SmartRel2Abs(
558 0 : INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) );
559 0 : if( !bValidURL )
560 0 : return xPropSet;
561 :
562 0 : uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
563 : try
564 : {
565 : // create object with desired ClassId
566 0 : OUString aName("DummyName");
567 : uno::Reference < embed::XEmbeddedObjectCreator > xFactory =
568 0 : embed::OOoEmbeddedObjectFactory::create(::comphelper::getProcessComponentContext());
569 :
570 0 : uno::Sequence< beans::PropertyValue > aMediaDescriptor( 1 );
571 0 : aMediaDescriptor[0].Name = "URL";
572 0 : aMediaDescriptor[0].Value <<= OUString( aURLObj.GetMainURL( INetURLObject::NO_DECODE ) );
573 0 : if ( pDoc->GetDocShell() && pDoc->GetDocShell()->GetMedium() )
574 : {
575 : uno::Reference< task::XInteractionHandler > xInteraction =
576 0 : pDoc->GetDocShell()->GetMedium()->GetInteractionHandler();
577 0 : if ( xInteraction.is() )
578 : {
579 0 : aMediaDescriptor.realloc( 2 );
580 0 : aMediaDescriptor[1].Name = "InteractionHandler";
581 0 : aMediaDescriptor[1].Value <<= xInteraction;
582 0 : }
583 : }
584 :
585 : uno::Reference < embed::XEmbeddedObject > xObj(
586 0 : xFactory->createInstanceLink(
587 0 : xStorage, aName, aMediaDescriptor, uno::Sequence< beans::PropertyValue >() ),
588 0 : uno::UNO_QUERY_THROW );
589 :
590 : {
591 0 : SwFrmFmt *pFrmFmt = pDoc->Insert( *pTxtCrsr->GetPaM(),
592 : ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ),
593 : &aItemSet,
594 : NULL,
595 0 : NULL );
596 :
597 : // TODO/LATER: in future may need a way to set replacement image url to the link ( may be even to the object ), needs oasis cws???
598 :
599 0 : SwXFrame *pXFrame = SwXFrames::GetObject( *pFrmFmt, FLYCNTTYPE_OLE );
600 0 : xPropSet = pXFrame;
601 0 : if( pDoc->GetDrawModel() )
602 : SwXFrame::GetOrCreateSdrObject(
603 0 : static_cast<SwFlyFrmFmt*>( pXFrame->GetFrmFmt() ) ); // req for z-order
604 0 : }
605 : }
606 0 : catch ( uno::Exception& )
607 : {
608 : }
609 :
610 : // TODO/LATER: should the rStyleName and rTblName be handled as for usual embedded object?
611 :
612 0 : return xPropSet;
613 : }
614 :
615 0 : uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertApplet(
616 : const OUString &rName,
617 : const OUString &rCode,
618 : bool bMayScript,
619 : const OUString& rHRef,
620 : sal_Int32 nWidth, sal_Int32 nHeight )
621 : {
622 : // this method will modify the document directly -> lock SolarMutex
623 0 : SolarMutexGuard aGuard;
624 :
625 0 : uno::Reference < XPropertySet > xPropSet;
626 0 : uno::Reference<XUnoTunnel> xCrsrTunnel( GetCursor(), UNO_QUERY );
627 : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
628 : OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
629 0 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
630 : OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
631 0 : SwDoc *pDoc = pTxtCrsr->GetDoc();
632 :
633 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
634 0 : RES_FRMATR_END );
635 0 : lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
636 :
637 0 : SwApplet_Impl aAppletImpl ( aItemSet );
638 :
639 0 : OUString sCodeBase;
640 0 : if( !rHRef.isEmpty() )
641 0 : sCodeBase = GetXMLImport().GetAbsoluteReference( rHRef );
642 :
643 0 : aAppletImpl.CreateApplet ( rCode, rName, bMayScript, sCodeBase, GetXMLImport().GetDocumentBase() );
644 :
645 : // set the size of the applet
646 : lcl_setObjectVisualArea( aAppletImpl.GetApplet(),
647 : embed::Aspects::MSOLE_CONTENT,
648 : Size( nWidth, nHeight ),
649 0 : MAP_100TH_MM );
650 :
651 0 : SwFrmFmt *pFrmFmt = pDoc->Insert( *pTxtCrsr->GetPaM(),
652 : ::svt::EmbeddedObjectRef( aAppletImpl.GetApplet(), embed::Aspects::MSOLE_CONTENT ),
653 0 : &aAppletImpl.GetItemSet(),
654 : NULL,
655 0 : NULL);
656 0 : SwXFrame *pXFrame = SwXFrames::GetObject( *pFrmFmt, FLYCNTTYPE_OLE );
657 0 : xPropSet = pXFrame;
658 0 : if( pDoc->GetDrawModel() )
659 : SwXFrame::GetOrCreateSdrObject(
660 0 : static_cast<SwFlyFrmFmt*>( pXFrame->GetFrmFmt() ) ); // req for z-order
661 :
662 0 : return xPropSet;
663 : }
664 :
665 0 : uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertPlugin(
666 : const OUString &rMimeType,
667 : const OUString& rHRef,
668 : sal_Int32 nWidth, sal_Int32 nHeight )
669 : {
670 0 : uno::Reference < XPropertySet > xPropSet;
671 0 : uno::Reference<XUnoTunnel> xCrsrTunnel( GetCursor(), UNO_QUERY );
672 : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
673 : OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
674 0 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
675 : OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
676 0 : SwDoc *pDoc = pTxtCrsr->GetDoc();
677 :
678 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
679 0 : RES_FRMATR_END );
680 0 : lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
681 :
682 : // We'll need a (valid) URL, or we need a MIME type. If we don't have
683 : // either, do not insert plugin and return early. Copy URL into URL oject
684 : // on the way.
685 0 : INetURLObject aURLObj;
686 :
687 0 : bool bValidURL = !rHRef.isEmpty() &&
688 0 : aURLObj.SetURL( URIHelper::SmartRel2Abs( INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) );
689 0 : bool bValidMimeType = !rMimeType.isEmpty();
690 0 : if( !bValidURL && !bValidMimeType )
691 0 : return xPropSet;
692 :
693 0 : uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
694 : try
695 : {
696 : // create object with desired ClassId
697 0 : OUString aName("DummyName");
698 0 : uno::Sequence < sal_Int8 > aClass( SvGlobalName( SO3_PLUGIN_CLASSID ).GetByteSequence() );
699 0 : uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
700 : uno::Reference < embed::XEmbeddedObject > xObj =
701 0 : uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitNew(
702 : aClass, OUString(), xStorage, aName,
703 0 : uno::Sequence < beans::PropertyValue >() ), uno::UNO_QUERY );
704 :
705 : // set size to the object
706 : lcl_setObjectVisualArea( xObj,
707 : embed::Aspects::MSOLE_CONTENT,
708 : Size( nWidth, nHeight ),
709 0 : MAP_100TH_MM );
710 :
711 0 : if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
712 : {
713 0 : uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
714 0 : if ( xSet.is() )
715 : {
716 0 : if( bValidURL )
717 0 : xSet->setPropertyValue("PluginURL",
718 0 : makeAny( OUString( aURLObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) );
719 0 : if( bValidMimeType )
720 0 : xSet->setPropertyValue("PluginMimeType",
721 0 : makeAny( OUString( rMimeType ) ) );
722 : }
723 :
724 0 : SwFrmFmt *pFrmFmt = pDoc->Insert( *pTxtCrsr->GetPaM(),
725 : ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ),
726 : &aItemSet,
727 : NULL,
728 0 : NULL);
729 0 : SwXFrame *pXFrame = SwXFrames::GetObject( *pFrmFmt, FLYCNTTYPE_OLE );
730 0 : xPropSet = pXFrame;
731 0 : if( pDoc->GetDrawModel() )
732 : SwXFrame::GetOrCreateSdrObject(
733 0 : static_cast<SwFlyFrmFmt*>( pXFrame->GetFrmFmt() ) ); // req for z-order
734 0 : }
735 : }
736 0 : catch ( uno::Exception& )
737 : {
738 : }
739 :
740 0 : return xPropSet;
741 : }
742 0 : uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertFloatingFrame(
743 : const OUString& rName,
744 : const OUString& rHRef,
745 : const OUString& rStyleName,
746 : sal_Int32 nWidth, sal_Int32 nHeight )
747 : {
748 : // this method will modify the document directly -> lock SolarMutex
749 0 : SolarMutexGuard aGuard;
750 :
751 0 : uno::Reference < XPropertySet > xPropSet;
752 0 : uno::Reference<XUnoTunnel> xCrsrTunnel( GetCursor(), UNO_QUERY );
753 : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
754 : OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
755 0 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
756 : OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
757 0 : SwDoc *pDoc = pTxtCrsr->GetDoc();
758 :
759 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN,
760 0 : RES_FRMATR_END );
761 0 : lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
762 :
763 0 : ScrollingMode eScrollMode = ScrollingAuto;
764 0 : sal_Bool bHasBorder = sal_False;
765 0 : bool bIsBorderSet = false;
766 0 : Size aMargin( SIZE_NOT_SET, SIZE_NOT_SET );
767 0 : const XMLPropStyleContext *pStyle = 0;
768 0 : if( !rStyleName.isEmpty() )
769 : {
770 0 : pStyle = FindAutoFrameStyle( rStyleName );
771 0 : if( pStyle )
772 : {
773 : UniReference < SvXMLImportPropertyMapper > xImpPrMap =
774 0 : pStyle->GetStyles()
775 0 : ->GetImportPropertyMapper(pStyle->GetFamily());
776 : OSL_ENSURE( xImpPrMap.is(), "Where is the import prop mapper?" );
777 0 : if( xImpPrMap.is() )
778 : {
779 : UniReference<XMLPropertySetMapper> rPropMapper =
780 0 : xImpPrMap->getPropertySetMapper();
781 :
782 0 : sal_Int32 nCount = pStyle->GetProperties().size();
783 0 : for( sal_Int32 i=0; i < nCount; i++ )
784 : {
785 0 : const XMLPropertyState& rProp = pStyle->GetProperties()[i];
786 0 : sal_Int32 nIdx = rProp.mnIndex;
787 0 : if( -1 == nIdx )
788 0 : continue;
789 :
790 0 : switch( rPropMapper->GetEntryContextId(nIdx) )
791 : {
792 : case CTF_FRAME_DISPLAY_SCROLLBAR:
793 : {
794 0 : sal_Bool bYes = *(sal_Bool *)rProp.maValue.getValue();
795 0 : eScrollMode = bYes ? ScrollingYes : ScrollingNo;
796 : }
797 0 : break;
798 : case CTF_FRAME_DISPLAY_BORDER:
799 : {
800 0 : bHasBorder = *(sal_Bool *)rProp.maValue.getValue();
801 0 : bIsBorderSet = true;
802 : }
803 0 : break;
804 : case CTF_FRAME_MARGIN_HORI:
805 : {
806 0 : sal_Int32 nVal = SIZE_NOT_SET;
807 0 : rProp.maValue >>= nVal;
808 0 : aMargin.Width() = nVal;
809 : }
810 0 : break;
811 : case CTF_FRAME_MARGIN_VERT:
812 : {
813 0 : sal_Int32 nVal = SIZE_NOT_SET;
814 0 : rProp.maValue >>= nVal;
815 0 : aMargin.Height() = nVal;
816 : }
817 0 : break;
818 : }
819 0 : }
820 0 : }
821 : }
822 : }
823 :
824 0 : uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
825 : try
826 : {
827 : // create object with desired ClassId
828 0 : OUString aName("DummyName");
829 0 : uno::Sequence < sal_Int8 > aClass( SvGlobalName( SO3_IFRAME_CLASSID ).GetByteSequence() );
830 0 : uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
831 : uno::Reference < embed::XEmbeddedObject > xObj =
832 0 : uno::Reference < embed::XEmbeddedObject >( xFactory->createInstanceInitNew(
833 : aClass, OUString(), xStorage, aName,
834 0 : uno::Sequence < beans::PropertyValue >() ), uno::UNO_QUERY );
835 :
836 : // set size to the object
837 : lcl_setObjectVisualArea( xObj,
838 : embed::Aspects::MSOLE_CONTENT,
839 : Size( nWidth, nHeight ),
840 0 : MAP_100TH_MM );
841 :
842 0 : if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
843 : {
844 0 : uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
845 0 : if ( xSet.is() )
846 : {
847 0 : xSet->setPropertyValue("FrameURL",
848 : makeAny( OUString( URIHelper::SmartRel2Abs(
849 0 : INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) ) ) );
850 :
851 0 : xSet->setPropertyValue("FrameName",
852 0 : makeAny( OUString( rName ) ) );
853 :
854 0 : if ( eScrollMode == ScrollingAuto )
855 0 : xSet->setPropertyValue("FrameIsAutoScroll",
856 0 : makeAny( sal_True ) );
857 : else
858 0 : xSet->setPropertyValue("FrameIsScrollingMode",
859 0 : makeAny( (sal_Bool) (eScrollMode == ScrollingYes) ) );
860 :
861 0 : if ( bIsBorderSet )
862 0 : xSet->setPropertyValue("FrameIsBorder",
863 0 : makeAny( bHasBorder ) );
864 : else
865 0 : xSet->setPropertyValue("FrameIsAutoBorder",
866 0 : makeAny( sal_True ) );
867 :
868 0 : xSet->setPropertyValue("FrameMarginWidth",
869 0 : makeAny( sal_Int32( aMargin.Width() ) ) );
870 :
871 0 : xSet->setPropertyValue("FrameMarginHeight",
872 0 : makeAny( sal_Int32( aMargin.Height() ) ) );
873 : }
874 :
875 0 : SwFrmFmt *pFrmFmt = pDoc->Insert( *pTxtCrsr->GetPaM(),
876 : ::svt::EmbeddedObjectRef( xObj, embed::Aspects::MSOLE_CONTENT ),
877 : &aItemSet,
878 : NULL,
879 0 : NULL);
880 0 : SwXFrame *pXFrame = SwXFrames::GetObject( *pFrmFmt, FLYCNTTYPE_OLE );
881 0 : xPropSet = pXFrame;
882 0 : if( pDoc->GetDrawModel() )
883 : SwXFrame::GetOrCreateSdrObject(
884 0 : static_cast<SwFlyFrmFmt*>( pXFrame->GetFrmFmt() ) ); // req for z-order
885 0 : }
886 : }
887 0 : catch ( uno::Exception& )
888 : {
889 : }
890 :
891 0 : return xPropSet;
892 : }
893 :
894 0 : void SwXMLTextImportHelper::endAppletOrPlugin(
895 : const uno::Reference < XPropertySet > &rPropSet,
896 : ::std::map < const OUString, OUString > &rParamMap)
897 : {
898 : // this method will modify the document directly -> lock SolarMutex
899 0 : SolarMutexGuard aGuard;
900 :
901 0 : uno::Reference<XUnoTunnel> xCrsrTunnel( rPropSet, UNO_QUERY );
902 : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for embedded" );
903 : SwXFrame *pFrame = reinterpret_cast< SwXFrame * >(
904 0 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( SwXFrame::getUnoTunnelId() )));
905 : OSL_ENSURE( pFrame, "SwXFrame missing" );
906 0 : SwFrmFmt *pFrmFmt = pFrame->GetFrmFmt();
907 0 : const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
908 0 : const SwNodeIndex *pNdIdx = rCntnt.GetCntntIdx();
909 0 : SwOLENode *pOLENd = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetNoTxtNode()->GetOLENode();
910 0 : SwOLEObj& rOLEObj = pOLENd->GetOLEObj();
911 :
912 0 : uno::Reference < embed::XEmbeddedObject > xEmbObj( rOLEObj.GetOleRef() );
913 0 : if ( svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) )
914 : {
915 0 : uno::Reference < beans::XPropertySet > xSet( xEmbObj->getComponent(), uno::UNO_QUERY );
916 0 : if ( xSet.is() )
917 : {
918 0 : const sal_Int32 nCount = rParamMap.size();
919 0 : uno::Sequence< beans::PropertyValue > aCommandSequence( nCount );
920 :
921 0 : ::std::map < const OUString, OUString > ::iterator aIter = rParamMap.begin();
922 0 : ::std::map < const OUString, OUString > ::iterator aEnd = rParamMap.end();
923 0 : sal_Int32 nIndex=0;
924 0 : while (aIter != aEnd )
925 : {
926 0 : aCommandSequence[nIndex].Name = (*aIter).first;
927 0 : aCommandSequence[nIndex].Handle = -1;
928 0 : aCommandSequence[nIndex].Value = makeAny( OUString((*aIter).second) );
929 0 : aCommandSequence[nIndex].State = beans::PropertyState_DIRECT_VALUE;
930 0 : ++aIter, ++nIndex;
931 : }
932 :
933 : // unfortunately the names of the properties are depending on the object
934 0 : OUString aParaName("AppletCommands");
935 : try
936 : {
937 0 : xSet->setPropertyValue( aParaName, makeAny( aCommandSequence ) );
938 : }
939 0 : catch ( uno::Exception& )
940 : {
941 0 : aParaName = "PluginCommands";
942 : try
943 : {
944 0 : xSet->setPropertyValue( aParaName, makeAny( aCommandSequence ) );
945 : }
946 0 : catch ( uno::Exception& )
947 : {
948 : }
949 0 : }
950 0 : }
951 0 : }
952 0 : }
953 :
954 : // redlining helper methods
955 : // (override to provide the real implementation)
956 3 : void SwXMLTextImportHelper::RedlineAdd(
957 : const OUString& rType,
958 : const OUString& rId,
959 : const OUString& rAuthor,
960 : const OUString& rComment,
961 : const util::DateTime& rDateTime,
962 : bool bMergeLastPara)
963 : {
964 : // create redline helper on demand
965 : OSL_ENSURE(NULL != pRedlineHelper, "helper should have been created in constructor");
966 3 : if (NULL != pRedlineHelper)
967 : pRedlineHelper->Add(rType, rId, rAuthor, rComment, rDateTime,
968 3 : bMergeLastPara);
969 3 : }
970 :
971 1 : uno::Reference<XTextCursor> SwXMLTextImportHelper::RedlineCreateText(
972 : uno::Reference<XTextCursor> & rOldCursor,
973 : const OUString& rId)
974 : {
975 1 : uno::Reference<XTextCursor> xRet;
976 :
977 1 : if (NULL != pRedlineHelper)
978 : {
979 1 : xRet = pRedlineHelper->CreateRedlineTextSection(rOldCursor, rId);
980 : }
981 :
982 1 : return xRet;
983 : }
984 :
985 6 : void SwXMLTextImportHelper::RedlineSetCursor(
986 : const OUString& rId,
987 : bool bStart,
988 : bool bIsOutsideOfParagraph)
989 : {
990 6 : if (NULL != pRedlineHelper) {
991 6 : uno::Reference<XTextRange> xTextRange( GetCursor()->getStart() );
992 : pRedlineHelper->SetCursor(rId, bStart, xTextRange,
993 6 : bIsOutsideOfParagraph);
994 : }
995 : // else: ignore redline (wasn't added before, else we'd have a helper)
996 6 : }
997 :
998 655 : void SwXMLTextImportHelper::RedlineAdjustStartNodeCursor(
999 : bool bStart)
1000 : {
1001 655 : OUString rId = GetOpenRedlineId();
1002 655 : if ((NULL != pRedlineHelper) && !rId.isEmpty())
1003 : {
1004 0 : uno::Reference<XTextRange> xTextRange( GetCursor()->getStart() );
1005 0 : pRedlineHelper->AdjustStartNodeCursor(rId, bStart, xTextRange );
1006 0 : ResetOpenRedlineId();
1007 655 : }
1008 : // else: ignore redline (wasn't added before, or no open redline ID
1009 655 : }
1010 :
1011 112 : void SwXMLTextImportHelper::SetShowChanges( bool bShowChanges )
1012 : {
1013 112 : if ( NULL != pRedlineHelper )
1014 112 : pRedlineHelper->SetShowChanges( bShowChanges );
1015 112 : }
1016 :
1017 2 : void SwXMLTextImportHelper::SetRecordChanges( bool bRecordChanges )
1018 : {
1019 2 : if ( NULL != pRedlineHelper )
1020 2 : pRedlineHelper->SetRecordChanges( bRecordChanges );
1021 2 : }
1022 :
1023 112 : void SwXMLTextImportHelper::SetChangesProtectionKey(
1024 : const Sequence<sal_Int8> & rKey )
1025 : {
1026 112 : if ( NULL != pRedlineHelper )
1027 112 : pRedlineHelper->SetProtectionKey( rKey );
1028 112 : }
1029 :
1030 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|