1
0
Fork 0
libreoffice/svx/source/gallery2/galmisc.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

559 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 || SotClipboardFormatId::PNG == 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: */