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 <sal/config.h>
22 #include <sot/storage.hxx>
23 #include <unotools/streamwrap.hxx>
24 #include <comphelper/processfactory.hxx>
25 #include <comphelper/string.hxx>
26 #include <ucbhelper/content.hxx>
27 #include <com/sun/star/ucb/ContentCreationException.hpp>
28 #include <unotools/resmgr.hxx>
29 #include <tools/urlobj.hxx>
30 #include <svl/solar.hrc>
31 #include <svl/urihelper.hxx>
32 #include <vcl/graphicfilter.hxx>
33 #include <svl/itempool.hxx>
34 #include <sfx2/docfile.hxx>
35 #include <avmedia/mediawindow.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/settings.hxx>
38 #include <svx/svdpage.hxx>
39 #include <svx/dialmgr.hxx>
40 #include <svx/svdograf.hxx>
41 #include <svx/fmmodel.hxx>
42 #include <svx/fmview.hxx>
43 #include <svx/unomodel.hxx>
45 #include <svx/strings.hrc>
46 #include <svx/gallery1.hxx>
47 #include <svx/galtheme.hxx>
48 #include <svx/galmisc.hxx>
49 #include <com/sun/star/awt/XProgressMonitor.hpp>
50 #include <com/sun/star/sdbc/XResultSet.hpp>
51 #include <com/sun/star/ucb/XContentAccess.hpp>
52 #include <com/sun/star/ucb/TransferInfo.hpp>
53 #include <com/sun/star/ucb/NameClash.hpp>
56 using namespace ::com::sun::star
;
58 BitmapEx
GalleryResGetBitmapEx(const OUString
&rId
)
62 //TODO, check if any of these have no transparency layer
63 if (!aBmpEx
.IsTransparent())
64 aBmpEx
= BitmapEx(aBmpEx
.GetBitmap(), COL_LIGHTMAGENTA
);
69 GalleryGraphicImportRet
GalleryGraphicImport( const INetURLObject
& rURL
, Graphic
& rGraphic
,
70 OUString
& rFilterName
)
72 GalleryGraphicImportRet nRet
= GalleryGraphicImportRet::IMPORT_NONE
;
73 SfxMedium
aMedium( rURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::READ
);
77 SvStream
* pIStm
= aMedium
.GetInStream();
81 GraphicFilter
& rGraphicFilter
= GraphicFilter::GetGraphicFilter();
84 if( !rGraphicFilter
.ImportGraphic( rGraphic
, rURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), *pIStm
, GRFILTER_FORMAT_DONTKNOW
, &nFormat
) )
86 rFilterName
= rGraphicFilter
.GetImportFormatName( nFormat
);
87 nRet
= GalleryGraphicImportRet::IMPORT_FILE
;
94 bool GallerySvDrawImport( SvStream
& rIStm
, SdrModel
& rModel
)
99 if( GalleryCodec::IsCoded( rIStm
, nVersion
) )
101 SvMemoryStream
aMemStm( 65535, 65535 );
102 GalleryCodec
aCodec( rIStm
);
104 aCodec
.Read( aMemStm
);
109 OSL_FAIL( "staroffice binary file formats are no longer supported inside the gallery!" );
112 else if( 2 == nVersion
)
114 // recall to read as XML
115 bRet
= GallerySvDrawImport( aMemStm
, rModel
);
121 uno::Reference
< io::XInputStream
> xInputStream( new utl::OInputStreamWrapper( rIStm
) );
123 rModel
.GetItemPool().SetDefaultMetric( MapUnit::Map100thMM
);
124 uno::Reference
< lang::XComponent
> xComponent
;
126 bRet
= SvxDrawingLayerImport( &rModel
, xInputStream
, xComponent
, "com.sun.star.comp.Draw.XMLOasisImporter" );
127 if( !bRet
|| (rModel
.GetPageCount() == 0) )
130 bRet
= SvxDrawingLayerImport( &rModel
, xInputStream
, xComponent
, "com.sun.star.comp.Draw.XMLImporter" );
138 bool CreateIMapGraphic( const FmFormModel
& rModel
, Graphic
& rGraphic
, ImageMap
& rImageMap
)
142 if ( rModel
.GetPageCount() )
144 const SdrPage
* pPage
= rModel
.GetPage( 0 );
145 const SdrObject
* pObj
= pPage
->GetObj( 0 );
147 if ( pPage
->GetObjCount() == 1 && dynamic_cast<const SdrGrafObj
*>( pObj
) != nullptr )
149 const sal_uInt16 nCount
= pObj
->GetUserDataCount();
151 // Exist in the user data an IMap information?
152 for ( sal_uInt16 i
= 0; i
< nCount
; i
++ )
154 const SdrObjUserData
* pUserData
= pObj
->GetUserData( i
);
156 if ( ( pUserData
->GetInventor() == SdrInventor::SgaImap
) && ( pUserData
->GetId() == ID_IMAPINFO
) )
158 rGraphic
= static_cast<const SdrGrafObj
*>( pObj
)->GetGraphic();
159 rImageMap
= static_cast<const SgaIMapInfo
*>( pUserData
)->GetImageMap();
170 OUString
GetReducedString( const INetURLObject
& rURL
, sal_Int32 nMaxLen
)
172 OUString
aReduced( rURL
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
) );
174 aReduced
= aReduced
.copy(aReduced
.lastIndexOf('/')+1);
176 if( INetProtocol::PrivSoffice
!= rURL
.GetProtocol() )
178 sal_Unicode aDelimiter
;
179 const OUString
aPath( rURL
.getFSysPath( FSysStyle::Detect
, &aDelimiter
) );
180 const OUString
aName( aReduced
);
182 if( aPath
.getLength() > nMaxLen
)
184 sal_Int32 nPathPrefixLen
= nMaxLen
- aName
.getLength() - 4;
186 if (nPathPrefixLen
>= 0)
188 aReduced
= aPath
.copy(0, nPathPrefixLen
) + "..."
189 + OUStringChar(aDelimiter
) + aName
;
193 aReduced
+= "..." + OUStringChar(aDelimiter
) + "..."
194 + aName
.copy( aName
.getLength() - (nMaxLen
- 7) );
204 OUString
GetSvDrawStreamNameFromURL( const INetURLObject
& rSvDrawObjURL
)
208 if( rSvDrawObjURL
.GetProtocol() == INetProtocol::PrivSoffice
&&
209 comphelper::string::getTokenCount(rSvDrawObjURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), '/') == 3 )
211 aRet
= rSvDrawObjURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
).getToken( 2, '/' );
217 bool FileExists( const INetURLObject
& rURL
)
221 if( rURL
.GetProtocol() != INetProtocol::NotValid
)
225 ::ucbhelper::Content
aCnt( rURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), uno::Reference
< ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
228 aCnt
.getPropertyValue("Title") >>= aTitle
;
229 bRet
= ( !aTitle
.isEmpty() );
231 catch( const ucb::ContentCreationException
& )
234 catch( const uno::RuntimeException
& )
237 catch( const uno::Exception
& )
245 bool CreateDir( const INetURLObject
& rURL
)
247 bool bRet
= FileExists( rURL
);
253 uno::Reference
< ucb::XCommandEnvironment
> aCmdEnv
;
254 INetURLObject
aParentURL( rURL
);
255 aParentURL
.removeSegment();
256 ::ucbhelper::Content
aParent( aParentURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), aCmdEnv
, comphelper::getProcessComponentContext() );
257 uno::Sequence
< OUString
> aProps( 1 );
258 uno::Sequence
< uno::Any
> aValues( 1 );
261 aValues
[0] <<= rURL
.GetLastName();
263 ::ucbhelper::Content
aContent( rURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), aCmdEnv
, comphelper::getProcessComponentContext() );
264 bRet
= aParent
.insertNewContent( "application/vnd.sun.staroffice.fsys-folder", aProps
, aValues
, aContent
);
266 catch( const ucb::ContentCreationException
& )
269 catch( const uno::RuntimeException
& )
272 catch( const uno::Exception
& )
280 bool CopyFile( const INetURLObject
& rSrcURL
, const INetURLObject
& rDstURL
)
286 ::ucbhelper::Content
aDestPath( rDstURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), uno::Reference
< ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
288 aDestPath
.executeCommand( "transfer",
289 uno::makeAny( ucb::TransferInfo( false, rSrcURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
),
290 rDstURL
.GetLastName(), ucb::NameClash::OVERWRITE
) ) );
293 catch( const ucb::ContentCreationException
& )
296 catch( const uno::RuntimeException
& )
299 catch( const uno::Exception
& )
306 bool KillFile( const INetURLObject
& rURL
)
308 bool bRet
= FileExists( rURL
);
314 ::ucbhelper::Content
aCnt( rURL
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), uno::Reference
< ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
315 aCnt
.executeCommand( "delete", uno::makeAny( true ) );
317 catch( const ucb::ContentCreationException
& )
321 catch( const uno::RuntimeException
& )
325 catch( const uno::Exception
& )
335 GalleryProgress::GalleryProgress( const GraphicFilter
* pFilter
)
338 uno::Reference
< lang::XMultiServiceFactory
> xMgr( ::comphelper::getProcessServiceFactory() );
340 uno::Reference
< awt::XProgressMonitor
> xMonitor( xMgr
->createInstance( "com.sun.star.awt.XProgressMonitor" ),
345 mxProgressBar
= xMonitor
;
347 OUString aProgressText
;
351 aProgressText
= SvxResId(RID_SVXSTR_GALLERY_FILTER
);
352 // pFilter->SetUpdatePercentHdl( LINK( this, GalleryProgress, Update ) ); // sj: progress wasn't working up from SO7 at all
353 // // so I am removing this. The gallery progress should
354 // // be changed to use the XStatusIndicator instead of XProgressMonitor
357 aProgressText
= "Gallery";
359 xMonitor
->addText( "Gallery", aProgressText
, false ) ;
360 mxProgressBar
->setRange( 0, GALLERY_PROGRESS_RANGE
);
364 GalleryProgress::~GalleryProgress()
368 void GalleryProgress::Update( sal_Int32 nVal
, sal_Int32 nMaxVal
)
370 if( mxProgressBar
.is() && nMaxVal
)
371 mxProgressBar
->setValue( std::min
<sal_Int32
>( static_cast<double>(nVal
) / nMaxVal
* GALLERY_PROGRESS_RANGE
,
372 GALLERY_PROGRESS_RANGE
) );
376 GalleryTransferable::GalleryTransferable( GalleryTheme
* pTheme
, sal_uInt32 nObjectPos
, bool bLazy
) :
378 meObjectKind( mpTheme
->GetObjectKind( nObjectPos
) ),
379 mnObjectPos( nObjectPos
)
385 GalleryTransferable::~GalleryTransferable()
389 void GalleryTransferable::InitData( bool bLazy
)
391 switch( meObjectKind
)
393 case SgaObjKind::SvDraw
:
397 if( !mpGraphicObject
)
401 if( mpTheme
->GetGraphic( mnObjectPos
, aGraphic
) )
402 mpGraphicObject
.reset(new GraphicObject( aGraphic
));
405 if( !mxModelStream
.is() )
407 mxModelStream
= new SotStorageStream( "" );
408 mxModelStream
->SetBufferSize( 16348 );
410 if( !mpTheme
->GetModelStream( mnObjectPos
, mxModelStream
) )
411 mxModelStream
.clear();
413 mxModelStream
->Seek( 0 );
419 case SgaObjKind::Animation
:
420 case SgaObjKind::Bitmap
:
421 case SgaObjKind::Inet
:
422 case SgaObjKind::Sound
:
426 mpURL
.reset(new INetURLObject
);
428 if( !mpTheme
->GetURL( mnObjectPos
, *mpURL
) )
434 if( ( SgaObjKind::Sound
!= meObjectKind
) && !mpGraphicObject
)
438 if( mpTheme
->GetGraphic( mnObjectPos
, aGraphic
) )
439 mpGraphicObject
.reset(new GraphicObject( aGraphic
));
445 OSL_FAIL( "GalleryTransferable::GalleryTransferable: invalid object type" );
450 void GalleryTransferable::AddSupportedFormats()
452 if( SgaObjKind::SvDraw
== meObjectKind
)
454 AddFormat( SotClipboardFormatId::DRAWING
);
455 AddFormat( SotClipboardFormatId::SVXB
);
456 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
457 AddFormat( SotClipboardFormatId::BITMAP
);
462 AddFormat( SotClipboardFormatId::SIMPLE_FILE
);
464 if( mpGraphicObject
)
466 AddFormat( SotClipboardFormatId::SVXB
);
468 if( mpGraphicObject
->GetType() == GraphicType::GdiMetafile
)
470 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
471 AddFormat( SotClipboardFormatId::BITMAP
);
475 AddFormat( SotClipboardFormatId::BITMAP
);
476 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
482 bool GalleryTransferable::GetData( const datatransfer::DataFlavor
& rFlavor
, const OUString
& /*rDestDoc*/ )
484 SotClipboardFormatId nFormat
= SotExchange::GetFormat( rFlavor
);
489 if( ( SotClipboardFormatId::DRAWING
== nFormat
) && ( SgaObjKind::SvDraw
== meObjectKind
) )
491 bRet
= ( mxModelStream
.is() && SetObject( mxModelStream
.get(), 0, rFlavor
) );
493 else if( ( SotClipboardFormatId::SIMPLE_FILE
== nFormat
) && mpURL
)
495 bRet
= SetString( mpURL
->GetMainURL( INetURLObject::DecodeMechanism::NONE
), rFlavor
);
497 else if( ( SotClipboardFormatId::SVXB
== nFormat
) && mpGraphicObject
)
499 bRet
= SetGraphic( mpGraphicObject
->GetGraphic() );
501 else if( ( SotClipboardFormatId::GDIMETAFILE
== nFormat
) && mpGraphicObject
)
503 bRet
= SetGDIMetaFile( mpGraphicObject
->GetGraphic().GetGDIMetaFile() );
505 else if( ( SotClipboardFormatId::BITMAP
== nFormat
) && mpGraphicObject
)
507 bRet
= SetBitmapEx( mpGraphicObject
->GetGraphic().GetBitmapEx(), rFlavor
);
513 bool GalleryTransferable::WriteObject( tools::SvRef
<SotStorageStream
>& rxOStm
, void* pUserObject
,
514 sal_uInt32
, const datatransfer::DataFlavor
& )
520 rxOStm
->WriteStream( *static_cast< SotStorageStream
* >( pUserObject
) );
521 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
527 void GalleryTransferable::DragFinished( sal_Int8 nDropAction
)
529 mpTheme
->SetDragging( false );
530 mpTheme
->SetDragPos( 0 );
533 vcl::Window
*pFocusWindow
= Application::GetFocusWindow();
535 pFocusWindow
->GrabFocusToDocument();
539 void GalleryTransferable::ObjectReleased()
541 mxModelStream
.clear();
542 mpGraphicObject
.reset();
546 void GalleryTransferable::StartDrag( vcl::Window
* pWindow
, sal_Int8 nDragSourceActions
)
550 if( mpTheme
->GetURL( mnObjectPos
, aURL
) && ( aURL
.GetProtocol() != INetProtocol::NotValid
) )
552 mpTheme
->SetDragging( true );
553 mpTheme
->SetDragPos( mnObjectPos
);
554 TransferableHelper::StartDrag( pWindow
, nDragSourceActions
);
558 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */