sc: factor out some more code
[LibreOffice.git] / sw / source / filter / xml / xmltexti.cxx
blob93d698cac9eba91269c256c165bdf19924212e36
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <comphelper/storagehelper.hxx>
21 #include <comphelper/processfactory.hxx>
22 #include <comphelper/propertysequence.hxx>
23 #include <comphelper/propertyvalue.hxx>
24 #include <comphelper/servicehelper.hxx>
25 #include <com/sun/star/embed/EmbeddedObjectCreator.hpp>
26 #include <com/sun/star/embed/OOoEmbeddedObjectFactory.hpp>
27 #include <com/sun/star/embed/XEmbeddedObject.hpp>
28 #include <com/sun/star/embed/Aspects.hpp>
29 #include <com/sun/star/frame/XModel.hpp>
30 #include <com/sun/star/task/XInteractionHandler.hpp>
31 #include <o3tl/any.hxx>
32 #include <osl/diagnose.h>
33 #include <rtl/ustrbuf.hxx>
34 #include <sal/log.hxx>
35 #include <comphelper/classids.hxx>
36 #include <com/sun/star/lang/XUnoTunnel.hpp>
37 #include <xmloff/prstylei.hxx>
38 #include <xmloff/maptype.hxx>
39 #include <xmloff/xmlprmap.hxx>
40 #include <xmloff/txtprmap.hxx>
41 #include <xmloff/i18nmap.hxx>
42 #include <xmloff/xmlimppr.hxx>
43 #include <TextCursorHelper.hxx>
44 #include <unoframe.hxx>
45 #include <doc.hxx>
46 #include <IDocumentDrawModelAccess.hxx>
47 #include <IDocumentContentOperations.hxx>
48 #include <fmtfsize.hxx>
49 #include <fmtanchr.hxx>
50 #include <fmtcntnt.hxx>
51 #include "xmlimp.hxx"
52 #include "xmltbli.hxx"
53 #include "xmltexti.hxx"
54 #include "XMLRedlineImportHelper.hxx"
55 #include <xmloff/XMLFilterServiceNames.h>
56 #include <SwAppletImpl.hxx>
57 #include <ndole.hxx>
58 #include <docsh.hxx>
59 #include <sfx2/docfile.hxx>
60 #include <vcl/svapp.hxx>
61 #include <toolkit/helper/vclunohelper.hxx>
62 #include <svtools/embedhlp.hxx>
63 #include <svl/urihelper.hxx>
64 #include <sfx2/frmdescr.hxx>
65 #include <tools/globname.hxx>
67 #include <algorithm>
68 #include <utility>
70 using namespace ::com::sun::star;
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::lang;
73 using namespace ::com::sun::star::text;
74 using namespace ::com::sun::star::frame;
75 using namespace ::com::sun::star::beans;
76 using namespace xml::sax;
78 const std::pair<OUString, SvGUID> aServiceMap[] = {
79 { XML_IMPORT_FILTER_WRITER, { SO3_SW_CLASSID } },
80 { XML_IMPORT_FILTER_CALC, { SO3_SC_CLASSID } },
81 { XML_IMPORT_FILTER_DRAW, { SO3_SDRAW_CLASSID } },
82 { XML_IMPORT_FILTER_IMPRESS, { SO3_SIMPRESS_CLASSID } },
83 { XML_IMPORT_FILTER_CHART, { SO3_SCH_CLASSID } },
84 { XML_IMPORT_FILTER_MATH, { SO3_SM_CLASSID } },
86 static void lcl_putHeightAndWidth ( SfxItemSet &rItemSet,
87 sal_Int32 nHeight, sal_Int32 nWidth,
88 Size *pTwipSize = nullptr )
90 if( nWidth > 0 && nHeight > 0 )
92 nWidth = o3tl::toTwips(nWidth, o3tl::Length::mm100);
93 if( nWidth < MINFLY )
94 nWidth = MINFLY;
95 nHeight = o3tl::toTwips(nHeight, o3tl::Length::mm100);
96 if( nHeight < MINFLY )
97 nHeight = MINFLY;
98 rItemSet.Put( SwFormatFrameSize( SwFrameSize::Fixed, nWidth, nHeight ) );
101 SwFormatAnchor aAnchor( RndStdIds::FLY_AT_CHAR );
102 rItemSet.Put( aAnchor );
104 if( pTwipSize )
106 pTwipSize->setWidth( nWidth );
107 pTwipSize->setHeight( nHeight);
111 static void lcl_setObjectVisualArea( const uno::Reference< embed::XEmbeddedObject >& xObj,
112 sal_Int64 nAspect,
113 const Size& aVisSize,
114 const MapUnit& aUnit )
116 if( !(xObj.is() && nAspect != embed::Aspects::MSOLE_ICON) )
117 return;
119 // convert the visual area to the objects units
120 MapUnit aObjUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
121 Size aObjVisSize = OutputDevice::LogicToLogic(aVisSize, MapMode(aUnit), MapMode(aObjUnit));
122 awt::Size aSz;
123 aSz.Width = aObjVisSize.Width();
124 aSz.Height = aObjVisSize.Height();
128 xObj->setVisualAreaSize( nAspect, aSz );
130 catch( uno::Exception& )
132 OSL_FAIL( "Couldn't set visual area of the object!" );
136 SwXMLTextImportHelper::SwXMLTextImportHelper(
137 const uno::Reference < XModel>& rModel,
138 SwXMLImport& rImport,
139 const uno::Reference<XPropertySet> & rInfoSet,
140 bool bInsertM, bool bStylesOnlyM,
141 bool bBlockM, bool bOrganizerM ) :
142 XMLTextImportHelper( rModel, rImport, bInsertM, bStylesOnlyM, true/*bProgress*/,
143 bBlockM, bOrganizerM ),
144 m_pRedlineHelper( nullptr )
146 uno::Reference<XPropertySet> xDocPropSet( rModel, UNO_QUERY );
147 m_pRedlineHelper = new XMLRedlineImportHelper(rImport,
148 bInsertM || bBlockM, xDocPropSet, rInfoSet );
151 SwXMLTextImportHelper::~SwXMLTextImportHelper()
153 // the redline helper destructor sets properties on the document
154 // and may throw an exception while doing so... catch this
157 delete m_pRedlineHelper;
159 catch ( const RuntimeException& )
161 // ignore
165 SvXMLImportContext *SwXMLTextImportHelper::CreateTableChildContext(
166 SvXMLImport& rImport,
167 sal_Int32 /*nElement*/,
168 const uno::Reference< XFastAttributeList > & xAttrList )
170 return new SwXMLTableContext( static_cast<SwXMLImport&>(rImport), xAttrList );
173 bool SwXMLTextImportHelper::IsInHeaderFooter() const
175 OTextCursorHelper* pTextCursor = dynamic_cast<OTextCursorHelper*>(const_cast<SwXMLTextImportHelper *>(this)->GetCursor().get());
176 SAL_WARN_IF(!pTextCursor, "sw.uno", "SwXTextCursor missing");
177 SwDoc *pDoc = pTextCursor ? pTextCursor->GetDoc() : nullptr;
179 return pDoc && pDoc->IsInHeaderFooter( pTextCursor->GetPaM()->GetPoint()->GetNode() );
182 static SwOLENode *lcl_GetOLENode( const SwFrameFormat *pFrameFormat )
184 SwOLENode *pOLENd = nullptr;
185 if( pFrameFormat )
187 const SwFormatContent& rContent = pFrameFormat->GetContent();
188 const SwNodeIndex *pNdIdx = rContent.GetContentIdx();
189 pOLENd = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetOLENode();
191 OSL_ENSURE( pOLENd, "Where is the OLE node" );
192 return pOLENd;
195 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertOLEObject(
196 SvXMLImport& rImport,
197 const OUString& rHRef,
198 const OUString& rStyleName,
199 const OUString& rTableName,
200 sal_Int32 nWidth, sal_Int32 nHeight )
202 // this method will modify the document directly -> lock SolarMutex
203 SolarMutexGuard aGuard;
205 uno::Reference < XPropertySet > xPropSet;
207 sal_Int32 nPos = rHRef.indexOf( ':' );
208 if( -1 == nPos )
209 return xPropSet;
211 OUString aObjName( rHRef.copy( nPos+1) );
213 if( aObjName.isEmpty() )
214 return xPropSet;
216 OTextCursorHelper* pTextCursor = dynamic_cast<OTextCursorHelper*>(GetCursor().get());
217 SAL_WARN_IF(!pTextCursor, "sw.uno", "SwXTextCursor missing");
218 SwDoc *pDoc = static_cast<SwXMLImport&>(rImport).getDoc();
220 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
221 Size aTwipSize( 0, 0 );
222 tools::Rectangle aVisArea( 0, 0, nWidth, nHeight );
223 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth,
224 &aTwipSize );
226 SwFrameFormat *pFrameFormat = nullptr;
227 SwOLENode *pOLENd = nullptr;
228 if( rHRef.startsWith("vnd.sun.star.ServiceName:") )
230 bool bInsert = false;
231 SvGlobalName aClassName;
232 for (const auto& [sFilterService, rCLASSID] : aServiceMap)
234 if (aObjName == sFilterService)
236 aClassName = SvGlobalName(rCLASSID);
237 bInsert = true;
238 break;
242 if( bInsert )
244 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
247 // create object with desired ClassId
248 uno::Sequence < sal_Int8 > aClass( aClassName.GetByteSequence() );
249 uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
250 uno::Sequence<beans::PropertyValue> aObjArgs( comphelper::InitPropertySequence({
251 { "DefaultParentBaseURL", Any(GetXMLImport().GetBaseURL()) }
252 }));
253 uno::Reference < embed::XEmbeddedObject > xObj( xFactory->createInstanceInitNew(
254 aClass, OUString(), xStorage, u"DummyName"_ustr, aObjArgs), uno::UNO_QUERY );
255 if ( xObj.is() )
257 //TODO/LATER: is it enough to only set the VisAreaSize?
258 lcl_setObjectVisualArea( xObj, embed::Aspects::MSOLE_CONTENT, aTwipSize, MapUnit::MapTwip );
261 if( pTextCursor )
263 pFrameFormat = pDoc->getIDocumentContentOperations().InsertEmbObject(
264 *pTextCursor->GetPaM(),
265 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
266 &aItemSet);
267 pOLENd = lcl_GetOLENode( pFrameFormat );
270 if( pOLENd )
271 aObjName = pOLENd->GetOLEObj().GetCurrentPersistName();
273 catch ( uno::Exception& )
278 else
280 // check whether an object with this name already exists in the document
281 OUString aName;
282 SwIterator<SwContentNode,SwFormatColl> aIter( *pDoc->GetDfltGrfFormatColl() );
283 for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
285 SwOLENode* pExistingOLENd = pNd->GetOLENode();
286 if( pExistingOLENd )
288 OUString aExistingName = pExistingOLENd->GetOLEObj().GetCurrentPersistName();
289 if ( aExistingName == aObjName )
291 OSL_FAIL( "The document contains duplicate object references, means it is partially broken, please let developers know how this document was generated!" );
293 OUString aTmpName = pDoc->GetPersist()->GetEmbeddedObjectContainer().CreateUniqueObjectName();
296 pDoc->GetPersist()->GetStorage()->copyElementTo( aObjName,
297 pDoc->GetPersist()->GetStorage(),
298 aTmpName );
299 aName = aTmpName;
301 catch ( uno::Exception& )
303 OSL_FAIL( "Couldn't create a copy of the object!" );
306 break;
311 if ( aName.isEmpty() )
312 aName = aObjName;
314 // the correct aspect will be set later
315 // TODO/LATER: Actually it should be set here
316 if( pTextCursor )
318 pFrameFormat = pDoc->getIDocumentContentOperations().InsertOLE( *pTextCursor->GetPaM(), aName, embed::Aspects::MSOLE_CONTENT, &aItemSet, nullptr );
319 pOLENd = lcl_GetOLENode( pFrameFormat );
321 aObjName = aName;
324 if( !pFrameFormat )
325 return xPropSet;
327 if( IsInsertMode() )
329 if( !pOLENd )
330 pOLENd = lcl_GetOLENode( pFrameFormat );
331 if( pOLENd )
332 pOLENd->SetOLESizeInvalid( true );
335 xPropSet = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
336 *pDoc, pFrameFormat);
337 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
339 // req for z-order
340 SwXFrame::GetOrCreateSdrObject(*static_cast<SwFlyFrameFormat*>(pFrameFormat));
342 if( !rTableName.isEmpty() )
344 const SwFormatContent& rContent = pFrameFormat->GetContent();
345 const SwNodeIndex *pNdIdx = rContent.GetContentIdx();
346 SwOLENode *pOLENode = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetOLENode();
347 OSL_ENSURE( pOLENode, "Where is the OLE node" );
349 OUStringBuffer aBuffer( rTableName.getLength() );
350 bool bQuoted = false;
351 bool bEscape = false;
352 bool bError = false;
353 for( sal_Int32 i=0; i < rTableName.getLength(); i++ )
355 bool bEndOfNameFound = false;
356 sal_Unicode c = rTableName[i];
357 switch( c )
359 case '\'':
360 if( bEscape )
362 aBuffer.append( c );
363 bEscape = false;
365 else if( bQuoted )
367 bEndOfNameFound = true;
369 else if( 0 == i )
371 bQuoted = true;
373 else
375 bError = true;
377 break;
378 case '\\':
379 if( bEscape )
381 aBuffer.append( c );
382 bEscape = false;
384 else
386 bEscape = true;
388 break;
389 case ' ':
390 case '.':
391 if( !bQuoted )
393 bEndOfNameFound = true;
395 else
397 aBuffer.append( c );
398 bEscape = false;
400 break;
401 default:
403 aBuffer.append( c );
404 bEscape = false;
406 break;
408 if( bError || bEndOfNameFound )
409 break;
411 if( !bError )
413 OUString sTableName( aBuffer.makeStringAndClear() );
414 pOLENode->SetChartTableName( GetRenameMap().Get( XML_TEXT_RENAME_TYPE_TABLE, sTableName ) );
418 sal_Int64 nDrawAspect = 0;
419 const XMLPropStyleContext *pStyle = nullptr;
420 bool bHasSizeProps = false;
421 if( !rStyleName.isEmpty() )
423 pStyle = FindAutoFrameStyle( rStyleName );
424 if( pStyle )
426 rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
427 pStyle->GetStyles()
428 ->GetImportPropertyMapper(pStyle->GetFamily());
429 OSL_ENSURE( xImpPrMap.is(), "Where is the import prop mapper?" );
430 if( xImpPrMap.is() )
432 rtl::Reference<XMLPropertySetMapper> rPropMapper =
433 xImpPrMap->getPropertySetMapper();
435 sal_Int32 nCount = pStyle->GetProperties().size();
436 for( sal_Int32 i=0; i < nCount; i++ )
438 const XMLPropertyState& rProp = pStyle->GetProperties()[i];
439 sal_Int32 nIdx = rProp.mnIndex;
440 if( -1 == nIdx )
441 continue;
443 switch( rPropMapper->GetEntryContextId(nIdx) )
445 case CTF_OLE_VIS_AREA_LEFT:
447 sal_Int32 nVal = 0;
448 rProp.maValue >>= nVal;
449 aVisArea.SetPosX( nVal );
451 break;
452 case CTF_OLE_VIS_AREA_TOP:
454 sal_Int32 nVal = 0;
455 rProp.maValue >>= nVal;
456 aVisArea.SetPosY( nVal );
458 break;
459 case CTF_OLE_VIS_AREA_WIDTH:
461 sal_Int32 nVal = 0;
462 rProp.maValue >>= nVal;
463 aVisArea.setWidth( nVal );
464 bHasSizeProps = true;
466 break;
467 case CTF_OLE_VIS_AREA_HEIGHT:
469 sal_Int32 nVal = 0;
470 rProp.maValue >>= nVal;
471 aVisArea.setHeight( nVal );
472 bHasSizeProps = true;
474 break;
475 case CTF_OLE_DRAW_ASPECT:
477 rProp.maValue >>= nDrawAspect;
479 if ( !nDrawAspect )
480 nDrawAspect = embed::Aspects::MSOLE_CONTENT;
482 if ( pOLENd )
483 pOLENd->GetOLEObj().GetObject().SetViewAspect( nDrawAspect );
485 break;
492 if ( bHasSizeProps )
494 uno::Reference < embed::XEmbeddedObject > xObj =
495 pDoc->GetPersist()->GetEmbeddedObjectContainer().GetEmbeddedObject( aObjName );
496 if( xObj.is() )
497 lcl_setObjectVisualArea( xObj, ( nDrawAspect ? nDrawAspect : embed::Aspects::MSOLE_CONTENT ),
498 aVisArea.GetSize(), MapUnit::Map100thMM );
501 return xPropSet;
504 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertOOoLink(
505 SvXMLImport& rImport,
506 const OUString& rHRef,
507 const OUString& /*rStyleName*/,
508 const OUString& /*rTableName*/,
509 sal_Int32 nWidth, sal_Int32 nHeight )
511 // this method will modify the document directly -> lock SolarMutex
512 SolarMutexGuard aGuard;
514 uno::Reference < XPropertySet > xPropSet;
516 OTextCursorHelper* pTextCursor = dynamic_cast<OTextCursorHelper*>(GetCursor().get());
517 assert( pTextCursor && "SwXTextCursor missing" );
518 SwDoc *pDoc = static_cast<SwXMLImport&>(rImport).getDoc();
520 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
521 Size aTwipSize( 0, 0 );
522 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth,
523 &aTwipSize );
525 // We'll need a (valid) URL. If we don't have do not insert the link and return early.
526 // Copy URL into URL object on the way.
527 INetURLObject aURLObj;
528 bool bValidURL = !rHRef.isEmpty() &&
529 aURLObj.SetURL( URIHelper::SmartRel2Abs(
530 INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) );
531 if( !bValidURL )
532 return xPropSet;
534 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
537 // create object with desired ClassId
538 uno::Reference < embed::XEmbeddedObjectCreator > xFactory =
539 embed::OOoEmbeddedObjectFactory::create(::comphelper::getProcessComponentContext());
541 uno::Sequence< beans::PropertyValue > aMediaDescriptor{ comphelper::makePropertyValue(
542 u"URL"_ustr, aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE )) };
544 SwDocShell* pShell = pDoc->GetDocShell();
545 if (SfxMedium* pMedium = pShell ? pShell->GetMedium() : nullptr)
547 uno::Reference< task::XInteractionHandler > xInteraction = pMedium->GetInteractionHandler();
548 if ( xInteraction.is() )
550 aMediaDescriptor.realloc( 2 );
551 auto pMediaDescriptor = aMediaDescriptor.getArray();
552 pMediaDescriptor[1].Name = "InteractionHandler";
553 pMediaDescriptor[1].Value <<= xInteraction;
556 const auto nLen = aMediaDescriptor.getLength() + 1;
557 aMediaDescriptor.realloc(nLen);
558 auto pMediaDescriptor = aMediaDescriptor.getArray();
559 pMediaDescriptor[nLen - 1].Name = "Referer";
560 pMediaDescriptor[nLen - 1].Value <<= pMedium->GetName();
563 uno::Reference < embed::XEmbeddedObject > xObj(
564 xFactory->createInstanceLink(
565 xStorage, u"DummyName"_ustr, aMediaDescriptor, uno::Sequence< beans::PropertyValue >() ),
566 uno::UNO_QUERY_THROW );
569 SwFrameFormat *const pFrameFormat =
570 pDoc->getIDocumentContentOperations().InsertEmbObject(
571 *pTextCursor->GetPaM(),
572 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
573 &aItemSet );
575 // 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???
577 xPropSet = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
578 *pDoc, pFrameFormat);
579 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
581 SwXFrame::GetOrCreateSdrObject(*
582 static_cast<SwFlyFrameFormat*>(pFrameFormat)); // req for z-order
586 catch ( uno::Exception& )
590 // TODO/LATER: should the rStyleName and rTableName be handled as for usual embedded object?
592 return xPropSet;
595 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertApplet(
596 const OUString &rName,
597 const OUString &rCode,
598 bool bMayScript,
599 const OUString& rHRef,
600 sal_Int32 nWidth, sal_Int32 nHeight )
602 // this method will modify the document directly -> lock SolarMutex
603 SolarMutexGuard aGuard;
605 uno::Reference < XPropertySet > xPropSet;
606 OTextCursorHelper* pTextCursor = dynamic_cast<OTextCursorHelper*>(GetCursor().get());
607 assert( pTextCursor && "SwXTextCursor missing" );
608 SwDoc *pDoc = pTextCursor->GetDoc();
610 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
611 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
613 SwApplet_Impl aAppletImpl ( std::move(aItemSet) );
615 OUString sCodeBase;
616 if( !rHRef.isEmpty() )
617 sCodeBase = GetXMLImport().GetAbsoluteReference( rHRef );
619 aAppletImpl.CreateApplet ( rCode, rName, bMayScript, sCodeBase, GetXMLImport().GetDocumentBase() );
621 // set the size of the applet
622 lcl_setObjectVisualArea( aAppletImpl.GetApplet(),
623 embed::Aspects::MSOLE_CONTENT,
624 Size( nWidth, nHeight ),
625 MapUnit::Map100thMM );
627 SwFrameFormat *const pFrameFormat =
628 pDoc->getIDocumentContentOperations().InsertEmbObject( *pTextCursor->GetPaM(),
629 ::svt::EmbeddedObjectRef(aAppletImpl.GetApplet(), embed::Aspects::MSOLE_CONTENT),
630 &aAppletImpl.GetItemSet());
631 xPropSet = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
632 *pDoc, pFrameFormat);
633 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
635 // req for z-order
636 SwXFrame::GetOrCreateSdrObject(*static_cast<SwFlyFrameFormat*>(pFrameFormat));
639 return xPropSet;
642 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertPlugin(
643 const OUString &rMimeType,
644 const OUString& rHRef,
645 sal_Int32 nWidth, sal_Int32 nHeight )
647 uno::Reference < XPropertySet > xPropSet;
648 OTextCursorHelper* pTextCursor = dynamic_cast<OTextCursorHelper*>(GetCursor().get());
649 assert( pTextCursor && "SwXTextCursor missing" );
650 SwDoc *pDoc = pTextCursor->GetDoc();
652 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
653 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
655 // We'll need a (valid) URL, or we need a MIME type. If we don't have
656 // either, do not insert plugin and return early. Copy URL into URL object
657 // on the way.
658 INetURLObject aURLObj;
660 bool bValidURL = !rHRef.isEmpty() &&
661 aURLObj.SetURL( URIHelper::SmartRel2Abs( INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) );
662 bool bValidMimeType = !rMimeType.isEmpty();
663 if( !bValidURL && !bValidMimeType )
664 return xPropSet;
666 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
669 // create object with desired ClassId
670 uno::Sequence < sal_Int8 > aClass( SvGlobalName( SO3_PLUGIN_CLASSID ).GetByteSequence() );
671 uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
672 uno::Reference < embed::XEmbeddedObject > xObj( xFactory->createInstanceInitNew(
673 aClass, OUString(), xStorage, u"DummyName"_ustr,
674 uno::Sequence < beans::PropertyValue >() ), uno::UNO_QUERY );
676 // set size to the object
677 lcl_setObjectVisualArea( xObj,
678 embed::Aspects::MSOLE_CONTENT,
679 Size( nWidth, nHeight ),
680 MapUnit::Map100thMM );
682 if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
684 uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
685 if ( xSet.is() )
687 if( bValidURL )
688 xSet->setPropertyValue(u"PluginURL"_ustr,
689 Any( aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ) );
690 if( bValidMimeType )
691 xSet->setPropertyValue(u"PluginMimeType"_ustr,
692 Any( rMimeType ) );
695 SwFrameFormat *const pFrameFormat =
696 pDoc->getIDocumentContentOperations().InsertEmbObject(
697 *pTextCursor->GetPaM(),
698 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
699 &aItemSet);
700 xPropSet = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
701 *pDoc, pFrameFormat);
702 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
704 SwXFrame::GetOrCreateSdrObject(*
705 static_cast<SwFlyFrameFormat*>(pFrameFormat)); // req for z-order
709 catch ( uno::Exception& )
713 return xPropSet;
715 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertFloatingFrame(
716 const OUString& rName,
717 const OUString& rHRef,
718 const OUString& rStyleName,
719 sal_Int32 nWidth, sal_Int32 nHeight )
721 // this method will modify the document directly -> lock SolarMutex
722 SolarMutexGuard aGuard;
724 uno::Reference < XPropertySet > xPropSet;
725 OTextCursorHelper* pTextCursor = dynamic_cast<OTextCursorHelper*>(GetCursor().get());
726 assert( pTextCursor && "SwXTextCursor missing" );
727 SwDoc *pDoc = pTextCursor->GetDoc();
729 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
730 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
732 ScrollingMode eScrollMode = ScrollingMode::Auto;
733 bool bHasBorder = false;
734 bool bIsBorderSet = false;
735 Size aMargin( SIZE_NOT_SET, SIZE_NOT_SET );
736 const XMLPropStyleContext *pStyle = nullptr;
737 if( !rStyleName.isEmpty() )
739 pStyle = FindAutoFrameStyle( rStyleName );
740 if( pStyle )
742 rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
743 pStyle->GetStyles()
744 ->GetImportPropertyMapper(pStyle->GetFamily());
745 OSL_ENSURE( xImpPrMap.is(), "Where is the import prop mapper?" );
746 if( xImpPrMap.is() )
748 rtl::Reference<XMLPropertySetMapper> rPropMapper =
749 xImpPrMap->getPropertySetMapper();
751 sal_Int32 nCount = pStyle->GetProperties().size();
752 for( sal_Int32 i=0; i < nCount; i++ )
754 const XMLPropertyState& rProp = pStyle->GetProperties()[i];
755 sal_Int32 nIdx = rProp.mnIndex;
756 if( -1 == nIdx )
757 continue;
759 switch( rPropMapper->GetEntryContextId(nIdx) )
761 case CTF_FRAME_DISPLAY_SCROLLBAR:
763 bool bYes = *o3tl::doAccess<bool>(rProp.maValue);
764 eScrollMode = bYes ? ScrollingMode::Yes : ScrollingMode::No;
766 break;
767 case CTF_FRAME_DISPLAY_BORDER:
769 bHasBorder = *o3tl::doAccess<bool>(rProp.maValue);
770 bIsBorderSet = true;
772 break;
773 case CTF_FRAME_MARGIN_HORI:
775 sal_Int32 nVal = SIZE_NOT_SET;
776 rProp.maValue >>= nVal;
777 aMargin.setWidth( nVal );
779 break;
780 case CTF_FRAME_MARGIN_VERT:
782 sal_Int32 nVal = SIZE_NOT_SET;
783 rProp.maValue >>= nVal;
784 aMargin.setHeight( nVal );
786 break;
793 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
796 // create object with desired ClassId
797 uno::Sequence < sal_Int8 > aClass( SvGlobalName( SO3_IFRAME_CLASSID ).GetByteSequence() );
798 uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
799 uno::Reference < embed::XEmbeddedObject > xObj( xFactory->createInstanceInitNew(
800 aClass, OUString(), xStorage, u"DummyName"_ustr,
801 uno::Sequence < beans::PropertyValue >() ), uno::UNO_QUERY );
803 // set size to the object
804 lcl_setObjectVisualArea( xObj,
805 embed::Aspects::MSOLE_CONTENT,
806 Size( nWidth, nHeight ),
807 MapUnit::Map100thMM );
809 if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
811 uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
812 if ( xSet.is() )
814 OUString sHRef = URIHelper::SmartRel2Abs(
815 INetURLObject( GetXMLImport().GetBaseURL() ), rHRef );
817 if (INetURLObject(sHRef).IsExoticProtocol())
818 GetXMLImport().NotifyMacroEventRead();
820 xSet->setPropertyValue(u"FrameURL"_ustr,
821 Any( sHRef ) );
823 xSet->setPropertyValue(u"FrameName"_ustr,
824 Any( rName ) );
826 if ( eScrollMode == ScrollingMode::Auto )
827 xSet->setPropertyValue(u"FrameIsAutoScroll"_ustr,
828 Any( true ) );
829 else
830 xSet->setPropertyValue(u"FrameIsScrollingMode"_ustr,
831 Any( eScrollMode == ScrollingMode::Yes ) );
833 if ( bIsBorderSet )
834 xSet->setPropertyValue(u"FrameIsBorder"_ustr,
835 Any( bHasBorder ) );
836 else
837 xSet->setPropertyValue(u"FrameIsAutoBorder"_ustr,
838 Any( true ) );
840 xSet->setPropertyValue(u"FrameMarginWidth"_ustr,
841 Any( sal_Int32( aMargin.Width() ) ) );
843 xSet->setPropertyValue(u"FrameMarginHeight"_ustr,
844 Any( sal_Int32( aMargin.Height() ) ) );
847 SwFrameFormat *const pFrameFormat =
848 pDoc->getIDocumentContentOperations().InsertEmbObject(
849 *pTextCursor->GetPaM(),
850 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
851 &aItemSet);
852 xPropSet = SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
853 *pDoc, pFrameFormat);
854 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
856 // req for z-order
857 SwXFrame::GetOrCreateSdrObject(*
858 static_cast<SwFlyFrameFormat*>(pFrameFormat));
862 catch ( uno::Exception& )
866 return xPropSet;
869 void SwXMLTextImportHelper::endAppletOrPlugin(
870 const uno::Reference < XPropertySet > &rPropSet,
871 std::map < const OUString, OUString > &rParamMap)
873 // this method will modify the document directly -> lock SolarMutex
874 SolarMutexGuard aGuard;
876 SwXFrame* pFrame = dynamic_cast<SwXFrame*>(rPropSet.get());
877 assert(pFrame && "SwXFrame missing");
878 SwFrameFormat *pFrameFormat = pFrame->GetFrameFormat();
879 const SwFormatContent& rContent = pFrameFormat->GetContent();
880 const SwNodeIndex *pNdIdx = rContent.GetContentIdx();
881 SwOLENode *pOLENd = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetNoTextNode()->GetOLENode();
882 SwOLEObj& rOLEObj = pOLENd->GetOLEObj();
884 uno::Reference < embed::XEmbeddedObject > xEmbObj( rOLEObj.GetOleRef() );
885 if ( !svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) )
886 return;
888 uno::Reference < beans::XPropertySet > xSet( xEmbObj->getComponent(), uno::UNO_QUERY );
889 if ( !xSet.is() )
890 return;
892 const sal_Int32 nCount = rParamMap.size();
893 uno::Sequence< beans::PropertyValue > aCommandSequence( nCount );
895 std::transform(rParamMap.begin(), rParamMap.end(), aCommandSequence.getArray(),
896 [](const auto& rParam)
898 return beans::PropertyValue(/* Name */ rParam.first,
899 /* Handle */ -1,
900 /* Value */ uno::Any(rParam.second),
901 /* State */ beans::PropertyState_DIRECT_VALUE);
904 // unfortunately the names of the properties are depending on the object
905 OUString aParaName(u"AppletCommands"_ustr);
908 xSet->setPropertyValue( aParaName, Any( aCommandSequence ) );
910 catch ( uno::Exception& )
912 aParaName = "PluginCommands";
915 xSet->setPropertyValue( aParaName, Any( aCommandSequence ) );
917 catch ( uno::Exception& )
923 // redlining helper methods
924 // (override to provide the real implementation)
925 void SwXMLTextImportHelper::RedlineAdd(
926 const OUString& rType,
927 const OUString& rId,
928 const OUString& rAuthor,
929 const OUString& rComment,
930 const util::DateTime& rDateTime,
931 const OUString& rMovedID,
932 bool bMergeLastPara)
934 // create redline helper on demand
935 OSL_ENSURE(nullptr != m_pRedlineHelper, "helper should have been created in constructor");
936 if (nullptr != m_pRedlineHelper)
937 m_pRedlineHelper->Add(rType, rId, rAuthor, rComment, rDateTime, rMovedID,
938 bMergeLastPara);
941 uno::Reference<XTextCursor> SwXMLTextImportHelper::RedlineCreateText(
942 uno::Reference<XTextCursor> & rOldCursor,
943 const OUString& rId)
945 uno::Reference<XTextCursor> xRet;
947 if (nullptr != m_pRedlineHelper)
949 xRet = m_pRedlineHelper->CreateRedlineTextSection(rOldCursor, rId);
952 return xRet;
955 void SwXMLTextImportHelper::RedlineSetCursor(
956 const OUString& rId,
957 bool bStart,
958 bool bIsOutsideOfParagraph)
960 if (nullptr != m_pRedlineHelper) {
961 uno::Reference<XTextRange> xTextRange( GetCursor()->getStart() );
962 m_pRedlineHelper->SetCursor(rId, bStart, xTextRange,
963 bIsOutsideOfParagraph);
965 // else: ignore redline (wasn't added before, else we'd have a helper)
968 void SwXMLTextImportHelper::RedlineAdjustStartNodeCursor()
970 OUString rId = GetOpenRedlineId();
971 if ((nullptr != m_pRedlineHelper) && !rId.isEmpty())
973 m_pRedlineHelper->AdjustStartNodeCursor(rId);
974 ResetOpenRedlineId();
976 // else: ignore redline (wasn't added before, or no open redline ID
979 void SwXMLTextImportHelper::SetShowChanges( bool bShowChanges )
981 if ( nullptr != m_pRedlineHelper )
982 m_pRedlineHelper->SetShowChanges( bShowChanges );
985 void SwXMLTextImportHelper::SetRecordChanges( bool bRecordChanges )
987 if ( nullptr != m_pRedlineHelper )
988 m_pRedlineHelper->SetRecordChanges( bRecordChanges );
991 void SwXMLTextImportHelper::SetChangesProtectionKey(
992 const Sequence<sal_Int8> & rKey )
994 if ( nullptr != m_pRedlineHelper )
995 m_pRedlineHelper->SetProtectionKey( rKey );
998 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */