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/task/InteractionHandler.hpp>
26 #include <com/sun/star/ucb/CommandAbortedException.hpp>
27 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
28 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
29 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
30 #include <comphelper/processfactory.hxx>
33 #include <dialmgr.hxx>
34 #include <osl/diagnose.h>
35 #include <svtools/imagemgr.hxx>
36 #include <svtools/strings.hrc>
37 #include <svtools/svtresid.hxx>
39 #include <sal/log.hxx>
40 #include <tools/urlobj.hxx>
41 #include <tools/debug.hxx>
42 #include <tools/stream.hxx>
43 #include <vcl/image.hxx>
44 #include <vcl/weld.hxx>
45 #include <vcl/svapp.hxx>
46 #include <comphelper/classids.hxx>
47 #include <sfx2/filedlghelper.hxx>
48 #include <sfx2/frmdescr.hxx>
49 #include <sfx2/viewsh.hxx>
50 #include <comphelper/seqstream.hxx>
52 #include <strings.hrc>
54 using namespace ::com::sun::star
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star::uno
;
57 using namespace ::com::sun::star::container
;
58 using namespace ::com::sun::star::ui::dialogs
;
60 bool InsertObjectDialog_Impl::IsCreateNew() const
65 uno::Reference
< io::XInputStream
> InsertObjectDialog_Impl::GetIconIfIconified( OUString
* /*pGraphicMediaType*/ )
67 return uno::Reference
< io::XInputStream
>();
70 InsertObjectDialog_Impl::InsertObjectDialog_Impl(weld::Window
* pParent
,
71 const OUString
& rUIXMLDescription
, const OString
& rID
,
72 const css::uno::Reference
< css::embed::XStorage
>& xStorage
)
73 : GenericDialogController(pParent
, rUIXMLDescription
, rID
)
74 , m_xStorage( xStorage
)
79 IMPL_LINK_NOARG(SvInsertOleDlg
, DoubleClickHdl
, weld::TreeView
&, bool)
81 m_xDialog
->response(RET_OK
);
85 IMPL_LINK_NOARG(SvInsertOleDlg
, BrowseHdl
, weld::Button
&, void)
87 sfx2::FileDialogHelper
aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
, FileDialogFlags::NONE
, m_xDialog
.get());
88 const Reference
< XFilePicker3
>& xFilePicker
= aHelper
.GetFilePicker();
93 xFilePicker
->appendFilter(CuiResId(RID_SVXSTR_FILTER_ALL
), "*.*");
95 catch( const IllegalArgumentException
& )
97 SAL_WARN( "cui.dialogs", "caught IllegalArgumentException when registering filter" );
100 if( xFilePicker
->execute() == ExecutableDialogResults::OK
)
102 Sequence
< OUString
> aPathSeq( xFilePicker
->getSelectedFiles() );
103 INetURLObject
aObj( aPathSeq
[0] );
104 m_xEdFilepath
->set_text(aObj
.PathToFileName());
108 IMPL_LINK_NOARG(SvInsertOleDlg
, RadioHdl
, weld::Button
&, void)
110 if (m_xRbNewObject
->get_active())
112 m_xObjectTypeFrame
->show();
113 m_xFileFrame
->hide();
117 m_xFileFrame
->show();
118 m_xObjectTypeFrame
->hide();
122 SvInsertOleDlg::SvInsertOleDlg(weld::Window
* pParent
, const Reference
<embed::XStorage
>& xStorage
,
123 const SvObjectServerList
* pServers
)
124 : InsertObjectDialog_Impl( pParent
, "cui/ui/insertoleobject.ui", "InsertOLEObjectDialog", xStorage
)
125 , m_pServers( pServers
)
126 , m_xRbNewObject(m_xBuilder
->weld_radio_button("createnew"))
127 , m_xRbObjectFromfile(m_xBuilder
->weld_radio_button("createfromfile"))
128 , m_xObjectTypeFrame(m_xBuilder
->weld_frame("objecttypeframe"))
129 , m_xLbObjecttype(m_xBuilder
->weld_tree_view("types"))
130 , m_xFileFrame(m_xBuilder
->weld_frame("fileframe"))
131 , m_xEdFilepath(m_xBuilder
->weld_entry("urled"))
132 , m_xBtnFilepath(m_xBuilder
->weld_button("urlbtn"))
133 , m_xCbFilelink(m_xBuilder
->weld_check_button("linktofile"))
134 , m_xCbAsIcon(m_xBuilder
->weld_check_button("asicon"))
136 m_xLbObjecttype
->set_size_request(m_xLbObjecttype
->get_approximate_digit_width() * 32,
137 m_xLbObjecttype
->get_height_rows(6));
138 m_xLbObjecttype
->connect_row_activated(LINK(this, SvInsertOleDlg
, DoubleClickHdl
));
139 m_xBtnFilepath
->connect_clicked(LINK( this, SvInsertOleDlg
, BrowseHdl
));
140 Link
<weld::Button
&,void> aLink( LINK( this, SvInsertOleDlg
, RadioHdl
) );
141 m_xRbNewObject
->connect_clicked( aLink
);
142 m_xRbObjectFromfile
->connect_clicked( aLink
);
143 m_xRbNewObject
->set_active(true);
146 short SvInsertOleDlg::run()
149 SvObjectServerList aObjS
;
152 // if no list was provided, take the complete one
153 aObjS
.FillInsertObjects();
157 // fill listbox and select default
158 m_xLbObjecttype
->freeze();
159 for ( sal_uLong i
= 0; i
< m_pServers
->Count(); i
++ )
160 m_xLbObjecttype
->append_text((*m_pServers
)[i
].GetHumanName());
161 m_xLbObjecttype
->thaw();
162 m_xLbObjecttype
->select(0);
165 DBG_ASSERT( m_xStorage
.is(), "No storage!");
166 if ( m_xStorage
.is() && ( nRet
= InsertObjectDialog_Impl::run() ) == RET_OK
)
169 bool bCreateNew
= IsCreateNew();
172 // create and insert new embedded object
173 OUString aServerName
= m_xLbObjecttype
->get_selected_text();
174 const SvObjectServer
* pS
= m_pServers
->Get( aServerName
);
177 if( pS
->GetClassName() == SvGlobalName( SO3_OUT_CLASSID
) )
181 uno::Reference
< embed::XInsertObjectDialog
> xDialogCreator(
182 embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() ),
185 if ( xDialogCreator
.is() )
187 aName
= aCnt
.CreateUniqueObjectName();
188 embed::InsertedObjectInfo aNewInf
= xDialogCreator
->createInstanceByDialog(
191 uno::Sequence
< beans::PropertyValue
>() );
193 OSL_ENSURE( aNewInf
.Object
.is(), "The object must be created or an exception must be thrown!" );
194 m_xObj
= aNewInf
.Object
;
195 for ( sal_Int32 nInd
= 0; nInd
< aNewInf
.Options
.getLength(); nInd
++ )
196 if ( aNewInf
.Options
[nInd
].Name
== "Icon" )
198 aNewInf
.Options
[nInd
].Value
>>= m_aIconMetaFile
;
200 else if ( aNewInf
.Options
[nInd
].Name
== "IconFormat" )
202 datatransfer::DataFlavor aFlavor
;
203 if ( aNewInf
.Options
[nInd
].Value
>>= aFlavor
)
204 m_aIconMediaType
= aFlavor
.MimeType
;
209 catch( ucb::CommandAbortedException
& )
211 // the user has pressed cancel
213 catch( uno::Exception
& )
215 // TODO: Error handling
220 // create object with desired ClassId
221 m_xObj
= aCnt
.CreateEmbeddedObject( pS
->GetClassName().GetByteSequence(), aName
);
226 if( !aFileName
.isEmpty() ) // from OLE Dialog
228 // object couldn't be created from file
229 // global Resource from svtools (former so3 resource)
230 OUString
aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE
));
231 aErr
= aErr
.replaceFirst( "%", aFileName
);
233 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
234 VclMessageType::Warning
, VclButtonsType::Ok
, aErr
));
239 // object couldn't be created
240 // global Resource from svtools (former so3 resource)
241 OUString
aErr(SvtResId(STR_ERROR_OBJNOCREATE
));
242 aErr
= aErr
.replaceFirst( "%", aServerName
);
244 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
245 VclMessageType::Warning
, VclButtonsType::Ok
, aErr
));
253 aFileName
= m_xEdFilepath
->get_text();
255 aURL
.SetSmartProtocol( INetProtocol::File
);
256 aURL
.SetSmartURL( aFileName
);
257 aFileName
= aURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
258 bool bLink
= m_xCbFilelink
->get_active();
260 if ( !aFileName
.isEmpty() )
262 // create MediaDescriptor for file to create object from
263 uno::Sequence
< beans::PropertyValue
> aMedium( 2 );
264 aMedium
[0].Name
= "URL";
265 aMedium
[0].Value
<<= aFileName
;
267 uno::Reference
< uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
268 uno::Reference
< task::XInteractionHandler2
> xInteraction(
269 task::InteractionHandler::createWithParent(xContext
, nullptr) );
271 aMedium
[1].Name
= "InteractionHandler";
272 aMedium
[1].Value
<<= xInteraction
;
274 // create object from media descriptor
276 m_xObj
= aCnt
.InsertEmbeddedLink( aMedium
, aName
);
278 m_xObj
= aCnt
.InsertEmbeddedObject( aMedium
, aName
);
283 // object couldn't be created from file
284 // global Resource from svtools (former so3 resource)
285 OUString
aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE
));
286 aErr
= aErr
.replaceFirst( "%", aFileName
);
288 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
289 VclMessageType::Warning
, VclButtonsType::Ok
, aErr
));
294 if (m_xCbAsIcon
->get_active())
296 //something nice here I guess would be to write the filename into
297 //the image with this icon above it
298 Image aImage
= SvFileInformationManager::GetImage(aURL
, true);
299 SvMemoryStream aTemp
;
300 WriteDIBBitmapEx(aImage
.GetBitmapEx(), aTemp
);
301 m_aIconMetaFile
= Sequence
<sal_Int8
>(static_cast<const sal_Int8
*>(aTemp
.GetData()), aTemp
.TellEnd());
302 m_aIconMediaType
= "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
308 m_pServers
= nullptr;
312 uno::Reference
< io::XInputStream
> SvInsertOleDlg::GetIconIfIconified( OUString
* pGraphicMediaType
)
314 if ( m_aIconMetaFile
.hasElements() )
316 if ( pGraphicMediaType
)
317 *pGraphicMediaType
= m_aIconMediaType
;
319 return uno::Reference
< io::XInputStream
>( new ::comphelper::SequenceInputStream( m_aIconMetaFile
) );
322 return uno::Reference
< io::XInputStream
>();
326 SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window
*pParent
,
327 const css::uno::Reference
< css::embed::XStorage
>& xStorage
)
328 : InsertObjectDialog_Impl(pParent
, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
334 SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window
*pParent
,
335 const uno::Reference
< embed::XEmbeddedObject
>& xObj
)
336 : InsertObjectDialog_Impl(pParent
, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
337 uno::Reference
<embed::XStorage
>())
344 void SfxInsertFloatingFrameDialog::Init()
346 m_xEDName
= m_xBuilder
->weld_entry("edname");
347 m_xEDURL
= m_xBuilder
->weld_entry("edurl");
348 m_xBTOpen
= m_xBuilder
->weld_button("buttonbrowse");
349 m_xRBScrollingOn
= m_xBuilder
->weld_radio_button("scrollbaron");
350 m_xRBScrollingOff
= m_xBuilder
->weld_radio_button("scrollbaroff");
351 m_xRBScrollingAuto
= m_xBuilder
->weld_radio_button("scrollbarauto");
352 m_xRBFrameBorderOn
= m_xBuilder
->weld_radio_button("borderon");
353 m_xRBFrameBorderOff
= m_xBuilder
->weld_radio_button("borderoff");
354 m_xFTMarginWidth
= m_xBuilder
->weld_label("widthlabel");
355 m_xNMMarginWidth
= m_xBuilder
->weld_spin_button("width");
356 m_xCBMarginWidthDefault
= m_xBuilder
->weld_check_button("defaultwidth");
357 m_xFTMarginHeight
= m_xBuilder
->weld_label("heightlabel");
358 m_xNMMarginHeight
= m_xBuilder
->weld_spin_button("height");
359 m_xCBMarginHeightDefault
= m_xBuilder
->weld_check_button("defaultheight");
361 Link
<weld::Button
&, void> aLink(LINK(this, SfxInsertFloatingFrameDialog
, CheckHdl
));
362 m_xCBMarginWidthDefault
->connect_clicked(aLink
);
363 m_xCBMarginHeightDefault
->connect_clicked(aLink
);
365 m_xCBMarginWidthDefault
->set_active(true);
366 m_xCBMarginHeightDefault
->set_active(true);
367 m_xRBScrollingAuto
->set_active(true);
368 m_xRBFrameBorderOn
->set_active(true);
370 m_xBTOpen
->connect_clicked(LINK(this, SfxInsertFloatingFrameDialog
, OpenHdl
));
373 short SfxInsertFloatingFrameDialog::run()
377 uno::Reference
< beans::XPropertySet
> xSet
;
382 if ( m_xObj
->getCurrentState() == embed::EmbedStates::LOADED
)
383 m_xObj
->changeState( embed::EmbedStates::RUNNING
);
384 xSet
.set( m_xObj
->getComponent(), uno::UNO_QUERY
);
386 uno::Any aAny
= xSet
->getPropertyValue( "FrameURL" );
388 m_xEDURL
->set_text( aStr
);
389 aAny
= xSet
->getPropertyValue( "FrameName" );
391 m_xEDName
->set_text(aStr
);
393 sal_Int32 nSize
= SIZE_NOT_SET
;
394 aAny
= xSet
->getPropertyValue( "FrameMarginWidth" );
397 if ( nSize
== SIZE_NOT_SET
)
399 m_xCBMarginWidthDefault
->set_active(true);
400 m_xNMMarginWidth
->set_text(OUString::number(DEFAULT_MARGIN_WIDTH
));
401 m_xFTMarginWidth
->set_sensitive(false);
402 m_xNMMarginWidth
->set_sensitive(false);
405 m_xNMMarginWidth
->set_text(OUString::number(nSize
));
407 aAny
= xSet
->getPropertyValue( "FrameMarginHeight" );
410 if ( nSize
== SIZE_NOT_SET
)
412 m_xCBMarginHeightDefault
->set_active(true);
413 m_xNMMarginHeight
->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT
));
414 m_xFTMarginHeight
->set_sensitive(false);
415 m_xNMMarginHeight
->set_sensitive(false);
418 m_xNMMarginHeight
->set_text(OUString::number(nSize
));
420 bool bScrollOn
= false;
421 bool bScrollOff
= false;
422 bool bScrollAuto
= false;
425 aAny
= xSet
->getPropertyValue( "FrameIsAutoScroll" );
429 aAny
= xSet
->getPropertyValue( "FrameIsScrollingMode" );
437 m_xRBScrollingOn
->set_sensitive(bScrollOn
);
438 m_xRBScrollingOff
->set_sensitive(bScrollOff
);
439 m_xRBScrollingAuto
->set_sensitive(bScrollAuto
);
442 aAny
= xSet
->getPropertyValue( "FrameIsAutoBorder" );
446 aAny
= xSet
->getPropertyValue( "FrameIsBorder" );
448 m_xRBFrameBorderOn
->set_active(bSet
);
449 m_xRBFrameBorderOff
->set_active(!bSet
);
454 catch ( uno::Exception
& )
456 OSL_FAIL( "No IFrame!" );
461 DBG_ASSERT( m_xStorage
.is(), "No storage!");
462 bOK
= m_xStorage
.is();
465 if ( bOK
&& ( nRet
= InsertObjectDialog_Impl::run() ) == RET_OK
)
468 if (!m_xEDURL
->get_text().isEmpty())
470 // URL can be a valid and absolute URL or a system file name
472 aObj
.SetSmartProtocol( INetProtocol::File
);
473 if ( aObj
.SetSmartURL( m_xEDURL
->get_text() ) )
474 aURL
= aObj
.GetMainURL( INetURLObject::DecodeMechanism::NONE
);
477 if ( !m_xObj
.is() && !aURL
.isEmpty() )
481 SvGlobalName
aClassId( SO3_IFRAME_CLASSID
);
482 m_xObj
= aCnt
.CreateEmbeddedObject( aClassId
.GetByteSequence(), aName
);
483 if ( m_xObj
->getCurrentState() == embed::EmbedStates::LOADED
)
484 m_xObj
->changeState( embed::EmbedStates::RUNNING
);
485 xSet
.set( m_xObj
->getComponent(), uno::UNO_QUERY
);
492 bool bIPActive
= m_xObj
->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE
;
494 m_xObj
->changeState( embed::EmbedStates::RUNNING
);
496 OUString aName
= m_xEDName
->get_text();
497 ScrollingMode eScroll
= ScrollingMode::No
;
498 if (m_xRBScrollingOn
->get_active())
499 eScroll
= ScrollingMode::Yes
;
500 if (m_xRBScrollingOff
->get_active())
501 eScroll
= ScrollingMode::No
;
502 if (m_xRBScrollingAuto
->get_active())
503 eScroll
= ScrollingMode::Auto
;
505 bool bHasBorder
= m_xRBFrameBorderOn
->get_active();
508 if (!m_xCBMarginWidthDefault
->get_active())
509 lMarginWidth
= static_cast<long>(m_xNMMarginWidth
->get_text().toInt32());
511 lMarginWidth
= SIZE_NOT_SET
;
514 if (!m_xCBMarginHeightDefault
->get_active())
515 lMarginHeight
= static_cast<long>(m_xNMMarginHeight
->get_text().toInt32());
517 lMarginHeight
= SIZE_NOT_SET
;
519 xSet
->setPropertyValue( "FrameURL", Any( aURL
) );
520 xSet
->setPropertyValue( "FrameName", Any( aName
) );
522 if ( eScroll
== ScrollingMode::Auto
)
523 xSet
->setPropertyValue( "FrameIsAutoScroll", Any( true ) );
525 xSet
->setPropertyValue( "FrameIsScrollingMode", Any( eScroll
== ScrollingMode::Yes
) );
527 xSet
->setPropertyValue( "FrameIsBorder", Any( bHasBorder
) );
528 xSet
->setPropertyValue( "FrameMarginWidth", Any( sal_Int32( lMarginWidth
) ) );
529 xSet
->setPropertyValue( "FrameMarginHeight", Any( sal_Int32( lMarginHeight
) ) );
532 m_xObj
->changeState( embed::EmbedStates::INPLACE_ACTIVE
);
534 catch ( uno::Exception
& )
536 OSL_FAIL( "No IFrame!" );
544 IMPL_LINK(SfxInsertFloatingFrameDialog
, CheckHdl
, weld::Button
&, rButton
, void)
546 weld::CheckButton
& rCB
= dynamic_cast<weld::CheckButton
&>(rButton
);
547 if (&rCB
== m_xCBMarginWidthDefault
.get())
549 if (rCB
.get_active())
550 m_xNMMarginWidth
->set_text(OUString::number(DEFAULT_MARGIN_WIDTH
));
551 m_xFTMarginWidth
->set_sensitive(!rCB
.get_active());
552 m_xNMMarginWidth
->set_sensitive(!rCB
.get_active());
555 if (&rCB
== m_xCBMarginHeightDefault
.get())
557 if (rCB
.get_active())
558 m_xNMMarginHeight
->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT
));
559 m_xFTMarginHeight
->set_sensitive(!rCB
.get_active());
560 m_xNMMarginHeight
->set_sensitive(!rCB
.get_active());
564 IMPL_LINK_NOARG( SfxInsertFloatingFrameDialog
, OpenHdl
, weld::Button
&, void)
566 // create the file dialog
567 sfx2::FileDialogHelper
aFileDlg(
568 ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
, FileDialogFlags::NONE
, OUString(),
569 SfxFilterFlags::NONE
, SfxFilterFlags::NONE
, m_xDialog
.get());
572 aFileDlg
.SetTitle(CuiResId(RID_SVXSTR_SELECT_FILE_IFRAME
));
575 if ( aFileDlg
.Execute() == ERRCODE_NONE
)
576 m_xEDURL
->set_text(INetURLObject(aFileDlg
.GetPath()).GetMainURL(INetURLObject::DecodeMechanism::WithCharset
));
579 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */