check IFrame "FrameURL" target
[LibreOffice.git] / sfx2 / source / doc / iframe.cxx
blob80e0c4e684574c7d1d760254aec74de163dee35f
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 <sal/config.h>
22 #include <com/sun/star/awt/XWindowPeer.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/util/URLTransformer.hpp>
28 #include <com/sun/star/util/XURLTransformer.hpp>
29 #include <com/sun/star/util/XCloseable.hpp>
30 #include <com/sun/star/lang/XEventListener.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
34 #include <com/sun/star/embed/XEmbeddedObject.hpp>
36 #include <comphelper/propertyvalue.hxx>
37 #include <cppuhelper/implbase.hxx>
38 #include <cppuhelper/supportsservice.hxx>
39 #include <officecfg/Office/Common.hxx>
40 #include <svl/itemprop.hxx>
41 #include <sfx2/frmdescr.hxx>
42 #include <sfx2/objsh.hxx>
43 #include <sfx2/sfxdlg.hxx>
44 #include <toolkit/helper/vclunohelper.hxx>
45 #include <vcl/window.hxx>
46 #include <tools/debug.hxx>
47 #include <macroloader.hxx>
49 using namespace ::com::sun::star;
51 namespace {
53 class IFrameObject : public ::cppu::WeakImplHelper <
54 css::util::XCloseable,
55 css::lang::XEventListener,
56 css::frame::XSynchronousFrameLoader,
57 css::ui::dialogs::XExecutableDialog,
58 css::lang::XServiceInfo,
59 css::beans::XPropertySet >
61 css::uno::Reference < css::uno::XComponentContext > mxContext;
62 css::uno::Reference < css::frame::XFrame2 > mxFrame;
63 css::uno::Reference < css::embed::XEmbeddedObject > mxObj;
64 SfxItemPropertyMap maPropMap;
65 SfxFrameDescriptor maFrmDescr;
67 public:
68 /// @throws css::uno::Exception
69 /// @throws css::uno::RuntimeException
70 IFrameObject(const css::uno::Reference < css::uno::XComponentContext>& rxContext, const css::uno::Sequence< css::uno::Any >& aArguments);
72 virtual OUString SAL_CALL getImplementationName() override
74 return "com.sun.star.comp.sfx2.IFrameObject";
77 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
79 return cppu::supportsService(this, ServiceName);
82 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
84 css::uno::Sequence< OUString > aSeq { "com.sun.star.frame.SpecialEmbeddedObject" };
85 return aSeq;
88 virtual sal_Bool SAL_CALL load( const css::uno::Sequence < css::beans::PropertyValue >& lDescriptor,
89 const css::uno::Reference < css::frame::XFrame >& xFrame ) override;
90 virtual void SAL_CALL cancel() override;
91 virtual void SAL_CALL close( sal_Bool bDeliverOwnership ) override;
92 virtual void SAL_CALL addCloseListener( const css::uno::Reference < css::util::XCloseListener >& xListener ) override;
93 virtual void SAL_CALL removeCloseListener( const css::uno::Reference < css::util::XCloseListener >& xListener ) override;
94 virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) override ;
95 virtual void SAL_CALL setTitle( const OUString& aTitle ) override;
96 virtual ::sal_Int16 SAL_CALL execute( ) override;
97 virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
98 virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > & aListener) override;
99 virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > & aListener) override;
100 virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > & aListener) override;
101 virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > & aListener) override;
102 virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override;
103 virtual css::uno::Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
106 class IFrameWindow_Impl : public vcl::Window
108 public:
109 IFrameWindow_Impl( vcl::Window *pParent, bool bHasBorder );
112 IFrameWindow_Impl::IFrameWindow_Impl( vcl::Window *pParent, bool bHasBorder )
113 : Window( pParent, WB_CLIPCHILDREN | WB_NODIALOGCONTROL )
115 if ( !bHasBorder )
116 SetBorderStyle( WindowBorderStyle::NOBORDER );
117 else
118 SetBorderStyle( WindowBorderStyle::NORMAL );
121 #define PROPERTY_UNBOUND 0
123 #define WID_FRAME_URL 1
124 #define WID_FRAME_NAME 2
125 #define WID_FRAME_IS_AUTO_SCROLL 3
126 #define WID_FRAME_IS_SCROLLING_MODE 4
127 #define WID_FRAME_IS_BORDER 5
128 #define WID_FRAME_IS_AUTO_BORDER 6
129 #define WID_FRAME_MARGIN_WIDTH 7
130 #define WID_FRAME_MARGIN_HEIGHT 8
132 const SfxItemPropertyMapEntry* lcl_GetIFramePropertyMap_Impl()
134 static const SfxItemPropertyMapEntry aIFramePropertyMap_Impl[] =
136 { u"FrameIsAutoBorder", WID_FRAME_IS_AUTO_BORDER, cppu::UnoType<bool>::get(), PROPERTY_UNBOUND, 0 },
137 { u"FrameIsAutoScroll", WID_FRAME_IS_AUTO_SCROLL, cppu::UnoType<bool>::get(), PROPERTY_UNBOUND, 0 },
138 { u"FrameIsBorder", WID_FRAME_IS_BORDER, cppu::UnoType<bool>::get(), PROPERTY_UNBOUND, 0 },
139 { u"FrameIsScrollingMode", WID_FRAME_IS_SCROLLING_MODE,cppu::UnoType<bool>::get(), PROPERTY_UNBOUND, 0 },
140 { u"FrameMarginHeight", WID_FRAME_MARGIN_HEIGHT, cppu::UnoType<sal_Int32>::get(), PROPERTY_UNBOUND, 0 },
141 { u"FrameMarginWidth", WID_FRAME_MARGIN_WIDTH, cppu::UnoType<sal_Int32>::get(), PROPERTY_UNBOUND, 0 },
142 { u"FrameName", WID_FRAME_NAME, cppu::UnoType<OUString>::get(), PROPERTY_UNBOUND, 0 },
143 { u"FrameURL", WID_FRAME_URL, cppu::UnoType<OUString>::get(), PROPERTY_UNBOUND, 0 },
144 { u"", 0, css::uno::Type(), 0, 0 }
146 return aIFramePropertyMap_Impl;
149 IFrameObject::IFrameObject(const uno::Reference < uno::XComponentContext >& rxContext, const css::uno::Sequence< css::uno::Any >& aArguments)
150 : mxContext( rxContext )
151 , maPropMap( lcl_GetIFramePropertyMap_Impl() )
153 if ( aArguments.hasElements() )
154 aArguments[0] >>= mxObj;
157 sal_Bool SAL_CALL IFrameObject::load(
158 const uno::Sequence < css::beans::PropertyValue >& /*lDescriptor*/,
159 const uno::Reference < frame::XFrame >& xFrame )
161 if ( officecfg::Office::Common::Misc::PluginsEnabled::get() )
163 util::URL aTargetURL;
164 aTargetURL.Complete = maFrmDescr.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE );
165 uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( mxContext ) );
166 xTrans->parseStrict( aTargetURL );
168 if (INetURLObject(aTargetURL.Complete).GetProtocol() == INetProtocol::Macro)
170 uno::Reference<frame::XFramesSupplier> xParentFrame = xFrame->getCreator();
171 SfxObjectShell* pDoc = SfxMacroLoader::GetObjectShell(xParentFrame);
172 if (pDoc && !pDoc->AdjustMacroMode())
173 return false;
176 DBG_ASSERT( !mxFrame.is(), "Frame already existing!" );
177 VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() );
178 VclPtr<IFrameWindow_Impl> pWin = VclPtr<IFrameWindow_Impl>::Create( pParent, maFrmDescr.IsFrameBorderOn() );
179 pWin->SetSizePixel( pParent->GetOutputSizePixel() );
180 pWin->SetBackground();
181 pWin->Show();
183 uno::Reference < awt::XWindow > xWindow( pWin->GetComponentInterface(), uno::UNO_QUERY );
184 xFrame->setComponent( xWindow, uno::Reference < frame::XController >() );
186 // we must destroy the IFrame before the parent is destroyed
187 xWindow->addEventListener( this );
189 mxFrame = frame::Frame::create( mxContext );
190 uno::Reference < awt::XWindow > xWin( pWin->GetComponentInterface(), uno::UNO_QUERY );
191 mxFrame->initialize( xWin );
192 mxFrame->setName( maFrmDescr.GetName() );
194 uno::Reference < frame::XFramesSupplier > xFramesSupplier( xFrame, uno::UNO_QUERY );
195 if ( xFramesSupplier.is() )
196 mxFrame->setCreator( xFramesSupplier );
198 uno::Sequence < beans::PropertyValue > aProps{
199 comphelper::makePropertyValue("PluginMode", sal_Int16(2)),
200 comphelper::makePropertyValue("ReadOnly", true)
202 uno::Reference < frame::XDispatch > xDisp = mxFrame->queryDispatch( aTargetURL, "_self", 0 );
203 if ( xDisp.is() )
204 xDisp->dispatch( aTargetURL, aProps );
206 return true;
209 return false;
212 void SAL_CALL IFrameObject::cancel()
216 uno::Reference < util::XCloseable > xClose( mxFrame, uno::UNO_QUERY );
217 if ( xClose.is() )
218 xClose->close( true );
219 mxFrame = nullptr;
221 catch (const uno::Exception&)
226 void SAL_CALL IFrameObject::close( sal_Bool /*bDeliverOwnership*/ )
230 void SAL_CALL IFrameObject::addCloseListener( const css::uno::Reference < css::util::XCloseListener >& )
234 void SAL_CALL IFrameObject::removeCloseListener( const css::uno::Reference < css::util::XCloseListener >& )
238 void SAL_CALL IFrameObject::disposing( const css::lang::EventObject& )
240 cancel();
243 uno::Reference< beans::XPropertySetInfo > SAL_CALL IFrameObject::getPropertySetInfo()
245 static uno::Reference< beans::XPropertySetInfo > xInfo = new SfxItemPropertySetInfo( maPropMap );
246 return xInfo;
249 void SAL_CALL IFrameObject::setPropertyValue(const OUString& aPropertyName, const uno::Any& aAny)
251 const SfxItemPropertyMapEntry* pEntry = maPropMap.getByName( aPropertyName );
252 if( !pEntry )
253 throw beans::UnknownPropertyException(aPropertyName);
254 switch( pEntry->nWID )
256 case WID_FRAME_URL:
258 OUString aURL;
259 aAny >>= aURL;
260 maFrmDescr.SetURL( aURL );
262 break;
263 case WID_FRAME_NAME:
265 OUString aName;
266 if ( aAny >>= aName )
267 maFrmDescr.SetName( aName );
269 break;
270 case WID_FRAME_IS_AUTO_SCROLL:
272 bool bIsAutoScroll;
273 if ( (aAny >>= bIsAutoScroll) && bIsAutoScroll )
274 maFrmDescr.SetScrollingMode( ScrollingMode::Auto );
276 break;
277 case WID_FRAME_IS_SCROLLING_MODE:
279 bool bIsScroll;
280 if ( aAny >>= bIsScroll )
281 maFrmDescr.SetScrollingMode( bIsScroll ? ScrollingMode::Yes : ScrollingMode::No );
283 break;
284 case WID_FRAME_IS_BORDER:
286 bool bIsBorder;
287 if ( aAny >>= bIsBorder )
288 maFrmDescr.SetFrameBorder( bIsBorder );
290 break;
291 case WID_FRAME_IS_AUTO_BORDER:
293 bool bIsAutoBorder;
294 if ( aAny >>= bIsAutoBorder )
296 bool bBorder = maFrmDescr.IsFrameBorderOn();
297 maFrmDescr.ResetBorder();
298 if ( bIsAutoBorder )
299 maFrmDescr.SetFrameBorder( bBorder );
302 break;
303 case WID_FRAME_MARGIN_WIDTH:
305 sal_Int32 nMargin = 0;
306 Size aSize = maFrmDescr.GetMargin();
307 if ( aAny >>= nMargin )
309 aSize.setWidth( nMargin );
310 maFrmDescr.SetMargin( aSize );
313 break;
314 case WID_FRAME_MARGIN_HEIGHT:
316 sal_Int32 nMargin = 0;
317 Size aSize = maFrmDescr.GetMargin();
318 if ( aAny >>= nMargin )
320 aSize.setHeight( nMargin );
321 maFrmDescr.SetMargin( aSize );
324 break;
325 default: ;
329 uno::Any SAL_CALL IFrameObject::getPropertyValue(const OUString& aPropertyName)
331 const SfxItemPropertyMapEntry* pEntry = maPropMap.getByName( aPropertyName );
332 if( !pEntry )
333 throw beans::UnknownPropertyException(aPropertyName);
334 uno::Any aAny;
335 switch( pEntry->nWID )
337 case WID_FRAME_URL:
339 aAny <<= maFrmDescr.GetURL().GetMainURL( INetURLObject::DecodeMechanism::NONE );
341 break;
342 case WID_FRAME_NAME:
344 aAny <<= maFrmDescr.GetName();
346 break;
347 case WID_FRAME_IS_AUTO_SCROLL:
349 bool bIsAutoScroll = ( maFrmDescr.GetScrollingMode() == ScrollingMode::Auto );
350 aAny <<= bIsAutoScroll;
352 break;
353 case WID_FRAME_IS_SCROLLING_MODE:
355 bool bIsScroll = ( maFrmDescr.GetScrollingMode() == ScrollingMode::Yes );
356 aAny <<= bIsScroll;
358 break;
359 case WID_FRAME_IS_BORDER:
361 bool bIsBorder = maFrmDescr.IsFrameBorderOn();
362 aAny <<= bIsBorder;
364 break;
365 case WID_FRAME_IS_AUTO_BORDER:
367 bool bIsAutoBorder = !maFrmDescr.IsFrameBorderSet();
368 aAny <<= bIsAutoBorder;
370 break;
371 case WID_FRAME_MARGIN_WIDTH:
373 aAny <<= static_cast<sal_Int32>(maFrmDescr.GetMargin().Width());
375 break;
376 case WID_FRAME_MARGIN_HEIGHT:
378 aAny <<= static_cast<sal_Int32>(maFrmDescr.GetMargin().Height());
380 break;
381 default: ;
383 return aAny;
386 void SAL_CALL IFrameObject::addPropertyChangeListener(const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener > & )
390 void SAL_CALL IFrameObject::removePropertyChangeListener(const OUString&, const css::uno::Reference< css::beans::XPropertyChangeListener > & )
394 void SAL_CALL IFrameObject::addVetoableChangeListener(const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener > & )
398 void SAL_CALL IFrameObject::removeVetoableChangeListener(const OUString&, const css::uno::Reference< css::beans::XVetoableChangeListener > & )
402 ::sal_Int16 SAL_CALL IFrameObject::execute()
404 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
405 //we really should set a parent here
406 ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateEditObjectDialog(nullptr, ".uno:InsertObjectFloatingFrame", mxObj));
407 pDlg->Execute();
408 return 0;
411 void SAL_CALL IFrameObject::setTitle( const OUString& )
417 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
418 com_sun_star_comp_sfx2_IFrameObject_get_implementation(
419 css::uno::XComponentContext *context,
420 css::uno::Sequence<css::uno::Any> const &arguments)
422 return cppu::acquire(new IFrameObject(context, arguments));
425 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */