check IFrame "FrameURL" target
[LibreOffice.git] / sw / source / filter / xml / xmltexti.cxx
blobc14bd16e80e2f6939061511c4f884753c7439b07
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 <com/sun/star/embed/EmbeddedObjectCreator.hpp>
25 #include <com/sun/star/embed/OOoEmbeddedObjectFactory.hpp>
26 #include <com/sun/star/embed/XEmbeddedObject.hpp>
27 #include <com/sun/star/embed/Aspects.hpp>
28 #include <com/sun/star/frame/XModel.hpp>
29 #include <com/sun/star/task/XInteractionHandler.hpp>
30 #include <o3tl/any.hxx>
31 #include <osl/diagnose.h>
32 #include <rtl/ustrbuf.hxx>
33 #include <sal/log.hxx>
34 #include <comphelper/classids.hxx>
35 #include <com/sun/star/lang/XUnoTunnel.hpp>
36 #include <xmloff/prstylei.hxx>
37 #include <xmloff/maptype.hxx>
38 #include <xmloff/xmlprmap.hxx>
39 #include <xmloff/txtprmap.hxx>
40 #include <xmloff/i18nmap.hxx>
41 #include <xmloff/xmlimppr.hxx>
42 #include <TextCursorHelper.hxx>
43 #include <unoframe.hxx>
44 #include <doc.hxx>
45 #include <IDocumentDrawModelAccess.hxx>
46 #include <IDocumentContentOperations.hxx>
47 #include <fmtfsize.hxx>
48 #include <fmtanchr.hxx>
49 #include <fmtcntnt.hxx>
50 #include "xmlimp.hxx"
51 #include "xmltbli.hxx"
52 #include "xmltexti.hxx"
53 #include "XMLRedlineImportHelper.hxx"
54 #include <xmloff/XMLFilterServiceNames.h>
55 #include <SwAppletImpl.hxx>
56 #include <ndole.hxx>
57 #include <docsh.hxx>
58 #include <sfx2/docfile.hxx>
59 #include <vcl/svapp.hxx>
60 #include <toolkit/helper/vclunohelper.hxx>
61 #include <svtools/embedhlp.hxx>
62 #include <svl/urihelper.hxx>
63 #include <sfx2/frmdescr.hxx>
64 #include <tools/globname.hxx>
65 #include <tools/UnitConversion.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 SvXMLImport& 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 uno::Reference<XUnoTunnel> xCursorTunnel(
176 const_cast<SwXMLTextImportHelper *>(this)->GetCursor(), UNO_QUERY );
177 assert(xCursorTunnel.is() && "missing XUnoTunnel for Cursor");
178 OTextCursorHelper* pTextCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
179 SAL_WARN_IF(!pTextCursor, "sw.uno", "SwXTextCursor missing");
180 SwDoc *pDoc = pTextCursor ? pTextCursor->GetDoc() : nullptr;
182 return pDoc && pDoc->IsInHeaderFooter( pTextCursor->GetPaM()->GetPoint()->nNode );
185 static SwOLENode *lcl_GetOLENode( const SwFrameFormat *pFrameFormat )
187 SwOLENode *pOLENd = nullptr;
188 if( pFrameFormat )
190 const SwFormatContent& rContent = pFrameFormat->GetContent();
191 const SwNodeIndex *pNdIdx = rContent.GetContentIdx();
192 pOLENd = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetOLENode();
194 OSL_ENSURE( pOLENd, "Where is the OLE node" );
195 return pOLENd;
198 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertOLEObject(
199 SvXMLImport& rImport,
200 const OUString& rHRef,
201 const OUString& rStyleName,
202 const OUString& rTableName,
203 sal_Int32 nWidth, sal_Int32 nHeight )
205 // this method will modify the document directly -> lock SolarMutex
206 SolarMutexGuard aGuard;
208 uno::Reference < XPropertySet > xPropSet;
210 sal_Int32 nPos = rHRef.indexOf( ':' );
211 if( -1 == nPos )
212 return xPropSet;
214 OUString aObjName( rHRef.copy( nPos+1) );
216 if( aObjName.isEmpty() )
217 return xPropSet;
219 uno::Reference<XUnoTunnel> xCursorTunnel( GetCursor(), UNO_QUERY );
220 assert(xCursorTunnel.is() && "missing XUnoTunnel for Cursor");
221 OTextCursorHelper* pTextCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
222 SAL_WARN_IF(!pTextCursor, "sw.uno", "SwXTextCursor missing");
223 SwDoc *pDoc = SwImport::GetDocFromXMLImport( rImport );
225 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
226 Size aTwipSize( 0, 0 );
227 tools::Rectangle aVisArea( 0, 0, nWidth, nHeight );
228 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth,
229 &aTwipSize );
231 SwFrameFormat *pFrameFormat = nullptr;
232 SwOLENode *pOLENd = nullptr;
233 if( rHRef.startsWith("vnd.sun.star.ServiceName:") )
235 bool bInsert = false;
236 SvGlobalName aClassName;
237 for (const auto& [sFilterService, rCLASSID] : aServiceMap)
239 if (aObjName == sFilterService)
241 aClassName = SvGlobalName(rCLASSID);
242 bInsert = true;
243 break;
247 if( bInsert )
249 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
252 // create object with desired ClassId
253 uno::Sequence < sal_Int8 > aClass( aClassName.GetByteSequence() );
254 uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
255 uno::Sequence<beans::PropertyValue> aObjArgs( comphelper::InitPropertySequence({
256 { "DefaultParentBaseURL", Any(GetXMLImport().GetBaseURL()) }
257 }));
258 uno::Reference < embed::XEmbeddedObject > xObj( xFactory->createInstanceInitNew(
259 aClass, OUString(), xStorage, "DummyName", aObjArgs), uno::UNO_QUERY );
260 if ( xObj.is() )
262 //TODO/LATER: is it enough to only set the VisAreaSize?
263 lcl_setObjectVisualArea( xObj, embed::Aspects::MSOLE_CONTENT, aTwipSize, MapUnit::MapTwip );
266 if( pTextCursor )
268 pFrameFormat = pDoc->getIDocumentContentOperations().InsertEmbObject(
269 *pTextCursor->GetPaM(),
270 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
271 &aItemSet);
272 pOLENd = lcl_GetOLENode( pFrameFormat );
275 if( pOLENd )
276 aObjName = pOLENd->GetOLEObj().GetCurrentPersistName();
278 catch ( uno::Exception& )
283 else
285 // check whether an object with this name already exists in the document
286 OUString aName;
287 SwIterator<SwContentNode,SwFormatColl> aIter( *pDoc->GetDfltGrfFormatColl() );
288 for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() )
290 SwOLENode* pExistingOLENd = pNd->GetOLENode();
291 if( pExistingOLENd )
293 OUString aExistingName = pExistingOLENd->GetOLEObj().GetCurrentPersistName();
294 if ( aExistingName == aObjName )
296 OSL_FAIL( "The document contains duplicate object references, means it is partially broken, please let developers know how this document was generated!" );
298 OUString aTmpName = pDoc->GetPersist()->GetEmbeddedObjectContainer().CreateUniqueObjectName();
301 pDoc->GetPersist()->GetStorage()->copyElementTo( aObjName,
302 pDoc->GetPersist()->GetStorage(),
303 aTmpName );
304 aName = aTmpName;
306 catch ( uno::Exception& )
308 OSL_FAIL( "Couldn't create a copy of the object!" );
311 break;
316 if ( aName.isEmpty() )
317 aName = aObjName;
319 // the correct aspect will be set later
320 // TODO/LATER: Actually it should be set here
321 if( pTextCursor )
323 pFrameFormat = pDoc->getIDocumentContentOperations().InsertOLE( *pTextCursor->GetPaM(), aName, embed::Aspects::MSOLE_CONTENT, &aItemSet, nullptr );
324 pOLENd = lcl_GetOLENode( pFrameFormat );
326 aObjName = aName;
329 if( !pFrameFormat )
330 return xPropSet;
332 if( IsInsertMode() )
334 if( !pOLENd )
335 pOLENd = lcl_GetOLENode( pFrameFormat );
336 if( pOLENd )
337 pOLENd->SetOLESizeInvalid( true );
340 xPropSet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
341 *pDoc, pFrameFormat), uno::UNO_QUERY);
342 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
344 // req for z-order
345 SwXFrame::GetOrCreateSdrObject(*static_cast<SwFlyFrameFormat*>(pFrameFormat));
347 if( !rTableName.isEmpty() )
349 const SwFormatContent& rContent = pFrameFormat->GetContent();
350 const SwNodeIndex *pNdIdx = rContent.GetContentIdx();
351 SwOLENode *pOLENode = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetOLENode();
352 OSL_ENSURE( pOLENode, "Where is the OLE node" );
354 OUStringBuffer aBuffer( rTableName.getLength() );
355 bool bQuoted = false;
356 bool bEscape = false;
357 bool bError = false;
358 for( sal_Int32 i=0; i < rTableName.getLength(); i++ )
360 bool bEndOfNameFound = false;
361 sal_Unicode c = rTableName[i];
362 switch( c )
364 case '\'':
365 if( bEscape )
367 aBuffer.append( c );
368 bEscape = false;
370 else if( bQuoted )
372 bEndOfNameFound = true;
374 else if( 0 == i )
376 bQuoted = true;
378 else
380 bError = true;
382 break;
383 case '\\':
384 if( bEscape )
386 aBuffer.append( c );
387 bEscape = false;
389 else
391 bEscape = true;
393 break;
394 case ' ':
395 case '.':
396 if( !bQuoted )
398 bEndOfNameFound = true;
400 else
402 aBuffer.append( c );
403 bEscape = false;
405 break;
406 default:
408 aBuffer.append( c );
409 bEscape = false;
411 break;
413 if( bError || bEndOfNameFound )
414 break;
416 if( !bError )
418 OUString sTableName( aBuffer.makeStringAndClear() );
419 pOLENode->SetChartTableName( GetRenameMap().Get( XML_TEXT_RENAME_TYPE_TABLE, sTableName ) );
423 sal_Int64 nDrawAspect = 0;
424 const XMLPropStyleContext *pStyle = nullptr;
425 bool bHasSizeProps = false;
426 if( !rStyleName.isEmpty() )
428 pStyle = FindAutoFrameStyle( rStyleName );
429 if( pStyle )
431 rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
432 pStyle->GetStyles()
433 ->GetImportPropertyMapper(pStyle->GetFamily());
434 OSL_ENSURE( xImpPrMap.is(), "Where is the import prop mapper?" );
435 if( xImpPrMap.is() )
437 rtl::Reference<XMLPropertySetMapper> rPropMapper =
438 xImpPrMap->getPropertySetMapper();
440 sal_Int32 nCount = pStyle->GetProperties().size();
441 for( sal_Int32 i=0; i < nCount; i++ )
443 const XMLPropertyState& rProp = pStyle->GetProperties()[i];
444 sal_Int32 nIdx = rProp.mnIndex;
445 if( -1 == nIdx )
446 continue;
448 switch( rPropMapper->GetEntryContextId(nIdx) )
450 case CTF_OLE_VIS_AREA_LEFT:
452 sal_Int32 nVal = 0;
453 rProp.maValue >>= nVal;
454 aVisArea.SetPosX( nVal );
456 break;
457 case CTF_OLE_VIS_AREA_TOP:
459 sal_Int32 nVal = 0;
460 rProp.maValue >>= nVal;
461 aVisArea.SetPosY( nVal );
463 break;
464 case CTF_OLE_VIS_AREA_WIDTH:
466 sal_Int32 nVal = 0;
467 rProp.maValue >>= nVal;
468 aVisArea.setWidth( nVal );
469 bHasSizeProps = true;
471 break;
472 case CTF_OLE_VIS_AREA_HEIGHT:
474 sal_Int32 nVal = 0;
475 rProp.maValue >>= nVal;
476 aVisArea.setHeight( nVal );
477 bHasSizeProps = true;
479 break;
480 case CTF_OLE_DRAW_ASPECT:
482 rProp.maValue >>= nDrawAspect;
484 if ( !nDrawAspect )
485 nDrawAspect = embed::Aspects::MSOLE_CONTENT;
487 if ( pOLENd )
488 pOLENd->GetOLEObj().GetObject().SetViewAspect( nDrawAspect );
490 break;
497 if ( bHasSizeProps )
499 uno::Reference < embed::XEmbeddedObject > xObj =
500 pDoc->GetPersist()->GetEmbeddedObjectContainer().GetEmbeddedObject( aObjName );
501 if( xObj.is() )
502 lcl_setObjectVisualArea( xObj, ( nDrawAspect ? nDrawAspect : embed::Aspects::MSOLE_CONTENT ),
503 aVisArea.GetSize(), MapUnit::Map100thMM );
506 return xPropSet;
509 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertOOoLink(
510 SvXMLImport& rImport,
511 const OUString& rHRef,
512 const OUString& /*rStyleName*/,
513 const OUString& /*rTableName*/,
514 sal_Int32 nWidth, sal_Int32 nHeight )
516 // this method will modify the document directly -> lock SolarMutex
517 SolarMutexGuard aGuard;
519 uno::Reference < XPropertySet > xPropSet;
521 uno::Reference<XUnoTunnel> xCursorTunnel( GetCursor(), UNO_QUERY );
522 assert(xCursorTunnel.is() && "missing XUnoTunnel for Cursor");
523 OTextCursorHelper* pTextCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
524 OSL_ENSURE( pTextCursor, "SwXTextCursor missing" );
525 SwDoc *pDoc = SwImport::GetDocFromXMLImport( rImport );
527 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
528 Size aTwipSize( 0, 0 );
529 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth,
530 &aTwipSize );
532 // We'll need a (valid) URL. If we don't have do not insert the link and return early.
533 // Copy URL into URL object on the way.
534 INetURLObject aURLObj;
535 bool bValidURL = !rHRef.isEmpty() &&
536 aURLObj.SetURL( URIHelper::SmartRel2Abs(
537 INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) );
538 if( !bValidURL )
539 return xPropSet;
541 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
544 // create object with desired ClassId
545 uno::Reference < embed::XEmbeddedObjectCreator > xFactory =
546 embed::OOoEmbeddedObjectFactory::create(::comphelper::getProcessComponentContext());
548 uno::Sequence< beans::PropertyValue > aMediaDescriptor{ comphelper::makePropertyValue(
549 "URL", aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE )) };
551 if (SfxMedium* pMedium = pDoc->GetDocShell() ? pDoc->GetDocShell()->GetMedium() : nullptr)
553 uno::Reference< task::XInteractionHandler > xInteraction = pMedium->GetInteractionHandler();
554 if ( xInteraction.is() )
556 aMediaDescriptor.realloc( 2 );
557 auto pMediaDescriptor = aMediaDescriptor.getArray();
558 pMediaDescriptor[1].Name = "InteractionHandler";
559 pMediaDescriptor[1].Value <<= xInteraction;
562 const auto nLen = aMediaDescriptor.getLength() + 1;
563 aMediaDescriptor.realloc(nLen);
564 auto pMediaDescriptor = aMediaDescriptor.getArray();
565 pMediaDescriptor[nLen - 1].Name = "Referer";
566 pMediaDescriptor[nLen - 1].Value <<= pMedium->GetName();
569 uno::Reference < embed::XEmbeddedObject > xObj(
570 xFactory->createInstanceLink(
571 xStorage, "DummyName", aMediaDescriptor, uno::Sequence< beans::PropertyValue >() ),
572 uno::UNO_QUERY_THROW );
575 SwFrameFormat *const pFrameFormat =
576 pDoc->getIDocumentContentOperations().InsertEmbObject(
577 *pTextCursor->GetPaM(),
578 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
579 &aItemSet );
581 // 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???
583 xPropSet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
584 *pDoc, pFrameFormat), uno::UNO_QUERY);
585 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
587 SwXFrame::GetOrCreateSdrObject(*
588 static_cast<SwFlyFrameFormat*>(pFrameFormat)); // req for z-order
592 catch ( uno::Exception& )
596 // TODO/LATER: should the rStyleName and rTableName be handled as for usual embedded object?
598 return xPropSet;
601 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertApplet(
602 const OUString &rName,
603 const OUString &rCode,
604 bool bMayScript,
605 const OUString& rHRef,
606 sal_Int32 nWidth, sal_Int32 nHeight )
608 // this method will modify the document directly -> lock SolarMutex
609 SolarMutexGuard aGuard;
611 uno::Reference < XPropertySet > xPropSet;
612 uno::Reference<XUnoTunnel> xCursorTunnel( GetCursor(), UNO_QUERY );
613 assert(xCursorTunnel.is() && "missing XUnoTunnel for Cursor");
614 OTextCursorHelper* pTextCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
615 OSL_ENSURE( pTextCursor, "SwXTextCursor missing" );
616 SwDoc *pDoc = pTextCursor->GetDoc();
618 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
619 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
621 SwApplet_Impl aAppletImpl ( aItemSet );
623 OUString sCodeBase;
624 if( !rHRef.isEmpty() )
625 sCodeBase = GetXMLImport().GetAbsoluteReference( rHRef );
627 aAppletImpl.CreateApplet ( rCode, rName, bMayScript, sCodeBase, GetXMLImport().GetDocumentBase() );
629 // set the size of the applet
630 lcl_setObjectVisualArea( aAppletImpl.GetApplet(),
631 embed::Aspects::MSOLE_CONTENT,
632 Size( nWidth, nHeight ),
633 MapUnit::Map100thMM );
635 SwFrameFormat *const pFrameFormat =
636 pDoc->getIDocumentContentOperations().InsertEmbObject( *pTextCursor->GetPaM(),
637 ::svt::EmbeddedObjectRef(aAppletImpl.GetApplet(), embed::Aspects::MSOLE_CONTENT),
638 &aAppletImpl.GetItemSet());
639 xPropSet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
640 *pDoc, pFrameFormat), uno::UNO_QUERY);
641 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
643 // req for z-order
644 SwXFrame::GetOrCreateSdrObject(*static_cast<SwFlyFrameFormat*>(pFrameFormat));
647 return xPropSet;
650 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertPlugin(
651 const OUString &rMimeType,
652 const OUString& rHRef,
653 sal_Int32 nWidth, sal_Int32 nHeight )
655 uno::Reference < XPropertySet > xPropSet;
656 uno::Reference<XUnoTunnel> xCursorTunnel( GetCursor(), UNO_QUERY );
657 assert(xCursorTunnel.is() && "missing XUnoTunnel for Cursor");
658 OTextCursorHelper* pTextCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
659 OSL_ENSURE( pTextCursor, "SwXTextCursor missing" );
660 SwDoc *pDoc = pTextCursor->GetDoc();
662 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
663 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
665 // We'll need a (valid) URL, or we need a MIME type. If we don't have
666 // either, do not insert plugin and return early. Copy URL into URL object
667 // on the way.
668 INetURLObject aURLObj;
670 bool bValidURL = !rHRef.isEmpty() &&
671 aURLObj.SetURL( URIHelper::SmartRel2Abs( INetURLObject( GetXMLImport().GetBaseURL() ), rHRef ) );
672 bool bValidMimeType = !rMimeType.isEmpty();
673 if( !bValidURL && !bValidMimeType )
674 return xPropSet;
676 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
679 // create object with desired ClassId
680 uno::Sequence < sal_Int8 > aClass( SvGlobalName( SO3_PLUGIN_CLASSID ).GetByteSequence() );
681 uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
682 uno::Reference < embed::XEmbeddedObject > xObj( xFactory->createInstanceInitNew(
683 aClass, OUString(), xStorage, "DummyName",
684 uno::Sequence < beans::PropertyValue >() ), uno::UNO_QUERY );
686 // set size to the object
687 lcl_setObjectVisualArea( xObj,
688 embed::Aspects::MSOLE_CONTENT,
689 Size( nWidth, nHeight ),
690 MapUnit::Map100thMM );
692 if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
694 uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
695 if ( xSet.is() )
697 if( bValidURL )
698 xSet->setPropertyValue("PluginURL",
699 makeAny( aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ) );
700 if( bValidMimeType )
701 xSet->setPropertyValue("PluginMimeType",
702 makeAny( rMimeType ) );
705 SwFrameFormat *const pFrameFormat =
706 pDoc->getIDocumentContentOperations().InsertEmbObject(
707 *pTextCursor->GetPaM(),
708 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
709 &aItemSet);
710 xPropSet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
711 *pDoc, pFrameFormat), uno::UNO_QUERY);
712 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
714 SwXFrame::GetOrCreateSdrObject(*
715 static_cast<SwFlyFrameFormat*>(pFrameFormat)); // req for z-order
719 catch ( uno::Exception& )
723 return xPropSet;
725 uno::Reference< XPropertySet > SwXMLTextImportHelper::createAndInsertFloatingFrame(
726 const OUString& rName,
727 const OUString& rHRef,
728 const OUString& rStyleName,
729 sal_Int32 nWidth, sal_Int32 nHeight )
731 // this method will modify the document directly -> lock SolarMutex
732 SolarMutexGuard aGuard;
734 uno::Reference < XPropertySet > xPropSet;
735 uno::Reference<XUnoTunnel> xCursorTunnel( GetCursor(), UNO_QUERY );
736 assert(xCursorTunnel.is() && "missing XUnoTunnel for Cursor");
737 OTextCursorHelper* pTextCursor = comphelper::getFromUnoTunnel<OTextCursorHelper>(xCursorTunnel);
738 OSL_ENSURE( pTextCursor, "SwXTextCursor missing" );
739 SwDoc *pDoc = pTextCursor->GetDoc();
741 SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END> aItemSet( pDoc->GetAttrPool() );
742 lcl_putHeightAndWidth( aItemSet, nHeight, nWidth);
744 ScrollingMode eScrollMode = ScrollingMode::Auto;
745 bool bHasBorder = false;
746 bool bIsBorderSet = false;
747 Size aMargin( SIZE_NOT_SET, SIZE_NOT_SET );
748 const XMLPropStyleContext *pStyle = nullptr;
749 if( !rStyleName.isEmpty() )
751 pStyle = FindAutoFrameStyle( rStyleName );
752 if( pStyle )
754 rtl::Reference < SvXMLImportPropertyMapper > xImpPrMap =
755 pStyle->GetStyles()
756 ->GetImportPropertyMapper(pStyle->GetFamily());
757 OSL_ENSURE( xImpPrMap.is(), "Where is the import prop mapper?" );
758 if( xImpPrMap.is() )
760 rtl::Reference<XMLPropertySetMapper> rPropMapper =
761 xImpPrMap->getPropertySetMapper();
763 sal_Int32 nCount = pStyle->GetProperties().size();
764 for( sal_Int32 i=0; i < nCount; i++ )
766 const XMLPropertyState& rProp = pStyle->GetProperties()[i];
767 sal_Int32 nIdx = rProp.mnIndex;
768 if( -1 == nIdx )
769 continue;
771 switch( rPropMapper->GetEntryContextId(nIdx) )
773 case CTF_FRAME_DISPLAY_SCROLLBAR:
775 bool bYes = *o3tl::doAccess<bool>(rProp.maValue);
776 eScrollMode = bYes ? ScrollingMode::Yes : ScrollingMode::No;
778 break;
779 case CTF_FRAME_DISPLAY_BORDER:
781 bHasBorder = *o3tl::doAccess<bool>(rProp.maValue);
782 bIsBorderSet = true;
784 break;
785 case CTF_FRAME_MARGIN_HORI:
787 sal_Int32 nVal = SIZE_NOT_SET;
788 rProp.maValue >>= nVal;
789 aMargin.setWidth( nVal );
791 break;
792 case CTF_FRAME_MARGIN_VERT:
794 sal_Int32 nVal = SIZE_NOT_SET;
795 rProp.maValue >>= nVal;
796 aMargin.setHeight( nVal );
798 break;
805 uno::Reference < embed::XStorage > xStorage = comphelper::OStorageHelper::GetTemporaryStorage();
808 // create object with desired ClassId
809 uno::Sequence < sal_Int8 > aClass( SvGlobalName( SO3_IFRAME_CLASSID ).GetByteSequence() );
810 uno::Reference < embed::XEmbeddedObjectCreator > xFactory = embed::EmbeddedObjectCreator::create( ::comphelper::getProcessComponentContext() );
811 uno::Reference < embed::XEmbeddedObject > xObj( xFactory->createInstanceInitNew(
812 aClass, OUString(), xStorage, "DummyName",
813 uno::Sequence < beans::PropertyValue >() ), uno::UNO_QUERY );
815 // set size to the object
816 lcl_setObjectVisualArea( xObj,
817 embed::Aspects::MSOLE_CONTENT,
818 Size( nWidth, nHeight ),
819 MapUnit::Map100thMM );
821 if ( svt::EmbeddedObjectRef::TryRunningState( xObj ) )
823 uno::Reference < beans::XPropertySet > xSet( xObj->getComponent(), uno::UNO_QUERY );
824 if ( xSet.is() )
826 OUString sHRef = URIHelper::SmartRel2Abs(
827 INetURLObject( GetXMLImport().GetBaseURL() ), rHRef );
829 if (INetURLObject(sHRef).GetProtocol() == INetProtocol::Macro)
830 GetXMLImport().NotifyMacroEventRead();
832 xSet->setPropertyValue("FrameURL",
833 makeAny( rHRef ) );
835 xSet->setPropertyValue("FrameName",
836 makeAny( rName ) );
838 if ( eScrollMode == ScrollingMode::Auto )
839 xSet->setPropertyValue("FrameIsAutoScroll",
840 makeAny( true ) );
841 else
842 xSet->setPropertyValue("FrameIsScrollingMode",
843 makeAny( eScrollMode == ScrollingMode::Yes ) );
845 if ( bIsBorderSet )
846 xSet->setPropertyValue("FrameIsBorder",
847 makeAny( bHasBorder ) );
848 else
849 xSet->setPropertyValue("FrameIsAutoBorder",
850 makeAny( true ) );
852 xSet->setPropertyValue("FrameMarginWidth",
853 makeAny( sal_Int32( aMargin.Width() ) ) );
855 xSet->setPropertyValue("FrameMarginHeight",
856 makeAny( sal_Int32( aMargin.Height() ) ) );
859 SwFrameFormat *const pFrameFormat =
860 pDoc->getIDocumentContentOperations().InsertEmbObject(
861 *pTextCursor->GetPaM(),
862 ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
863 &aItemSet);
864 xPropSet.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
865 *pDoc, pFrameFormat), uno::UNO_QUERY);
866 if( pDoc->getIDocumentDrawModelAccess().GetDrawModel() )
868 // req for z-order
869 SwXFrame::GetOrCreateSdrObject(*
870 static_cast<SwFlyFrameFormat*>(pFrameFormat));
874 catch ( uno::Exception& )
878 return xPropSet;
881 void SwXMLTextImportHelper::endAppletOrPlugin(
882 const uno::Reference < XPropertySet > &rPropSet,
883 std::map < const OUString, OUString > &rParamMap)
885 // this method will modify the document directly -> lock SolarMutex
886 SolarMutexGuard aGuard;
888 uno::Reference<XUnoTunnel> xCursorTunnel( rPropSet, UNO_QUERY );
889 assert(xCursorTunnel.is() && "missing XUnoTunnel for embedded");
890 SwXFrame* pFrame = comphelper::getFromUnoTunnel<SwXFrame>(xCursorTunnel);
891 OSL_ENSURE( pFrame, "SwXFrame missing" );
892 SwFrameFormat *pFrameFormat = pFrame->GetFrameFormat();
893 const SwFormatContent& rContent = pFrameFormat->GetContent();
894 const SwNodeIndex *pNdIdx = rContent.GetContentIdx();
895 SwOLENode *pOLENd = pNdIdx->GetNodes()[pNdIdx->GetIndex() + 1]->GetNoTextNode()->GetOLENode();
896 SwOLEObj& rOLEObj = pOLENd->GetOLEObj();
898 uno::Reference < embed::XEmbeddedObject > xEmbObj( rOLEObj.GetOleRef() );
899 if ( !svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) )
900 return;
902 uno::Reference < beans::XPropertySet > xSet( xEmbObj->getComponent(), uno::UNO_QUERY );
903 if ( !xSet.is() )
904 return;
906 const sal_Int32 nCount = rParamMap.size();
907 uno::Sequence< beans::PropertyValue > aCommandSequence( nCount );
909 std::transform(rParamMap.begin(), rParamMap.end(), aCommandSequence.getArray(),
910 [](const auto& rParam)
912 return beans::PropertyValue(/* Name */ rParam.first,
913 /* Handle */ -1,
914 /* Value */ uno::Any(rParam.second),
915 /* State */ beans::PropertyState_DIRECT_VALUE);
918 // unfortunately the names of the properties are depending on the object
919 OUString aParaName("AppletCommands");
922 xSet->setPropertyValue( aParaName, makeAny( aCommandSequence ) );
924 catch ( uno::Exception& )
926 aParaName = "PluginCommands";
929 xSet->setPropertyValue( aParaName, makeAny( aCommandSequence ) );
931 catch ( uno::Exception& )
937 // redlining helper methods
938 // (override to provide the real implementation)
939 void SwXMLTextImportHelper::RedlineAdd(
940 const OUString& rType,
941 const OUString& rId,
942 const OUString& rAuthor,
943 const OUString& rComment,
944 const util::DateTime& rDateTime,
945 bool bMergeLastPara)
947 // create redline helper on demand
948 OSL_ENSURE(nullptr != m_pRedlineHelper, "helper should have been created in constructor");
949 if (nullptr != m_pRedlineHelper)
950 m_pRedlineHelper->Add(rType, rId, rAuthor, rComment, rDateTime,
951 bMergeLastPara);
954 uno::Reference<XTextCursor> SwXMLTextImportHelper::RedlineCreateText(
955 uno::Reference<XTextCursor> & rOldCursor,
956 const OUString& rId)
958 uno::Reference<XTextCursor> xRet;
960 if (nullptr != m_pRedlineHelper)
962 xRet = m_pRedlineHelper->CreateRedlineTextSection(rOldCursor, rId);
965 return xRet;
968 void SwXMLTextImportHelper::RedlineSetCursor(
969 const OUString& rId,
970 bool bStart,
971 bool bIsOutsideOfParagraph)
973 if (nullptr != m_pRedlineHelper) {
974 uno::Reference<XTextRange> xTextRange( GetCursor()->getStart() );
975 m_pRedlineHelper->SetCursor(rId, bStart, xTextRange,
976 bIsOutsideOfParagraph);
978 // else: ignore redline (wasn't added before, else we'd have a helper)
981 void SwXMLTextImportHelper::RedlineAdjustStartNodeCursor()
983 OUString rId = GetOpenRedlineId();
984 if ((nullptr != m_pRedlineHelper) && !rId.isEmpty())
986 m_pRedlineHelper->AdjustStartNodeCursor(rId);
987 ResetOpenRedlineId();
989 // else: ignore redline (wasn't added before, or no open redline ID
992 void SwXMLTextImportHelper::SetShowChanges( bool bShowChanges )
994 if ( nullptr != m_pRedlineHelper )
995 m_pRedlineHelper->SetShowChanges( bShowChanges );
998 void SwXMLTextImportHelper::SetRecordChanges( bool bRecordChanges )
1000 if ( nullptr != m_pRedlineHelper )
1001 m_pRedlineHelper->SetRecordChanges( bRecordChanges );
1004 void SwXMLTextImportHelper::SetChangesProtectionKey(
1005 const Sequence<sal_Int8> & rKey )
1007 if ( nullptr != m_pRedlineHelper )
1008 m_pRedlineHelper->SetProtectionKey( rKey );
1011 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */