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 <com/sun/star/beans/XPropertySet.hpp>
21 #include <com/sun/star/beans/PropertyValue.hpp>
22 #include <com/sun/star/embed/EmbedStates.hpp>
23 #include <com/sun/star/embed/XInsertObjectDialog.hpp>
24 #include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
25 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 #include <com/sun/star/lang/XInitialization.hpp>
27 #include <com/sun/star/task/InteractionHandler.hpp>
28 #include <com/sun/star/ucb/CommandAbortedException.hpp>
29 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
30 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
31 #include <com/sun/star/ui/dialogs/FilePicker.hpp>
32 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
33 #include <comphelper/processfactory.hxx>
36 #include <dialmgr.hxx>
37 #include <svtools/imagemgr.hxx>
38 #include <svtools/strings.hrc>
39 #include <svtools/svtresid.hxx>
41 #include <sal/log.hxx>
42 #include <tools/urlobj.hxx>
43 #include <tools/debug.hxx>
44 #include <tools/stream.hxx>
45 #include <svl/urihelper.hxx>
46 #include <vcl/image.hxx>
47 #include <vcl/weld.hxx>
48 #include <vcl/svapp.hxx>
49 #include <comphelper/classids.hxx>
50 #include <sfx2/filedlghelper.hxx>
51 #include <sfx2/frmdescr.hxx>
52 #include <sfx2/viewsh.hxx>
53 #include <svl/ownlist.hxx>
54 #include <comphelper/seqstream.hxx>
56 #include <strings.hrc>
58 #include <osl/file.hxx>
60 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
61 #include <com/sun/star/container/XNameAccess.hpp>
62 #include <vcl/settings.hxx>
64 using namespace ::com::sun::star
;
65 using namespace ::com::sun::star::lang
;
66 using namespace ::com::sun::star::uno
;
67 using namespace ::com::sun::star::container
;
68 using namespace ::com::sun::star::ui::dialogs
;
70 bool InsertObjectDialog_Impl::IsCreateNew() const
75 uno::Reference
< io::XInputStream
> InsertObjectDialog_Impl::GetIconIfIconified( OUString
* /*pGraphicMediaType*/ )
77 return uno::Reference
< io::XInputStream
>();
80 InsertObjectDialog_Impl::InsertObjectDialog_Impl(weld::Window
* pParent
,
81 const OUString
& rUIXMLDescription
, const OString
& rID
,
82 const css::uno::Reference
< css::embed::XStorage
>& xStorage
)
83 : GenericDialogController(pParent
, rUIXMLDescription
, rID
)
84 , m_xStorage( xStorage
)
89 IMPL_LINK_NOARG(SvInsertOleDlg
, DoubleClickHdl
, weld::TreeView
&, void)
91 m_xDialog
->response(RET_OK
);
94 IMPL_LINK_NOARG(SvInsertOleDlg
, BrowseHdl
, weld::Button
&, void)
96 sfx2::FileDialogHelper
aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
, FileDialogFlags::NONE
, m_xDialog
.get());
97 const Reference
< XFilePicker3
>& xFilePicker
= aHelper
.GetFilePicker();
102 xFilePicker
->appendFilter(CuiResId(RID_SVXSTR_FILTER_ALL
), "*.*");
104 catch( const IllegalArgumentException
& )
106 SAL_WARN( "cui.dialogs", "caught IllegalArgumentException when registering filter" );
109 if( xFilePicker
->execute() == ExecutableDialogResults::OK
)
111 Sequence
< OUString
> aPathSeq( xFilePicker
->getSelectedFiles() );
112 INetURLObject
aObj( aPathSeq
[0] );
113 m_xEdFilepath
->set_text(aObj
.PathToFileName());
117 IMPL_LINK_NOARG(SvInsertOleDlg
, RadioHdl
, weld::Button
&, void)
119 if (m_xRbNewObject
->get_active())
121 m_xObjectTypeFrame
->show();
122 m_xFileFrame
->hide();
126 m_xFileFrame
->show();
127 m_xObjectTypeFrame
->hide();
131 SvInsertOleDlg::SvInsertOleDlg(weld::Window
* pParent
, const Reference
<embed::XStorage
>& xStorage
,
132 const SvObjectServerList
* pServers
)
133 : InsertObjectDialog_Impl( pParent
, "cui/ui/insertoleobject.ui", "InsertOLEObjectDialog", xStorage
)
134 , m_pServers( pServers
)
135 , m_xRbNewObject(m_xBuilder
->weld_radio_button("createnew"))
136 , m_xRbObjectFromfile(m_xBuilder
->weld_radio_button("createfromfile"))
137 , m_xObjectTypeFrame(m_xBuilder
->weld_frame("objecttypeframe"))
138 , m_xLbObjecttype(m_xBuilder
->weld_tree_view("types"))
139 , m_xFileFrame(m_xBuilder
->weld_frame("fileframe"))
140 , m_xEdFilepath(m_xBuilder
->weld_entry("urled"))
141 , m_xBtnFilepath(m_xBuilder
->weld_button("urlbtn"))
142 , m_xCbFilelink(m_xBuilder
->weld_check_button("linktofile"))
143 , m_xCbAsIcon(m_xBuilder
->weld_check_button("asicon"))
145 m_xLbObjecttype
->set_size_request(m_xLbObjecttype
->get_approximate_digit_width() * 32,
146 m_xLbObjecttype
->get_height_rows(6));
147 m_xLbObjecttype
->connect_row_activated(LINK(this, SvInsertOleDlg
, DoubleClickHdl
));
148 m_xBtnFilepath
->connect_clicked(LINK( this, SvInsertOleDlg
, BrowseHdl
));
149 Link
<weld::Button
&,void> aLink( LINK( this, SvInsertOleDlg
, RadioHdl
) );
150 m_xRbNewObject
->connect_clicked( aLink
);
151 m_xRbObjectFromfile
->connect_clicked( aLink
);
152 m_xRbNewObject
->set_active(true);
155 short SvInsertOleDlg::run()
158 SvObjectServerList aObjS
;
161 // if no list was provided, take the complete one
162 aObjS
.FillInsertObjects();
166 // fill listbox and select default
167 m_xLbObjecttype
->freeze();
168 for ( sal_uLong i
= 0; i
< m_pServers
->Count(); i
++ )
169 m_xLbObjecttype
->append_text((*m_pServers
)[i
].GetHumanName());
170 m_xLbObjecttype
->thaw();
171 m_xLbObjecttype
->select(0);
174 DBG_ASSERT( m_xStorage
.is(), "No storage!");
175 if ( m_xStorage
.is() && ( nRet
= InsertObjectDialog_Impl::run() ) == RET_OK
)
178 bool bCreateNew
= IsCreateNew();
181 // create and insert new embedded object
182 OUString aServerName
= m_xLbObjecttype
->get_selected_text();
183 const SvObjectServer
* pS
= m_pServers
->Get( aServerName
);
186 if( pS
->GetClassName() == SvGlobalName( SO3_OUT_CLASSID
) )
190 uno::Reference
< embed::XInsertObjectDialog
> xDialogCreator(
191 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() ),
194 if ( xDialogCreator
.is() )
196 aName
= aCnt
.CreateUniqueObjectName();
197 embed::InsertedObjectInfo aNewInf
= xDialogCreator
->createInstanceByDialog(
200 uno::Sequence
< beans::PropertyValue
>() );
202 OSL_ENSURE( aNewInf
.Object
.is(), "The object must be created or an exception must be thrown!" );
203 m_xObj
= aNewInf
.Object
;
204 for ( sal_Int32 nInd
= 0; nInd
< aNewInf
.Options
.getLength(); nInd
++ )
205 if ( aNewInf
.Options
[nInd
].Name
== "Icon" )
207 aNewInf
.Options
[nInd
].Value
>>= m_aIconMetaFile
;
209 else if ( aNewInf
.Options
[nInd
].Name
== "IconFormat" )
211 datatransfer::DataFlavor aFlavor
;
212 if ( aNewInf
.Options
[nInd
].Value
>>= aFlavor
)
213 m_aIconMediaType
= aFlavor
.MimeType
;
218 catch( ucb::CommandAbortedException
& )
220 // the user has pressed cancel
222 catch( uno::Exception
& )
224 // TODO: Error handling
229 // create object with desired ClassId
230 m_xObj
= aCnt
.CreateEmbeddedObject( pS
->GetClassName().GetByteSequence(), aName
);
235 if( !aFileName
.isEmpty() ) // from OLE Dialog
237 // object couldn't be created from file
238 // global Resource from svtools (former so3 resource)
239 OUString
aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE
));
240 aErr
= aErr
.replaceFirst( "%", aFileName
);
242 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
243 VclMessageType::Warning
, VclButtonsType::Ok
, aErr
));
248 // object couldn't be created
249 // global Resource from svtools (former so3 resource)
250 OUString
aErr(SvtResId(STR_ERROR_OBJNOCREATE
));
251 aErr
= aErr
.replaceFirst( "%", aServerName
);
253 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
254 VclMessageType::Warning
, VclButtonsType::Ok
, aErr
));
262 aFileName
= m_xEdFilepath
->get_text();
264 aURL
.SetSmartProtocol( INetProtocol::File
);
265 aURL
.SetSmartURL( aFileName
);
266 aFileName
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
267 bool bLink
= m_xCbFilelink
->get_active();
269 if ( !aFileName
.isEmpty() )
271 // create MediaDescriptor for file to create object from
272 uno::Sequence
< beans::PropertyValue
> aMedium( 2 );
273 aMedium
[0].Name
= "URL";
274 aMedium
[0].Value
<<= aFileName
;
276 uno::Reference
< uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
277 uno::Reference
< task::XInteractionHandler2
> xInteraction(
278 task::InteractionHandler::createWithParent(xContext
, nullptr) );
280 aMedium
[1].Name
= "InteractionHandler";
281 aMedium
[1].Value
<<= xInteraction
;
283 // create object from media descriptor
285 m_xObj
= aCnt
.InsertEmbeddedLink( aMedium
, aName
);
287 m_xObj
= aCnt
.InsertEmbeddedObject( aMedium
, aName
);
292 // object couldn't be created from file
293 // global Resource from svtools (former so3 resource)
294 OUString
aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE
));
295 aErr
= aErr
.replaceFirst( "%", aFileName
);
297 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
298 VclMessageType::Warning
, VclButtonsType::Ok
, aErr
));
303 if (m_xCbAsIcon
->get_active())
305 //something nice here I guess would be to write the filename into
306 //the image with this icon above it
307 Image aImage
= SvFileInformationManager::GetImage(aURL
, true);
308 SvMemoryStream aTemp
;
309 WriteDIBBitmapEx(aImage
.GetBitmapEx(), aTemp
);
310 m_aIconMetaFile
= Sequence
<sal_Int8
>(static_cast<const sal_Int8
*>(aTemp
.GetData()), aTemp
.TellEnd());
311 m_aIconMediaType
= "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
317 m_pServers
= nullptr;
321 uno::Reference
< io::XInputStream
> SvInsertOleDlg::GetIconIfIconified( OUString
* pGraphicMediaType
)
323 if ( m_aIconMetaFile
.getLength() )
325 if ( pGraphicMediaType
)
326 *pGraphicMediaType
= m_aIconMediaType
;
328 return uno::Reference
< io::XInputStream
>( new ::comphelper::SequenceInputStream( m_aIconMetaFile
) );
331 return uno::Reference
< io::XInputStream
>();
335 SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window
*pParent
,
336 const css::uno::Reference
< css::embed::XStorage
>& xStorage
)
337 : InsertObjectDialog_Impl(pParent
, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
343 SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window
*pParent
,
344 const uno::Reference
< embed::XEmbeddedObject
>& xObj
)
345 : InsertObjectDialog_Impl(pParent
, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
346 uno::Reference
<embed::XStorage
>())
353 void SfxInsertFloatingFrameDialog::Init()
355 m_xEDName
= m_xBuilder
->weld_entry("edname");
356 m_xEDURL
= m_xBuilder
->weld_entry("edurl");
357 m_xBTOpen
= m_xBuilder
->weld_button("buttonbrowse");
358 m_xRBScrollingOn
= m_xBuilder
->weld_radio_button("scrollbaron");
359 m_xRBScrollingOff
= m_xBuilder
->weld_radio_button("scrollbaroff");
360 m_xRBScrollingAuto
= m_xBuilder
->weld_radio_button("scrollbarauto");
361 m_xRBFrameBorderOn
= m_xBuilder
->weld_radio_button("borderon");
362 m_xRBFrameBorderOff
= m_xBuilder
->weld_radio_button("borderoff");
363 m_xFTMarginWidth
= m_xBuilder
->weld_label("widthlabel");
364 m_xNMMarginWidth
= m_xBuilder
->weld_spin_button("width");
365 m_xCBMarginWidthDefault
= m_xBuilder
->weld_check_button("defaultwidth");
366 m_xFTMarginHeight
= m_xBuilder
->weld_label("heightlabel");
367 m_xNMMarginHeight
= m_xBuilder
->weld_spin_button("height");
368 m_xCBMarginHeightDefault
= m_xBuilder
->weld_check_button("defaultheight");
370 Link
<weld::Button
&, void> aLink(LINK(this, SfxInsertFloatingFrameDialog
, CheckHdl
));
371 m_xCBMarginWidthDefault
->connect_clicked(aLink
);
372 m_xCBMarginHeightDefault
->connect_clicked(aLink
);
374 m_xCBMarginWidthDefault
->set_active(true);
375 m_xCBMarginHeightDefault
->set_active(true);
376 m_xRBScrollingAuto
->set_active(true);
377 m_xRBFrameBorderOn
->set_active(true);
379 m_xBTOpen
->connect_clicked(LINK(this, SfxInsertFloatingFrameDialog
, OpenHdl
));
382 short SfxInsertFloatingFrameDialog::run()
386 uno::Reference
< beans::XPropertySet
> xSet
;
391 if ( m_xObj
->getCurrentState() == embed::EmbedStates::LOADED
)
392 m_xObj
->changeState( embed::EmbedStates::RUNNING
);
393 xSet
.set( m_xObj
->getComponent(), uno::UNO_QUERY
);
395 uno::Any aAny
= xSet
->getPropertyValue( "FrameURL" );
397 m_xEDURL
->set_text( aStr
);
398 aAny
= xSet
->getPropertyValue( "FrameName" );
400 m_xEDName
->set_text(aStr
);
402 sal_Int32 nSize
= SIZE_NOT_SET
;
403 aAny
= xSet
->getPropertyValue( "FrameMarginWidth" );
406 if ( nSize
== SIZE_NOT_SET
)
408 m_xCBMarginWidthDefault
->set_active(true);
409 m_xNMMarginWidth
->set_text(OUString::number(DEFAULT_MARGIN_WIDTH
));
410 m_xFTMarginWidth
->set_sensitive(false);
411 m_xNMMarginWidth
->set_sensitive(false);
414 m_xNMMarginWidth
->set_text(OUString::number(nSize
));
416 aAny
= xSet
->getPropertyValue( "FrameMarginHeight" );
419 if ( nSize
== SIZE_NOT_SET
)
421 m_xCBMarginHeightDefault
->set_active(true);
422 m_xNMMarginHeight
->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT
));
423 m_xFTMarginHeight
->set_sensitive(false);
424 m_xNMMarginHeight
->set_sensitive(false);
427 m_xNMMarginHeight
->set_text(OUString::number(nSize
));
429 bool bScrollOn
= false;
430 bool bScrollOff
= false;
431 bool bScrollAuto
= false;
434 aAny
= xSet
->getPropertyValue( "FrameIsAutoScroll" );
438 aAny
= xSet
->getPropertyValue( "FrameIsScrollingMode" );
446 m_xRBScrollingOn
->set_sensitive(bScrollOn
);
447 m_xRBScrollingOff
->set_sensitive(bScrollOff
);
448 m_xRBScrollingAuto
->set_sensitive(bScrollAuto
);
451 aAny
= xSet
->getPropertyValue( "FrameIsAutoBorder" );
455 aAny
= xSet
->getPropertyValue( "FrameIsBorder" );
457 m_xRBFrameBorderOn
->set_active(bSet
);
458 m_xRBFrameBorderOff
->set_active(!bSet
);
463 catch ( uno::Exception
& )
465 OSL_FAIL( "No IFrame!" );
470 DBG_ASSERT( m_xStorage
.is(), "No storage!");
471 bOK
= m_xStorage
.is();
474 if ( bOK
&& ( nRet
= InsertObjectDialog_Impl::run() ) == RET_OK
)
477 if (!m_xEDURL
->get_text().isEmpty())
479 // URL can be a valid and absolute URL or a system file name
481 aObj
.SetSmartProtocol( INetProtocol::File
);
482 if ( aObj
.SetSmartURL( m_xEDURL
->get_text() ) )
483 aURL
= aObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
486 if ( !m_xObj
.is() && !aURL
.isEmpty() )
490 SvGlobalName
aClassId( SO3_IFRAME_CLASSID
);
491 m_xObj
= aCnt
.CreateEmbeddedObject( aClassId
.GetByteSequence(), aName
);
492 if ( m_xObj
->getCurrentState() == embed::EmbedStates::LOADED
)
493 m_xObj
->changeState( embed::EmbedStates::RUNNING
);
494 xSet
.set( m_xObj
->getComponent(), uno::UNO_QUERY
);
501 bool bIPActive
= m_xObj
->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE
;
503 m_xObj
->changeState( embed::EmbedStates::RUNNING
);
505 OUString aName
= m_xEDName
->get_text();
506 ScrollingMode eScroll
= ScrollingMode::No
;
507 if (m_xRBScrollingOn
->get_active())
508 eScroll
= ScrollingMode::Yes
;
509 if (m_xRBScrollingOff
->get_active())
510 eScroll
= ScrollingMode::No
;
511 if (m_xRBScrollingAuto
->get_active())
512 eScroll
= ScrollingMode::Auto
;
514 bool bHasBorder
= m_xRBFrameBorderOn
->get_active();
517 if (!m_xCBMarginWidthDefault
->get_active())
518 lMarginWidth
= static_cast<long>(m_xNMMarginWidth
->get_text().toInt32());
520 lMarginWidth
= SIZE_NOT_SET
;
523 if (!m_xCBMarginHeightDefault
->get_active())
524 lMarginHeight
= static_cast<long>(m_xNMMarginHeight
->get_text().toInt32());
526 lMarginHeight
= SIZE_NOT_SET
;
528 xSet
->setPropertyValue( "FrameURL", Any( aURL
) );
529 xSet
->setPropertyValue( "FrameName", Any( aName
) );
531 if ( eScroll
== ScrollingMode::Auto
)
532 xSet
->setPropertyValue( "FrameIsAutoScroll", Any( true ) );
534 xSet
->setPropertyValue( "FrameIsScrollingMode", Any( eScroll
== ScrollingMode::Yes
) );
536 xSet
->setPropertyValue( "FrameIsBorder", Any( bHasBorder
) );
537 xSet
->setPropertyValue( "FrameMarginWidth", Any( sal_Int32( lMarginWidth
) ) );
538 xSet
->setPropertyValue( "FrameMarginHeight", Any( sal_Int32( lMarginHeight
) ) );
541 m_xObj
->changeState( embed::EmbedStates::INPLACE_ACTIVE
);
543 catch ( uno::Exception
& )
545 OSL_FAIL( "No IFrame!" );
553 IMPL_LINK(SfxInsertFloatingFrameDialog
, CheckHdl
, weld::Button
&, rButton
, void)
555 weld::CheckButton
& rCB
= dynamic_cast<weld::CheckButton
&>(rButton
);
556 if (&rCB
== m_xCBMarginWidthDefault
.get())
558 if (rCB
.get_active())
559 m_xNMMarginWidth
->set_text(OUString::number(DEFAULT_MARGIN_WIDTH
));
560 m_xFTMarginWidth
->set_sensitive(!rCB
.get_active());
561 m_xNMMarginWidth
->set_sensitive(!rCB
.get_active());
564 if (&rCB
== m_xCBMarginHeightDefault
.get())
566 if (rCB
.get_active())
567 m_xNMMarginHeight
->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT
));
568 m_xFTMarginHeight
->set_sensitive(!rCB
.get_active());
569 m_xNMMarginHeight
->set_sensitive(!rCB
.get_active());
573 IMPL_LINK_NOARG( SfxInsertFloatingFrameDialog
, OpenHdl
, weld::Button
&, void)
575 // create the file dialog
576 sfx2::FileDialogHelper
aFileDlg(
577 ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
, FileDialogFlags::NONE
, OUString(),
578 SfxFilterFlags::NONE
, SfxFilterFlags::NONE
, m_xDialog
.get());
581 aFileDlg
.SetTitle(CuiResId(RID_SVXSTR_SELECT_FILE_IFRAME
));
584 if ( aFileDlg
.Execute() == ERRCODE_NONE
)
585 m_xEDURL
->set_text(INetURLObject(aFileDlg
.GetPath()).GetMainURL(INetURLObject::DecodeMechanism::WithCharset
));
588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */