1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
45 #include <IDocumentDrawModelAccess.hxx>
46 #include <IDocumentContentOperations.hxx>
47 #include <fmtfsize.hxx>
48 #include <fmtanchr.hxx>
49 #include <fmtcntnt.hxx>
51 #include "xmltbli.hxx"
52 #include "xmltexti.hxx"
53 #include "XMLRedlineImportHelper.hxx"
54 #include <xmloff/XMLFilterServiceNames.h>
55 #include <SwAppletImpl.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>
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
);
95 nHeight
= o3tl::toTwips(nHeight
, o3tl::Length::mm100
);
96 if( nHeight
< MINFLY
)
98 rItemSet
.Put( SwFormatFrameSize( SwFrameSize::Fixed
, nWidth
, nHeight
) );
101 SwFormatAnchor
aAnchor( RndStdIds::FLY_AT_CHAR
);
102 rItemSet
.Put( aAnchor
);
106 pTwipSize
->setWidth( nWidth
);
107 pTwipSize
->setHeight( nHeight
);
111 static void lcl_setObjectVisualArea( const uno::Reference
< embed::XEmbeddedObject
>& xObj
,
113 const Size
& aVisSize
,
114 const MapUnit
& aUnit
)
116 if( !(xObj
.is() && nAspect
!= embed::Aspects::MSOLE_ICON
) )
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
));
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
& )
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;
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" );
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( ':' );
214 OUString
aObjName( rHRef
.copy( nPos
+1) );
216 if( aObjName
.isEmpty() )
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
,
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
);
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()) }
258 uno::Reference
< embed::XEmbeddedObject
> xObj( xFactory
->createInstanceInitNew(
259 aClass
, OUString(), xStorage
, "DummyName", aObjArgs
), uno::UNO_QUERY
);
262 //TODO/LATER: is it enough to only set the VisAreaSize?
263 lcl_setObjectVisualArea( xObj
, embed::Aspects::MSOLE_CONTENT
, aTwipSize
, MapUnit::MapTwip
);
268 pFrameFormat
= pDoc
->getIDocumentContentOperations().InsertEmbObject(
269 *pTextCursor
->GetPaM(),
270 ::svt::EmbeddedObjectRef(xObj
, embed::Aspects::MSOLE_CONTENT
),
272 pOLENd
= lcl_GetOLENode( pFrameFormat
);
276 aObjName
= pOLENd
->GetOLEObj().GetCurrentPersistName();
278 catch ( uno::Exception
& )
285 // check whether an object with this name already exists in the document
287 SwIterator
<SwContentNode
,SwFormatColl
> aIter( *pDoc
->GetDfltGrfFormatColl() );
288 for( SwContentNode
* pNd
= aIter
.First(); pNd
; pNd
= aIter
.Next() )
290 SwOLENode
* pExistingOLENd
= pNd
->GetOLENode();
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(),
306 catch ( uno::Exception
& )
308 OSL_FAIL( "Couldn't create a copy of the object!" );
316 if ( aName
.isEmpty() )
319 // the correct aspect will be set later
320 // TODO/LATER: Actually it should be set here
323 pFrameFormat
= pDoc
->getIDocumentContentOperations().InsertOLE( *pTextCursor
->GetPaM(), aName
, embed::Aspects::MSOLE_CONTENT
, &aItemSet
, nullptr );
324 pOLENd
= lcl_GetOLENode( pFrameFormat
);
335 pOLENd
= lcl_GetOLENode( pFrameFormat
);
337 pOLENd
->SetOLESizeInvalid( true );
340 xPropSet
.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
341 *pDoc
, pFrameFormat
), uno::UNO_QUERY
);
342 if( pDoc
->getIDocumentDrawModelAccess().GetDrawModel() )
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;
358 for( sal_Int32 i
=0; i
< rTableName
.getLength(); i
++ )
360 bool bEndOfNameFound
= false;
361 sal_Unicode c
= rTableName
[i
];
372 bEndOfNameFound
= true;
398 bEndOfNameFound
= true;
413 if( bError
|| bEndOfNameFound
)
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
);
431 rtl::Reference
< SvXMLImportPropertyMapper
> xImpPrMap
=
433 ->GetImportPropertyMapper(pStyle
->GetFamily());
434 OSL_ENSURE( xImpPrMap
.is(), "Where is the import prop mapper?" );
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
;
448 switch( rPropMapper
->GetEntryContextId(nIdx
) )
450 case CTF_OLE_VIS_AREA_LEFT
:
453 rProp
.maValue
>>= nVal
;
454 aVisArea
.SetPosX( nVal
);
457 case CTF_OLE_VIS_AREA_TOP
:
460 rProp
.maValue
>>= nVal
;
461 aVisArea
.SetPosY( nVal
);
464 case CTF_OLE_VIS_AREA_WIDTH
:
467 rProp
.maValue
>>= nVal
;
468 aVisArea
.setWidth( nVal
);
469 bHasSizeProps
= true;
472 case CTF_OLE_VIS_AREA_HEIGHT
:
475 rProp
.maValue
>>= nVal
;
476 aVisArea
.setHeight( nVal
);
477 bHasSizeProps
= true;
480 case CTF_OLE_DRAW_ASPECT
:
482 rProp
.maValue
>>= nDrawAspect
;
485 nDrawAspect
= embed::Aspects::MSOLE_CONTENT
;
488 pOLENd
->GetOLEObj().GetObject().SetViewAspect( nDrawAspect
);
499 uno::Reference
< embed::XEmbeddedObject
> xObj
=
500 pDoc
->GetPersist()->GetEmbeddedObjectContainer().GetEmbeddedObject( aObjName
);
502 lcl_setObjectVisualArea( xObj
, ( nDrawAspect
? nDrawAspect
: embed::Aspects::MSOLE_CONTENT
),
503 aVisArea
.GetSize(), MapUnit::Map100thMM
);
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
,
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
) );
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
),
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?
601 uno::Reference
< XPropertySet
> SwXMLTextImportHelper::createAndInsertApplet(
602 const OUString
&rName
,
603 const OUString
&rCode
,
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
);
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() )
644 SwXFrame::GetOrCreateSdrObject(*static_cast<SwFlyFrameFormat
*>(pFrameFormat
));
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
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
)
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
);
698 xSet
->setPropertyValue("PluginURL",
699 makeAny( aURLObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
) ) );
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
),
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
& )
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
);
754 rtl::Reference
< SvXMLImportPropertyMapper
> xImpPrMap
=
756 ->GetImportPropertyMapper(pStyle
->GetFamily());
757 OSL_ENSURE( xImpPrMap
.is(), "Where is the import prop mapper?" );
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
;
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
;
779 case CTF_FRAME_DISPLAY_BORDER
:
781 bHasBorder
= *o3tl::doAccess
<bool>(rProp
.maValue
);
785 case CTF_FRAME_MARGIN_HORI
:
787 sal_Int32 nVal
= SIZE_NOT_SET
;
788 rProp
.maValue
>>= nVal
;
789 aMargin
.setWidth( nVal
);
792 case CTF_FRAME_MARGIN_VERT
:
794 sal_Int32 nVal
= SIZE_NOT_SET
;
795 rProp
.maValue
>>= nVal
;
796 aMargin
.setHeight( nVal
);
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
);
826 OUString sHRef
= URIHelper::SmartRel2Abs(
827 INetURLObject( GetXMLImport().GetBaseURL() ), rHRef
);
829 if (INetURLObject(sHRef
).GetProtocol() == INetProtocol::Macro
)
830 GetXMLImport().NotifyMacroEventRead();
832 xSet
->setPropertyValue("FrameURL",
835 xSet
->setPropertyValue("FrameName",
838 if ( eScrollMode
== ScrollingMode::Auto
)
839 xSet
->setPropertyValue("FrameIsAutoScroll",
842 xSet
->setPropertyValue("FrameIsScrollingMode",
843 makeAny( eScrollMode
== ScrollingMode::Yes
) );
846 xSet
->setPropertyValue("FrameIsBorder",
847 makeAny( bHasBorder
) );
849 xSet
->setPropertyValue("FrameIsAutoBorder",
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
),
864 xPropSet
.set(SwXTextEmbeddedObject::CreateXTextEmbeddedObject(
865 *pDoc
, pFrameFormat
), uno::UNO_QUERY
);
866 if( pDoc
->getIDocumentDrawModelAccess().GetDrawModel() )
869 SwXFrame::GetOrCreateSdrObject(*
870 static_cast<SwFlyFrameFormat
*>(pFrameFormat
));
874 catch ( uno::Exception
& )
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
) )
902 uno::Reference
< beans::XPropertySet
> xSet( xEmbObj
->getComponent(), uno::UNO_QUERY
);
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
,
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
,
942 const OUString
& rAuthor
,
943 const OUString
& rComment
,
944 const util::DateTime
& rDateTime
,
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
,
954 uno::Reference
<XTextCursor
> SwXMLTextImportHelper::RedlineCreateText(
955 uno::Reference
<XTextCursor
> & rOldCursor
,
958 uno::Reference
<XTextCursor
> xRet
;
960 if (nullptr != m_pRedlineHelper
)
962 xRet
= m_pRedlineHelper
->CreateRedlineTextSection(rOldCursor
, rId
);
968 void SwXMLTextImportHelper::RedlineSetCursor(
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: */