diff options
Diffstat (limited to 'svx/source/gallery2/galmisc.cxx')
-rw-r--r-- | svx/source/gallery2/galmisc.cxx | 563 |
1 files changed, 563 insertions, 0 deletions
diff --git a/svx/source/gallery2/galmisc.cxx b/svx/source/gallery2/galmisc.cxx new file mode 100644 index 0000000000..ab5713f7a4 --- /dev/null +++ b/svx/source/gallery2/galmisc.cxx @@ -0,0 +1,563 @@ +/* -*- 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 <sal/config.h> + +#include <sot/storage.hxx> +#include <unotools/streamwrap.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/string.hxx> +#include <ucbhelper/content.hxx> +#include <com/sun/star/ucb/ContentCreationException.hpp> +#include <tools/urlobj.hxx> +#include <vcl/graphicfilter.hxx> +#include <svl/itempool.hxx> +#include <sfx2/docfile.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <svx/svdpage.hxx> +#include <svx/dialmgr.hxx> +#include <svx/svdograf.hxx> +#include <svx/fmmodel.hxx> +#include <svx/unomodel.hxx> +#include "codec.hxx" +#include <svx/strings.hrc> +#include <svx/galtheme.hxx> +#include <svx/galmisc.hxx> +#include <osl/diagnose.h> +#include <com/sun/star/awt/XProgressMonitor.hpp> +#include <com/sun/star/ucb/TransferInfo.hpp> +#include <com/sun/star/ucb/NameClash.hpp> +#include <memory> + +using namespace ::com::sun::star; + +GalleryGraphicImportRet GalleryGraphicImport( const INetURLObject& rURL, Graphic& rGraphic, + OUString& rFilterName ) +{ + GalleryGraphicImportRet nRet = GalleryGraphicImportRet::IMPORT_NONE; + SfxMedium aMedium( rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ); + + aMedium.Download(); + + SvStream* pIStm = aMedium.GetInStream(); + + if( pIStm ) + { + GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter(); + sal_uInt16 nFormat; + + if( !rGraphicFilter.ImportGraphic( rGraphic, rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), *pIStm, GRFILTER_FORMAT_DONTKNOW, &nFormat ) ) + { + rFilterName = rGraphicFilter.GetImportFormatName( nFormat ); + nRet = GalleryGraphicImportRet::IMPORT_FILE; + } + } + + return nRet; +} + +bool GallerySvDrawImport( SvStream& rIStm, SdrModel& rModel ) +{ + sal_uInt32 nVersion; + bool bRet = false; + + if( GalleryCodec::IsCoded( rIStm, nVersion ) ) + { + SvMemoryStream aMemStm( 65535, 65535 ); + GalleryCodec aCodec( rIStm ); + + aCodec.Read( aMemStm ); + aMemStm.Seek( 0 ); + + if( 1 == nVersion ) + { + OSL_FAIL( "staroffice binary file formats are no longer supported inside the gallery!" ); + bRet = false; + } + else if( 2 == nVersion ) + { + // recall to read as XML + bRet = GallerySvDrawImport( aMemStm, rModel ); + } + } + else + { + // read as XML + uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rIStm ) ); + + rModel.GetItemPool().SetDefaultMetric( MapUnit::Map100thMM ); + uno::Reference< lang::XComponent > xComponent; + + bRet = SvxDrawingLayerImport( &rModel, xInputStream, xComponent, "com.sun.star.comp.Draw.XMLOasisImporter" ); + if( !bRet || (rModel.GetPageCount() == 0) ) + { + rIStm.Seek(0); + bRet = SvxDrawingLayerImport( &rModel, xInputStream, xComponent, "com.sun.star.comp.Draw.XMLImporter" ); + } + + } + + return bRet; +} + +bool CreateIMapGraphic( const FmFormModel& rModel, Graphic& rGraphic, ImageMap& rImageMap ) +{ + if (! rModel.GetPageCount() ) + return false; + + const SdrPage* pPage = rModel.GetPage( 0 ); + const SdrObject* pObj = pPage->GetObj( 0 ); + + if ( pPage->GetObjCount() != 1 ) + return false; + auto pGrafObj = dynamic_cast<const SdrGrafObj*>( pObj); + if (!pGrafObj) + return false; + + bool bRet = false; + const sal_uInt16 nCount = pObj->GetUserDataCount(); + + // Exist in the user data an IMap information? + for ( sal_uInt16 i = 0; i < nCount; i++ ) + { + const SdrObjUserData* pUserData = pObj->GetUserData( i ); + + if ( ( pUserData->GetInventor() == SdrInventor::SgaImap ) && ( pUserData->GetId() == ID_IMAPINFO ) ) + { + rGraphic = pGrafObj->GetGraphic(); + rImageMap = static_cast<const SgaIMapInfo*>( pUserData )->GetImageMap(); + bRet = true; + break; + } + } + + return bRet; +} + +OUString GetReducedString( const INetURLObject& rURL, sal_Int32 nMaxLen ) +{ + OUString aReduced( rURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ) ); + + aReduced = aReduced.copy(aReduced.lastIndexOf('/')+1); + + if( INetProtocol::PrivSoffice != rURL.GetProtocol() ) + { + sal_Unicode aDelimiter; + const OUString aPath( rURL.getFSysPath( FSysStyle::Detect, &aDelimiter ) ); + const OUString aName( aReduced ); + + if( aPath.getLength() > nMaxLen ) + { + sal_Int32 nPathPrefixLen = nMaxLen - aName.getLength() - 4; + + if (nPathPrefixLen >= 0) + { + aReduced = OUString::Concat(aPath.subView(0, nPathPrefixLen)) + "..." + + OUStringChar(aDelimiter) + aName; + } + else + { + aReduced += "..." + OUStringChar(aDelimiter) + "..." + + aName.subView( aName.getLength() - (nMaxLen - 7) ); + } + } + else + aReduced = aPath; + } + + return aReduced; +} + +OUString GetSvDrawStreamNameFromURL( const INetURLObject& rSvDrawObjURL ) +{ + OUString aRet; + + if( rSvDrawObjURL.GetProtocol() == INetProtocol::PrivSoffice && + comphelper::string::getTokenCount(rSvDrawObjURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), '/') == 3 ) + { + aRet = rSvDrawObjURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getToken( 2, '/' ); + } + + return aRet; +} + +bool FileExists( const INetURLObject& rURL ) +{ + bool bRet = false; + + if( rURL.GetProtocol() != INetProtocol::NotValid ) + { + try + { + ::ucbhelper::Content aCnt( rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() ); + OUString aTitle; + + aCnt.getPropertyValue("Title") >>= aTitle; + bRet = ( !aTitle.isEmpty() ); + } + catch( const ucb::ContentCreationException& ) + { + } + catch( const uno::RuntimeException& ) + { + } + catch( const uno::Exception& ) + { + } + } + + return bRet; +} + +bool CreateDir( const INetURLObject& rURL ) +{ + bool bRet = FileExists( rURL ); + + if( !bRet ) + { + try + { + uno::Reference< ucb::XCommandEnvironment > aCmdEnv; + INetURLObject aParentURL( rURL ); + aParentURL.removeSegment(); + ::ucbhelper::Content aParent( aParentURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aCmdEnv, comphelper::getProcessComponentContext() ); + uno::Sequence< OUString > aProps{ "Title" }; + uno::Sequence< uno::Any > aValues{ uno::Any(rURL.GetLastName()) }; + + ::ucbhelper::Content aContent( rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aCmdEnv, comphelper::getProcessComponentContext() ); + bRet = aParent.insertNewContent( "application/vnd.sun.staroffice.fsys-folder", aProps, aValues, aContent ); + } + catch( const ucb::ContentCreationException& ) + { + } + catch( const uno::RuntimeException& ) + { + } + catch( const uno::Exception& ) + { + } + } + + return bRet; +} + +bool CopyFile( const INetURLObject& rSrcURL, const INetURLObject& rDstURL ) +{ + bool bRet = false; + + try + { + ::ucbhelper::Content aDestPath( rDstURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() ); + + aDestPath.executeCommand( "transfer", + uno::Any( ucb::TransferInfo( false, rSrcURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), + rDstURL.GetLastName(), ucb::NameClash::OVERWRITE ) ) ); + bRet = true; + } + catch( const ucb::ContentCreationException& ) + { + } + catch( const uno::RuntimeException& ) + { + } + catch( const uno::Exception& ) + { + } + + return bRet; +} + +bool KillFile( const INetURLObject& rURL ) +{ + bool bRet = FileExists( rURL ); + + if( bRet ) + { + try + { + ::ucbhelper::Content aCnt( rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() ); + aCnt.executeCommand( "delete", uno::Any( true ) ); + } + catch( const ucb::ContentCreationException& ) + { + bRet = false; + } + catch( const uno::RuntimeException& ) + { + bRet = false; + } + catch( const uno::Exception& ) + { + bRet = false; + } + } + + return bRet; +} + + +GalleryProgress::GalleryProgress( const GraphicFilter* pFilter ) +{ + + uno::Reference< lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); + + uno::Reference< awt::XProgressMonitor > xMonitor( xMgr->createInstance( "com.sun.star.awt.XProgressMonitor" ), + uno::UNO_QUERY ); + + if ( !xMonitor.is() ) + return; + + mxProgressBar = xMonitor; + + OUString aProgressText; + + if( pFilter ) + { + aProgressText = SvxResId(RID_SVXSTR_GALLERY_FILTER); +// pFilter->SetUpdatePercentHdl( LINK( this, GalleryProgress, Update ) ); // sj: progress wasn't working up from SO7 at all +// // so I am removing this. The gallery progress should +// // be changed to use the XStatusIndicator instead of XProgressMonitor + } + else + aProgressText = "Gallery"; + + xMonitor->addText( "Gallery", aProgressText, false ) ; + mxProgressBar->setRange( 0, GALLERY_PROGRESS_RANGE ); +} + +GalleryProgress::~GalleryProgress() +{ +} + +void GalleryProgress::Update( sal_Int32 nVal, sal_Int32 nMaxVal ) +{ + if( mxProgressBar.is() && nMaxVal ) + mxProgressBar->setValue( std::min<sal_Int32>( static_cast<double>(nVal) / nMaxVal * GALLERY_PROGRESS_RANGE, + GALLERY_PROGRESS_RANGE ) ); +} + + +GalleryTransferable::GalleryTransferable( GalleryTheme* pTheme, sal_uInt32 nObjectPos, bool bLazy ) : + mpTheme( pTheme ), + meObjectKind( pTheme ? mpTheme->GetObjectKind(nObjectPos) : SgaObjKind::NONE), + mnObjectPos( nObjectPos ) +{ + + InitData( bLazy ); +} + +void GalleryTransferable::SelectObject(sal_uInt32 nObjectPos) +{ + if (nObjectPos == mnObjectPos) + return; + ClearFormats(); + mnObjectPos = nObjectPos; + meObjectKind = mpTheme ? mpTheme->GetObjectKind(mnObjectPos) : SgaObjKind::NONE; + ObjectReleased(); + InitData(true); +} + +GalleryTransferable::~GalleryTransferable() +{ +} + +void GalleryTransferable::InitData( bool bLazy ) +{ + switch( meObjectKind ) + { + case SgaObjKind::SvDraw: + { + if( !bLazy ) + { + if( !mpGraphicObject ) + { + Graphic aGraphic; + + if (mpTheme && mpTheme->GetGraphic(mnObjectPos, aGraphic)) + mpGraphicObject.reset(new GraphicObject( std::move(aGraphic) )); + } + + if( !mxModelStream.is() ) + { + mxModelStream = new SotTempStream( "" ); + mxModelStream->SetBufferSize( 16348 ); + + if (!mpTheme || !mpTheme->GetModelStream(mnObjectPos, mxModelStream)) + mxModelStream.clear(); + else + mxModelStream->Seek( 0 ); + } + } + } + break; + + case SgaObjKind::Animation: + case SgaObjKind::Bitmap: + case SgaObjKind::Inet: + case SgaObjKind::Sound: + { + if( !mpURL ) + { + mpURL.reset(new INetURLObject); + + if (!mpTheme || !mpTheme->GetURL(mnObjectPos, *mpURL)) + { + mpURL.reset(); + } + } + + if( ( SgaObjKind::Sound != meObjectKind ) && !mpGraphicObject ) + { + Graphic aGraphic; + + if (mpTheme && mpTheme->GetGraphic(mnObjectPos, aGraphic)) + mpGraphicObject.reset(new GraphicObject( std::move(aGraphic) )); + } + } + break; + + default: + OSL_FAIL( "GalleryTransferable::GalleryTransferable: invalid object type" ); + break; + } +} + +void GalleryTransferable::AddSupportedFormats() +{ + if( SgaObjKind::SvDraw == meObjectKind ) + { + AddFormat( SotClipboardFormatId::DRAWING ); + AddFormat( SotClipboardFormatId::SVXB ); + AddFormat( SotClipboardFormatId::GDIMETAFILE ); + AddFormat( SotClipboardFormatId::BITMAP ); + } + else + { + if( mpURL ) + AddFormat( SotClipboardFormatId::SIMPLE_FILE ); + + if( mpGraphicObject ) + { + AddFormat( SotClipboardFormatId::SVXB ); + + if( mpGraphicObject->GetType() == GraphicType::GdiMetafile ) + { + AddFormat( SotClipboardFormatId::GDIMETAFILE ); + AddFormat( SotClipboardFormatId::BITMAP ); + } + else + { + AddFormat( SotClipboardFormatId::BITMAP ); + AddFormat( SotClipboardFormatId::GDIMETAFILE ); + } + } + } +} + +bool GalleryTransferable::GetData( const datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ ) +{ + SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor ); + bool bRet = false; + + InitData( false ); + + if( ( SotClipboardFormatId::DRAWING == nFormat ) && ( SgaObjKind::SvDraw == meObjectKind ) ) + { + bRet = ( mxModelStream.is() && SetObject( mxModelStream.get(), 0, rFlavor ) ); + } + else if( ( SotClipboardFormatId::SIMPLE_FILE == nFormat ) && mpURL ) + { + bRet = SetString( mpURL->GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); + } + else if( ( SotClipboardFormatId::SVXB == nFormat ) && mpGraphicObject ) + { + bRet = SetGraphic( mpGraphicObject->GetGraphic() ); + } + else if( ( SotClipboardFormatId::GDIMETAFILE == nFormat ) && mpGraphicObject ) + { + bRet = SetGDIMetaFile( mpGraphicObject->GetGraphic().GetGDIMetaFile() ); + } + else if( ( SotClipboardFormatId::BITMAP == nFormat ) && mpGraphicObject ) + { + bRet = SetBitmapEx( mpGraphicObject->GetGraphic().GetBitmapEx(), rFlavor ); + } + + return bRet; +} + +bool GalleryTransferable::WriteObject( tools::SvRef<SotTempStream>& rxOStm, void* pUserObject, + sal_uInt32, const datatransfer::DataFlavor& ) +{ + bool bRet = false; + + if( pUserObject ) + { + rxOStm->WriteStream( *static_cast< SotStorageStream* >( pUserObject ) ); + bRet = ( rxOStm->GetError() == ERRCODE_NONE ); + } + + return bRet; +} + +void GalleryTransferable::DragFinished( sal_Int8 nDropAction ) +{ + if (mpTheme) + { + mpTheme->SetDragging( false ); + mpTheme->SetDragPos( 0 ); + } + if ( nDropAction ) + { + vcl::Window *pFocusWindow = Application::GetFocusWindow(); + if ( pFocusWindow ) + pFocusWindow->GrabFocusToDocument(); + } +} + +void GalleryTransferable::ObjectReleased() +{ + mxModelStream.clear(); + mpGraphicObject.reset(); + mpURL.reset(); +} + +bool GalleryTransferable::StartDrag() +{ + INetURLObject aURL; + if (mpTheme && mpTheme->GetURL(mnObjectPos, aURL) && aURL.GetProtocol() != INetProtocol::NotValid) + { + mpTheme->SetDragging( true ); + mpTheme->SetDragPos( mnObjectPos ); + return false; + } + return true; +} + +INetURLObject ImplGetURL(const GalleryObject* pObject) +{ + INetURLObject aURL; + + if (pObject) + aURL = *pObject->m_oStorageUrl; + + return aURL; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |