/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ui::dialogs; bool InsertObjectDialog_Impl::IsCreateNew() const { return false; } uno::Reference< io::XInputStream > InsertObjectDialog_Impl::GetIconIfIconified( OUString* /*pGraphicMediaType*/ ) { return uno::Reference< io::XInputStream >(); } InsertObjectDialog_Impl::InsertObjectDialog_Impl(weld::Window* pParent, const OUString& rUIXMLDescription, const OUString& rID, css::uno::Reference < css::embed::XStorage > xStorage) : GenericDialogController(pParent, rUIXMLDescription, rID) , m_xStorage(std::move( xStorage )) , aCnt( m_xStorage ) { } IMPL_LINK_NOARG(SvInsertOleDlg, DoubleClickHdl, weld::TreeView&, bool) { m_xDialog->response(RET_OK); return true; } IMPL_LINK_NOARG(SvInsertOleDlg, BrowseHdl, weld::Button&, void) { sfx2::FileDialogHelper aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_xDialog.get()); aHelper.SetContext(sfx2::FileDialogHelper::InsertOLE); const Reference< XFilePicker3 >& xFilePicker = aHelper.GetFilePicker(); // add filter try { xFilePicker->appendFilter(CuiResId(RID_CUISTR_FILTER_ALL), u"*.*"_ustr); } catch( const IllegalArgumentException& ) { TOOLS_WARN_EXCEPTION("cui.dialogs", "caught IllegalArgumentException when registering filter" ); } if( xFilePicker->execute() == ExecutableDialogResults::OK ) { Sequence< OUString > aPathSeq( xFilePicker->getSelectedFiles() ); INetURLObject aObj( aPathSeq[0] ); m_xEdFilepath->set_text(aObj.PathToFileName()); } } IMPL_LINK(SvInsertOleDlg, RadioHdl, weld::Toggleable&, rButton, void) { if (!rButton.get_active()) return; if (m_xRbNewObject->get_active()) { m_xObjectTypeFrame->show(); m_xFileFrame->hide(); } else { m_xFileFrame->show(); m_xObjectTypeFrame->hide(); } } SvInsertOleDlg::SvInsertOleDlg(weld::Window* pParent, const Reference& xStorage, const SvObjectServerList* pServers) : InsertObjectDialog_Impl( pParent, u"cui/ui/insertoleobject.ui"_ustr, u"InsertOLEObjectDialog"_ustr, xStorage) , m_pServers( pServers ) , m_xRbNewObject(m_xBuilder->weld_radio_button(u"createnew"_ustr)) , m_xRbObjectFromfile(m_xBuilder->weld_radio_button(u"createfromfile"_ustr)) , m_xObjectTypeFrame(m_xBuilder->weld_frame(u"objecttypeframe"_ustr)) , m_xLbObjecttype(m_xBuilder->weld_tree_view(u"types"_ustr)) , m_xFileFrame(m_xBuilder->weld_frame(u"fileframe"_ustr)) , m_xEdFilepath(m_xBuilder->weld_entry(u"urled"_ustr)) , m_xBtnFilepath(m_xBuilder->weld_button(u"urlbtn"_ustr)) , m_xCbFilelink(m_xBuilder->weld_check_button(u"linktofile"_ustr)) , m_xCbAsIcon(m_xBuilder->weld_check_button(u"asicon"_ustr)) { m_xLbObjecttype->set_size_request(m_xLbObjecttype->get_approximate_digit_width() * 32, m_xLbObjecttype->get_height_rows(6)); m_xLbObjecttype->connect_row_activated(LINK(this, SvInsertOleDlg, DoubleClickHdl)); m_xBtnFilepath->connect_clicked(LINK( this, SvInsertOleDlg, BrowseHdl)); Link aLink( LINK( this, SvInsertOleDlg, RadioHdl ) ); m_xRbNewObject->connect_toggled( aLink ); m_xRbObjectFromfile->connect_toggled( aLink ); m_xRbNewObject->set_active(true); } short SvInsertOleDlg::run() { short nRet = RET_OK; SvObjectServerList aObjS; if ( !m_pServers ) { // if no list was provided, take the complete one aObjS.FillInsertObjects(); m_pServers = &aObjS; } // fill listbox and select default m_xLbObjecttype->freeze(); for ( size_t i = 0; i < m_pServers->Count(); i++ ) m_xLbObjecttype->append_text((*m_pServers)[i].GetHumanName()); m_xLbObjecttype->thaw(); m_xLbObjecttype->select(0); DBG_ASSERT( m_xStorage.is(), "No storage!"); if ( m_xStorage.is() && ( nRet = InsertObjectDialog_Impl::run() ) == RET_OK ) { OUString aFileName; OUString aName; bool bCreateNew = IsCreateNew(); if ( bCreateNew ) { // create and insert new embedded object OUString aServerName = m_xLbObjecttype->get_selected_text(); const SvObjectServer* pS = m_pServers->Get( aServerName ); if ( pS ) { if( pS->GetClassName() == SvGlobalName( SO3_OUT_CLASSID ) ) { try { uno::Reference < embed::XInsertObjectDialog > xDialogCreator( embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); if ( xDialogCreator.is() ) { aName = aCnt.CreateUniqueObjectName(); uno::Reference xProgress; OUString aProgressText; if (SfxViewFrame* pFrame = SfxViewFrame::Current()) { // Have a current frame, create a matching progressbar, but don't start it yet. uno::Reference xFrame = pFrame->GetFrame().GetFrameInterface(); uno::Reference xProgressFactory( xFrame, uno::UNO_QUERY); if (xProgressFactory.is()) { xProgress = xProgressFactory->createStatusIndicator(); if (xProgress) { aProgressText = CuiResId(RID_CUISTR_OLE_INSERT); } } } const embed::InsertedObjectInfo aNewInf = xDialogCreator->createInstanceByDialog( m_xStorage, aName, {comphelper::makePropertyValue(u"StatusIndicator"_ustr, xProgress), comphelper::makePropertyValue(u"StatusIndicatorText"_ustr, aProgressText)} ); OSL_ENSURE( aNewInf.Object.is(), "The object must be created or an exception must be thrown!" ); m_xObj = aNewInf.Object; for ( const auto& opt : aNewInf.Options ) if ( opt.Name == "Icon" ) { opt.Value >>= m_aIconMetaFile; } else if ( opt.Name == "IconFormat" ) { datatransfer::DataFlavor aFlavor; if ( opt.Value >>= aFlavor ) m_aIconMediaType = aFlavor.MimeType; } } } catch( ucb::CommandAbortedException& ) { // the user has pressed cancel } catch( uno::Exception& ) { // TODO: Error handling } } else { // create object with desired ClassId m_xObj = aCnt.CreateEmbeddedObject( pS->GetClassName().GetByteSequence(), aName ); } if ( !m_xObj.is() ) { if( !aFileName.isEmpty() ) // from OLE Dialog { // object couldn't be created from file // global Resource from svtools (former so3 resource) OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE)); aErr = aErr.replaceFirst( "%", aFileName ); std::unique_ptr xBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok, aErr)); xBox->run(); } else { // object couldn't be created // global Resource from svtools (former so3 resource) OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE)); aErr = aErr.replaceFirst( "%", aServerName ); std::unique_ptr xBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok, aErr)); xBox->run(); } } } } else { aFileName = m_xEdFilepath->get_text(); INetURLObject aURL; aURL.SetSmartProtocol( INetProtocol::File ); aURL.SetSmartURL( aFileName ); aFileName = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); bool bLink = m_xCbFilelink->get_active(); if ( !aFileName.isEmpty() ) { const uno::Reference< uno::XComponentContext >& xContext = ::comphelper::getProcessComponentContext(); uno::Reference< task::XInteractionHandler2 > xInteraction( task::InteractionHandler::createWithParent(xContext, nullptr) ); // create MediaDescriptor for file to create object from uno::Sequence < beans::PropertyValue > aMedium{ comphelper::makePropertyValue(u"URL"_ustr, aFileName), comphelper::makePropertyValue(u"InteractionHandler"_ustr, xInteraction) }; // create object from media descriptor uno::Reference xProgress; if (SfxViewFrame* pFrame = SfxViewFrame::Current()) { // Have a current frame, create visual indication that insert is in progress. uno::Reference xFrame = pFrame->GetFrame().GetFrameInterface(); uno::Reference xProgressFactory(xFrame, uno::UNO_QUERY); if (xProgressFactory.is()) { xProgress = xProgressFactory->createStatusIndicator(); if (xProgress) { OUString aOleInsert(CuiResId(RID_CUISTR_OLE_INSERT)); xProgress->start(aOleInsert, 100); } } } if ( bLink ) m_xObj = aCnt.InsertEmbeddedLink( aMedium, aName ); else m_xObj = aCnt.InsertEmbeddedObject( aMedium, aName ); if (xProgress.is()) { xProgress->end(); } } if ( !m_xObj.is() ) { // object couldn't be created from file // global Resource from svtools (former so3 resource) OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE)); aErr = aErr.replaceFirst( "%", aFileName ); std::unique_ptr xBox(Application::CreateMessageDialog(m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok, aErr)); xBox->run(); } else { if (m_xCbAsIcon->get_active()) { //something nice here I guess would be to write the filename into //the image with this icon above it Image aImage = SvFileInformationManager::GetImage(aURL, true); SvMemoryStream aTemp; WriteDIBBitmapEx(aImage.GetBitmapEx(), aTemp); m_aIconMetaFile = Sequence(static_cast(aTemp.GetData()), aTemp.TellEnd()); m_aIconMediaType = "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\""; } } } } m_pServers = nullptr; return nRet; } uno::Reference< io::XInputStream > SvInsertOleDlg::GetIconIfIconified( OUString* pGraphicMediaType ) { if ( m_aIconMetaFile.hasElements() ) { if ( pGraphicMediaType ) *pGraphicMediaType = m_aIconMediaType; return uno::Reference< io::XInputStream >( new ::comphelper::SequenceInputStream( m_aIconMetaFile ) ); } return uno::Reference< io::XInputStream >(); } SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window *pParent, const css::uno::Reference < css::embed::XStorage >& xStorage) : InsertObjectDialog_Impl(pParent, u"cui/ui/insertfloatingframe.ui"_ustr, u"InsertFloatingFrameDialog"_ustr, xStorage) { Init(); } SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window *pParent, const uno::Reference < embed::XEmbeddedObject >& xObj) : InsertObjectDialog_Impl(pParent, u"cui/ui/insertfloatingframe.ui"_ustr, u"InsertFloatingFrameDialog"_ustr, uno::Reference()) { m_xObj = xObj; Init(); } void SfxInsertFloatingFrameDialog::Init() { m_xEDName = m_xBuilder->weld_entry(u"edname"_ustr); m_xEDURL = m_xBuilder->weld_entry(u"edurl"_ustr); m_xBTOpen = m_xBuilder->weld_button(u"buttonbrowse"_ustr); m_xRBScrollingOn = m_xBuilder->weld_radio_button(u"scrollbaron"_ustr); m_xRBScrollingOff = m_xBuilder->weld_radio_button(u"scrollbaroff"_ustr); m_xRBScrollingAuto = m_xBuilder->weld_radio_button(u"scrollbarauto"_ustr); m_xRBFrameBorderOn = m_xBuilder->weld_radio_button(u"borderon"_ustr); m_xRBFrameBorderOff = m_xBuilder->weld_radio_button(u"borderoff"_ustr); m_xFTMarginWidth = m_xBuilder->weld_label(u"widthlabel"_ustr); m_xNMMarginWidth = m_xBuilder->weld_spin_button(u"width"_ustr); m_xCBMarginWidthDefault = m_xBuilder->weld_check_button(u"defaultwidth"_ustr); m_xFTMarginHeight = m_xBuilder->weld_label(u"heightlabel"_ustr); m_xNMMarginHeight = m_xBuilder->weld_spin_button(u"height"_ustr); m_xCBMarginHeightDefault = m_xBuilder->weld_check_button(u"defaultheight"_ustr); Link aLink(LINK(this, SfxInsertFloatingFrameDialog, CheckHdl)); m_xCBMarginWidthDefault->connect_toggled(aLink); m_xCBMarginHeightDefault->connect_toggled(aLink); m_xCBMarginWidthDefault->set_active(true); m_xCBMarginHeightDefault->set_active(true); m_xRBScrollingAuto->set_active(true); m_xRBFrameBorderOn->set_active(true); m_xBTOpen->connect_clicked(LINK(this, SfxInsertFloatingFrameDialog, OpenHdl)); } short SfxInsertFloatingFrameDialog::run() { short nRet = RET_OK; bool bOK = false; uno::Reference < beans::XPropertySet > xSet; if ( m_xObj.is() ) { try { if ( m_xObj->getCurrentState() == embed::EmbedStates::LOADED ) m_xObj->changeState( embed::EmbedStates::RUNNING ); xSet.set( m_xObj->getComponent(), uno::UNO_QUERY ); OUString aStr; uno::Any aAny = xSet->getPropertyValue( u"FrameURL"_ustr ); if ( aAny >>= aStr ) m_xEDURL->set_text( aStr ); aAny = xSet->getPropertyValue( u"FrameName"_ustr ); if ( aAny >>= aStr ) m_xEDName->set_text(aStr); sal_Int32 nSize = SIZE_NOT_SET; aAny = xSet->getPropertyValue( u"FrameMarginWidth"_ustr ); aAny >>= nSize; if ( nSize == SIZE_NOT_SET ) { m_xCBMarginWidthDefault->set_active(true); m_xNMMarginWidth->set_text(OUString::number(DEFAULT_MARGIN_WIDTH)); m_xFTMarginWidth->set_sensitive(false); m_xNMMarginWidth->set_sensitive(false); } else m_xNMMarginWidth->set_text(OUString::number(nSize)); aAny = xSet->getPropertyValue( u"FrameMarginHeight"_ustr ); aAny >>= nSize; if ( nSize == SIZE_NOT_SET ) { m_xCBMarginHeightDefault->set_active(true); m_xNMMarginHeight->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT)); m_xFTMarginHeight->set_sensitive(false); m_xNMMarginHeight->set_sensitive(false); } else m_xNMMarginHeight->set_text(OUString::number(nSize)); bool bScrollOn = false; bool bScrollOff = false; bool bScrollAuto = false; bool bSet = false; aAny = xSet->getPropertyValue( u"FrameIsAutoScroll"_ustr ); aAny >>= bSet; if ( !bSet ) { aAny = xSet->getPropertyValue( u"FrameIsScrollingMode"_ustr ); aAny >>= bSet; bScrollOn = bSet; bScrollOff = !bSet; } else bScrollAuto = true; m_xRBScrollingOn->set_sensitive(bScrollOn); m_xRBScrollingOff->set_sensitive(bScrollOff); m_xRBScrollingAuto->set_sensitive(bScrollAuto); bSet = false; aAny = xSet->getPropertyValue( u"FrameIsAutoBorder"_ustr ); aAny >>= bSet; if ( !bSet ) { aAny = xSet->getPropertyValue( u"FrameIsBorder"_ustr ); aAny >>= bSet; m_xRBFrameBorderOn->set_active(bSet); m_xRBFrameBorderOff->set_active(!bSet); } bOK = true; } catch ( uno::Exception& ) { OSL_FAIL( "No IFrame!" ); } } else { DBG_ASSERT( m_xStorage.is(), "No storage!"); bOK = m_xStorage.is(); } if (!bOK) return RET_OK; nRet = InsertObjectDialog_Impl::run(); if ( nRet == RET_OK ) { OUString aURL; if (!m_xEDURL->get_text().isEmpty()) { // URL can be a valid and absolute URL or a system file name INetURLObject aObj; aObj.SetSmartProtocol( INetProtocol::File ); if ( aObj.SetSmartURL( m_xEDURL->get_text() ) ) aURL = aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ); } if ( !m_xObj.is() && !aURL.isEmpty() ) { // create the object OUString aName; SvGlobalName aClassId( SO3_IFRAME_CLASSID ); m_xObj = aCnt.CreateEmbeddedObject( aClassId.GetByteSequence(), aName ); if ( m_xObj->getCurrentState() == embed::EmbedStates::LOADED ) m_xObj->changeState( embed::EmbedStates::RUNNING ); xSet.set( m_xObj->getComponent(), uno::UNO_QUERY ); } if ( m_xObj.is() ) { try { bool bIPActive = m_xObj->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE; if ( bIPActive ) m_xObj->changeState( embed::EmbedStates::RUNNING ); OUString aName = m_xEDName->get_text(); ScrollingMode eScroll = ScrollingMode::No; if (m_xRBScrollingOn->get_active()) eScroll = ScrollingMode::Yes; if (m_xRBScrollingOff->get_active()) eScroll = ScrollingMode::No; if (m_xRBScrollingAuto->get_active()) eScroll = ScrollingMode::Auto; bool bHasBorder = m_xRBFrameBorderOn->get_active(); tools::Long lMarginWidth; if (!m_xCBMarginWidthDefault->get_active()) lMarginWidth = static_cast(m_xNMMarginWidth->get_text().toInt32()); else lMarginWidth = SIZE_NOT_SET; tools::Long lMarginHeight; if (!m_xCBMarginHeightDefault->get_active()) lMarginHeight = static_cast(m_xNMMarginHeight->get_text().toInt32()); else lMarginHeight = SIZE_NOT_SET; xSet->setPropertyValue( u"FrameURL"_ustr, Any( aURL ) ); xSet->setPropertyValue( u"FrameName"_ustr, Any( aName ) ); if ( eScroll == ScrollingMode::Auto ) xSet->setPropertyValue( u"FrameIsAutoScroll"_ustr, Any( true ) ); else xSet->setPropertyValue( u"FrameIsScrollingMode"_ustr, Any( eScroll == ScrollingMode::Yes ) ); xSet->setPropertyValue( u"FrameIsBorder"_ustr, Any( bHasBorder ) ); xSet->setPropertyValue( u"FrameMarginWidth"_ustr, Any( sal_Int32( lMarginWidth ) ) ); xSet->setPropertyValue( u"FrameMarginHeight"_ustr, Any( sal_Int32( lMarginHeight ) ) ); if ( bIPActive ) m_xObj->changeState( embed::EmbedStates::INPLACE_ACTIVE ); } catch ( uno::Exception& ) { OSL_FAIL( "No IFrame!" ); } } } return nRet; } IMPL_LINK(SfxInsertFloatingFrameDialog, CheckHdl, weld::Toggleable&, rButton, void) { weld::CheckButton& rCB = dynamic_cast(rButton); if (&rCB == m_xCBMarginWidthDefault.get()) { if (rCB.get_active()) m_xNMMarginWidth->set_text(OUString::number(DEFAULT_MARGIN_WIDTH)); m_xFTMarginWidth->set_sensitive(!rCB.get_active()); m_xNMMarginWidth->set_sensitive(!rCB.get_active()); } if (&rCB == m_xCBMarginHeightDefault.get()) { if (rCB.get_active()) m_xNMMarginHeight->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT)); m_xFTMarginHeight->set_sensitive(!rCB.get_active()); m_xNMMarginHeight->set_sensitive(!rCB.get_active()); } } IMPL_LINK_NOARG( SfxInsertFloatingFrameDialog, OpenHdl, weld::Button&, void) { // create the file dialog sfx2::FileDialogHelper aFileDlg( ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, OUString(), SfxFilterFlags::NONE, SfxFilterFlags::NONE, m_xDialog.get()); // set the title aFileDlg.SetTitle(CuiResId(RID_CUISTR_SELECT_FILE_IFRAME)); // show the dialog if ( aFileDlg.Execute() == ERRCODE_NONE ) m_xEDURL->set_text(INetURLObject(aFileDlg.GetPath()).GetMainURL(INetURLObject::DecodeMechanism::WithCharset)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */