6d0a1664d3
no point reading this to just to discard it later the only places reading this are just opening, using and close the streams afterwards, so the need to even skip over this data doesn't seem to arise. Change-Id: Ieb2498f458534770c167bbbfb3a4792162238986 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176004 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
558 lines
16 KiB
C++
558 lines
16 KiB
C++
/* -*- 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 ( 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(u"Title"_ustr) >>= 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{ u"Title"_ustr };
|
|
uno::Sequence< uno::Any > aValues{ uno::Any(rURL.GetLastName()) };
|
|
|
|
::ucbhelper::Content aContent( rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aCmdEnv, comphelper::getProcessComponentContext() );
|
|
bRet = aParent.insertNewContent( u"application/vnd.sun.staroffice.fsys-folder"_ustr, 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( u"transfer"_ustr,
|
|
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( u"delete"_ustr, 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( u"com.sun.star.awt.XProgressMonitor"_ustr ),
|
|
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( u"Gallery"_ustr, 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 )
|
|
{
|
|
mxModelStream = SotTempStream::Create( u""_ustr );
|
|
mxModelStream->SetBufferSize( 16348 );
|
|
|
|
if (!mpTheme || !mpTheme->GetModelStream(mnObjectPos, *mxModelStream))
|
|
mxModelStream.reset();
|
|
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 && 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( SvStream& rOStm, void* pUserObject,
|
|
sal_uInt32, const datatransfer::DataFlavor& )
|
|
{
|
|
bool bRet = false;
|
|
|
|
if( pUserObject )
|
|
{
|
|
rOStm.WriteStream( *static_cast< SotStorageStream* >( pUserObject ) );
|
|
bRet = ( rOStm.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.reset();
|
|
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: */
|