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 <sal/config.h>
22 #include <com/sun/star/awt/XVclWindowPeer.hpp>
23 #include <com/sun/star/frame/XDispatch.hpp>
24 #include <com/sun/star/frame/Frame.hpp>
25 #include <com/sun/star/frame/XFrame2.hpp>
26 #include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
27 #include <com/sun/star/task/InteractionHandler.hpp>
28 #include <com/sun/star/util/URLTransformer.hpp>
29 #include <com/sun/star/util/XURLTransformer.hpp>
30 #include <com/sun/star/util/XCloseable.hpp>
31 #include <com/sun/star/lang/XEventListener.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
35 #include <com/sun/star/embed/XEmbeddedObject.hpp>
37 #include <comphelper/propertyvalue.hxx>
38 #include <cppuhelper/implbase.hxx>
39 #include <cppuhelper/supportsservice.hxx>
40 #include <officecfg/Office/Common.hxx>
41 #include <svl/itemprop.hxx>
42 #include <sfx2/docfile.hxx>
43 #include <sfx2/frmdescr.hxx>
44 #include <sfx2/objsh.hxx>
45 #include <sfx2/sfxdlg.hxx>
46 #include <toolkit/helper/vclunohelper.hxx>
48 #include <vcl/window.hxx>
49 #include <tools/debug.hxx>
50 #include <macroloader.hxx>
51 #include <eventsupplier.hxx>
53 using namespace ::com::sun::star
;
57 class IFrameObject
: public ::cppu::WeakImplHelper
<
58 css::util::XCloseable
,
59 css::lang::XEventListener
,
60 css::frame::XSynchronousFrameLoader
,
61 css::ui::dialogs::XExecutableDialog
,
62 css::lang::XServiceInfo
,
63 css::beans::XPropertySet
>
65 css::uno::Reference
< css::uno::XComponentContext
> mxContext
;
66 css::uno::Reference
< css::frame::XFrame2
> mxFrame
;
67 css::uno::Reference
< css::embed::XEmbeddedObject
> mxObj
;
68 SfxItemPropertyMap maPropMap
;
69 SfxFrameDescriptor maFrmDescr
;
72 /// @throws css::uno::Exception
73 /// @throws css::uno::RuntimeException
74 IFrameObject(css::uno::Reference
< css::uno::XComponentContext
> xContext
, const css::uno::Sequence
< css::uno::Any
>& aArguments
);
76 virtual OUString SAL_CALL
getImplementationName() override
78 return u
"com.sun.star.comp.sfx2.IFrameObject"_ustr
;
81 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
83 return cppu::supportsService(this, ServiceName
);
86 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
88 css::uno::Sequence
< OUString
> aSeq
{ u
"com.sun.star.frame.SpecialEmbeddedObject"_ustr
};
92 virtual sal_Bool SAL_CALL
load( const css::uno::Sequence
< css::beans::PropertyValue
>& lDescriptor
,
93 const css::uno::Reference
< css::frame::XFrame
>& xFrame
) override
;
94 virtual void SAL_CALL
cancel() override
;
95 virtual void SAL_CALL
close( sal_Bool bDeliverOwnership
) override
;
96 virtual void SAL_CALL
addCloseListener( const css::uno::Reference
< css::util::XCloseListener
>& xListener
) override
;
97 virtual void SAL_CALL
removeCloseListener( const css::uno::Reference
< css::util::XCloseListener
>& xListener
) override
;
98 virtual void SAL_CALL
disposing( const css::lang::EventObject
& aEvent
) override
;
99 virtual void SAL_CALL
setTitle( const OUString
& aTitle
) override
;
100 virtual ::sal_Int16 SAL_CALL
execute( ) override
;
101 virtual css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
getPropertySetInfo() override
;
102 virtual void SAL_CALL
addPropertyChangeListener(const OUString
& aPropertyName
, const css::uno::Reference
< css::beans::XPropertyChangeListener
> & aListener
) override
;
103 virtual void SAL_CALL
removePropertyChangeListener(const OUString
& aPropertyName
, const css::uno::Reference
< css::beans::XPropertyChangeListener
> & aListener
) override
;
104 virtual void SAL_CALL
addVetoableChangeListener(const OUString
& aPropertyName
, const css::uno::Reference
< css::beans::XVetoableChangeListener
> & aListener
) override
;
105 virtual void SAL_CALL
removeVetoableChangeListener(const OUString
& aPropertyName
, const css::uno::Reference
< css::beans::XVetoableChangeListener
> & aListener
) override
;
106 virtual void SAL_CALL
setPropertyValue( const OUString
& aPropertyName
, const css::uno::Any
& aValue
) override
;
107 virtual css::uno::Any SAL_CALL
getPropertyValue( const OUString
& PropertyName
) override
;
110 class IFrameWindow_Impl
: public vcl::Window
113 IFrameWindow_Impl( vcl::Window
*pParent
, bool bHasBorder
);
116 IFrameWindow_Impl::IFrameWindow_Impl( vcl::Window
*pParent
, bool bHasBorder
)
117 : Window( pParent
, WB_CLIPCHILDREN
| WB_NODIALOGCONTROL
)
120 SetBorderStyle( WindowBorderStyle::NOBORDER
);
122 SetBorderStyle( WindowBorderStyle::NORMAL
);
125 #define PROPERTY_UNBOUND 0
127 #define WID_FRAME_URL 1
128 #define WID_FRAME_NAME 2
129 #define WID_FRAME_IS_AUTO_SCROLL 3
130 #define WID_FRAME_IS_SCROLLING_MODE 4
131 #define WID_FRAME_IS_BORDER 5
132 #define WID_FRAME_IS_AUTO_BORDER 6
133 #define WID_FRAME_MARGIN_WIDTH 7
134 #define WID_FRAME_MARGIN_HEIGHT 8
136 std::span
<const SfxItemPropertyMapEntry
> lcl_GetIFramePropertyMap_Impl()
138 static const SfxItemPropertyMapEntry aIFramePropertyMap_Impl
[] =
140 { u
"FrameIsAutoBorder"_ustr
, WID_FRAME_IS_AUTO_BORDER
, cppu::UnoType
<bool>::get(), PROPERTY_UNBOUND
, 0 },
141 { u
"FrameIsAutoScroll"_ustr
, WID_FRAME_IS_AUTO_SCROLL
, cppu::UnoType
<bool>::get(), PROPERTY_UNBOUND
, 0 },
142 { u
"FrameIsBorder"_ustr
, WID_FRAME_IS_BORDER
, cppu::UnoType
<bool>::get(), PROPERTY_UNBOUND
, 0 },
143 { u
"FrameIsScrollingMode"_ustr
, WID_FRAME_IS_SCROLLING_MODE
,cppu::UnoType
<bool>::get(), PROPERTY_UNBOUND
, 0 },
144 { u
"FrameMarginHeight"_ustr
, WID_FRAME_MARGIN_HEIGHT
, cppu::UnoType
<sal_Int32
>::get(), PROPERTY_UNBOUND
, 0 },
145 { u
"FrameMarginWidth"_ustr
, WID_FRAME_MARGIN_WIDTH
, cppu::UnoType
<sal_Int32
>::get(), PROPERTY_UNBOUND
, 0 },
146 { u
"FrameName"_ustr
, WID_FRAME_NAME
, cppu::UnoType
<OUString
>::get(), PROPERTY_UNBOUND
, 0 },
147 { u
"FrameURL"_ustr
, WID_FRAME_URL
, cppu::UnoType
<OUString
>::get(), PROPERTY_UNBOUND
, 0 },
149 return aIFramePropertyMap_Impl
;
152 IFrameObject::IFrameObject(uno::Reference
< uno::XComponentContext
> xContext
, const css::uno::Sequence
< css::uno::Any
>& aArguments
)
153 : mxContext(std::move( xContext
))
154 , maPropMap( lcl_GetIFramePropertyMap_Impl() )
156 if ( aArguments
.hasElements() )
157 aArguments
[0] >>= mxObj
;
160 sal_Bool SAL_CALL
IFrameObject::load(
161 const uno::Sequence
< css::beans::PropertyValue
>& /*lDescriptor*/,
162 const uno::Reference
< frame::XFrame
>& xFrame
)
164 if ( officecfg::Office::Common::Misc::PluginsEnabled::get() )
166 util::URL aTargetURL
;
167 aTargetURL
.Complete
= maFrmDescr
.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
168 uno::Reference
< util::XURLTransformer
> xTrans( util::URLTransformer::create( mxContext
) );
169 xTrans
->parseStrict( aTargetURL
);
171 INetURLObject
aURLObject(aTargetURL
.Complete
);
172 if (aURLObject
.IsExoticProtocol())
174 SAL_WARN("sfx", "IFrameObject::load ignoring: " << aTargetURL
.Complete
);
178 uno::Reference
<frame::XFramesSupplier
> xParentFrame
= xFrame
->getCreator();
179 SfxObjectShell
* pDoc
= SfxMacroLoader::GetObjectShell(xParentFrame
);
181 const bool bIsFactoryURL
= aTargetURL
.Complete
.startsWith("private:factory/");
184 bool bUpdateAllowed(true);
187 comphelper::EmbeddedObjectContainer
& rEmbeddedObjectContainer
= pDoc
->getEmbeddedObjectContainer();
188 bUpdateAllowed
= rEmbeddedObjectContainer
.getUserAllowsLinkUpdate();
195 if (pDoc
&& pDoc
->HasName())
196 sReferer
= pDoc
->GetMedium()->GetName();
198 uno::Reference
<css::awt::XWindow
> xParentWindow(xFrame
->getContainerWindow());
202 VclPtr
<vcl::Window
> pParent
= VCLUnoHelper::GetWindow(xParentWindow
);
203 VclPtr
<IFrameWindow_Impl
> pWin
= VclPtr
<IFrameWindow_Impl
>::Create( pParent
, maFrmDescr
.IsFrameBorderOn() );
204 pWin
->SetSizePixel( pParent
->GetOutputSizePixel() );
205 pWin
->SetBackground();
208 uno::Reference
< awt::XWindow
> xWindow( pWin
->GetComponentInterface(), uno::UNO_QUERY
);
209 xFrame
->setComponent( xWindow
, uno::Reference
< frame::XController
>() );
211 // we must destroy the IFrame before the parent is destroyed
212 xWindow
->addEventListener( this );
214 mxFrame
= frame::Frame::create( mxContext
);
215 uno::Reference
< awt::XWindow
> xWin( pWin
->GetComponentInterface(), uno::UNO_QUERY
);
216 mxFrame
->initialize( xWin
);
217 mxFrame
->setName( maFrmDescr
.GetName() );
219 uno::Reference
< frame::XFramesSupplier
> xFramesSupplier( xFrame
, uno::UNO_QUERY
);
220 if ( xFramesSupplier
.is() )
221 mxFrame
->setCreator( xFramesSupplier
);
224 uno::Reference
<task::XInteractionHandler
> xInteractionHandler(task::InteractionHandler::createWithParent(mxContext
, xParentWindow
));
225 uno::Sequence
< beans::PropertyValue
> aProps
{
226 comphelper::makePropertyValue(u
"PluginMode"_ustr
, sal_Int16(2)),
227 comphelper::makePropertyValue(u
"ReadOnly"_ustr
, true),
228 comphelper::makePropertyValue(u
"InteractionHandler"_ustr
, xInteractionHandler
),
229 comphelper::makePropertyValue(u
"Referer"_ustr
, sReferer
)
231 uno::Reference
< frame::XDispatch
> xDisp
= mxFrame
->queryDispatch( aTargetURL
, u
"_self"_ustr
, 0 );
233 xDisp
->dispatch( aTargetURL
, aProps
);
241 void SAL_CALL
IFrameObject::cancel()
245 uno::Reference
< util::XCloseable
> xClose( mxFrame
, uno::UNO_QUERY
);
247 xClose
->close( true );
250 catch (const uno::Exception
&)
255 void SAL_CALL
IFrameObject::close( sal_Bool
/*bDeliverOwnership*/ )
259 void SAL_CALL
IFrameObject::addCloseListener( const css::uno::Reference
< css::util::XCloseListener
>& )
263 void SAL_CALL
IFrameObject::removeCloseListener( const css::uno::Reference
< css::util::XCloseListener
>& )
267 void SAL_CALL
IFrameObject::disposing( const css::lang::EventObject
& )
272 uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
IFrameObject::getPropertySetInfo()
274 static uno::Reference
< beans::XPropertySetInfo
> xInfo
= new SfxItemPropertySetInfo( maPropMap
);
278 void SAL_CALL
IFrameObject::setPropertyValue(const OUString
& aPropertyName
, const uno::Any
& aAny
)
280 const SfxItemPropertyMapEntry
* pEntry
= maPropMap
.getByName( aPropertyName
);
282 throw beans::UnknownPropertyException(aPropertyName
);
283 switch( pEntry
->nWID
)
289 maFrmDescr
.SetURL( aURL
);
295 if ( aAny
>>= aName
)
296 maFrmDescr
.SetName( aName
);
299 case WID_FRAME_IS_AUTO_SCROLL
:
302 if ( (aAny
>>= bIsAutoScroll
) && bIsAutoScroll
)
303 maFrmDescr
.SetScrollingMode( ScrollingMode::Auto
);
306 case WID_FRAME_IS_SCROLLING_MODE
:
309 if ( aAny
>>= bIsScroll
)
310 maFrmDescr
.SetScrollingMode( bIsScroll
? ScrollingMode::Yes
: ScrollingMode::No
);
313 case WID_FRAME_IS_BORDER
:
316 if ( aAny
>>= bIsBorder
)
317 maFrmDescr
.SetFrameBorder( bIsBorder
);
320 case WID_FRAME_IS_AUTO_BORDER
:
323 if ( aAny
>>= bIsAutoBorder
)
325 bool bBorder
= maFrmDescr
.IsFrameBorderOn();
326 maFrmDescr
.ResetBorder();
328 maFrmDescr
.SetFrameBorder( bBorder
);
332 case WID_FRAME_MARGIN_WIDTH
:
334 sal_Int32 nMargin
= 0;
335 Size aSize
= maFrmDescr
.GetMargin();
336 if ( aAny
>>= nMargin
)
338 aSize
.setWidth( nMargin
);
339 maFrmDescr
.SetMargin( aSize
);
343 case WID_FRAME_MARGIN_HEIGHT
:
345 sal_Int32 nMargin
= 0;
346 Size aSize
= maFrmDescr
.GetMargin();
347 if ( aAny
>>= nMargin
)
349 aSize
.setHeight( nMargin
);
350 maFrmDescr
.SetMargin( aSize
);
358 uno::Any SAL_CALL
IFrameObject::getPropertyValue(const OUString
& aPropertyName
)
360 const SfxItemPropertyMapEntry
* pEntry
= maPropMap
.getByName( aPropertyName
);
362 throw beans::UnknownPropertyException(aPropertyName
);
364 switch( pEntry
->nWID
)
368 aAny
<<= maFrmDescr
.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE
);
373 aAny
<<= maFrmDescr
.GetName();
376 case WID_FRAME_IS_AUTO_SCROLL
:
378 bool bIsAutoScroll
= ( maFrmDescr
.GetScrollingMode() == ScrollingMode::Auto
);
379 aAny
<<= bIsAutoScroll
;
382 case WID_FRAME_IS_SCROLLING_MODE
:
384 bool bIsScroll
= ( maFrmDescr
.GetScrollingMode() == ScrollingMode::Yes
);
388 case WID_FRAME_IS_BORDER
:
390 bool bIsBorder
= maFrmDescr
.IsFrameBorderOn();
394 case WID_FRAME_IS_AUTO_BORDER
:
396 bool bIsAutoBorder
= !maFrmDescr
.IsFrameBorderSet();
397 aAny
<<= bIsAutoBorder
;
400 case WID_FRAME_MARGIN_WIDTH
:
402 aAny
<<= static_cast<sal_Int32
>(maFrmDescr
.GetMargin().Width());
405 case WID_FRAME_MARGIN_HEIGHT
:
407 aAny
<<= static_cast<sal_Int32
>(maFrmDescr
.GetMargin().Height());
415 void SAL_CALL
IFrameObject::addPropertyChangeListener(const OUString
&, const css::uno::Reference
< css::beans::XPropertyChangeListener
> & )
419 void SAL_CALL
IFrameObject::removePropertyChangeListener(const OUString
&, const css::uno::Reference
< css::beans::XPropertyChangeListener
> & )
423 void SAL_CALL
IFrameObject::addVetoableChangeListener(const OUString
&, const css::uno::Reference
< css::beans::XVetoableChangeListener
> & )
427 void SAL_CALL
IFrameObject::removeVetoableChangeListener(const OUString
&, const css::uno::Reference
< css::beans::XVetoableChangeListener
> & )
431 ::sal_Int16 SAL_CALL
IFrameObject::execute()
433 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
434 //we really should set a parent here
435 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateEditObjectDialog(nullptr, u
".uno:InsertObjectFloatingFrame"_ustr
, mxObj
));
440 void SAL_CALL
IFrameObject::setTitle( const OUString
& )
446 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
447 com_sun_star_comp_sfx2_IFrameObject_get_implementation(
448 css::uno::XComponentContext
*context
,
449 css::uno::Sequence
<css::uno::Any
> const &arguments
)
451 return cppu::acquire(new IFrameObject(context
, arguments
));
454 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */