fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svtools / source / misc / transfer.cxx
blob88086ef26fadccc60aa5d0981e6eff5be588b541
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 #ifdef WNT
21 #include <prewin.h>
22 #include <postwin.h>
23 #include <shlobj.h>
24 #endif
25 #include <osl/mutex.hxx>
26 #include <rtl/uri.hxx>
27 #include <tools/debug.hxx>
28 #include <tools/urlobj.hxx>
29 #include <unotools/ucbstreamhelper.hxx>
30 #include <sot/exchange.hxx>
31 #include <sot/storage.hxx>
32 #include <vcl/bitmap.hxx>
33 #include <vcl/gdimtf.hxx>
34 #include <vcl/graph.hxx>
35 #include <vcl/cvtgrf.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/window.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/servicehelper.hxx>
40 #include <sot/filelist.hxx>
41 #include <cppuhelper/implbase1.hxx>
43 #include <comphelper/seqstream.hxx>
44 #include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp>
45 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
46 #include <com/sun/star/datatransfer/MimeContentTypeFactory.hpp>
47 #include <com/sun/star/datatransfer/XMimeContentType.hpp>
48 #include <com/sun/star/frame/Desktop.hpp>
49 #include <com/sun/star/lang/XInitialization.hpp>
51 #include "svl/urlbmk.hxx"
52 #include "inetimg.hxx"
53 #include <vcl/wmf.hxx>
54 #include <svtools/imap.hxx>
55 #include <svtools/transfer.hxx>
56 #include <rtl/strbuf.hxx>
57 #include <cstdio>
59 // --------------
60 // - Namespaces -
61 // --------------
63 using namespace ::com::sun::star::uno;
64 using namespace ::com::sun::star::lang;
65 using namespace ::com::sun::star::frame;
66 using namespace ::com::sun::star::io;
67 using namespace ::com::sun::star::datatransfer;
68 using namespace ::com::sun::star::datatransfer::clipboard;
69 using namespace ::com::sun::star::datatransfer::dnd;
71 // --------------------------------
72 // - TransferableObjectDescriptor -
73 // --------------------------------
75 #define TOD_SIG1 0x01234567
76 #define TOD_SIG2 0x89abcdef
78 SvStream& operator>>( SvStream& rIStm, TransferableObjectDescriptor& rObjDesc )
80 sal_uInt32 nSize, nViewAspect, nSig1, nSig2;
81 //#fdo39428 Remove SvStream operator>>(long&)
82 sal_Int32 nTmp(0);
84 rIStm >> nSize;
85 rIStm >> rObjDesc.maClassName;
86 rIStm >> nViewAspect;
87 rIStm >> nTmp;
88 rObjDesc.maSize.Width() = nTmp;
89 rIStm >> nTmp;
90 rObjDesc.maSize.Height() = nTmp;
91 rIStm >> nTmp;
92 rObjDesc.maDragStartPos.X() = nTmp;
93 rIStm >> nTmp;
94 rObjDesc.maDragStartPos.Y() = nTmp;
95 rObjDesc.maTypeName = rIStm.ReadUniOrByteString(osl_getThreadTextEncoding());
96 rObjDesc.maDisplayName = rIStm.ReadUniOrByteString(osl_getThreadTextEncoding());
98 rIStm >> nSig1 >> nSig2;
100 rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( nViewAspect );
102 // don't use width/height info from external objects
103 if( ( TOD_SIG1 != nSig1 ) || ( TOD_SIG2 != nSig2 ) )
105 rObjDesc.maSize.Width() = 0;
106 rObjDesc.maSize.Height() = 0;
109 return rIStm;
112 // -----------------------------------------------------------------------------
114 SvStream& operator<<( SvStream& rOStm, const TransferableObjectDescriptor& rObjDesc )
116 const sal_uInt32 nFirstPos = rOStm.Tell(), nViewAspect = rObjDesc.mnViewAspect;
117 const sal_uInt32 nSig1 = TOD_SIG1, nSig2 = TOD_SIG2;
119 rOStm.SeekRel( 4 );
120 rOStm << rObjDesc.maClassName;
121 rOStm << nViewAspect;
122 //#fdo39428 Remove SvStream operator<<(long)
123 rOStm << sal::static_int_cast<sal_Int32>(rObjDesc.maSize.Width());
124 rOStm << sal::static_int_cast<sal_Int32>(rObjDesc.maSize.Height());
125 rOStm << sal::static_int_cast<sal_Int32>(rObjDesc.maDragStartPos.X());
126 rOStm << sal::static_int_cast<sal_Int32>(rObjDesc.maDragStartPos.Y());
127 rOStm.WriteUniOrByteString( rObjDesc.maTypeName, osl_getThreadTextEncoding() );
128 rOStm.WriteUniOrByteString( rObjDesc.maDisplayName, osl_getThreadTextEncoding() );
129 rOStm << nSig1 << nSig2;
131 const sal_uInt32 nLastPos = rOStm.Tell();
133 rOStm.Seek( nFirstPos );
134 rOStm << ( nLastPos - nFirstPos );
135 rOStm.Seek( nLastPos );
137 return rOStm;
140 // -----------------------------------------------------------------------------
141 // the reading of the parameter is done using the special service ::com::sun::star::datatransfer::MimeContentType,
142 // a similar approach should be implemented for creation of the mimetype string;
143 // for now the set of acceptable characters has to be hardcoded, in future it should be part of the service that creates the mimetype
145 static OUString ImplGetParameterString( const TransferableObjectDescriptor& rObjDesc )
147 const OUString aChar( "\"" );
148 const OUString aClassName( rObjDesc.maClassName.GetHexName() );
149 OUString aParams;
151 if( !aClassName.isEmpty() )
153 aParams += OUString( ";classname=\"" );
154 aParams += aClassName;
155 aParams += aChar;
158 if( !rObjDesc.maTypeName.isEmpty() )
160 aParams += OUString( ";typename=\"" );
161 aParams += rObjDesc.maTypeName;
162 aParams += aChar;
165 if( !rObjDesc.maDisplayName.isEmpty() )
167 // the display name might contain unacceptable characters, encode all of them
168 // this seems to be the only parameter currently that might contain such characters
169 sal_Bool pToAccept[128];
170 for ( sal_Int32 nBInd = 0; nBInd < 128; nBInd++ )
171 pToAccept[nBInd] = sal_False;
173 const char aQuotedParamChars[] =
174 "()<>@,;:/[]?=!#$&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. ";
176 for ( sal_Int32 nInd = 0; nInd < RTL_CONSTASCII_LENGTH(aQuotedParamChars); ++nInd )
178 sal_Unicode nChar = aQuotedParamChars[nInd];
179 if ( nChar < 128 )
180 pToAccept[nChar] = sal_True;
183 aParams += OUString( ";displayname=\"" );
184 aParams += ::rtl::Uri::encode( rObjDesc.maDisplayName, pToAccept, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 );
185 aParams += aChar;
188 aParams += OUString( ";viewaspect=\"" );
189 aParams += OUString::number( rObjDesc.mnViewAspect );
190 aParams += aChar;
192 aParams += OUString( ";width=\"" );
193 aParams += OUString::valueOf( rObjDesc.maSize.Width() );
194 aParams += aChar;
196 aParams += OUString( ";height=\"" );
197 aParams += OUString::valueOf( rObjDesc.maSize.Height() );
198 aParams += aChar;
200 aParams += OUString( ";posx=\"" );
201 aParams += OUString::valueOf( rObjDesc.maDragStartPos.X() );
202 aParams += aChar;
204 aParams += OUString( ";posy=\"" );
205 aParams += OUString::valueOf( rObjDesc.maDragStartPos.X() );
206 aParams += aChar;
208 return aParams;
211 // -----------------------------------------------------------------------------
213 static void ImplSetParameterString( TransferableObjectDescriptor& rObjDesc, const DataFlavorEx& rFlavorEx )
215 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
219 Reference< XMimeContentTypeFactory > xMimeFact = MimeContentTypeFactory::create( xContext );
221 Reference< XMimeContentType > xMimeType( xMimeFact->createMimeContentType( rFlavorEx.MimeType ) );
223 if( xMimeType.is() )
225 const OUString aClassNameString( "classname" );
226 const OUString aTypeNameString( "typename" );
227 const OUString aDisplayNameString( "displayname" );
228 const OUString aViewAspectString( "viewaspect" );
229 const OUString aWidthString( "width" );
230 const OUString aHeightString( "height" );
231 const OUString aPosXString( "posx" );
232 const OUString aPosYString( "posy" );
234 if( xMimeType->hasParameter( aClassNameString ) )
236 rObjDesc.maClassName.MakeId( xMimeType->getParameterValue( aClassNameString ) );
239 if( xMimeType->hasParameter( aTypeNameString ) )
241 rObjDesc.maTypeName = xMimeType->getParameterValue( aTypeNameString );
244 if( xMimeType->hasParameter( aDisplayNameString ) )
246 // the display name might contain unacceptable characters, in this case they should be encoded
247 // this seems to be the only parameter currently that might contain such characters
248 rObjDesc.maDisplayName = ::rtl::Uri::decode( xMimeType->getParameterValue( aDisplayNameString ), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
251 if( xMimeType->hasParameter( aViewAspectString ) )
253 rObjDesc.mnViewAspect = static_cast< sal_uInt16 >( xMimeType->getParameterValue( aViewAspectString ).toInt32() );
256 if( xMimeType->hasParameter( aWidthString ) )
258 rObjDesc.maSize.Width() = xMimeType->getParameterValue( aWidthString ).toInt32();
261 if( xMimeType->hasParameter( aHeightString ) )
263 rObjDesc.maSize.Height() = xMimeType->getParameterValue( aHeightString ).toInt32();
266 if( xMimeType->hasParameter( aPosXString ) )
268 rObjDesc.maDragStartPos.X() = xMimeType->getParameterValue( aPosXString ).toInt32();
271 if( xMimeType->hasParameter( aPosYString ) )
273 rObjDesc.maDragStartPos.Y() = xMimeType->getParameterValue( aPosYString ).toInt32();
277 catch( const ::com::sun::star::uno::Exception& )
282 // -----------------------------------------
283 // - TransferableHelper::TerminateListener -
284 // -----------------------------------------
286 TransferableHelper::TerminateListener::TerminateListener( TransferableHelper& rTransferableHelper ) :
287 mrParent( rTransferableHelper )
291 // -----------------------------------------------------------------------------
293 TransferableHelper::TerminateListener::~TerminateListener()
297 // -----------------------------------------------------------------------------
299 void SAL_CALL TransferableHelper::TerminateListener::disposing( const EventObject& ) throw( RuntimeException )
303 // -----------------------------------------------------------------------------
305 void SAL_CALL TransferableHelper::TerminateListener::queryTermination( const EventObject& ) throw( TerminationVetoException, RuntimeException )
309 // -----------------------------------------------------------------------------
311 void SAL_CALL TransferableHelper::TerminateListener::notifyTermination( const EventObject& ) throw( RuntimeException )
313 mrParent.ImplFlush();
316 // ----------------------
317 // - TransferableHelper -
318 // ----------------------
320 TransferableHelper::TransferableHelper() :
321 mpFormats( new DataFlavorExVector ),
322 mpObjDesc( NULL )
326 // -----------------------------------------------------------------------------
328 TransferableHelper::~TransferableHelper()
330 delete mpObjDesc;
331 delete mpFormats;
334 // -----------------------------------------------------------------------------
336 Any SAL_CALL TransferableHelper::getTransferData( const DataFlavor& rFlavor ) throw( UnsupportedFlavorException, IOException, RuntimeException )
338 if( !maAny.hasValue() || !mpFormats->size() || ( maLastFormat != rFlavor.MimeType ) )
340 const SolarMutexGuard aGuard;
342 maLastFormat = rFlavor.MimeType;
343 maAny = Any();
347 DataFlavor aSubstFlavor;
348 sal_Bool bDone = sal_False;
350 // add formats if not already done
351 if( !mpFormats->size() )
352 AddSupportedFormats();
354 // check alien formats first and try to get a substitution format
355 if( SotExchange::GetFormatDataFlavor( FORMAT_STRING, aSubstFlavor ) &&
356 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) )
358 GetData( aSubstFlavor );
359 bDone = maAny.hasValue();
361 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
362 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
363 SotExchange::GetFormatDataFlavor( FORMAT_BITMAP, aSubstFlavor ) )
365 GetData( aSubstFlavor );
366 bDone = sal_True;
368 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
369 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
370 SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
372 GetData( aSubstFlavor );
374 if( maAny.hasValue() )
376 Sequence< sal_Int8 > aSeq;
378 if( maAny >>= aSeq )
380 SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
381 GDIMetaFile aMtf;
383 *pSrcStm >> aMtf;
384 delete pSrcStm;
386 Graphic aGraphic( aMtf );
387 SvMemoryStream aDstStm( 65535, 65535 );
389 if( GraphicConverter::Export( aDstStm, aGraphic, CVT_EMF ) == ERRCODE_NONE )
391 maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
392 aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
393 bDone = sal_True;
398 else if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
399 TransferableDataHelper::IsEqual( aSubstFlavor, rFlavor ) &&
400 SotExchange::GetFormatDataFlavor( FORMAT_GDIMETAFILE, aSubstFlavor ) )
402 GetData( aSubstFlavor );
404 if( maAny.hasValue() )
406 Sequence< sal_Int8 > aSeq;
408 if( maAny >>= aSeq )
410 SvMemoryStream* pSrcStm = new SvMemoryStream( (char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_WRITE | STREAM_TRUNC );
411 GDIMetaFile aMtf;
413 *pSrcStm >> aMtf;
414 delete pSrcStm;
416 SvMemoryStream aDstStm( 65535, 65535 );
418 // taking wmf without file header
419 if ( ConvertGDIMetaFileToWMF( aMtf, aDstStm, NULL, sal_False ) )
421 maAny <<= ( aSeq = Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aDstStm.GetData() ),
422 aDstStm.Seek( STREAM_SEEK_TO_END ) ) );
423 bDone = sal_True;
429 // reset Any if substitute doesn't work
430 if( !bDone && maAny.hasValue() )
431 maAny = Any();
433 // if any is not yet filled, use standard format
434 if( !maAny.hasValue() )
435 GetData( rFlavor );
437 #ifdef DEBUG
438 if( maAny.hasValue() && ::com::sun::star::uno::TypeClass_STRING != maAny.getValueType().getTypeClass() )
439 fprintf( stderr, "TransferableHelper delivers sequence of data [ %s ]\n", OUStringToOString(rFlavor.MimeType, RTL_TEXTENCODING_ASCII_US).getStr() );
440 #endif
442 catch( const ::com::sun::star::uno::Exception& )
446 if( !maAny.hasValue() )
447 throw UnsupportedFlavorException();
450 return maAny;
453 // -----------------------------------------------------------------------------
455 Sequence< DataFlavor > SAL_CALL TransferableHelper::getTransferDataFlavors() throw( RuntimeException )
457 const SolarMutexGuard aGuard;
461 if( !mpFormats->size() )
462 AddSupportedFormats();
464 catch( const ::com::sun::star::uno::Exception& )
468 Sequence< DataFlavor > aRet( mpFormats->size() );
469 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
470 sal_uInt32 nCurPos = 0;
472 while( aIter != aEnd )
474 aRet[ nCurPos++ ] = *aIter++;
477 return aRet;
480 // -----------------------------------------------------------------------------
482 sal_Bool SAL_CALL TransferableHelper::isDataFlavorSupported( const DataFlavor& rFlavor ) throw( RuntimeException )
484 const SolarMutexGuard aGuard;
485 sal_Bool bRet = sal_False;
489 if( !mpFormats->size() )
490 AddSupportedFormats();
492 catch( const ::com::sun::star::uno::Exception& )
496 for (DataFlavorExVector::const_iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() ); aIter != aEnd ; ++aIter)
498 if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
500 bRet = sal_True;
501 break;
505 return bRet;
508 // -----------------------------------------------------------------------------
510 void SAL_CALL TransferableHelper::lostOwnership( const Reference< XClipboard >&, const Reference< XTransferable >& ) throw( RuntimeException )
512 const SolarMutexGuard aGuard;
516 if( mxTerminateListener.is() )
518 Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
519 xDesktop->removeTerminateListener( mxTerminateListener );
521 mxTerminateListener = Reference< XTerminateListener >();
524 ObjectReleased();
526 catch( const ::com::sun::star::uno::Exception& )
531 // -----------------------------------------------------------------------------
533 void SAL_CALL TransferableHelper::disposing( const EventObject& ) throw( RuntimeException )
537 // -----------------------------------------------------------------------------
539 void SAL_CALL TransferableHelper::dragDropEnd( const DragSourceDropEvent& rDSDE ) throw( RuntimeException )
541 const SolarMutexGuard aGuard;
545 DragFinished( rDSDE.DropSuccess ? ( rDSDE.DropAction & ~DNDConstants::ACTION_DEFAULT ) : DNDConstants::ACTION_NONE );
546 ObjectReleased();
548 catch( const ::com::sun::star::uno::Exception& )
553 // -----------------------------------------------------------------------------
555 void SAL_CALL TransferableHelper::dragEnter( const DragSourceDragEvent& ) throw( RuntimeException )
559 // -----------------------------------------------------------------------------
561 void SAL_CALL TransferableHelper::dragExit( const DragSourceEvent& ) throw( RuntimeException )
565 // -----------------------------------------------------------------------------
567 void SAL_CALL TransferableHelper::dragOver( const DragSourceDragEvent& ) throw( RuntimeException )
571 // -----------------------------------------------------------------------------
573 void SAL_CALL TransferableHelper::dropActionChanged( const DragSourceDragEvent& ) throw( RuntimeException )
577 // -----------------------------------------------------------------------------
579 sal_Int64 SAL_CALL TransferableHelper::getSomething( const Sequence< sal_Int8 >& rId ) throw( RuntimeException )
581 sal_Int64 nRet;
583 if( ( rId.getLength() == 16 ) &&
584 ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
586 nRet = sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
588 else
589 nRet = 0;
591 return nRet;
594 // -----------------------------------------------------------------------------
596 void TransferableHelper::ImplFlush()
598 if( mxClipboard.is() )
600 Reference< XFlushableClipboard > xFlushableClipboard( mxClipboard, UNO_QUERY );
601 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
605 if( xFlushableClipboard.is() )
606 xFlushableClipboard->flushClipboard();
608 catch( const ::com::sun::star::uno::Exception& )
610 OSL_FAIL( "Could not flush clipboard" );
613 Application::AcquireSolarMutex( nRef );
617 // -----------------------------------------------------------------------------
619 void TransferableHelper::AddFormat( SotFormatStringId nFormat )
621 DataFlavor aFlavor;
623 if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
624 AddFormat( aFlavor );
627 // -----------------------------------------------------------------------------
629 void TransferableHelper::AddFormat( const DataFlavor& rFlavor )
631 sal_Bool bAdd = sal_True;
633 for (DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() ); aIter != aEnd ; ++aIter)
635 if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
637 // update MimeType for SOT_FORMATSTR_ID_OBJECTDESCRIPTOR in every case
638 if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId ) && mpObjDesc )
640 DataFlavor aObjDescFlavor;
642 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR, aObjDescFlavor );
643 aIter->MimeType = aObjDescFlavor.MimeType;
644 aIter->MimeType += ::ImplGetParameterString( *mpObjDesc );
646 #ifdef DEBUG
647 fprintf( stderr, "TransferableHelper exchanged objectdescriptor [ %s ]\n",
648 OUStringToOString(aIter->MimeType, RTL_TEXTENCODING_ASCII_US).getStr() );
649 #endif
652 bAdd = sal_False;
653 break;
657 if( bAdd )
659 DataFlavorEx aFlavorEx;
660 DataFlavor aObjDescFlavor;
662 aFlavorEx.MimeType = rFlavor.MimeType;
663 aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
664 aFlavorEx.DataType = rFlavor.DataType;
665 aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
667 if( ( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aFlavorEx.mnSotId ) && mpObjDesc )
668 aFlavorEx.MimeType += ::ImplGetParameterString( *mpObjDesc );
670 mpFormats->push_back( aFlavorEx );
672 if( FORMAT_BITMAP == aFlavorEx.mnSotId )
674 AddFormat( SOT_FORMATSTR_ID_BMP );
676 else if( FORMAT_GDIMETAFILE == aFlavorEx.mnSotId )
678 AddFormat( SOT_FORMATSTR_ID_EMF );
679 AddFormat( SOT_FORMATSTR_ID_WMF );
684 // -----------------------------------------------------------------------------
686 void TransferableHelper::RemoveFormat( SotFormatStringId nFormat )
688 DataFlavor aFlavor;
690 if( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
691 RemoveFormat( aFlavor );
694 // -----------------------------------------------------------------------------
696 void TransferableHelper::RemoveFormat( const DataFlavor& rFlavor )
698 DataFlavorExVector::iterator aIter( mpFormats->begin() );
700 while (aIter != mpFormats->end())
702 if( TransferableDataHelper::IsEqual( *aIter, rFlavor ) )
703 aIter = mpFormats->erase( aIter );
704 else
705 ++aIter;
709 // -----------------------------------------------------------------------------
711 sal_Bool TransferableHelper::HasFormat( SotFormatStringId nFormat )
713 sal_Bool bRet = sal_False;
715 for (DataFlavorExVector::const_iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() ); aIter != aEnd ; ++aIter)
717 if( nFormat == (*aIter).mnSotId )
719 bRet = sal_True;
720 break;
724 return bRet;
727 // -----------------------------------------------------------------------------
729 void TransferableHelper::ClearFormats()
731 mpFormats->clear();
732 maAny.clear();
735 // -----------------------------------------------------------------------------
737 sal_Bool TransferableHelper::SetAny( const Any& rAny, const DataFlavor& )
739 maAny = rAny;
740 return( maAny.hasValue() );
743 // -----------------------------------------------------------------------------
745 sal_Bool TransferableHelper::SetString( const OUString& rString, const DataFlavor& rFlavor )
747 DataFlavor aFileFlavor;
749 if( !rString.isEmpty() &&
750 SotExchange::GetFormatDataFlavor( FORMAT_FILE, aFileFlavor ) &&
751 TransferableDataHelper::IsEqual( aFileFlavor, rFlavor ) )
753 const OString aByteStr(OUStringToOString(rString, osl_getThreadTextEncoding()));
754 Sequence< sal_Int8 > aSeq( aByteStr.getLength() + 1 );
756 memcpy( aSeq.getArray(), aByteStr.getStr(), aByteStr.getLength() );
757 aSeq[ aByteStr.getLength() ] = 0;
758 maAny <<= aSeq;
760 else
761 maAny <<= rString;
763 return( maAny.hasValue() );
766 // -----------------------------------------------------------------------------
768 sal_Bool TransferableHelper::SetBitmap( const Bitmap& rBitmap, const DataFlavor& )
770 if( !rBitmap.IsEmpty() )
772 SvMemoryStream aMemStm( 65535, 65535 );
774 aMemStm << rBitmap;
775 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
778 return( maAny.hasValue() );
781 // -----------------------------------------------------------------------------
783 sal_Bool TransferableHelper::SetGDIMetaFile( const GDIMetaFile& rMtf, const DataFlavor& )
785 if( rMtf.GetActionSize() )
787 SvMemoryStream aMemStm( 65535, 65535 );
789 ( (GDIMetaFile&) rMtf ).Write( aMemStm );
790 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
793 return( maAny.hasValue() );
796 // -----------------------------------------------------------------------------
798 sal_Bool TransferableHelper::SetGraphic( const Graphic& rGraphic, const DataFlavor& )
800 if( rGraphic.GetType() != GRAPHIC_NONE )
802 SvMemoryStream aMemStm( 65535, 65535 );
804 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
805 aMemStm.SetCompressMode( COMPRESSMODE_NATIVE );
806 aMemStm << rGraphic;
807 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
810 return( maAny.hasValue() );
813 // -----------------------------------------------------------------------------
815 sal_Bool TransferableHelper::SetImageMap( const ImageMap& rIMap, const ::com::sun::star::datatransfer::DataFlavor& )
817 SvMemoryStream aMemStm( 8192, 8192 );
819 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
820 rIMap.Write( aMemStm, String() );
821 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
823 return( maAny.hasValue() );
826 // -----------------------------------------------------------------------------
828 sal_Bool TransferableHelper::SetTransferableObjectDescriptor( const TransferableObjectDescriptor& rDesc,
829 const ::com::sun::star::datatransfer::DataFlavor& )
831 PrepareOLE( rDesc );
833 SvMemoryStream aMemStm( 1024, 1024 );
835 aMemStm << rDesc;
836 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Tell() );
838 return( maAny.hasValue() );
841 // -----------------------------------------------------------------------------
843 sal_Bool TransferableHelper::SetINetBookmark( const INetBookmark& rBmk,
844 const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
846 rtl_TextEncoding eSysCSet = osl_getThreadTextEncoding();
848 switch( SotExchange::GetFormat( rFlavor ) )
850 case( SOT_FORMATSTR_ID_SOLK ):
852 OString sURL(OUStringToOString(rBmk.GetURL(), eSysCSet));
853 OString sDesc(OUStringToOString(rBmk.GetDescription(), eSysCSet));
854 OStringBuffer sOut;
855 sOut.append(sURL.getLength());
856 sOut.append('@').append(sURL);
857 sOut.append(sDesc.getLength());
858 sOut.append('@').append(sDesc);
860 Sequence< sal_Int8 > aSeq(sOut.getLength());
861 memcpy(aSeq.getArray(), sOut.getStr(), sOut.getLength());
862 maAny <<= aSeq;
864 break;
866 case( FORMAT_STRING ):
867 maAny <<= OUString( rBmk.GetURL() );
868 break;
870 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
872 OString sURL(OUStringToOString(rBmk.GetURL(), eSysCSet));
873 Sequence< sal_Int8 > aSeq( sURL.getLength() );
874 memcpy( aSeq.getArray(), sURL.getStr(), sURL.getLength() );
875 maAny <<= aSeq;
877 break;
879 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
881 Sequence< sal_Int8 > aSeq( 2048 );
883 memset( aSeq.getArray(), 0, 2048 );
884 strcpy( reinterpret_cast< char* >( aSeq.getArray() ), OUStringToOString(rBmk.GetURL(), eSysCSet).getStr() );
885 strcpy( reinterpret_cast< char* >( aSeq.getArray() ) + 1024, OUStringToOString(rBmk.GetDescription(), eSysCSet).getStr() );
887 maAny <<= aSeq;
889 break;
891 #ifdef WNT
892 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
894 Sequence< sal_Int8 > aSeq( sizeof( FILEGROUPDESCRIPTOR ) );
895 FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getArray();
896 FILEDESCRIPTOR& rFDesc1 = pFDesc->fgd[ 0 ];
898 pFDesc->cItems = 1;
899 memset( &rFDesc1, 0, sizeof( FILEDESCRIPTOR ) );
900 rFDesc1.dwFlags = FD_LINKUI;
902 OStringBuffer aStr(OUStringToOString(
903 rBmk.GetDescription(), eSysCSet));
904 for( sal_uInt16 nChar = 0; nChar < aStr.getLength(); ++nChar )
905 if( strchr( "\\/:*?\"<>|", aStr[nChar] ) )
906 aStr.remove(nChar--, 1);
908 aStr.insert(0, RTL_CONSTASCII_STRINGPARAM("Shortcut to "));
909 aStr.append(RTL_CONSTASCII_STRINGPARAM(".URL"));
910 strcpy( rFDesc1.cFileName, aStr.getStr() );
912 maAny <<= aSeq;
914 break;
916 case SOT_FORMATSTR_ID_FILECONTENT:
918 String aStr( RTL_CONSTASCII_USTRINGPARAM( "[InternetShortcut]\x0aURL=" ) );
919 maAny <<= OUString( aStr += rBmk.GetURL() );
921 break;
922 #endif
924 default:
925 break;
928 return( maAny.hasValue() );
931 // -----------------------------------------------------------------------------
933 sal_Bool TransferableHelper::SetINetImage( const INetImage& rINtImg,
934 const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
936 SvMemoryStream aMemStm( 1024, 1024 );
938 aMemStm.SetVersion( SOFFICE_FILEFORMAT_50 );
939 rINtImg.Write( aMemStm, SotExchange::GetFormat( rFlavor ) );
941 maAny <<= Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aMemStm.GetData() ), aMemStm.Seek( STREAM_SEEK_TO_END ) );
943 return( maAny.hasValue() );
946 // -----------------------------------------------------------------------------
948 sal_Bool TransferableHelper::SetObject( void* pUserObject, sal_uInt32 nUserObjectId, const DataFlavor& rFlavor )
950 SotStorageStreamRef xStm( new SotStorageStream( String() ) );
952 xStm->SetVersion( SOFFICE_FILEFORMAT_50 );
954 if( pUserObject && WriteObject( xStm, pUserObject, nUserObjectId, rFlavor ) )
956 const sal_uInt32 nLen = xStm->Seek( STREAM_SEEK_TO_END );
957 Sequence< sal_Int8 > aSeq( nLen );
959 xStm->Seek( STREAM_SEEK_TO_BEGIN );
960 xStm->Read( aSeq.getArray(), nLen );
962 if( nLen && ( SotExchange::GetFormat( rFlavor ) == SOT_FORMAT_STRING ) )
964 //JP 24.7.2001: as I know was this only for the writer application and this
965 // writes now UTF16 format into the stream
966 //JP 6.8.2001: and now it writes UTF8 because then exist no problem with
967 // little / big endians! - Bug 88121
968 maAny <<= OUString( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), nLen - 1, RTL_TEXTENCODING_UTF8 );
970 else
971 maAny <<= aSeq;
974 return( maAny.hasValue() );
977 // -----------------------------------------------------------------------------
979 sal_Bool TransferableHelper::WriteObject( SotStorageStreamRef&, void*, sal_uInt32, const DataFlavor& )
981 OSL_FAIL( "TransferableHelper::WriteObject( ... ) not implemented" );
982 return sal_False;
985 // -----------------------------------------------------------------------------
987 void TransferableHelper::DragFinished( sal_Int8 )
991 // -----------------------------------------------------------------------------
993 void TransferableHelper::ObjectReleased()
997 // -----------------------------------------------------------------------------
999 void TransferableHelper::PrepareOLE( const TransferableObjectDescriptor& rObjDesc )
1001 delete mpObjDesc;
1002 mpObjDesc = new TransferableObjectDescriptor( rObjDesc );
1004 if( HasFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR ) )
1005 AddFormat( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR );
1008 // -----------------------------------------------------------------------------
1010 void TransferableHelper::CopyToClipboard( Window *pWindow ) const
1012 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1013 Reference< XClipboard > xClipboard;
1015 if( pWindow )
1016 xClipboard = pWindow->GetClipboard();
1018 if( xClipboard.is() )
1019 mxClipboard = xClipboard;
1021 if( mxClipboard.is() && !mxTerminateListener.is() )
1023 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1027 TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1028 Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
1029 xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1031 mxClipboard->setContents( pThis, pThis );
1033 catch( const ::com::sun::star::uno::Exception& )
1037 Application::AcquireSolarMutex( nRef );
1041 // -----------------------------------------------------------------------------
1043 void TransferableHelper::CopyToSelection( Window *pWindow ) const
1045 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1046 Reference< XClipboard > xSelection;
1048 if( pWindow )
1049 xSelection = pWindow->GetPrimarySelection();
1051 if( xSelection.is() && !mxTerminateListener.is() )
1053 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1057 TransferableHelper* pThis = const_cast< TransferableHelper* >( this );
1058 Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
1059 xDesktop->addTerminateListener( pThis->mxTerminateListener = new TerminateListener( *pThis ) );
1061 xSelection->setContents( pThis, pThis );
1063 catch( const ::com::sun::star::uno::Exception& )
1067 Application::AcquireSolarMutex( nRef );
1071 // -----------------------------------------------------------------------------
1073 void TransferableHelper::StartDrag( Window* pWindow, sal_Int8 nDnDSourceActions,
1074 sal_Int32 nDnDPointer, sal_Int32 nDnDImage )
1077 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1078 Reference< XDragSource > xDragSource( pWindow->GetDragSource() );
1080 if( xDragSource.is() )
1083 * #96792# release mouse before actually starting DnD.
1084 * This is necessary for the X11 DnD implementation to work.
1086 if( pWindow->IsMouseCaptured() )
1087 pWindow->ReleaseMouse();
1089 const Point aPt( pWindow->GetPointerPosPixel() );
1091 // On Mac OS X we are forced to execute 'startDrag' synchronously
1092 // contrary to the XDragSource interface specification because
1093 // we can receive drag events from the system only in the main
1094 // thread
1095 #if !defined(MACOSX)
1096 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
1097 #endif
1101 DragGestureEvent aEvt;
1102 aEvt.DragAction = DNDConstants::ACTION_COPY;
1103 aEvt.DragOriginX = aPt.X();
1104 aEvt.DragOriginY = aPt.Y();
1105 aEvt.DragSource = xDragSource;
1107 xDragSource->startDrag( aEvt, nDnDSourceActions, nDnDPointer, nDnDImage, this, this );
1109 catch( const ::com::sun::star::uno::Exception& )
1113 // See above for the reason of this define
1114 #if !defined(MACOSX)
1115 Application::AcquireSolarMutex( nRef );
1116 #endif
1120 // -----------------------------------------------------------------------------
1122 void TransferableHelper::ClearSelection( Window *pWindow )
1124 DBG_ASSERT( pWindow, "Window pointer is NULL" );
1125 Reference< XClipboard > xSelection( pWindow->GetPrimarySelection() );
1127 if( xSelection.is() )
1128 xSelection->setContents( NULL, NULL );
1131 // -----------------------------------------------------------------------------
1133 Reference< XClipboard> TransferableHelper::GetSystemClipboard()
1135 Window *pFocusWindow = Application::GetFocusWindow();
1137 if( pFocusWindow )
1138 return pFocusWindow->GetClipboard();
1140 return Reference< XClipboard > ();
1143 namespace
1145 class theTransferableHelperUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theTransferableHelperUnoTunnelId > {};
1148 const Sequence< sal_Int8 >& TransferableHelper::getUnoTunnelId()
1150 return theTransferableHelperUnoTunnelId::get().getSeq();
1153 // ---------------------------------
1154 // - TransferableClipboardNotifier -
1155 // ---------------------------------
1157 class TransferableClipboardNotifier : public ::cppu::WeakImplHelper1< XClipboardListener >
1159 private:
1160 ::osl::Mutex& mrMutex;
1161 Reference< XClipboardNotifier > mxNotifier;
1162 TransferableDataHelper* mpListener;
1164 protected:
1165 // XClipboardListener
1166 virtual void SAL_CALL changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException);
1168 // XEventListener
1169 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
1171 public:
1172 TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex );
1174 /// determines whether we're currently listening
1175 inline bool isListening() const { return !isDisposed(); }
1177 /// determines whether the instance is disposed
1178 inline bool isDisposed() const { return mpListener == NULL; }
1180 /// makes the instance non-functional
1181 void dispose();
1184 // -----------------------------------------------------------------------------
1186 TransferableClipboardNotifier::TransferableClipboardNotifier( const Reference< XClipboard >& _rxClipboard, TransferableDataHelper& _rListener, ::osl::Mutex& _rMutex )
1187 :mrMutex( _rMutex )
1188 ,mxNotifier( _rxClipboard, UNO_QUERY )
1189 ,mpListener( &_rListener )
1191 osl_atomic_increment( &m_refCount );
1193 if ( mxNotifier.is() )
1194 mxNotifier->addClipboardListener( this );
1195 else
1196 // born dead
1197 mpListener = NULL;
1199 osl_atomic_decrement( &m_refCount );
1202 // -----------------------------------------------------------------------------
1204 void SAL_CALL TransferableClipboardNotifier::changedContents( const clipboard::ClipboardEvent& event ) throw (RuntimeException)
1206 SolarMutexGuard aSolarGuard;
1207 // the SolarMutex here is necessary, since
1208 // - we cannot call mpListener without our own mutex locked
1209 // - Rebind respectively InitFormats (called by Rebind) will
1210 // try to lock the SolarMutex, too
1211 ::osl::MutexGuard aGuard( mrMutex );
1212 if( mpListener )
1213 mpListener->Rebind( event.Contents );
1216 // -----------------------------------------------------------------------------
1218 void SAL_CALL TransferableClipboardNotifier::disposing( const EventObject& ) throw (RuntimeException)
1220 // clipboard is being disposed. Hmm. Okay, become disfunctional myself.
1221 dispose();
1224 // -----------------------------------------------------------------------------
1226 void TransferableClipboardNotifier::dispose()
1228 ::osl::MutexGuard aGuard( mrMutex );
1230 Reference< XClipboardListener > xKeepMeAlive( this );
1232 if ( mxNotifier.is() )
1233 mxNotifier->removeClipboardListener( this );
1234 mxNotifier.clear();
1236 mpListener = NULL;
1239 // -------------------------------
1240 // - TransferableDataHelper_Impl -
1241 // -------------------------------
1243 struct TransferableDataHelper_Impl
1245 ::osl::Mutex maMutex;
1246 TransferableClipboardNotifier* mpClipboardListener;
1248 TransferableDataHelper_Impl()
1249 :mpClipboardListener( NULL )
1254 // --------------------------
1255 // - TransferableDataHelper -
1256 // --------------------------
1258 TransferableDataHelper::TransferableDataHelper() :
1259 mpFormats( new DataFlavorExVector ),
1260 mpObjDesc( new TransferableObjectDescriptor ),
1261 mpImpl( new TransferableDataHelper_Impl )
1265 // -----------------------------------------------------------------------------
1267 TransferableDataHelper::TransferableDataHelper( const Reference< ::com::sun::star::datatransfer::XTransferable >& rxTransferable ) :
1268 mxTransfer( rxTransferable ),
1269 mpFormats( new DataFlavorExVector ),
1270 mpObjDesc( new TransferableObjectDescriptor ),
1271 mpImpl( new TransferableDataHelper_Impl )
1273 InitFormats();
1276 // -----------------------------------------------------------------------------
1278 TransferableDataHelper::TransferableDataHelper( const TransferableDataHelper& rDataHelper ) :
1279 mxTransfer( rDataHelper.mxTransfer ),
1280 mxClipboard( rDataHelper.mxClipboard ),
1281 mpFormats( new DataFlavorExVector( *rDataHelper.mpFormats ) ),
1282 mpObjDesc( new TransferableObjectDescriptor( *rDataHelper.mpObjDesc ) ),
1283 mpImpl( new TransferableDataHelper_Impl )
1287 // -----------------------------------------------------------------------------
1289 TransferableDataHelper& TransferableDataHelper::operator=( const TransferableDataHelper& rDataHelper )
1291 if ( this != &rDataHelper )
1293 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1295 bool bWasClipboardListening = ( NULL != mpImpl->mpClipboardListener );
1297 if ( bWasClipboardListening )
1298 StopClipboardListening();
1300 mxTransfer = rDataHelper.mxTransfer;
1301 delete mpFormats, mpFormats = new DataFlavorExVector( *rDataHelper.mpFormats );
1302 delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor( *rDataHelper.mpObjDesc );
1303 mxClipboard = rDataHelper.mxClipboard;
1305 if ( bWasClipboardListening )
1306 StartClipboardListening();
1309 return *this;
1312 // -----------------------------------------------------------------------------
1314 TransferableDataHelper::~TransferableDataHelper()
1316 StopClipboardListening( );
1318 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1319 delete mpFormats, mpFormats = NULL;
1320 delete mpObjDesc, mpObjDesc = NULL;
1322 delete mpImpl;
1325 // -----------------------------------------------------------------------------
1327 void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor >& rDataFlavorSeq,
1328 DataFlavorExVector& rDataFlavorExVector )
1332 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
1333 Reference< XMimeContentTypeFactory > xMimeFact = MimeContentTypeFactory::create( xContext );
1334 DataFlavorEx aFlavorEx;
1335 const OUString aCharsetStr( "charset" );
1338 for( sal_Int32 i = 0; i < rDataFlavorSeq.getLength(); i++ )
1340 const DataFlavor& rFlavor = rDataFlavorSeq[ i ];
1341 Reference< XMimeContentType > xMimeType;
1345 if( !rFlavor.MimeType.isEmpty() )
1346 xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType );
1348 catch( const ::com::sun::star::uno::Exception& )
1353 aFlavorEx.MimeType = rFlavor.MimeType;
1354 aFlavorEx.HumanPresentableName = rFlavor.HumanPresentableName;
1355 aFlavorEx.DataType = rFlavor.DataType;
1356 aFlavorEx.mnSotId = SotExchange::RegisterFormat( rFlavor );
1358 rDataFlavorExVector.push_back( aFlavorEx );
1360 // add additional formats for special mime types
1361 if( SOT_FORMATSTR_ID_BMP == aFlavorEx.mnSotId )
1363 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavorEx ) )
1365 aFlavorEx.mnSotId = SOT_FORMAT_BITMAP;
1366 rDataFlavorExVector.push_back( aFlavorEx );
1369 else if( SOT_FORMATSTR_ID_WMF == aFlavorEx.mnSotId || SOT_FORMATSTR_ID_EMF == aFlavorEx.mnSotId )
1371 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavorEx ) )
1373 aFlavorEx.mnSotId = SOT_FORMAT_GDIMETAFILE;
1374 rDataFlavorExVector.push_back( aFlavorEx );
1377 else if ( SOT_FORMATSTR_ID_HTML_SIMPLE == aFlavorEx.mnSotId )
1379 // #104735# HTML_SIMPLE may also be inserted without comments
1380 aFlavorEx.mnSotId = SOT_FORMATSTR_ID_HTML_NO_COMMENT;
1381 rDataFlavorExVector.push_back( aFlavorEx );
1383 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/plain" ) ) )
1385 // add, if it is a UTF-8 byte buffer
1386 if( xMimeType->hasParameter( aCharsetStr ) )
1388 if( xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( OUString( "unicode" ) ) ||
1389 xMimeType->getParameterValue( aCharsetStr ).equalsIgnoreAsciiCase( OUString( "utf-16" ) ) )
1391 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_STRING;
1396 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/rtf" ) ) )
1398 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = FORMAT_RTF;
1400 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/html" ) ) )
1403 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_HTML;
1405 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/uri-list" ) ) )
1407 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMAT_FILE_LIST;
1409 else if( xMimeType.is() && xMimeType->getFullMediaType().equalsIgnoreAsciiCase( OUString( "application/x-openoffice-objectdescriptor-xml" ) ) )
1411 rDataFlavorExVector[ rDataFlavorExVector.size() - 1 ].mnSotId = SOT_FORMATSTR_ID_OBJECTDESCRIPTOR;
1415 catch( const ::com::sun::star::uno::Exception& )
1420 // -----------------------------------------------------------------------------
1422 void TransferableDataHelper::InitFormats()
1424 SolarMutexGuard aSolarGuard;
1425 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1427 mpFormats->clear();
1428 delete mpObjDesc, mpObjDesc = new TransferableObjectDescriptor;
1430 if( mxTransfer.is() )
1432 TransferableDataHelper::FillDataFlavorExVector( mxTransfer->getTransferDataFlavors(), *mpFormats );
1434 for (DataFlavorExVector::const_iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() ); aIter != aEnd ; ++aIter)
1436 if( SOT_FORMATSTR_ID_OBJECTDESCRIPTOR == aIter->mnSotId )
1438 ImplSetParameterString( *mpObjDesc, *aIter );
1439 break;
1445 // -----------------------------------------------------------------------------
1447 sal_Bool TransferableDataHelper::HasFormat( SotFormatStringId nFormat ) const
1449 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1451 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1452 sal_Bool bRet = sal_False;
1454 while( aIter != aEnd )
1456 if( nFormat == (*aIter++).mnSotId )
1458 aIter = aEnd;
1459 bRet = sal_True;
1463 return bRet;
1466 // -----------------------------------------------------------------------------
1468 sal_Bool TransferableDataHelper::HasFormat( const DataFlavor& rFlavor ) const
1470 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1472 DataFlavorExVector::iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() );
1473 sal_Bool bRet = sal_False;
1475 while( aIter != aEnd )
1477 if( TransferableDataHelper::IsEqual( rFlavor, *aIter++ ) )
1479 aIter = aEnd;
1480 bRet = sal_True;
1484 return bRet;
1487 // -----------------------------------------------------------------------------
1489 sal_uInt32 TransferableDataHelper::GetFormatCount() const
1491 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1492 return mpFormats->size();
1495 // -----------------------------------------------------------------------------
1498 SotFormatStringId TransferableDataHelper::GetFormat( sal_uInt32 nFormat ) const
1500 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1501 DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1502 return( ( nFormat < mpFormats->size() ) ? (*mpFormats)[ nFormat ].mnSotId : 0 );
1505 // -----------------------------------------------------------------------------
1507 DataFlavor TransferableDataHelper::GetFormatDataFlavor( sal_uInt32 nFormat ) const
1509 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1510 DBG_ASSERT( nFormat < mpFormats->size(), "TransferableDataHelper::GetFormat: invalid format index" );
1512 DataFlavor aRet;
1514 if( nFormat < mpFormats->size() )
1515 aRet = (*mpFormats)[ nFormat ];
1517 return aRet;
1520 // -----------------------------------------------------------------------------
1522 Reference< XTransferable > TransferableDataHelper::GetXTransferable() const
1524 Reference< XTransferable > xRet;
1526 if( mxTransfer.is() )
1530 xRet = mxTransfer;
1532 // do a dummy call to check, if this interface is valid (nasty)
1533 Sequence< DataFlavor > aTestSeq( xRet->getTransferDataFlavors() );
1536 catch( const ::com::sun::star::uno::Exception& )
1538 xRet = Reference< XTransferable >();
1542 return xRet;
1545 // -----------------------------------------------------------------------------
1547 Any TransferableDataHelper::GetAny( SotFormatStringId nFormat ) const
1549 Any aReturn;
1551 DataFlavor aFlavor;
1552 if ( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) )
1553 aReturn = GetAny( aFlavor );
1555 return aReturn;
1559 // -----------------------------------------------------------------------------
1561 Any TransferableDataHelper::GetAny( const DataFlavor& rFlavor ) const
1563 ::osl::MutexGuard aGuard( mpImpl->maMutex );
1564 Any aRet;
1568 if( mxTransfer.is() )
1570 const SotFormatStringId nRequestFormat = SotExchange::GetFormat( rFlavor );
1572 if( nRequestFormat )
1574 // try to get alien format first
1575 for (DataFlavorExVector::const_iterator aIter( mpFormats->begin() ), aEnd( mpFormats->end() ); aIter != aEnd ; ++aIter)
1577 if( ( nRequestFormat == (*aIter).mnSotId ) && !rFlavor.MimeType.equalsIgnoreAsciiCase( (*aIter).MimeType ) )
1578 aRet = mxTransfer->getTransferData( *aIter );
1580 if( aRet.hasValue() )
1581 break;
1585 if( !aRet.hasValue() )
1586 aRet = mxTransfer->getTransferData( rFlavor );
1589 catch( const ::com::sun::star::uno::Exception& )
1593 return aRet;
1596 // -----------------------------------------------------------------------------
1598 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, String& rStr )
1600 OUString aOUString;
1601 sal_Bool bRet = GetString( nFormat, aOUString );
1603 rStr = aOUString;
1605 return bRet;
1608 // -----------------------------------------------------------------------------
1610 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, String& rStr )
1612 OUString aOUString;
1613 sal_Bool bRet = GetString( rFlavor, aOUString );
1615 rStr = aOUString;
1617 return bRet;
1620 // -----------------------------------------------------------------------------
1622 sal_Bool TransferableDataHelper::GetString( SotFormatStringId nFormat, OUString& rStr )
1624 DataFlavor aFlavor;
1625 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetString( aFlavor, rStr ) );
1628 // -----------------------------------------------------------------------------
1630 sal_Bool TransferableDataHelper::GetString( const DataFlavor& rFlavor, OUString& rStr )
1632 Any aAny( GetAny( rFlavor ) );
1633 sal_Bool bRet = sal_False;
1635 if( aAny.hasValue() )
1637 OUString aOUString;
1638 Sequence< sal_Int8 > aSeq;
1640 if( aAny >>= aOUString )
1642 rStr = aOUString;
1643 bRet = sal_True;
1645 else if( aAny >>= aSeq )
1648 const sal_Char* pChars = reinterpret_cast< const sal_Char* >( aSeq.getConstArray() );
1649 sal_Int32 nLen = aSeq.getLength();
1651 //JP 10.10.2001: 92930 - don't copy the last zero characterinto the string.
1652 //DVO 2002-05-27: strip _all_ trailing zeros
1653 while( nLen && ( 0 == *( pChars + nLen - 1 ) ) )
1654 --nLen;
1656 rStr = OUString( pChars, nLen, osl_getThreadTextEncoding() );
1657 bRet = sal_True;
1661 return bRet;
1664 // -----------------------------------------------------------------------------
1666 sal_Bool TransferableDataHelper::GetBitmap( SotFormatStringId nFormat, Bitmap& rBmp )
1668 DataFlavor aFlavor;
1669 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetBitmap( aFlavor, rBmp ) );
1672 // -----------------------------------------------------------------------------
1674 sal_Bool TransferableDataHelper::GetBitmap( const DataFlavor& rFlavor, Bitmap& rBmp )
1676 SotStorageStreamRef xStm;
1677 DataFlavor aSubstFlavor;
1678 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
1680 if( bRet )
1682 *xStm >> rBmp;
1683 bRet = ( xStm->GetError() == ERRCODE_NONE );
1685 /* SJ: #110748# At the moment we are having problems with DDB inserted as DIB. The
1686 problem is, that some graphics are inserted much too big because the nXPelsPerMeter
1687 and nYPelsPerMeter of the bitmap fileheader isn't including the correct value.
1688 Due to this reason the following code assumes that bitmaps with a logical size
1689 greater than 50 cm aren't having the correct mapmode set.
1691 The following code should be removed if DDBs and DIBs are supported via clipboard
1692 properly.
1694 if ( bRet )
1696 MapMode aMapMode = rBmp.GetPrefMapMode();
1697 if ( aMapMode.GetMapUnit() != MAP_PIXEL )
1699 Size aSize = OutputDevice::LogicToLogic( rBmp.GetPrefSize(), aMapMode, MAP_100TH_MM );
1700 if ( ( aSize.Width() > 5000 ) || ( aSize.Height() > 5000 ) )
1701 rBmp.SetPrefMapMode( MAP_PIXEL );
1706 if( !bRet &&
1707 HasFormat( SOT_FORMATSTR_ID_BMP ) &&
1708 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_BMP, aSubstFlavor ) &&
1709 GetSotStorageStream( aSubstFlavor, xStm ) )
1711 xStm->ResetError();
1712 *xStm >> rBmp;
1713 bRet = ( xStm->GetError() == ERRCODE_NONE );
1716 return bRet;
1719 // -----------------------------------------------------------------------------
1721 sal_Bool TransferableDataHelper::GetGDIMetaFile( SotFormatStringId nFormat, GDIMetaFile& rMtf )
1723 DataFlavor aFlavor;
1724 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGDIMetaFile( aFlavor, rMtf ) );
1727 // -----------------------------------------------------------------------------
1729 sal_Bool TransferableDataHelper::GetGDIMetaFile( const DataFlavor& rFlavor, GDIMetaFile& rMtf )
1731 SotStorageStreamRef xStm;
1732 DataFlavor aSubstFlavor;
1733 sal_Bool bRet = sal_False;
1735 if( GetSotStorageStream( rFlavor, xStm ) )
1737 *xStm >> rMtf;
1738 bRet = ( xStm->GetError() == ERRCODE_NONE );
1741 if( !bRet &&
1742 HasFormat( SOT_FORMATSTR_ID_EMF ) &&
1743 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EMF, aSubstFlavor ) &&
1744 GetSotStorageStream( aSubstFlavor, xStm ) )
1746 Graphic aGraphic;
1748 if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1750 rMtf = aGraphic.GetGDIMetaFile();
1751 bRet = sal_True;
1755 if( !bRet &&
1756 HasFormat( SOT_FORMATSTR_ID_WMF ) &&
1757 SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_WMF, aSubstFlavor ) &&
1758 GetSotStorageStream( aSubstFlavor, xStm ) )
1760 Graphic aGraphic;
1762 if( GraphicConverter::Import( *xStm, aGraphic ) == ERRCODE_NONE )
1764 rMtf = aGraphic.GetGDIMetaFile();
1765 bRet = sal_True;
1769 return bRet;
1772 // -----------------------------------------------------------------------------
1774 sal_Bool TransferableDataHelper::GetGraphic( SotFormatStringId nFormat, Graphic& rGraphic )
1776 DataFlavor aFlavor;
1777 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetGraphic( aFlavor, rGraphic ) );
1780 // -----------------------------------------------------------------------------
1782 sal_Bool TransferableDataHelper::GetGraphic( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, Graphic& rGraphic )
1784 DataFlavor aFlavor;
1785 sal_Bool bRet = sal_False;
1787 if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_BITMAP, aFlavor ) &&
1788 TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1790 Bitmap aBmp;
1792 if( ( bRet = GetBitmap( aFlavor, aBmp ) ) == sal_True )
1793 rGraphic = aBmp;
1795 else if( SotExchange::GetFormatDataFlavor( SOT_FORMAT_GDIMETAFILE, aFlavor ) &&
1796 TransferableDataHelper::IsEqual( aFlavor, rFlavor ) )
1798 GDIMetaFile aMtf;
1800 if( ( bRet = GetGDIMetaFile( aFlavor, aMtf ) ) == sal_True )
1801 rGraphic = aMtf;
1803 else
1805 SotStorageStreamRef xStm;
1807 if( GetSotStorageStream( rFlavor, xStm ) )
1809 *xStm >> rGraphic;
1810 bRet = ( xStm->GetError() == ERRCODE_NONE );
1814 return bRet;
1817 // -----------------------------------------------------------------------------
1819 sal_Bool TransferableDataHelper::GetImageMap( SotFormatStringId nFormat, ImageMap& rIMap )
1821 DataFlavor aFlavor;
1822 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetImageMap( aFlavor, rIMap ) );
1825 // -----------------------------------------------------------------------------
1827 sal_Bool TransferableDataHelper::GetImageMap( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, ImageMap& rIMap )
1829 SotStorageStreamRef xStm;
1830 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
1832 if( bRet )
1834 rIMap.Read( *xStm, String() );
1835 bRet = ( xStm->GetError() == ERRCODE_NONE );
1838 return bRet;
1841 // -----------------------------------------------------------------------------
1843 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( SotFormatStringId nFormat, TransferableObjectDescriptor& rDesc )
1845 DataFlavor aFlavor;
1846 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetTransferableObjectDescriptor( aFlavor, rDesc ) );
1849 // -----------------------------------------------------------------------------
1851 sal_Bool TransferableDataHelper::GetTransferableObjectDescriptor( const ::com::sun::star::datatransfer::DataFlavor&, TransferableObjectDescriptor& rDesc )
1853 rDesc = *mpObjDesc;
1854 return true;
1857 // -----------------------------------------------------------------------------
1859 sal_Bool TransferableDataHelper::GetINetBookmark( SotFormatStringId nFormat, INetBookmark& rBmk )
1861 DataFlavor aFlavor;
1862 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetBookmark( aFlavor, rBmk ) );
1865 // -----------------------------------------------------------------------------
1867 sal_Bool TransferableDataHelper::GetINetBookmark( const ::com::sun::star::datatransfer::DataFlavor& rFlavor, INetBookmark& rBmk )
1869 sal_Bool bRet = sal_False;
1870 if( HasFormat( rFlavor ))
1872 const SotFormatStringId nFormat = SotExchange::GetFormat( rFlavor );
1873 switch( nFormat )
1875 case( SOT_FORMATSTR_ID_SOLK ):
1876 case( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR ):
1878 String aString;
1879 if( GetString( rFlavor, aString ) )
1881 if( SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR == nFormat )
1883 rBmk = INetBookmark( aString, aString );
1884 bRet = sal_True;
1886 else
1888 String aURL, aDesc;
1889 sal_uInt16 nStart = aString.Search( '@' ), nLen = (sal_uInt16) aString.ToInt32();
1891 if( !nLen && aString.GetChar( 0 ) != '0' )
1893 DBG_WARNING( "SOLK: 1. len=0" );
1895 if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 3 )
1897 DBG_WARNING( "SOLK: 1. illegal start or wrong len" );
1899 aURL = aString.Copy( nStart + 1, nLen );
1901 aString.Erase( 0, nStart + 1 + nLen );
1902 nStart = aString.Search( '@' );
1903 nLen = (sal_uInt16) aString.ToInt32();
1905 if( !nLen && aString.GetChar( 0 ) != '0' )
1907 DBG_WARNING( "SOLK: 2. len=0" );
1909 if( nStart == STRING_NOTFOUND || nLen > aString.Len() - nStart - 1 )
1911 DBG_WARNING( "SOLK: 2. illegal start or wrong len" );
1913 aDesc = aString.Copy( nStart+1, nLen );
1915 rBmk = INetBookmark( aURL, aDesc );
1916 bRet = sal_True;
1920 break;
1922 case( SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK ):
1924 Sequence< sal_Int8 > aSeq;
1926 if( GetSequence( rFlavor, aSeq ) && ( 2048 == aSeq.getLength() ) )
1928 rBmk = INetBookmark( String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ), osl_getThreadTextEncoding() ),
1929 String( reinterpret_cast< const sal_Char* >( aSeq.getConstArray() ) + 1024, osl_getThreadTextEncoding() ) );
1930 bRet = sal_True;
1933 break;
1935 #ifdef WNT
1936 case SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR:
1938 Sequence< sal_Int8 > aSeq;
1940 if( GetSequence( rFlavor, aSeq ) && aSeq.getLength() )
1942 FILEGROUPDESCRIPTOR* pFDesc = (FILEGROUPDESCRIPTOR*) aSeq.getConstArray();
1944 if( pFDesc->cItems )
1946 OString aDesc( pFDesc->fgd[ 0 ].cFileName );
1947 rtl_TextEncoding eTextEncoding = osl_getThreadTextEncoding();
1949 if( ( aDesc.getLength() > 4 ) && aDesc.copy(aDesc.getLength() - 4).equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM(".URL")) )
1951 SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( INetURLObject( OStringToOUString(aDesc, eTextEncoding) ).GetMainURL( INetURLObject::NO_DECODE ),
1952 STREAM_STD_READ );
1954 if( !pStream || pStream->GetError() )
1956 DataFlavor aFileContentFlavor;
1958 aSeq.realloc( 0 );
1959 delete pStream;
1961 if( SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_FILECONTENT, aFileContentFlavor ) &&
1962 GetSequence( aFileContentFlavor, aSeq ) && aSeq.getLength() )
1964 pStream = new SvMemoryStream( (sal_Char*) aSeq.getConstArray(), aSeq.getLength(), STREAM_STD_READ );
1966 else
1967 pStream = NULL;
1970 if( pStream )
1972 OString aLine;
1973 sal_Bool bSttFnd = sal_False;
1975 while( pStream->ReadLine( aLine ) )
1977 if (aLine.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("[InternetShortcut]")))
1978 bSttFnd = sal_True;
1979 else if (bSttFnd && aLine.copy(0, 4).equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("URL=")))
1981 rBmk = INetBookmark( OStringToOUString(aLine.copy(4), eTextEncoding),
1982 OStringToOUString(aDesc.copy(0, aDesc.getLength() - 4), eTextEncoding) );
1983 bRet = sal_True;
1984 break;
1988 delete pStream;
1994 break;
1995 #endif
1999 return bRet;
2002 // -----------------------------------------------------------------------------
2004 sal_Bool TransferableDataHelper::GetINetImage( SotFormatStringId nFormat,
2005 INetImage& rINtImg )
2007 DataFlavor aFlavor;
2008 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetINetImage( aFlavor, rINtImg ) );
2011 // -----------------------------------------------------------------------------
2013 sal_Bool TransferableDataHelper::GetINetImage(
2014 const ::com::sun::star::datatransfer::DataFlavor& rFlavor,
2015 INetImage& rINtImg )
2017 SotStorageStreamRef xStm;
2018 sal_Bool bRet = GetSotStorageStream( rFlavor, xStm );
2020 if( bRet )
2021 bRet = rINtImg.Read( *xStm, SotExchange::GetFormat( rFlavor ) );
2022 return bRet;
2025 // -----------------------------------------------------------------------------
2027 sal_Bool TransferableDataHelper::GetFileList( SotFormatStringId nFormat,
2028 FileList& rFileList )
2030 DataFlavor aFlavor;
2031 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetFileList( aFlavor, rFileList ) );
2034 // -----------------------------------------------------------------------------
2036 sal_Bool TransferableDataHelper::GetFileList(
2037 const ::com::sun::star::datatransfer::DataFlavor&,
2038 FileList& rFileList )
2040 SotStorageStreamRef xStm;
2041 sal_Bool bRet = sal_False;
2043 for( sal_uInt32 i = 0, nFormatCount = GetFormatCount(); ( i < nFormatCount ) && !bRet; ++i )
2045 if( SOT_FORMAT_FILE_LIST == GetFormat( i ) )
2047 const DataFlavor aFlavor( GetFormatDataFlavor( i ) );
2049 if( GetSotStorageStream( aFlavor, xStm ) )
2051 if( aFlavor.MimeType.indexOf( "text/uri-list" ) > -1 )
2053 OString aDiskString;
2055 while( xStm->ReadLine( aDiskString ) )
2056 if( !aDiskString.isEmpty() && aDiskString[0] != '#' )
2057 rFileList.AppendFile( OStringToOUString(aDiskString, RTL_TEXTENCODING_UTF8) );
2059 bRet = sal_True;
2061 else
2062 bRet = ( ( *xStm >> rFileList ).GetError() == ERRCODE_NONE );
2067 return bRet;
2070 // -----------------------------------------------------------------------------
2072 sal_Bool TransferableDataHelper::GetSequence( SotFormatStringId nFormat, Sequence< sal_Int8 >& rSeq )
2074 DataFlavor aFlavor;
2075 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSequence( aFlavor, rSeq ) );
2078 // -----------------------------------------------------------------------------
2080 sal_Bool TransferableDataHelper::GetSequence( const DataFlavor& rFlavor, Sequence< sal_Int8 >& rSeq )
2082 #ifdef DEBUG
2083 fprintf( stderr, "TransferableDataHelper requests sequence of data\n" );
2084 #endif
2086 const Any aAny( GetAny( rFlavor ) );
2087 return( aAny.hasValue() && ( aAny >>= rSeq ) );
2090 // -----------------------------------------------------------------------------
2092 sal_Bool TransferableDataHelper::GetSotStorageStream( SotFormatStringId nFormat, SotStorageStreamRef& rxStream )
2094 DataFlavor aFlavor;
2095 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetSotStorageStream( aFlavor, rxStream ) );
2098 // -----------------------------------------------------------------------------
2100 sal_Bool TransferableDataHelper::GetSotStorageStream( const DataFlavor& rFlavor, SotStorageStreamRef& rxStream )
2102 Sequence< sal_Int8 > aSeq;
2103 sal_Bool bRet = GetSequence( rFlavor, aSeq );
2105 if( bRet )
2107 rxStream = new SotStorageStream( String() );
2108 rxStream->Write( aSeq.getConstArray(), aSeq.getLength() );
2109 rxStream->Seek( 0 );
2112 return bRet;
2115 sal_Bool TransferableDataHelper::GetInputStream( SotFormatStringId nFormat, Reference < XInputStream >& rxStream )
2117 DataFlavor aFlavor;
2118 return( SotExchange::GetFormatDataFlavor( nFormat, aFlavor ) && GetInputStream( aFlavor, rxStream ) );
2121 // -----------------------------------------------------------------------------
2123 sal_Bool TransferableDataHelper::GetInputStream( const DataFlavor& rFlavor, Reference < XInputStream >& rxStream )
2125 Sequence< sal_Int8 > aSeq;
2126 sal_Bool bRet = GetSequence( rFlavor, aSeq );
2128 if( bRet )
2129 rxStream = new ::comphelper::SequenceInputStream( aSeq );
2131 return bRet;
2134 // -----------------------------------------------------------------------------
2136 void TransferableDataHelper::Rebind( const Reference< XTransferable >& _rxNewContent )
2138 mxTransfer = _rxNewContent;
2139 InitFormats();
2142 // -----------------------------------------------------------------------------
2144 sal_Bool TransferableDataHelper::StartClipboardListening( )
2146 ::osl::MutexGuard aGuard( mpImpl->maMutex );
2148 StopClipboardListening( );
2150 mpImpl->mpClipboardListener = new TransferableClipboardNotifier( mxClipboard, *this, mpImpl->maMutex );
2151 mpImpl->mpClipboardListener->acquire();
2153 return mpImpl->mpClipboardListener->isListening();
2156 // -----------------------------------------------------------------------------
2158 void TransferableDataHelper::StopClipboardListening( )
2160 ::osl::MutexGuard aGuard( mpImpl->maMutex );
2162 if ( mpImpl->mpClipboardListener )
2164 mpImpl->mpClipboardListener->dispose();
2165 mpImpl->mpClipboardListener->release();
2166 mpImpl->mpClipboardListener = NULL;
2170 // -----------------------------------------------------------------------------
2172 TransferableDataHelper TransferableDataHelper::CreateFromSystemClipboard( Window * pWindow )
2174 DBG_ASSERT( pWindow, "Window pointer is NULL" );
2176 Reference< XClipboard > xClipboard;
2177 TransferableDataHelper aRet;
2179 if( pWindow )
2180 xClipboard = pWindow->GetClipboard();
2182 if( xClipboard.is() )
2186 Reference< XTransferable > xTransferable( xClipboard->getContents() );
2188 if( xTransferable.is() )
2190 aRet = TransferableDataHelper( xTransferable );
2191 // also copy the clipboard
2192 aRet.mxClipboard = xClipboard;
2195 catch( const ::com::sun::star::uno::Exception& )
2200 return aRet;
2204 // -----------------------------------------------------------------------------
2206 TransferableDataHelper TransferableDataHelper::CreateFromSelection( Window* pWindow )
2208 DBG_ASSERT( pWindow, "Window pointer is NULL" );
2210 Reference< XClipboard > xSelection;
2211 TransferableDataHelper aRet;
2213 if( pWindow )
2214 xSelection = pWindow->GetPrimarySelection();
2216 if( xSelection.is() )
2218 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
2222 Reference< XTransferable > xTransferable( xSelection->getContents() );
2224 if( xTransferable.is() )
2226 aRet = TransferableDataHelper( xTransferable );
2227 aRet.mxClipboard = xSelection;
2230 catch( const ::com::sun::star::uno::Exception& )
2234 Application::AcquireSolarMutex( nRef );
2237 return aRet;
2240 // -----------------------------------------------------------------------------
2241 sal_Bool TransferableDataHelper::IsEqual( const ::com::sun::star::datatransfer::DataFlavor& rInternalFlavor,
2242 const ::com::sun::star::datatransfer::DataFlavor& rRequestFlavor,
2243 sal_Bool )
2245 Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
2246 sal_Bool bRet = sal_False;
2250 Reference< XMimeContentTypeFactory > xMimeFact = MimeContentTypeFactory::create( xContext );
2252 Reference< XMimeContentType > xRequestType1( xMimeFact->createMimeContentType( rInternalFlavor.MimeType ) );
2253 Reference< XMimeContentType > xRequestType2( xMimeFact->createMimeContentType( rRequestFlavor.MimeType ) );
2255 if( xRequestType1.is() && xRequestType2.is() )
2257 if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( xRequestType2->getFullMediaType() ) )
2259 if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( OUString( "text/plain" ) ) )
2261 // special handling for text/plain media types
2262 const OUString aCharsetString( "charset" );
2264 if( !xRequestType2->hasParameter( aCharsetString ) ||
2265 xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( OUString( "utf-16" ) ) ||
2266 xRequestType2->getParameterValue( aCharsetString ).equalsIgnoreAsciiCase( OUString( "unicode" ) ) )
2268 bRet = sal_True;
2271 else if( xRequestType1->getFullMediaType().equalsIgnoreAsciiCase( OUString( "application/x-openoffice" ) ) )
2273 // special handling for application/x-openoffice media types
2274 const OUString aFormatString( "windows_formatname" );
2276 if( xRequestType1->hasParameter( aFormatString ) &&
2277 xRequestType2->hasParameter( aFormatString ) &&
2278 xRequestType1->getParameterValue( aFormatString ).equalsIgnoreAsciiCase( xRequestType2->getParameterValue( aFormatString ) ) )
2280 bRet = sal_True;
2283 else
2284 bRet = sal_True;
2288 catch( const ::com::sun::star::uno::Exception& )
2290 bRet = rInternalFlavor.MimeType.equalsIgnoreAsciiCase( rRequestFlavor.MimeType );
2293 return bRet;
2296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */