bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / gallery2 / galmisc.cxx
blob368f955923e560053d8cee804720982fb8a714c4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
43 #include "codec.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;
60 if( !pGalleryResMgr )
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 );
76 return aBmpEx;
79 IMPL_STATIC_LINK(
80 SgaUserDataFactory, MakeUserData, SdrObjFactory*, pObjFactory )
82 if ( pObjFactory->nInventor == IV_IMAPINFO && pObjFactory->nIdentifier == ID_IMAPINFO )
83 pObjFactory->pNewData = new SgaIMapInfo;
85 return 0L;
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 );
94 aMedium.Download();
96 SvStream* pIStm = aMedium.GetInStream();
98 if( pIStm )
100 GraphicFilter& rGraphicFilter = GraphicFilter::GetGraphicFilter();
101 boost::scoped_ptr<GalleryProgress> pProgress(bShowProgress ? new GalleryProgress( &rGraphicFilter ) : NULL);
102 sal_uInt16 nFormat;
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;
111 return nRet;
114 bool GallerySvDrawImport( SvStream& rIStm, SdrModel& rModel )
116 sal_uInt32 nVersion;
117 bool bRet = false;
119 if( GalleryCodec::IsCoded( rIStm, nVersion ) )
121 SvMemoryStream aMemStm( 65535, 65535 );
122 GalleryCodec aCodec( rIStm );
124 aCodec.Read( aMemStm );
125 aMemStm.Seek( 0UL );
127 if( 1 == nVersion )
129 OSL_FAIL( "staroffice binary file formats are no longer supported inside the gallery!" );
130 bRet = false;
132 else if( 2 == nVersion )
134 // recall to read as XML
135 bRet = GallerySvDrawImport( aMemStm, rModel );
138 else
140 // read as XML
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) )
149 rIStm.Seek(0);
150 bRet = SvxDrawingLayerImport( &rModel, xInputStream, xComponent, "com.sun.star.comp.Draw.XMLImporter" );
155 return bRet;
158 bool CreateIMapGraphic( const FmFormModel& rModel, Graphic& rGraphic, ImageMap& rImageMap )
160 bool bRet = false;
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();
180 bRet = true;
181 break;
187 return bRet;
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);
209 aReduced += "...";
210 aReduced += OUString(aDelimiter);
211 aReduced += aName;
213 else
215 aReduced += "...";
216 aReduced += OUString(aDelimiter);
217 aReduced += "...";
218 aReduced += aName.copy( aName.getLength() - (nMaxLen - 7) );
221 else
222 aReduced = aPath;
225 return aReduced;
228 OUString GetSvDrawStreamNameFromURL( const INetURLObject& rSvDrawObjURL )
230 OUString aRet;
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, '/' );
238 return aRet;
241 bool FileExists( const INetURLObject& rURL )
243 bool bRet = false;
245 if( rURL.GetProtocol() != INetProtocol::NotValid )
249 ::ucbhelper::Content aCnt( rURL.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
250 OUString aTitle;
252 aCnt.getPropertyValue("Title") >>= aTitle;
253 bRet = ( !aTitle.isEmpty() );
255 catch( const ucb::ContentCreationException& )
258 catch( const uno::RuntimeException& )
261 catch( const uno::Exception& )
266 return bRet;
269 bool CreateDir( const INetURLObject& rURL )
271 bool bRet = FileExists( rURL );
273 if( !bRet )
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 );
284 aProps[0] = "Title";
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& )
301 return bRet;
304 bool CopyFile( const INetURLObject& rSrcURL, const INetURLObject& rDstURL )
306 bool bRet = false;
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 ) ) );
315 bRet = true;
317 catch( const ucb::ContentCreationException& )
320 catch( const uno::RuntimeException& )
323 catch( const uno::Exception& )
327 return bRet;
330 bool KillFile( const INetURLObject& rURL )
332 bool bRet = FileExists( rURL );
334 if( bRet )
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& )
343 bRet = false;
345 catch( const uno::RuntimeException& )
347 bRet = false;
349 catch( const uno::Exception& )
351 bRet = false;
355 return bRet;
359 GalleryProgress::GalleryProgress( GraphicFilter* pFilter ) :
360 mpFilter( pFilter )
363 uno::Reference< lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
365 uno::Reference< awt::XProgressMonitor > xMonitor( xMgr->createInstance(
366 OUString("com.sun.star.awt.XProgressMonitor") ),
367 uno::UNO_QUERY );
369 if ( xMonitor.is() )
371 mxProgressBar = uno::Reference< awt::XProgressBar >( xMonitor, uno::UNO_QUERY );
373 if( mxProgressBar.is() )
375 OUString aProgressText;
377 if( mpFilter )
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
384 else
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 ) :
405 mpTheme( pTheme ),
406 meObjectKind( mpTheme->GetObjectKind( nObjectPos ) ),
407 mnObjectPos( nObjectPos ),
408 mpGraphicObject( NULL ),
409 mpImageMap( NULL ),
410 mpURL( NULL )
413 InitData( bLazy );
416 GalleryTransferable::~GalleryTransferable()
420 void GalleryTransferable::InitData( bool bLazy )
422 switch( meObjectKind )
424 case( SGA_OBJ_SVDRAW ):
426 if( !bLazy )
428 if( !mpGraphicObject )
430 Graphic aGraphic;
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();
443 else
444 mxModelStream->Seek( 0 );
448 break;
450 case( SGA_OBJ_ANIM ):
451 case( SGA_OBJ_BMP ):
452 case( SGA_OBJ_INET ):
453 case( SGA_OBJ_SOUND ):
455 if( !mpURL )
457 mpURL = new INetURLObject;
459 if( !mpTheme->GetURL( mnObjectPos, *mpURL ) )
460 delete mpURL, mpURL = NULL;
463 if( ( SGA_OBJ_SOUND != meObjectKind ) && !mpGraphicObject )
465 Graphic aGraphic;
467 if( mpTheme->GetGraphic( mnObjectPos, aGraphic ) )
468 mpGraphicObject = new GraphicObject( aGraphic );
471 break;
473 default:
474 OSL_FAIL( "GalleryTransferable::GalleryTransferable: invalid object type" );
475 break;
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 );
488 else
490 if( mpURL )
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 );
502 else
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 );
514 bool bRet = false;
516 InitData( false );
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 );
544 return bRet;
547 bool GalleryTransferable::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pUserObject,
548 SotClipboardFormatId, const datatransfer::DataFlavor& )
550 bool bRet = false;
552 if( pUserObject )
554 rxOStm->WriteStream( *static_cast< SotStorageStream* >( pUserObject ) );
555 bRet = ( rxOStm->GetError() == ERRCODE_NONE );
558 return bRet;
561 void GalleryTransferable::DragFinished( sal_Int8 nDropAction )
563 mpTheme->SetDragging( false );
564 mpTheme->SetDragPos( 0 );
565 if ( nDropAction )
567 vcl::Window *pFocusWindow = Application::GetFocusWindow();
568 if ( pFocusWindow )
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 )
589 INetURLObject aURL;
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: */