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 <unotools/ucbstreamhelper.hxx>
25 #include <comphelper/processfactory.hxx>
26 #include <comphelper/string.hxx>
27 #include <ucbhelper/content.hxx>
28 #include <tools/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/svdograf.hxx>
40 #include <svx/fmmodel.hxx>
41 #include <svx/fmview.hxx>
42 #include <svx/unomodel.hxx>
44 #include "gallery.hrc"
45 #include "svx/gallery1.hxx"
46 #include "svx/galtheme.hxx"
47 #include "svx/galmisc.hxx"
48 #include <com/sun/star/sdbc/XResultSet.hpp>
49 #include <com/sun/star/ucb/XContentAccess.hpp>
50 #include <com/sun/star/ucb/TransferInfo.hpp>
51 #include <com/sun/star/ucb/NameClash.hpp>
52 #include <boost/scoped_ptr.hpp>
54 using namespace ::com::sun::star
;
56 ResMgr
* GetGalleryResMgr()
58 static ResMgr
* pGalleryResMgr
= NULL
;
62 pGalleryResMgr
= ResMgr::CreateResMgr(
63 "gal", Application::GetSettings().GetUILanguageTag() );
66 return pGalleryResMgr
;
69 BitmapEx
GalleryResGetBitmapEx( sal_uInt32 nId
)
71 BitmapEx
aBmpEx( GAL_RES( nId
) );
73 if( !aBmpEx
.IsTransparent() )
74 aBmpEx
= BitmapEx( aBmpEx
.GetBitmap(), COL_LIGHTMAGENTA
);
80 SgaUserDataFactory
, MakeUserData
, SdrObjFactory
*, pObjFactory
)
82 if ( pObjFactory
->nInventor
== IV_IMAPINFO
&& pObjFactory
->nIdentifier
== ID_IMAPINFO
)
83 pObjFactory
->pNewData
= new SgaIMapInfo
;
88 GalleryGraphicImportRet
GalleryGraphicImport( const INetURLObject
& rURL
, Graphic
& rGraphic
,
89 OUString
& rFilterName
, bool bShowProgress
)
91 GalleryGraphicImportRet nRet
= GalleryGraphicImportRet::IMPORT_NONE
;
92 SfxMedium
aMedium( rURL
.GetMainURL( INetURLObject::NO_DECODE
), StreamMode::READ
);
96 SvStream
* pIStm
= aMedium
.GetInStream();
100 GraphicFilter
& rGraphicFilter
= GraphicFilter::GetGraphicFilter();
101 boost::scoped_ptr
<GalleryProgress
> pProgress(bShowProgress
? new GalleryProgress( &rGraphicFilter
) : NULL
);
104 if( !rGraphicFilter
.ImportGraphic( rGraphic
, rURL
.GetMainURL( INetURLObject::NO_DECODE
), *pIStm
, GRFILTER_FORMAT_DONTKNOW
, &nFormat
) )
106 rFilterName
= rGraphicFilter
.GetImportFormatName( nFormat
);
107 nRet
= GalleryGraphicImportRet::IMPORT_FILE
;
114 bool GallerySvDrawImport( SvStream
& rIStm
, SdrModel
& rModel
)
119 if( GalleryCodec::IsCoded( rIStm
, nVersion
) )
121 SvMemoryStream
aMemStm( 65535, 65535 );
122 GalleryCodec
aCodec( rIStm
);
124 aCodec
.Read( aMemStm
);
129 OSL_FAIL( "staroffice binary file formats are no longer supported inside the gallery!" );
132 else if( 2 == nVersion
)
134 // recall to read as XML
135 bRet
= GallerySvDrawImport( aMemStm
, rModel
);
141 uno::Reference
< io::XInputStream
> xInputStream( new utl::OInputStreamWrapper( rIStm
) );
143 rModel
.GetItemPool().SetDefaultMetric( SFX_MAPUNIT_100TH_MM
);
144 uno::Reference
< lang::XComponent
> xComponent
;
146 bRet
= SvxDrawingLayerImport( &rModel
, xInputStream
, xComponent
, "com.sun.star.comp.Draw.XMLOasisImporter" );
147 if( !bRet
|| (rModel
.GetPageCount() == 0) )
150 bRet
= SvxDrawingLayerImport( &rModel
, xInputStream
, xComponent
, "com.sun.star.comp.Draw.XMLImporter" );
158 bool CreateIMapGraphic( const FmFormModel
& rModel
, Graphic
& rGraphic
, ImageMap
& rImageMap
)
162 if ( rModel
.GetPageCount() )
164 const SdrPage
* pPage
= rModel
.GetPage( 0 );
165 const SdrObject
* pObj
= pPage
->GetObj( 0 );
167 if ( pPage
->GetObjCount() == 1 && pObj
->ISA( SdrGrafObj
) )
169 const sal_uInt16 nCount
= pObj
->GetUserDataCount();
171 // Exist in the user data an IMap information?
172 for ( sal_uInt16 i
= 0; i
< nCount
; i
++ )
174 const SdrObjUserData
* pUserData
= pObj
->GetUserData( i
);
176 if ( ( pUserData
->GetInventor() == IV_IMAPINFO
) && ( pUserData
->GetId() == ID_IMAPINFO
) )
178 rGraphic
= static_cast<const SdrGrafObj
*>( pObj
)->GetGraphic();
179 rImageMap
= static_cast<const SgaIMapInfo
*>( pUserData
)->GetImageMap();
190 OUString
GetReducedString( const INetURLObject
& rURL
, sal_Int32 nMaxLen
)
192 OUString
aReduced( rURL
.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS
) );
194 aReduced
= aReduced
.getToken( comphelper::string::getTokenCount(aReduced
, '/') - 1, '/' );
196 if( INetProtocol::PrivSoffice
!= rURL
.GetProtocol() )
198 sal_Unicode aDelimiter
;
199 const OUString
aPath( rURL
.getFSysPath( INetURLObject::FSYS_DETECT
, &aDelimiter
) );
200 const OUString
aName( aReduced
);
202 if( aPath
.getLength() > nMaxLen
)
204 sal_Int32 nPathPrefixLen
= nMaxLen
- aName
.getLength() - 4;
206 if (nPathPrefixLen
>= 0)
208 aReduced
= aPath
.copy(0, nPathPrefixLen
);
210 aReduced
+= OUString(aDelimiter
);
216 aReduced
+= OUString(aDelimiter
);
218 aReduced
+= aName
.copy( aName
.getLength() - (nMaxLen
- 7) );
228 OUString
GetSvDrawStreamNameFromURL( const INetURLObject
& rSvDrawObjURL
)
232 if( rSvDrawObjURL
.GetProtocol() == INetProtocol::PrivSoffice
&&
233 comphelper::string::getTokenCount(rSvDrawObjURL
.GetMainURL( INetURLObject::NO_DECODE
), '/') == 3 )
235 aRet
= rSvDrawObjURL
.GetMainURL( INetURLObject::NO_DECODE
).getToken( 2, '/' );
241 bool FileExists( const INetURLObject
& rURL
)
245 if( rURL
.GetProtocol() != INetProtocol::NotValid
)
249 ::ucbhelper::Content
aCnt( rURL
.GetMainURL( INetURLObject::NO_DECODE
), uno::Reference
< ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
252 aCnt
.getPropertyValue("Title") >>= aTitle
;
253 bRet
= ( !aTitle
.isEmpty() );
255 catch( const ucb::ContentCreationException
& )
258 catch( const uno::RuntimeException
& )
261 catch( const uno::Exception
& )
269 bool CreateDir( const INetURLObject
& rURL
)
271 bool bRet
= FileExists( rURL
);
277 uno::Reference
< ucb::XCommandEnvironment
> aCmdEnv
;
278 INetURLObject
aNewFolderURL( rURL
);
279 INetURLObject
aParentURL( aNewFolderURL
); aParentURL
.removeSegment();
280 ::ucbhelper::Content
aParent( aParentURL
.GetMainURL( INetURLObject::NO_DECODE
), aCmdEnv
, comphelper::getProcessComponentContext() );
281 uno::Sequence
< OUString
> aProps( 1 );
282 uno::Sequence
< uno::Any
> aValues( 1 );
285 aValues
[0] = uno::makeAny( OUString( aNewFolderURL
.GetName() ) );
287 ::ucbhelper::Content
aContent( aNewFolderURL
.GetMainURL( INetURLObject::NO_DECODE
), aCmdEnv
, comphelper::getProcessComponentContext() );
288 bRet
= aParent
.insertNewContent( OUString("application/vnd.sun.staroffice.fsys-folder"), aProps
, aValues
, aContent
);
290 catch( const ucb::ContentCreationException
& )
293 catch( const uno::RuntimeException
& )
296 catch( const uno::Exception
& )
304 bool CopyFile( const INetURLObject
& rSrcURL
, const INetURLObject
& rDstURL
)
310 ::ucbhelper::Content
aDestPath( rDstURL
.GetMainURL( INetURLObject::NO_DECODE
), uno::Reference
< ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
312 aDestPath
.executeCommand( OUString("transfer"),
313 uno::makeAny( ucb::TransferInfo( sal_False
, rSrcURL
.GetMainURL( INetURLObject::NO_DECODE
),
314 rDstURL
.GetName(), ucb::NameClash::OVERWRITE
) ) );
317 catch( const ucb::ContentCreationException
& )
320 catch( const uno::RuntimeException
& )
323 catch( const uno::Exception
& )
330 bool KillFile( const INetURLObject
& rURL
)
332 bool bRet
= FileExists( rURL
);
338 ::ucbhelper::Content
aCnt( rURL
.GetMainURL( INetURLObject::NO_DECODE
), uno::Reference
< ucb::XCommandEnvironment
>(), comphelper::getProcessComponentContext() );
339 aCnt
.executeCommand( OUString("delete"), uno::makeAny( true ) );
341 catch( const ucb::ContentCreationException
& )
345 catch( const uno::RuntimeException
& )
349 catch( const uno::Exception
& )
359 GalleryProgress::GalleryProgress( GraphicFilter
* pFilter
) :
363 uno::Reference
< lang::XMultiServiceFactory
> xMgr( ::comphelper::getProcessServiceFactory() );
365 uno::Reference
< awt::XProgressMonitor
> xMonitor( xMgr
->createInstance(
366 OUString("com.sun.star.awt.XProgressMonitor") ),
371 mxProgressBar
= uno::Reference
< awt::XProgressBar
>( xMonitor
, uno::UNO_QUERY
);
373 if( mxProgressBar
.is() )
375 OUString aProgressText
;
379 aProgressText
= GAL_RESSTR(RID_SVXSTR_GALLERY_FILTER
);
380 // mpFilter->SetUpdatePercentHdl( LINK( this, GalleryProgress, Update ) ); // sj: progress wasn't working up from SO7 at all
381 // // so I am removing this. The gallery progress should
382 // // be changed to use the XStatusIndicator instead of XProgressMonitor
385 aProgressText
= "Gallery";
387 xMonitor
->addText( "Gallery", aProgressText
, sal_False
) ;
388 mxProgressBar
->setRange( 0, GALLERY_PROGRESS_RANGE
);
393 GalleryProgress::~GalleryProgress()
397 void GalleryProgress::Update( sal_uIntPtr nVal
, sal_uIntPtr nMaxVal
)
399 if( mxProgressBar
.is() && nMaxVal
)
400 mxProgressBar
->setValue( std::min( (sal_uIntPtr
)( (double) nVal
/ nMaxVal
* GALLERY_PROGRESS_RANGE
), (sal_uIntPtr
) GALLERY_PROGRESS_RANGE
) );
404 GalleryTransferable::GalleryTransferable( GalleryTheme
* pTheme
, sal_uIntPtr nObjectPos
, bool bLazy
) :
406 meObjectKind( mpTheme
->GetObjectKind( nObjectPos
) ),
407 mnObjectPos( nObjectPos
),
408 mpGraphicObject( NULL
),
416 GalleryTransferable::~GalleryTransferable()
420 void GalleryTransferable::InitData( bool bLazy
)
422 switch( meObjectKind
)
424 case( SGA_OBJ_SVDRAW
):
428 if( !mpGraphicObject
)
432 if( mpTheme
->GetGraphic( mnObjectPos
, aGraphic
) )
433 mpGraphicObject
= new GraphicObject( aGraphic
);
436 if( !mxModelStream
.Is() )
438 mxModelStream
= new SotStorageStream( "" );
439 mxModelStream
->SetBufferSize( 16348 );
441 if( !mpTheme
->GetModelStream( mnObjectPos
, mxModelStream
) )
442 mxModelStream
.Clear();
444 mxModelStream
->Seek( 0 );
450 case( SGA_OBJ_ANIM
):
452 case( SGA_OBJ_INET
):
453 case( SGA_OBJ_SOUND
):
457 mpURL
= new INetURLObject
;
459 if( !mpTheme
->GetURL( mnObjectPos
, *mpURL
) )
460 delete mpURL
, mpURL
= NULL
;
463 if( ( SGA_OBJ_SOUND
!= meObjectKind
) && !mpGraphicObject
)
467 if( mpTheme
->GetGraphic( mnObjectPos
, aGraphic
) )
468 mpGraphicObject
= new GraphicObject( aGraphic
);
474 OSL_FAIL( "GalleryTransferable::GalleryTransferable: invalid object type" );
479 void GalleryTransferable::AddSupportedFormats()
481 if( SGA_OBJ_SVDRAW
== meObjectKind
)
483 AddFormat( SotClipboardFormatId::DRAWING
);
484 AddFormat( SotClipboardFormatId::SVXB
);
485 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
486 AddFormat( SotClipboardFormatId::BITMAP
);
491 AddFormat( SotClipboardFormatId::SIMPLE_FILE
);
493 if( mpGraphicObject
)
495 AddFormat( SotClipboardFormatId::SVXB
);
497 if( mpGraphicObject
->GetType() == GRAPHIC_GDIMETAFILE
)
499 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
500 AddFormat( SotClipboardFormatId::BITMAP
);
504 AddFormat( SotClipboardFormatId::BITMAP
);
505 AddFormat( SotClipboardFormatId::GDIMETAFILE
);
511 bool GalleryTransferable::GetData( const datatransfer::DataFlavor
& rFlavor
, const OUString
& /*rDestDoc*/ )
513 SotClipboardFormatId nFormat
= SotExchange::GetFormat( rFlavor
);
518 if( ( SotClipboardFormatId::DRAWING
== nFormat
) && ( SGA_OBJ_SVDRAW
== meObjectKind
) )
520 bRet
= ( mxModelStream
.Is() && SetObject( &mxModelStream
, SotClipboardFormatId::NONE
, rFlavor
) );
522 else if( ( SotClipboardFormatId::SVIM
== nFormat
) && mpImageMap
)
524 // TODO/MBA: do we need a BaseURL here?!
525 bRet
= SetImageMap( *mpImageMap
, rFlavor
);
527 else if( ( SotClipboardFormatId::SIMPLE_FILE
== nFormat
) && mpURL
)
529 bRet
= SetString( mpURL
->GetMainURL( INetURLObject::NO_DECODE
), rFlavor
);
531 else if( ( SotClipboardFormatId::SVXB
== nFormat
) && mpGraphicObject
)
533 bRet
= SetGraphic( mpGraphicObject
->GetGraphic(), rFlavor
);
535 else if( ( SotClipboardFormatId::GDIMETAFILE
== nFormat
) && mpGraphicObject
)
537 bRet
= SetGDIMetaFile( mpGraphicObject
->GetGraphic().GetGDIMetaFile(), rFlavor
);
539 else if( ( SotClipboardFormatId::BITMAP
== nFormat
) && mpGraphicObject
)
541 bRet
= SetBitmapEx( mpGraphicObject
->GetGraphic().GetBitmapEx(), rFlavor
);
547 bool GalleryTransferable::WriteObject( tools::SvRef
<SotStorageStream
>& rxOStm
, void* pUserObject
,
548 SotClipboardFormatId
, const datatransfer::DataFlavor
& )
554 rxOStm
->WriteStream( *static_cast< SotStorageStream
* >( pUserObject
) );
555 bRet
= ( rxOStm
->GetError() == ERRCODE_NONE
);
561 void GalleryTransferable::DragFinished( sal_Int8 nDropAction
)
563 mpTheme
->SetDragging( false );
564 mpTheme
->SetDragPos( 0 );
567 vcl::Window
*pFocusWindow
= Application::GetFocusWindow();
569 pFocusWindow
->GrabFocusToDocument();
573 void GalleryTransferable::ObjectReleased()
575 mxModelStream
.Clear();
576 delete mpGraphicObject
, mpGraphicObject
= NULL
;
577 delete mpImageMap
, mpImageMap
= NULL
;
578 delete mpURL
, mpURL
= NULL
;
581 void GalleryTransferable::CopyToClipboard( vcl::Window
* pWindow
)
583 TransferableHelper::CopyToClipboard( pWindow
);
586 void GalleryTransferable::StartDrag( vcl::Window
* pWindow
, sal_Int8 nDragSourceActions
,
587 sal_Int32 nDragPointer
, sal_Int32 nDragImage
)
591 if( mpTheme
->GetURL( mnObjectPos
, aURL
) && ( aURL
.GetProtocol() != INetProtocol::NotValid
) )
593 mpTheme
->SetDragging( true );
594 mpTheme
->SetDragPos( mnObjectPos
);
595 TransferableHelper::StartDrag( pWindow
, nDragSourceActions
, nDragPointer
, nDragImage
);
599 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */