diff options
Diffstat (limited to 'dtrans')
120 files changed, 19184 insertions, 0 deletions
diff --git a/dtrans/inc/makefile.mk b/dtrans/inc/makefile.mk new file mode 100644 index 000000000000..2738985607cb --- /dev/null +++ b/dtrans/inc/makefile.mk @@ -0,0 +1,47 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=.. + +PRJNAME=dtrans +TARGET=inc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.IF "$(ENABLE_PCH)"!="" +ALLTAR : \ + $(SLO)$/precompiled.pch \ + $(SLO)$/precompiled_ex.pch + +.ENDIF # "$(ENABLE_PCH)"!="" + diff --git a/dtrans/inc/pch/precompiled_dtrans.cxx b/dtrans/inc/pch/precompiled_dtrans.cxx new file mode 100644 index 000000000000..97ae0d1450c1 --- /dev/null +++ b/dtrans/inc/pch/precompiled_dtrans.cxx @@ -0,0 +1,29 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_dtrans.hxx" + diff --git a/dtrans/inc/pch/precompiled_dtrans.hxx b/dtrans/inc/pch/precompiled_dtrans.hxx new file mode 100644 index 000000000000..fe3362638432 --- /dev/null +++ b/dtrans/inc/pch/precompiled_dtrans.hxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): Generated on 2006-09-01 17:49:39.639664 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/dtrans/prj/build.lst b/dtrans/prj/build.lst new file mode 100644 index 000000000000..bd9c73582361 --- /dev/null +++ b/dtrans/prj/build.lst @@ -0,0 +1,15 @@ +dr dtrans : unotools offapi offuh rdbmaker vos stoc NULL +dr dtrans usr1 - all dr_mkout NULL +dr dtrans\inc nmake - all dr_inc NULL +dr dtrans\source\cnttype nmake - all dr_cnttype dr_generic dr_inc NULL +dr dtrans\source\win32\misc nmake - w dr_win32_misc dr_inc NULL +dr dtrans\source\win32\mtaole nmake - w dr_win32_mtaole dr_inc NULL +dr dtrans\source\win32\ftransl nmake - w dr_win32_ftransl dr_cnttype dr_win32_misc.w dr_inc NULL +dr dtrans\source\win32\clipb nmake - w dr_win32_clipb dr_win32_misc.w dr_inc NULL +dr dtrans\source\win32\dnd nmake - w dr_win32_dnd dr_cnttype dr_win32_misc.w dr_win32_dtobj.w dr_inc NULL +dr dtrans\source\win32\dtobj nmake - w dr_win32_dtobj dr_win32_clipb.w dr_win32_misc.w dr_win32_ftransl.w dr_inc NULL +dr dtrans\source\os2\clipb nmake - p dr_os2_clipb dr_inc NULL +dr dtrans\util nmake - all dr_util dr_cnttype dr_win32_misc.w dr_win32_mtaole.w dr_win32_ftransl.w dr_win32_clipb.w dr_win32_dnd.w dr_win32_dtobj.w dr_inc NULL +dr dtrans\source\generic nmake - all dr_generic dr_inc NULL + + diff --git a/dtrans/prj/d.lst b/dtrans/prj/d.lst new file mode 100644 index 000000000000..955aa075f24b --- /dev/null +++ b/dtrans/prj/d.lst @@ -0,0 +1,14 @@ +..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT% +..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*.dll +..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.dylib + +..\source\win32\clipb\sysdtrans.xml %_DEST%\xml%_EXT%\sysdtrans.xml +..\source\win32\dnd\dnd.xml %_DEST%\xml%_EXT%\dnd.xml +..\source\win32\ftransl\ftransl.xml %_DEST%\xml%_EXT%\ftransl.xml +..\source\cnttype\mcnttype.xml %_DEST%\xml%_EXT%\mcnttype.xml +..\source\generic\dtrans.xml %_DEST%\xml%_EXT%\dtrans.xml +..\%__SRC%\misc\dnd.component %_DEST%\xml%_EXT%\dnd.component +..\%__SRC%\misc\dtrans.component %_DEST%\xml%_EXT%\dtrans.component +..\%__SRC%\misc\ftransl.component %_DEST%\xml%_EXT%\ftransl.component +..\%__SRC%\misc\mcnttype.component %_DEST%\xml%_EXT%\mcnttype.component +..\%__SRC%\misc\sysdtrans.component %_DEST%\xml%_EXT%\sysdtrans.component diff --git a/dtrans/source/cnttype/exports.dxp b/dtrans/source/cnttype/exports.dxp new file mode 100644 index 000000000000..f0e1c69934bc --- /dev/null +++ b/dtrans/source/cnttype/exports.dxp @@ -0,0 +1,2 @@ +component_getImplementationEnvironment +component_getFactory diff --git a/dtrans/source/cnttype/makefile.mk b/dtrans/source/cnttype/makefile.mk new file mode 100644 index 000000000000..d99b8d4c9ac6 --- /dev/null +++ b/dtrans/source/cnttype/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=dtrans +TARGET=mcnttype +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +USE_BOUNDCHK= + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES=$(SLO)$/mctfentry.obj \ + $(SLO)$/mcnttfactory.obj \ + $(SLO)$/mcnttype.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/dtrans/source/cnttype/mcnttfactory.cxx b/dtrans/source/cnttype/mcnttfactory.cxx new file mode 100644 index 000000000000..07b557350bc0 --- /dev/null +++ b/dtrans/source/cnttype/mcnttfactory.cxx @@ -0,0 +1,123 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "mcnttfactory.hxx" +#include "mcnttype.hxx" + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define MIMECONTENTTYPEFACTORY_IMPL_NAME "com.sun.star.datatransfer.MimeCntTypeFactory" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace ::rtl; +using namespace ::osl; +using namespace ::cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::datatransfer; + +//------------------------------------------------------------------------ +// helper functions +//------------------------------------------------------------------------ + +namespace +{ + Sequence< OUString > SAL_CALL MimeContentTypeFactory_getSupportedServiceNames( ) + { + Sequence< OUString > aRet(1); + aRet[0] = OUString::createFromAscii("com.sun.star.datatransfer.MimeContentTypeFactory"); + return aRet; + } +} + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +CMimeContentTypeFactory::CMimeContentTypeFactory( const Reference< XMultiServiceFactory >& rSrvMgr ) : + m_SrvMgr( rSrvMgr ) +{ +} + +//------------------------------------------------------------------------ +// createMimeContentType +//------------------------------------------------------------------------ + +Reference< XMimeContentType > CMimeContentTypeFactory::createMimeContentType( const OUString& aContentType ) + throw( IllegalArgumentException, RuntimeException ) +{ + MutexGuard aGuard( m_aMutex ); + return Reference< XMimeContentType >( new CMimeContentType( aContentType ) ); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +OUString SAL_CALL CMimeContentTypeFactory::getImplementationName( ) + throw( RuntimeException ) +{ + return OUString::createFromAscii( MIMECONTENTTYPEFACTORY_IMPL_NAME ); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +sal_Bool SAL_CALL CMimeContentTypeFactory::supportsService( const OUString& ServiceName ) + throw( RuntimeException ) +{ + Sequence < OUString > SupportedServicesNames = MimeContentTypeFactory_getSupportedServiceNames(); + + for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +Sequence< OUString > SAL_CALL CMimeContentTypeFactory::getSupportedServiceNames( ) + throw( RuntimeException ) +{ + return MimeContentTypeFactory_getSupportedServiceNames( ); +} diff --git a/dtrans/source/cnttype/mcnttfactory.hxx b/dtrans/source/cnttype/mcnttfactory.hxx new file mode 100644 index 000000000000..608a6a5b4e19 --- /dev/null +++ b/dtrans/source/cnttype/mcnttfactory.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _MCNTTFACTORY_HXX_ +#define _MCNTTFACTORY_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <cppuhelper/compbase2.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp> + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +class CMimeContentTypeFactory : public + cppu::WeakImplHelper2< com::sun::star::datatransfer::XMimeContentTypeFactory, \ + com::sun::star::lang::XServiceInfo > +{ + +public: + CMimeContentTypeFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSrvMgr ); + + //------------------------------------------------ + // XMimeContentTypeFactory + //------------------------------------------------ + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XMimeContentType > SAL_CALL createMimeContentType( const ::rtl::OUString& aContentType ) + throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XServiceInfo + //------------------------------------------------ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException); + +private: + ::osl::Mutex m_aMutex; + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr; +}; + + +#endif + diff --git a/dtrans/source/cnttype/mcnttype.cxx b/dtrans/source/cnttype/mcnttype.cxx new file mode 100644 index 000000000000..bc5a52920bfb --- /dev/null +++ b/dtrans/source/cnttype/mcnttype.cxx @@ -0,0 +1,427 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include "mcnttype.hxx" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace rtl; +using namespace std; +using namespace osl; + +//------------------------------------------------------------------------ +// constants +//------------------------------------------------------------------------ + +const OUString TSPECIALS = OUString::createFromAscii( "()<>@,;:\\\"/[]?=" ); +const OUString TOKEN = OUString::createFromAscii( "!#$%&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~." ); +const OUString SPACE = OUString::createFromAscii( " " ); +const OUString SEMICOLON = OUString::createFromAscii( ";" ); + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +CMimeContentType::CMimeContentType( const OUString& aCntType ) +{ + init( aCntType ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::getMediaType( ) throw(RuntimeException) +{ + return m_MediaType; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::getMediaSubtype( ) throw(RuntimeException) +{ + return m_MediaSubtype; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::getFullMediaType( ) throw(RuntimeException) +{ + return m_MediaType + OUString::createFromAscii( "/" ) + m_MediaSubtype; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +Sequence< OUString > SAL_CALL CMimeContentType::getParameters( ) throw(RuntimeException) +{ + MutexGuard aGuard( m_aMutex ); + + Sequence< OUString > seqParams; + + map< OUString, OUString >::iterator iter; + map< OUString, OUString >::iterator iter_end = m_ParameterMap.end( ); + + for ( iter = m_ParameterMap.begin( ); iter != iter_end; ++iter ) + { + seqParams.realloc( seqParams.getLength( ) + 1 ); + seqParams[seqParams.getLength( ) - 1] = iter->first; + } + + return seqParams; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CMimeContentType::hasParameter( const OUString& aName ) throw(RuntimeException) +{ + MutexGuard aGuard( m_aMutex ); + return ( m_ParameterMap.end( ) != m_ParameterMap.find( aName ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::getParameterValue( const OUString& aName ) throw(NoSuchElementException, RuntimeException) +{ + MutexGuard aGuard( m_aMutex ); + + if ( !hasParameter( aName ) ) + throw NoSuchElementException( ); + + return m_ParameterMap.find( aName )->second; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::init( const OUString& aCntType ) throw( IllegalArgumentException ) +{ + if ( !aCntType.getLength( ) ) + throw IllegalArgumentException( ); + + m_nPos = 0; + m_ContentType = aCntType; + getSym( ); + type(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::getSym( void ) +{ + if ( m_nPos < m_ContentType.getLength( ) ) + { + m_nxtSym = OUString( &m_ContentType[m_nPos], 1 ); + ++m_nPos; + return; + } + + m_nxtSym = OUString( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::acceptSym( const OUString& pSymTlb ) +{ + if ( pSymTlb.indexOf( m_nxtSym ) < 0 ) + throw IllegalArgumentException( ); + + getSym(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::skipSpaces( void ) +{ + while ( SPACE == m_nxtSym ) + getSym( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::type( void ) +{ + skipSpaces( ); + + // check FIRST( type ) + if ( !isInRange( m_nxtSym, TOKEN ) ) + throw IllegalArgumentException( ); + + // parse + while( m_nxtSym.getLength( ) ) + { + if ( isInRange( m_nxtSym, TOKEN ) ) + m_MediaType += m_nxtSym; + else if ( isInRange( m_nxtSym, OUString::createFromAscii( "/ " ) ) ) + break; + else + throw IllegalArgumentException( ); + getSym( ); + } + + // check FOLLOW( type ) + skipSpaces( ); + acceptSym( OUString::createFromAscii( "/" ) ); + + subtype( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::subtype( void ) +{ + skipSpaces( ); + + // check FIRST( subtype ) + if ( !isInRange( m_nxtSym, TOKEN ) ) + throw IllegalArgumentException( ); + + while( m_nxtSym.getLength( ) ) + { + if ( isInRange( m_nxtSym, TOKEN ) ) + m_MediaSubtype += m_nxtSym; + else if ( isInRange( m_nxtSym, OUString::createFromAscii( "; " ) ) ) + break; + else + throw IllegalArgumentException( ); + getSym( ); + } + + // parse the rest + skipSpaces( ); + trailer(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::trailer( void ) +{ + while( m_nxtSym.getLength( ) ) + { + if ( m_nxtSym == OUString::createFromAscii( "(" ) ) + { + getSym( ); + comment( ); + acceptSym( OUString::createFromAscii( ")" ) ); + } + else if ( m_nxtSym == OUString::createFromAscii( ";" ) ) + { + // get the parameter name + getSym( ); + skipSpaces( ); + + if ( !isInRange( m_nxtSym, TOKEN ) ) + throw IllegalArgumentException( ); + + OUString pname = pName( ); + + skipSpaces(); + acceptSym( OUString::createFromAscii( "=" ) ); + + // get the parameter value + skipSpaces( ); + + OUString pvalue = pValue( ); + + // insert into map + if ( !m_ParameterMap.insert( pair < const OUString, OUString > ( pname, pvalue ) ).second ) + throw IllegalArgumentException( ); + } + else + throw IllegalArgumentException( ); + + skipSpaces( ); + } +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::pName( ) +{ + OUString pname; + + while( m_nxtSym.getLength( ) ) + { + if ( isInRange( m_nxtSym, TOKEN ) ) + pname += m_nxtSym; + else if ( isInRange( m_nxtSym, OUString::createFromAscii( "= " ) ) ) + break; + else + throw IllegalArgumentException( ); + getSym( ); + } + + return pname; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::pValue( ) +{ + OUString pvalue; + + // quoted pvalue + if ( m_nxtSym == OUString::createFromAscii( "\"" ) ) + { + getSym( ); + pvalue = quotedPValue( ); + + if ( OUString( &pvalue[pvalue.getLength() - 1], 1 ) != OUString::createFromAscii( "\"" ) ) + throw IllegalArgumentException( ); + + // remove the last quote-sign + OUString qpvalue( pvalue, pvalue.getLength( ) - 1 ); + pvalue = qpvalue; + + if ( !pvalue.getLength( ) ) + throw IllegalArgumentException( ); + } + else if ( isInRange( m_nxtSym, TOKEN ) ) // unquoted pvalue + { + pvalue = nonquotedPValue( ); + } + else + throw IllegalArgumentException( ); + + return pvalue; +} + +//------------------------------------------------------------------------ +// the following combinations within a quoted value are not allowed: +// '";' (quote sign followed by semicolon) and '" ' (quote sign followed +// by space) +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::quotedPValue( ) +{ + OUString pvalue; + sal_Bool bAfterQuoteSign = sal_False; + + while ( m_nxtSym.getLength( ) ) + { + if ( bAfterQuoteSign && ((m_nxtSym == SPACE)||(m_nxtSym == SEMICOLON) ) ) + break; + else if ( isInRange( m_nxtSym, TOKEN + TSPECIALS + SPACE ) ) + { + pvalue += m_nxtSym; + if ( m_nxtSym == OUString::createFromAscii( "\"" ) ) + bAfterQuoteSign = sal_True; + else + bAfterQuoteSign = sal_False; + } + else + throw IllegalArgumentException( ); + getSym( ); + } + + return pvalue; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CMimeContentType::nonquotedPValue( ) +{ + OUString pvalue; + + while ( m_nxtSym.getLength( ) ) + { + if ( isInRange( m_nxtSym, TOKEN ) ) + pvalue += m_nxtSym; + else if ( isInRange( m_nxtSym, OUString::createFromAscii( "; " ) ) ) + break; + else + throw IllegalArgumentException( ); + getSym( ); + } + + return pvalue; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CMimeContentType::comment( void ) +{ + while ( m_nxtSym.getLength( ) ) + { + if ( isInRange( m_nxtSym, TOKEN + SPACE ) ) + getSym( ); + else if ( m_nxtSym == OUString::createFromAscii( ")" ) ) + break; + else + throw IllegalArgumentException( ); + } +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CMimeContentType::isInRange( const rtl::OUString& aChr, const rtl::OUString& aRange ) +{ + return ( aRange.indexOf( aChr ) > -1 ); +} diff --git a/dtrans/source/cnttype/mcnttype.hxx b/dtrans/source/cnttype/mcnttype.hxx new file mode 100644 index 000000000000..f9b416b51de4 --- /dev/null +++ b/dtrans/source/cnttype/mcnttype.hxx @@ -0,0 +1,97 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _MCNTTYPE_HXX_ +#define _MCNTTYPE_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <cppuhelper/compbase1.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/datatransfer/XMimeContentType.hpp> + +#include <map> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +class CMimeContentType : public + cppu::WeakImplHelper1< com::sun::star::datatransfer::XMimeContentType > +{ +public: + CMimeContentType( const rtl::OUString& aCntType ); + + //------------------------------------------- + // XMimeContentType + //------------------------------------------- + + virtual ::rtl::OUString SAL_CALL getMediaType( ) throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getMediaSubtype( ) throw(::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getFullMediaType( ) throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getParameters( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL hasParameter( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getParameterValue( const ::rtl::OUString& aName ) + throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException); + +private: + void SAL_CALL init( const rtl::OUString& aCntType ) throw( com::sun::star::lang::IllegalArgumentException ); + void SAL_CALL getSym( void ); + void SAL_CALL acceptSym( const rtl::OUString& pSymTlb ); + void SAL_CALL skipSpaces( void ); + void SAL_CALL type( void ); + void SAL_CALL subtype( void ); + void SAL_CALL trailer( void ); + rtl::OUString SAL_CALL pName( ); + rtl::OUString SAL_CALL pValue( ); + rtl::OUString SAL_CALL quotedPValue( ); + rtl::OUString SAL_CALL nonquotedPValue( ); + void SAL_CALL comment( void ); + sal_Bool SAL_CALL isInRange( const rtl::OUString& aChr, const rtl::OUString& aRange ); + +private: + ::osl::Mutex m_aMutex; + rtl::OUString m_MediaType; + rtl::OUString m_MediaSubtype; + rtl::OUString m_ContentType; + std::map< rtl::OUString, rtl::OUString > m_ParameterMap; + sal_Int32 m_nPos; + rtl::OUString m_nxtSym; +}; + +#endif + diff --git a/dtrans/source/cnttype/mcnttype.xml b/dtrans/source/cnttype/mcnttype.xml new file mode 100644 index 000000000000..2a362699eec2 --- /dev/null +++ b/dtrans/source/cnttype/mcnttype.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> mcnttype </module-name> + <component-description> + <author> Tino Rachui </author> + <name> com.sun.star.comp.datatransfer.MimeContentTypeFactory </name> + <description> + The win32 implementation of the datatransfer service. +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.datatransfer.MimeContentTypeFactory </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.datatransfer.XMimeContentTypeFactory </type> + <type> com.sun.star.datatransfer.XMimeContentType </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.container.XSet </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/dtrans/source/cnttype/mctfentry.cxx b/dtrans/source/cnttype/mctfentry.cxx new file mode 100644 index 000000000000..3d2e41201887 --- /dev/null +++ b/dtrans/source/cnttype/mctfentry.cxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//----------------------------------------------------------------- +// includes of other projects +//----------------------------------------------------------------- +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> +#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp> +#include "mcnttfactory.hxx" + +//----------------------------------------------------------------- +// some defines +//----------------------------------------------------------------- + +// the service names +#define MIMECONTENTTYPEFACTORY_SERVICE_NAME "com.sun.star.datatransfer.MimeContentTypeFactory" + +// the implementation names +#define MIMECONTENTTYPEFACTORY_IMPL_NAME "com.sun.star.datatransfer.MimeCntTypeFactory" + +// the registry key names +// a key under which this service will be registered, Format: -> "/ImplName/UNO/SERVICES/ServiceName" +// < Implementation-Name ></UNO/SERVICES/>< Service-Name > +#define MIMECONTENTTYPEFACTORY_REGKEY_NAME "/com.sun.star.datatransfer.MimeCntTypeFactory/UNO/SERVICES/com.sun.star.datatransfer.MimeContentTypeFactory" + +//----------------------------------------------------------------------------------------------------------- +// namespace directives +//----------------------------------------------------------------------------------------------------------- + +using namespace ::rtl ; +using namespace ::cppu ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::registry ; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::datatransfer; + +//----------------------------------------------------------------- +// create a static object to initialize the shell9x library +//----------------------------------------------------------------- + +namespace +{ + + //----------------------------------------------------------------------------------------------------------- + // functions to create a new Clipboad instance; is needed by factory helper implementation + // @param rServiceManager - service manager, useful if the component needs other uno services + // so we should give it to every UNO-Implementation component + //----------------------------------------------------------------------------------------------------------- + + Reference< XInterface > SAL_CALL createInstance( const Reference< XMultiServiceFactory >& rServiceManager ) + { + return Reference< XInterface >( static_cast< XMimeContentTypeFactory* >( new CMimeContentTypeFactory( rServiceManager ) ) ); + } +} + +//----------------------------------------------------------------------------------------------------------- +// the 3 important functions which will be exported +//----------------------------------------------------------------------------------------------------------- + +extern "C" +{ + +//---------------------------------------------------------------------- +// component_getImplementationEnvironment +//---------------------------------------------------------------------- + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//---------------------------------------------------------------------- +// component_getFactory +// returns a factory to create XFilePicker-Services +//---------------------------------------------------------------------- + +void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* /*pRegistryKey*/ ) +{ + void* pRet = 0; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, MIMECONTENTTYPEFACTORY_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( MIMECONTENTTYPEFACTORY_SERVICE_NAME ) ); + + Reference< XSingleServiceFactory > xFactory ( createSingleFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createInstance, + aSNS ) ); + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +} // extern "C" diff --git a/dtrans/source/cnttype/wbench/makefile.mk b/dtrans/source/cnttype/wbench/makefile.mk new file mode 100644 index 000000000000..e154a5ac633e --- /dev/null +++ b/dtrans/source/cnttype/wbench/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=dtrans +TARGET=testcnttype +LIBTARGET=NO +TARGETTYPE=CUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-GX + +# --- Files -------------------------------------------------------- + +OBJFILES= $(OBJ)$/testcnttype.obj +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJ)$/testcnttype.obj + +APP1STDLIBS= $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk + diff --git a/dtrans/source/cnttype/wbench/testcnttype.cxx b/dtrans/source/cnttype/wbench/testcnttype.cxx new file mode 100644 index 000000000000..ff3587ee22e6 --- /dev/null +++ b/dtrans/source/cnttype/wbench/testcnttype.cxx @@ -0,0 +1,269 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +//_________________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________________ +#include <cppuhelper/servicefactory.hxx> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/container/NoSuchElementException.hpp> +#include <com/sun/star/datatransfer/XMimeContentType.hpp> +#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <osl/diagnose.h> + +#include <stdio.h> + +#include <vector> + +//------------------------------------------------------------- +// my defines +//------------------------------------------------------------- + +#define TEST_CLIPBOARD +#define RDB_SYSPATH "d:\\projects\\src621\\dtrans\\wntmsci7\\bin\\applicat.rdb" + +//------------------------------------------------------------ +// namesapces +//------------------------------------------------------------ + +using namespace ::rtl; +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::container; + +//------------------------------------------------------------ +// globales +//------------------------------------------------------------ + +//################################################################ + +/* +void CheckMimeContentType( const OUString& aCntType, const OUString& aType, const OUString& aSubtype, sal_Int32 nParams ) +{ + + Reference< XMimeContentType > xMimeCntType = xMCntTypeFactory->createMimeContentType( aCntType ); + + OSL_ASSERT( aType == xMimeCntType->getMediaType ( ) ); + OSL_ASSERT( aSubtype == xMimeCntType->getMediaSubtype ( ) ); + + try + { + Sequence< OUString > seqParam = xMimeCntType->getParameters( ); + OSL_ASSERT( seqParam.getLength( ) == nParams ); + + OUString param; + OUString pvalue; + for ( sal_Int32 i = 0; i < seqParam.getLength( ); i++ ) + { + param = seqParam[i]; + OSL_ASSERT( xMimeCntType->hasParameter( param ) ); + + pvalue = xMimeCntType->getParameterValue( param ); + } + + pvalue = xMimeCntType->getParameterValue( OUString::createFromAscii( "aparam" ) ); + } + catch( IllegalArgumentException& ) + { + printf( "FAILED: Invalid Mime Contenttype detected\n" ); + } + catch( NoSuchElementException& ) + { + + } +} +*/ + +//---------------------------------------------------------------- +// +//---------------------------------------------------------------- + +void ShutdownServiceMgr( Reference< XMultiServiceFactory >& SrvMgr ) +{ + // Cast factory to XComponent + Reference< XComponent > xComponent( SrvMgr, UNO_QUERY ); + + if ( !xComponent.is() ) + OSL_ENSURE(sal_False, "Error shuting down"); + + // Dispose and clear factory + xComponent->dispose(); + SrvMgr.clear(); + SrvMgr = Reference< XMultiServiceFactory >(); +} + +//---------------------------------------------------------------- +// +//---------------------------------------------------------------- + +sal_Bool readCntTypesFromFileIntoVector( char* fname, vector< string >& vecData ) +{ + FILE* fstream; + + fstream = fopen( fname, "r+" ); + if ( !fstream ) + return sal_False; + + // set pointer to file start + fseek( fstream, 0L, SEEK_SET ); + + char line[1024]; + while ( fscanf( fstream, "%[^\n]s", line ) != EOF ) + { + vecData.push_back( line ); + fgetc( fstream ); + } + + fclose( fstream ); + + return sal_True; +} + +//---------------------------------------------------------------- +// +//---------------------------------------------------------------- + +sal_Bool processCntTypesAndWriteResultIntoFile( char* fname, vector< string >& vecData, Reference< XMimeContentTypeFactory > cnttypeFactory ) +{ + FILE* fstream; + + fstream = fopen( fname, "w" ); + if ( !fstream ) + return sal_False; + + // set pointer to file start + fseek( fstream, 0L, SEEK_SET ); + + vector< string >::iterator iter_end = vecData.end( ); + const char* pStr = NULL; + + for ( vector< string >::iterator iter = vecData.begin( ); iter != iter_end; ++iter ) + { + try + { + fprintf( fstream, "Gelesen: %s\n", iter->c_str( ) ); + + Reference< XMimeContentType > xMCntTyp = cnttypeFactory->createMimeContentType( OUString::createFromAscii( iter->c_str( ) ) ); + + fwprintf( fstream, OUString::createFromAscii( "Type: %s\n" ), xMCntTyp->getMediaType( ).getStr( ) ); + fwprintf( fstream, OUString::createFromAscii( "Subtype: %s\n" ), xMCntTyp->getMediaSubtype( ).getStr( ) ); + + Sequence< OUString > seqParam = xMCntTyp->getParameters( ); + sal_Int32 nParams = seqParam.getLength( ); + + for ( sal_Int32 i = 0; i < nParams; i++ ) + { + fwprintf( fstream, OUString::createFromAscii("PName: %s\n" ), seqParam[i].getStr( ) ); + fwprintf( fstream, OUString::createFromAscii("PValue: %s\n" ), xMCntTyp->getParameterValue( seqParam[i] ).getStr( ) ); + } + } + catch( IllegalArgumentException& ex ) + { + fwprintf( fstream, OUString::createFromAscii( "Fehlerhafter Content-Type gelesen!!!\n\n" ) ); + } + catch( NoSuchElementException& ) + { + fwprintf( fstream, OUString::createFromAscii( "Parameterwert nicht vorhanden\n" ) ); + } + catch( ... ) + { + fwprintf( fstream, OUString::createFromAscii( "Unbekannter Fehler!!!\n\n" ) ); + } + + fwprintf( fstream, OUString::createFromAscii( "\n#############################################\n\n" ) ); + } + + fclose( fstream ); + + return sal_True; +} + +//---------------------------------------------------------------- +// main +//---------------------------------------------------------------- + +int SAL_CALL main( int nArgc, char* argv[] ) +{ + if ( nArgc != 3 ) + printf( "Start with: testcnttype input-file output-file\n" ); + + //------------------------------------------------- + // get the global service-manager + //------------------------------------------------- + OUString rdbName = OUString( RTL_CONSTASCII_USTRINGPARAM( RDB_SYSPATH ) ); + Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( rdbName ) ); + + // Print a message if an error occured. + if ( !g_xFactory.is( ) ) + { + OSL_ENSURE(sal_False, "Can't create RegistryServiceFactory"); + return(-1); + } + + vector< string > vecCntTypes; + + // open input-file and read the data + if ( !readCntTypesFromFileIntoVector( argv[1], vecCntTypes ) ) + { + printf( "Can't open input file" ); + ShutdownServiceMgr( g_xFactory ); + } + + Reference< XMimeContentTypeFactory > + xMCntTypeFactory( g_xFactory->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.MimeContentTypeFactory" ) ), UNO_QUERY ); + + if ( !xMCntTypeFactory.is( ) ) + { + OSL_ENSURE( sal_False, "Error creating MimeContentTypeFactory Service" ); + return(-1); + } + + if ( !processCntTypesAndWriteResultIntoFile( argv[2], vecCntTypes, xMCntTypeFactory ) ) + { + printf( "Can't open output file" ); + ShutdownServiceMgr( g_xFactory ); + } + + //-------------------------------------------------- + // shutdown the service manager + //-------------------------------------------------- + + ShutdownServiceMgr( g_xFactory ); + + return 0; +} diff --git a/dtrans/source/generic/clipboardmanager.cxx b/dtrans/source/generic/clipboardmanager.cxx new file mode 100644 index 000000000000..49b5cde947f7 --- /dev/null +++ b/dtrans/source/generic/clipboardmanager.cxx @@ -0,0 +1,266 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +#include <clipboardmanager.hxx> +#include <com/sun/star/lang/DisposedException.hpp> + +using namespace com::sun::star::container; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace cppu; +using namespace osl; +using namespace std; + +using ::dtrans::ClipboardManager; +using ::rtl::OUString; + +// ------------------------------------------------------------------------ + +ClipboardManager::ClipboardManager(): + WeakComponentImplHelper3< XClipboardManager, XEventListener, XServiceInfo > (m_aMutex), + m_aDefaultName(OUString::createFromAscii("default")) +{ +} + +// ------------------------------------------------------------------------ + +ClipboardManager::~ClipboardManager() +{ +} + +// ------------------------------------------------------------------------ + +OUString SAL_CALL ClipboardManager::getImplementationName( ) + throw(RuntimeException) +{ + return OUString::createFromAscii(CLIPBOARDMANAGER_IMPLEMENTATION_NAME); +} + +// ------------------------------------------------------------------------ + +sal_Bool SAL_CALL ClipboardManager::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + Sequence < OUString > SupportedServicesNames = ClipboardManager_getSupportedServiceNames(); + + for ( sal_Int32 n = 0, nmax = SupportedServicesNames.getLength(); n < nmax; n++ ) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------------------------------ + +Sequence< OUString > SAL_CALL ClipboardManager::getSupportedServiceNames( ) + throw(RuntimeException) +{ + return ClipboardManager_getSupportedServiceNames(); +} + +// ------------------------------------------------------------------------ + +Reference< XClipboard > SAL_CALL ClipboardManager::getClipboard( const OUString& aName ) + throw(NoSuchElementException, RuntimeException) +{ + MutexGuard aGuard(m_aMutex); + + // object is disposed already + if (rBHelper.bDisposed) + throw DisposedException(OUString::createFromAscii("object is disposed."), + static_cast < XClipboardManager * > (this)); + + ClipboardMap::iterator iter = + m_aClipboardMap.find(aName.getLength() ? aName : m_aDefaultName); + + if (iter != m_aClipboardMap.end()) + return iter->second; + + throw NoSuchElementException(aName, static_cast < XClipboardManager * > (this)); +} + +// ------------------------------------------------------------------------ + +void SAL_CALL ClipboardManager::addClipboard( const Reference< XClipboard >& xClipboard ) + throw(IllegalArgumentException, ElementExistException, RuntimeException) +{ + OSL_ASSERT(xClipboard.is()); + + // check parameter + if (!xClipboard.is()) + throw IllegalArgumentException(OUString::createFromAscii("empty reference"), + static_cast < XClipboardManager * > (this), 1); + + // the name "default" is reserved for internal use + OUString aName = xClipboard->getName(); + if (m_aDefaultName.compareTo(aName) == 0) + throw IllegalArgumentException(OUString::createFromAscii("name reserved"), + static_cast < XClipboardManager * > (this), 1); + + // try to add new clipboard to the list + ClearableMutexGuard aGuard(m_aMutex); + if (!rBHelper.bDisposed && !rBHelper.bInDispose) + { + pair< const OUString, Reference< XClipboard > > value ( + aName.getLength() ? aName : m_aDefaultName, + xClipboard ); + + pair< ClipboardMap::iterator, bool > p = m_aClipboardMap.insert(value); + aGuard.clear(); + + // insert failed, element must exist already + if (!p.second) + throw ElementExistException(aName, static_cast < XClipboardManager * > (this)); + + // request disposing notifications + Reference< XComponent > xComponent(xClipboard, UNO_QUERY); + if (xComponent.is()) + xComponent->addEventListener(static_cast < XEventListener * > (this)); + } +} + +// ------------------------------------------------------------------------ + +void SAL_CALL ClipboardManager::removeClipboard( const OUString& aName ) + throw(RuntimeException) +{ + MutexGuard aGuard(m_aMutex); + if (!rBHelper.bDisposed) + m_aClipboardMap.erase(aName.getLength() ? aName : m_aDefaultName ); +} + +// ------------------------------------------------------------------------ + +Sequence< OUString > SAL_CALL ClipboardManager::listClipboardNames() + throw(RuntimeException) +{ + MutexGuard aGuard(m_aMutex); + + if (rBHelper.bDisposed) + throw DisposedException(OUString::createFromAscii("object is disposed."), + static_cast < XClipboardManager * > (this)); + + if (rBHelper.bInDispose) + return Sequence< OUString > (); + + Sequence< OUString > aRet(m_aClipboardMap.size()); + ClipboardMap::iterator iter = m_aClipboardMap.begin(); + ClipboardMap::iterator imax = m_aClipboardMap.end(); + + for (sal_Int32 n = 0; iter != imax; iter++) + aRet[n++] = iter->first; + + return aRet; +} + +// ------------------------------------------------------------------------ + +void SAL_CALL ClipboardManager::dispose() + throw(RuntimeException) +{ + ClearableMutexGuard aGuard( rBHelper.rMutex ); + if (!rBHelper.bDisposed && !rBHelper.bInDispose) + { + rBHelper.bInDispose = sal_True; + aGuard.clear(); + + // give everyone a chance to save his clipboard instance + EventObject aEvt(static_cast < XClipboardManager * > (this)); + rBHelper.aLC.disposeAndClear( aEvt ); + + // removeClipboard is still allowed here, so make a copy of the + // list (to ensure integrety) and clear the original. + ClearableMutexGuard aGuard2( rBHelper.rMutex ); + ClipboardMap aCopy(m_aClipboardMap); + m_aClipboardMap.clear(); + aGuard2.clear(); + + // dispose all clipboards still in list + ClipboardMap::iterator iter = aCopy.begin(); + ClipboardMap::iterator imax = aCopy.end(); + + for (; iter != imax; iter++) + { + Reference< XComponent > xComponent(iter->second, UNO_QUERY); + if (xComponent.is()) + { + try + { + xComponent->removeEventListener(static_cast < XEventListener * > (this)); + xComponent->dispose(); + } + + catch(Exception e) + { + // exceptions can be safely ignored here. + } + } + } + + rBHelper.bDisposed = sal_True; + rBHelper.bInDispose = sal_False; + } +} + +// ------------------------------------------------------------------------ + +void SAL_CALL ClipboardManager::disposing( const EventObject& event ) + throw(RuntimeException) +{ + Reference < XClipboard > xClipboard(event.Source, UNO_QUERY); + + if (xClipboard.is()) + removeClipboard(xClipboard->getName()); +} + +// ------------------------------------------------------------------------ + +Reference< XInterface > SAL_CALL ClipboardManager_createInstance( + const Reference< XMultiServiceFactory > & /*xMultiServiceFactory*/) +{ + return Reference < XInterface >( ( OWeakObject * ) new ClipboardManager()); +} + +// ------------------------------------------------------------------------ + +Sequence< OUString > SAL_CALL ClipboardManager_getSupportedServiceNames() +{ + Sequence < OUString > SupportedServicesNames( 1 ); + SupportedServicesNames[0] = + OUString::createFromAscii("com.sun.star.datatransfer.clipboard.ClipboardManager"); + return SupportedServicesNames; +} + + + + + diff --git a/dtrans/source/generic/clipboardmanager.hxx b/dtrans/source/generic/clipboardmanager.hxx new file mode 100644 index 000000000000..0429c7640ed7 --- /dev/null +++ b/dtrans/source/generic/clipboardmanager.hxx @@ -0,0 +1,127 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DTRANS_CLIPBOARDMANAGER_HXX_ +#define _DTRANS_CLIPBOARDMANAGER_HXX_ + +#include <cppuhelper/compbase3.hxx> + +#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBAORD_XCLIPBOARDMANAGER_HPP_ +#include <com/sun/star/datatransfer/clipboard/XClipboardManager.hpp> +#endif +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <map> + +// ------------------------------------------------------------------------ + +#define CLIPBOARDMANAGER_IMPLEMENTATION_NAME "com.sun.star.comp.datatransfer.ClipboardManager" + +// ------------------------------------------------------------------------ + +typedef ::std::map< ::rtl::OUString, ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard > > ClipboardMap; + +// ------------------------------------------------------------------------ + +namespace dtrans +{ + + class ClipboardManager : public ::cppu::WeakComponentImplHelper3 < \ + ::com::sun::star::datatransfer::clipboard::XClipboardManager, \ + ::com::sun::star::lang::XEventListener, \ + ::com::sun::star::lang::XServiceInfo > + { + ClipboardMap m_aClipboardMap; + ::osl::Mutex m_aMutex; + + const ::rtl::OUString m_aDefaultName; + + virtual ~ClipboardManager(); + protected: + using WeakComponentImplHelperBase::disposing; + public: + + ClipboardManager(); + + /* + * XServiceInfo + */ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException); + + /* + * XComponent + */ + + virtual void SAL_CALL dispose() + throw(::com::sun::star::uno::RuntimeException); + + /* + * XEventListener + */ + + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw(::com::sun::star::uno::RuntimeException); + + /* + * XClipboardManager + */ + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard > SAL_CALL getClipboard( const ::rtl::OUString& aName ) + throw(::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL addClipboard( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard >& xClipboard ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::ElementExistException, + ::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removeClipboard( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL listClipboardNames( ) + throw(::com::sun::star::uno::RuntimeException); + + + }; + +} + +// ------------------------------------------------------------------------ + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL ClipboardManager_getSupportedServiceNames(); +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ClipboardManager_createInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xMultiServiceFactory); + +#endif diff --git a/dtrans/source/generic/dtrans.component b/dtrans/source/generic/dtrans.component new file mode 100644 index 000000000000..69034f716907 --- /dev/null +++ b/dtrans/source/generic/dtrans.component @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.datatransfer.ClipboardManager"> + <service name="com.sun.star.datatransfer.clipboard.ClipboardManager"/> + </implementation> + <implementation name="com.sun.star.comp.datatransfer.clipboard.GenericClipboard"> + <service name="com.sun.star.datatransfer.clipboard.GenericClipboard"/> + </implementation> +</component> diff --git a/dtrans/source/generic/dtrans.cxx b/dtrans/source/generic/dtrans.cxx new file mode 100644 index 000000000000..4b39298f97c2 --- /dev/null +++ b/dtrans/source/generic/dtrans.cxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +#include <cppuhelper/factory.hxx> +#include <clipboardmanager.hxx> +#include <generic_clipboard.hxx> + +using namespace com::sun::star::lang; +using namespace com::sun::star::registry; +using namespace com::sun::star::uno; +using namespace cppu; +using namespace rtl; + +extern "C" +{ + +//================================================================================================== + +void SAL_CALL component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName, + uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//================================================================================================== + +void * SAL_CALL component_getFactory( + const sal_Char * pImplName, + void * pServiceManager, + void * /*pRegistryKey*/ +) +{ + void * pRet = 0; + + if (pServiceManager) + { + Reference< XSingleServiceFactory > xFactory; + + if (rtl_str_compare( pImplName, CLIPBOARDMANAGER_IMPLEMENTATION_NAME ) == 0) + { + xFactory = createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + ClipboardManager_createInstance, + ClipboardManager_getSupportedServiceNames() ); + } + else if (rtl_str_compare( pImplName, GENERIC_CLIPBOARD_IMPLEMENTATION_NAME ) == 0) + { + xFactory = createSingleFactory( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ), + OUString::createFromAscii( pImplName ), + GenericClipboard_createInstance, + GenericClipboard_getSupportedServiceNames() ); + } + + if (xFactory.is()) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +} diff --git a/dtrans/source/generic/dtrans.xml b/dtrans/source/generic/dtrans.xml new file mode 100644 index 000000000000..58ae60cae7c6 --- /dev/null +++ b/dtrans/source/generic/dtrans.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> + +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> dtrans </module-name> + <component-description> + <author> Oliver Braun </author> + <name> com.sun.star.comp.datatransfer.generic </name> + <description> This module includes a generic clipboard implementation </description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.datatransfer.clipboard.GenericClipboard </supported-service> + <supported-service> com.sun.star.datatransfer.clipboard.ClipboardManager </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.datatransfer.clipboard.RenderingCapabilities </type> + <type> com.sun.star.datatransfer.clipboard.XClipboardEx </type> + <type> com.sun.star.datatransfer.clipboard.XClipboardManager </type> + <type> com.sun.star.datatransfer.clipboard.XClipboardNotifier </type> + <type> com.sun.star.datatransfer.XTransferableEx </type> + <type> com.sun.star.datatransfer.XTransferableSource </type> + <type> com.sun.star.io.XOutputStream </type> + <type> com.sun.star.lang.DisposedException </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleComponentFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XComponentContext </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/dtrans/source/generic/exports.dxp b/dtrans/source/generic/exports.dxp new file mode 100644 index 000000000000..f0e1c69934bc --- /dev/null +++ b/dtrans/source/generic/exports.dxp @@ -0,0 +1,2 @@ +component_getImplementationEnvironment +component_getFactory diff --git a/dtrans/source/generic/generic_clipboard.cxx b/dtrans/source/generic/generic_clipboard.cxx new file mode 100644 index 000000000000..046632d82bf8 --- /dev/null +++ b/dtrans/source/generic/generic_clipboard.cxx @@ -0,0 +1,205 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +#include <generic_clipboard.hxx> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> + +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace cppu; +using namespace osl; + +using ::dtrans::GenericClipboard; +using ::rtl::OUString; + +GenericClipboard::GenericClipboard() : + WeakComponentImplHelper4< XClipboardEx, XClipboardNotifier, XServiceInfo, XInitialization > (m_aMutex), + m_bInitialized(sal_False) +{ +} + +// ------------------------------------------------------------------------ + +GenericClipboard::~GenericClipboard() +{ +} + +// ------------------------------------------------------------------------ + +void SAL_CALL GenericClipboard::initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException) +{ + if (!m_bInitialized) + { + for (sal_Int32 n = 0, nmax = aArguments.getLength(); n < nmax; n++) + if (aArguments[n].getValueType() == getCppuType((OUString *) 0)) + { + aArguments[0] >>= m_aName; + break; + } + } +} + +// ------------------------------------------------------------------------ + +OUString SAL_CALL GenericClipboard::getImplementationName( ) + throw(RuntimeException) +{ + return OUString::createFromAscii(GENERIC_CLIPBOARD_IMPLEMENTATION_NAME); +} + +// ------------------------------------------------------------------------ + +sal_Bool SAL_CALL GenericClipboard::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + Sequence < OUString > SupportedServicesNames = GenericClipboard_getSupportedServiceNames(); + + for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------------------------------ + +Sequence< OUString > SAL_CALL GenericClipboard::getSupportedServiceNames( ) + throw(RuntimeException) +{ + return GenericClipboard_getSupportedServiceNames(); +} + +// ------------------------------------------------------------------------ + +Reference< XTransferable > SAL_CALL GenericClipboard::getContents() + throw(RuntimeException) +{ + MutexGuard aGuard(m_aMutex); + return m_aContents; +} + +// ------------------------------------------------------------------------ + +void SAL_CALL GenericClipboard::setContents(const Reference< XTransferable >& xTrans, + const Reference< XClipboardOwner >& xClipboardOwner ) + throw(RuntimeException) +{ + // remember old values for callbacks before setting the new ones. + ClearableMutexGuard aGuard(m_aMutex); + + Reference< XClipboardOwner > oldOwner(m_aOwner); + m_aOwner = xClipboardOwner; + + Reference< XTransferable > oldContents(m_aContents); + m_aContents = xTrans; + + aGuard.clear(); + + // notify old owner on loss of ownership + if( oldOwner.is() ) + oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents); + + // notify all listeners on content changes + OInterfaceContainerHelper *pContainer = + rBHelper.aLC.getContainer(getCppuType( (Reference < XClipboardListener > *) 0)); + if (pContainer) + { + ClipboardEvent aEvent(static_cast < XClipboard * > (this), m_aContents); + OInterfaceIteratorHelper aIterator(*pContainer); + + while (aIterator.hasMoreElements()) + { + Reference < XClipboardListener > xListener(aIterator.next(), UNO_QUERY); + if (xListener.is()) + xListener->changedContents(aEvent); + } + } +} + +// ------------------------------------------------------------------------ + +OUString SAL_CALL GenericClipboard::getName() + throw(RuntimeException) +{ + return m_aName; +} + +// ------------------------------------------------------------------------ + +sal_Int8 SAL_CALL GenericClipboard::getRenderingCapabilities() + throw(RuntimeException) +{ + return RenderingCapabilities::Delayed; +} + + +// ------------------------------------------------------------------------ + +void SAL_CALL GenericClipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) + throw(RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSURE( !rBHelper.bInDispose, "do not add listeners in the dispose call" ); + OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); + if (!rBHelper.bInDispose && !rBHelper.bDisposed) + rBHelper.aLC.addInterface( getCppuType( (const ::com::sun::star::uno::Reference< XClipboardListener > *) 0), listener ); +} + +// ------------------------------------------------------------------------ + +void SAL_CALL GenericClipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) + throw(RuntimeException) +{ + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); + if (!rBHelper.bInDispose && !rBHelper.bDisposed) + rBHelper.aLC.removeInterface( getCppuType( (const Reference< XClipboardListener > *) 0 ), listener ); \ +} + +// ------------------------------------------------------------------------ + +Sequence< OUString > SAL_CALL GenericClipboard_getSupportedServiceNames() +{ + Sequence< OUString > aRet(1); + aRet[0] = OUString::createFromAscii("com.sun.star.datatransfer.clipboard.GenericClipboard"); + return aRet; +} + +// ------------------------------------------------------------------------ + +Reference< XInterface > SAL_CALL GenericClipboard_createInstance( + const Reference< XMultiServiceFactory > & /*xMultiServiceFactory*/) +{ + return Reference < XInterface >( ( OWeakObject * ) new GenericClipboard()); +} diff --git a/dtrans/source/generic/generic_clipboard.hxx b/dtrans/source/generic/generic_clipboard.hxx new file mode 100644 index 000000000000..54308b0a1bdd --- /dev/null +++ b/dtrans/source/generic/generic_clipboard.hxx @@ -0,0 +1,135 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DTRANS_GENERIC_CLIPBOARD_HXX_ +#define _DTRANS_GENERIC_CLIPBOARD_HXX_ + +#include <cppuhelper/compbase4.hxx> + +#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBAORD_XCLIPBOARDEX_HPP_ +#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#endif + +#ifndef _COM_SUN_STAR_DATATRANSFER_CLIPBAORD_XCLIPBOARDNOTIFIER_HPP_ +#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#endif +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +// ------------------------------------------------------------------------ + +#define GENERIC_CLIPBOARD_IMPLEMENTATION_NAME "com.sun.star.comp.datatransfer.clipboard.GenericClipboard" + +// ------------------------------------------------------------------------ + +namespace dtrans +{ + + class GenericClipboard : public ::cppu::WeakComponentImplHelper4 < \ + ::com::sun::star::datatransfer::clipboard::XClipboardEx, \ + ::com::sun::star::datatransfer::clipboard::XClipboardNotifier, \ + ::com::sun::star::lang::XServiceInfo, \ + ::com::sun::star::lang::XInitialization > + { + ::osl::Mutex m_aMutex; + ::rtl::OUString m_aName; + + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > m_aContents; + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner > m_aOwner; + + sal_Bool m_bInitialized; + virtual ~GenericClipboard(); + + public: + + GenericClipboard(); + + /* + * XInitialization + */ + + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + /* + * XServiceInfo + */ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException); + + /* + * XClipboard + */ + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > SAL_CALL getContents() + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setContents( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& xTrans, + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getName() + throw(::com::sun::star::uno::RuntimeException); + + /* + * XClipboardEx + */ + + virtual sal_Int8 SAL_CALL getRenderingCapabilities() + throw(::com::sun::star::uno::RuntimeException); + + /* + * XClipboardNotifier + */ + + virtual void SAL_CALL addClipboardListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removeClipboardListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener ) + throw(::com::sun::star::uno::RuntimeException); + + }; + +} + +// ------------------------------------------------------------------------ + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL GenericClipboard_getSupportedServiceNames(); +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL GenericClipboard_createInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xMultiServiceFactory); + +#endif diff --git a/dtrans/source/generic/makefile.mk b/dtrans/source/generic/makefile.mk new file mode 100644 index 000000000000..2518b86a2d92 --- /dev/null +++ b/dtrans/source/generic/makefile.mk @@ -0,0 +1,75 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=dtrans +TARGET=generic +ENABLE_EXCEPTIONS=TRUE +LIBTARGET=NO +COMP1TYPELIST=dtrans + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.IF "$(L10N_framework)"=="" +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/generic_clipboard.obj \ + $(SLO)$/clipboardmanager.obj \ + $(SLO)$/dtrans.obj + +SHL1TARGET= dtrans + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map + +SHL1STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(SHL1TARGET) +SHL1OBJS= $(SLOFILES) +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + +# --- Targets ------------------------------------------------------ +.ENDIF # L10N_framework + +.INCLUDE : target.mk + +ALLTAR : $(MISC)/dtrans.component + +$(MISC)/dtrans.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + dtrans.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt dtrans.component diff --git a/dtrans/source/inc/DtObjFactory.hxx b/dtrans/source/inc/DtObjFactory.hxx new file mode 100644 index 000000000000..fc217e6d5982 --- /dev/null +++ b/dtrans/source/inc/DtObjFactory.hxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _DTOBJFACTORY_HXX_ +#define _DTOBJFACTORY_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <cppuhelper/servicefactory.hxx> + +#include <systools/win32/comtools.hxx> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +class CDTransObjFactory +{ +public: + virtual IDataObjectPtr SAL_CALL createDataObjFromTransferable( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager, + const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& refXTransferable ); + virtual com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > SAL_CALL createTransferableFromDataObj( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager, IDataObjectPtr pIDataObject ); +}; + +#endif diff --git a/dtrans/source/inc/MtaOleClipb.hxx b/dtrans/source/inc/MtaOleClipb.hxx new file mode 100644 index 000000000000..03facb73d18f --- /dev/null +++ b/dtrans/source/inc/MtaOleClipb.hxx @@ -0,0 +1,134 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _MTAOLECLIPB_HXX_ +#define _MTAOLECLIPB_HXX_ + +#include <sal/types.h> +#include <osl/mutex.hxx> + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <objidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//-------------------------------------------------------- +// the Mta-Ole clipboard class is for internal use only! +// only one instance of this class should be created, the +// user has to ensure this! +// the class is not thread-safe because it will be used +// only from within the clipboard service and the methods +// of the clipboard service are already synchronized +//-------------------------------------------------------- + +class CMtaOleClipboard +{ +public: + typedef void ( WINAPI *LPFNC_CLIPVIEWER_CALLBACK_t )( void ); + +public: + CMtaOleClipboard( ); + ~CMtaOleClipboard( ); + + // clipboard functions + HRESULT setClipboard( IDataObject* pIDataObject ); + HRESULT getClipboard( IDataObject** ppIDataObject ); + HRESULT flushClipboard( ); + + // register/unregister a clipboard viewer; there can only + // be one at a time; parameter NULL means unregister + // a clipboard viewer + // returns true on success else false; use GetLastError( ) in + // false case + sal_Bool registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback ); + +private: + unsigned int run( ); + + // create a hidden windows which serves as an request + // target; so we guarantee synchronization + void createMtaOleReqWnd( ); + + // message support + sal_Bool postMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 ); + LRESULT sendMessage( UINT msg, WPARAM wParam = 0, LPARAM lParam = 0 ); + + //--------------------------------------------------------------- + // message handler functions; remeber these functions are called + // from a different thread context! + //--------------------------------------------------------------- + + LRESULT onSetClipboard( IDataObject* pIDataObject ); + LRESULT onGetClipboard( LPSTREAM* ppStream ); + LRESULT onFlushClipboard( ); + sal_Bool onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback ); + + // win32 clipboard-viewer support + LRESULT onChangeCBChain( HWND hWndRemove, HWND hWndNext ); + LRESULT onDrawClipboard( ); + + static LRESULT CALLBACK mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + static unsigned int WINAPI oleThreadProc( LPVOID pParam ); + + static unsigned int WINAPI clipboardChangedNotifierThreadProc( LPVOID pParam ); + + sal_Bool WaitForThreadReady( ) const; + +private: + HANDLE m_hOleThread; + unsigned m_uOleThreadId; + HANDLE m_hEvtThrdReady; + HWND m_hwndMtaOleReqWnd; + ATOM m_MtaOleReqWndClassAtom; + HWND m_hwndNextClipViewer; + LPFNC_CLIPVIEWER_CALLBACK_t m_pfncClipViewerCallback; + sal_Bool m_bInRegisterClipViewer; + + sal_Bool m_bRunClipboardNotifierThread; + HANDLE m_hClipboardChangedNotifierThread; + HANDLE m_hClipboardChangedNotifierEvents[2]; + HANDLE& m_hClipboardChangedEvent; + HANDLE& m_hTerminateClipboardChangedNotifierEvent; + osl::Mutex m_ClipboardChangedEventCountMutex; + sal_Int32 m_ClipboardChangedEventCount; + + osl::Mutex m_pfncClipViewerCallbackMutex; + + static CMtaOleClipboard* s_theMtaOleClipboardInst; + +// not allowed +private: + CMtaOleClipboard( const CMtaOleClipboard& ); + CMtaOleClipboard& operator=( const CMtaOleClipboard& ); + + friend LRESULT CALLBACK mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); +}; + +#endif diff --git a/dtrans/source/os2/clipb/OS2Bitmap.cxx b/dtrans/source/os2/clipb/OS2Bitmap.cxx new file mode 100644 index 000000000000..53b78c7afaef --- /dev/null +++ b/dtrans/source/os2/clipb/OS2Bitmap.cxx @@ -0,0 +1,248 @@ +/************************************************************************* + * + * This code is property of Serenity Systems Intl + * All rights reserverd. + * + ************************************************************************/ + +#define INCL_WIN +#include <svpm.h> + +#ifndef _OS2CLIPBOARD_HXX_ +#include "Os2Clipboard.hxx" +#endif + +// same typedefs from win32 sdk +typedef unsigned short WORD; +typedef unsigned long DWORD; + +#pragma pack(push, 1) + +typedef struct { + PM_BYTE rgbBlue; + PM_BYTE rgbGreen; + PM_BYTE rgbRed; + PM_BYTE rgbReserved; +} RGBQUAD, *LPRGBQUAD; + +typedef struct +{ + WORD bfType; + DWORD bfSize; + WORD bfReserved1; + WORD bfReserved2; + DWORD bfOffBits; +} W32_BITMAPFILEHEADER, *PW32_BITMAPFILEHEADER; + +typedef struct +{ + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +} W32_BITMAPINFOHEADER, *PW32_BITMAPINFOHEADER; + +#pragma pack(pop) + +// store screen bitcount +LONG lBitCountScreen; + +/* + * Convert an OOo bitmap to an OS/2 bitmap handle + * + * An OOo bitmap is a BITMAPFILEHEADER structure followed by a Windows DIB + * + * OS/2 InfoHeader is a superset of Win32 InhoHeader, so we can just copy + * the win32 memory over the os2 memory and fix the cbFix field. + * colortable and bitmap data share the same format. + * +*/ +HBITMAP OOoBmpToOS2Handle( Any &aAnyB) +{ + // copy bitmap to clipboard + Sequence<sal_Int8> ByteStream; + aAnyB >>= ByteStream; + + // get w32 file header data + PW32_BITMAPFILEHEADER pbfh = (PW32_BITMAPFILEHEADER)ByteStream.getArray(); + // get w32 info header + PW32_BITMAPINFOHEADER pbih = (PW32_BITMAPINFOHEADER) (pbfh+1); + + // create os2 infoheader2 (same fields of w32) + BITMAPINFOHEADER2 bih2; + memset( &bih2, 0, sizeof( bih2)); + memcpy( &bih2, pbih, pbih->biSize); + bih2.cbFix = sizeof(bih2); + + // Determine size of color table + int iNumColors, numbits=bih2.cPlanes * bih2.cBitCount; + if (numbits != 24) + iNumColors = bih2.cclrUsed ? bih2.cclrUsed : 2<<numbits; + else + iNumColors = bih2.cclrUsed; + int iColorTableSize = iNumColors*sizeof(RGB2); + + // allocate bitmap info2 (header2+colortable) + PBITMAPINFO2 pbi2=(PBITMAPINFO2) malloc( sizeof(BITMAPINFOHEADER2)+iColorTableSize); + // setup header fields + memcpy( pbi2, &bih2, sizeof(BITMAPINFOHEADER2)); + // copy color palette (follows pbih) + memcpy( &pbi2->argbColor[0], (pbih+1), iColorTableSize); + + // get bitmap data + PBYTE pbPelData = (PBYTE)ByteStream.getArray() + pbfh->bfOffBits; + HPS hps = WinGetPS(HWND_DESKTOP); + HBITMAP hbm = GpiCreateBitmap( hps, &bih2, CBM_INIT, pbPelData, pbi2); + debug_printf( "OOoBmpToOS2Handle hbm %x\n", hbm); + WinReleasePS(hps); + + // return handle + return hbm; +} + +/* + * Convert an OS/2 bitmap handle to OOo bitmap + * + * First we need to copy the bitmap to a PS, then we can get bitmap data. + * +*/ +int OS2HandleToOOoBmp( HBITMAP hbm, Sequence< sal_Int8 >* OOoDIBStream) +{ + HAB hab = WinQueryAnchorBlock(HWND_DESKTOP); + HDC hdc; + SIZEL sizl; + HPS hps; + PM_BYTE* pbBuffer; + ULONG cbBuffer; + + struct { + BITMAPINFOHEADER2 bmp2; + RGB2 argb2Color[0x100]; + } bm; + + if (!lBitCountScreen) { + HPS hps = WinGetPS(HWND_DESKTOP); + HDC hdc = GpiQueryDevice(hps); + DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &lBitCountScreen); + WinReleasePS(hps); + } + + // STEP 1: get OS/2 bitmap data and header + // get bitmap header + memset(&(bm.bmp2), 0, sizeof(bm.bmp2)); + bm.bmp2.cbFix = 16; + GpiQueryBitmapInfoHeader(hbm, &bm.bmp2); + + /* Data only actually stored in clipboard quality */ + if ( lBitCountScreen < bm.bmp2.cBitCount ) + bm.bmp2.cBitCount = lBitCountScreen; + + if ( bm.bmp2.cBitCount == 16 ) + bm.bmp2.cBitCount = 24; + + if ( bm.bmp2.cPlanes != 1 ) { + return 0; + } + + if ( (hdc = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, (HDC) NULL)) == (HDC) NULL ) { + return 0; + } + + sizl.cx = bm.bmp2.cx; + sizl.cy = bm.bmp2.cy; + if ( (hps = GpiCreatePS(hab, hdc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == (HPS) NULL ) { + DevCloseDC(hdc); + return 0; + } + // copy bitmap to hps + GpiSetBitmap(hps, hbm); + + // buffer lengths + cbBuffer = (((bm.bmp2.cBitCount * bm.bmp2.cx) + 31) / 32) * 4 * bm.bmp2.cy * bm.bmp2.cPlanes; + pbBuffer = (PM_BYTE*) malloc( cbBuffer); + // now get bitmap data + GpiQueryBitmapBits(hps, 0L, (LONG) bm.bmp2.cy, pbBuffer, (BITMAPINFO2*)&bm); + // free OS/2 resources + GpiSetBitmap(hps, (HBITMAP) NULL); + GpiDestroyPS(hps); + DevCloseDC(hdc); + + // STEP 2: now convert to Win32 DIB + // Determine size of color table + int iNumColors, numbits=bm.bmp2.cPlanes * bm.bmp2.cBitCount; + if (numbits != 24) + iNumColors = bm.bmp2.cclrUsed ? bm.bmp2.cclrUsed : 2<<numbits; + else + iNumColors = bm.bmp2.cclrUsed; + int iColorTableSize = iNumColors*sizeof(RGBQUAD); + + // reallocate data stream object size + OOoDIBStream->realloc( sizeof( W32_BITMAPFILEHEADER ) + + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize + cbBuffer); + + // fill w32 file header data + PW32_BITMAPFILEHEADER pbfh = (PW32_BITMAPFILEHEADER) OOoDIBStream->getArray(); + memset( pbfh, 0, sizeof( W32_BITMAPFILEHEADER)); + pbfh->bfType = 'MB'; + pbfh->bfSize = sizeof( W32_BITMAPFILEHEADER ) + + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize + cbBuffer; + pbfh->bfOffBits = sizeof( W32_BITMAPFILEHEADER) + sizeof( W32_BITMAPINFOHEADER) + iColorTableSize; + + // fill w32 info header + PW32_BITMAPINFOHEADER pbih = (PW32_BITMAPINFOHEADER) (pbfh+1); + // copy header fields (only win32 ones) and fix size + memcpy( pbih, &bm.bmp2, sizeof(W32_BITMAPINFOHEADER)); + pbih->biSize = sizeof(W32_BITMAPINFOHEADER); + + // fill color palette (follows pbih) + memcpy( (pbih+1), &bm.argb2Color[0], iColorTableSize); + + // fill bitmap data + memcpy( (char*) pbfh + pbfh->bfOffBits, pbBuffer, cbBuffer); + + // done + free( pbBuffer); + return 1; +} + +#ifdef TESTBMP + +#include <io.h> +#include <fcntl.h> +#include <stdio.h> + +int main( void) +{ + HAB hAB = WinQueryAnchorBlock( HWND_DESKTOP ); + + // query clipboard data to get mimetype + if( WinOpenClipbrd( hAB ) ) + { + ULONG handle = WinQueryClipbrdData( hAB, CF_BITMAP); + if (handle) { + Sequence< sal_Int8 > winDIBStream; + // convert to oustring and return it + if (OS2HandleToOOoBmp( handle, &winDIBStream) == 1) { + printf( "Conversion ok.\n"); + int fd = open( "test.bmp", O_BINARY | O_CREAT | O_TRUNC | O_RDWR); + printf( "writing to fd %d\n", fd); + write( fd, winDIBStream.getArray(), winDIBStream.getLength()); + close( fd); + } else + printf( "failed conversion.\n"); + + } + WinCloseClipbrd( hAB); + } + return 0; +} + +#endif //TESTBMP + diff --git a/dtrans/source/os2/clipb/Os2Clipboard.cxx b/dtrans/source/os2/clipb/Os2Clipboard.cxx new file mode 100644 index 000000000000..494df04b640a --- /dev/null +++ b/dtrans/source/os2/clipb/Os2Clipboard.cxx @@ -0,0 +1,447 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include "Os2Clipboard.hxx" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities; +using namespace com::sun::star::lang; +using namespace com::sun::star::uno; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace os2; + +const Type CPPUTYPE_SEQINT8 = getCppuType( ( Sequence< sal_Int8 >* )0 ); +const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 ); + +#define DTRANS_OBJ_CLASSNAME "DTRANSOBJWND" + +// ----------------------------------------------------------------------- + +inline void SetWindowPtr( HWND hWnd, Os2Clipboard* pThis ) +{ + WinSetWindowULong( hWnd, QWL_USER, (ULONG)pThis ); +} + +inline Os2Clipboard* GetWindowPtr( HWND hWnd ) +{ + return (Os2Clipboard*)WinQueryWindowULong( hWnd, QWL_USER ); +} + +// ----------------------------------------------------------------------- + +MRESULT EXPENTRY DtransObjWndProc( HWND hWnd, ULONG nMsg, MPARAM nMP1, MPARAM nMP2 ) +{ + + switch ( nMsg ) + { + case WM_DRAWCLIPBOARD: // clipboard content has changed + { + Os2Clipboard* os2Clipboard = GetWindowPtr( hWnd); + if (os2Clipboard) + { + //MutexGuard aGuard(os2Clipboard->m_aMutex); + debug_printf("WM_DRAWCLIPBOARD os2Clipboard %08x\n", os2Clipboard); + if (os2Clipboard->m_bInSetClipboardData) + { + debug_printf("WM_DRAWCLIPBOARD our change\n"); + } + else + { + // notify listener for clipboard change + debug_printf("WM_DRAWCLIPBOARD notify change\n"); + os2Clipboard->notifyAllClipboardListener(); + } + } + } + break; + } + + return WinDefWindowProc( hWnd, nMsg, nMP1, nMP2 ); +} + +// ----------------------------------------------------------------------- + +Os2Clipboard::Os2Clipboard() : + m_aMutex(), + WeakComponentImplHelper4< XClipboardEx, XClipboardNotifier, XServiceInfo, XInitialization > (m_aMutex), + m_bInitialized(sal_False), + m_bInSetClipboardData(sal_False) +{ + MutexGuard aGuard(m_aMutex); + + debug_printf("Os2Clipboard::Os2Clipboard\n"); + hAB = WinQueryAnchorBlock( HWND_DESKTOP ); + hText = 0; + hBitmap = 0; + +#if 0 + // register object class + if ( WinRegisterClass( hAB, (PSZ)DTRANS_OBJ_CLASSNAME, + (PFNWP)DtransObjWndProc, 0, sizeof(ULONG) )) + { + APIRET rc; + // create object window to get clip viewer messages + hObjWnd = WinCreateWindow( HWND_OBJECT, (PCSZ)DTRANS_OBJ_CLASSNAME, + (PCSZ)"", 0, 0, 0, 0, 0, + HWND_OBJECT, HWND_TOP, + 222, NULL, NULL); + // store pointer + SetWindowPtr( hObjWnd, this); + // register the viewer window + rc = WinOpenClipbrd(hAB); + rc = WinSetClipbrdViewer(hAB, hObjWnd); + rc = WinCloseClipbrd(hAB); + } +#endif + +} + +Os2Clipboard::~Os2Clipboard() +{ + debug_printf("Os2Clipboard::~Os2Clipboard\n"); +} + +void SAL_CALL Os2Clipboard::initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException) +{ + if (!m_bInitialized) + { + for (sal_Int32 n = 0, nmax = aArguments.getLength(); n < nmax; n++) + if (aArguments[n].getValueType() == getCppuType((OUString *) 0)) + { + aArguments[0] >>= m_aName; + break; + } + } +} + +OUString SAL_CALL Os2Clipboard::getImplementationName() throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::getImplementationName\n"); + return OUString::createFromAscii( OS2_CLIPBOARD_IMPL_NAME ); +} + +sal_Bool SAL_CALL Os2Clipboard::supportsService( const OUString& ServiceName ) throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::supportsService\n"); + Sequence < OUString > SupportedServicesNames = Os2Clipboard_getSupportedServiceNames(); + + for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +Sequence< OUString > SAL_CALL Os2Clipboard::getSupportedServiceNames() throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::getSupportedServiceNames\n"); + return Os2Clipboard_getSupportedServiceNames(); +} + +Reference< XTransferable > SAL_CALL Os2Clipboard::getContents() throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::getContents\n"); + MutexGuard aGuard(m_aMutex); + + // os2 can have only one viewer at time, and we don't get a notification + // when the viewer changes. So we need to check handles of clipboard + // data and compare with previous handles + if (UWinOpenClipbrd(hAB)) { + sal_Bool fireChanged = sal_False; + ULONG handle = UWinQueryClipbrdData( hAB, UCLIP_CF_UNICODETEXT); + if (handle) { + if (handle != hText) { + hText = handle; + fireChanged = sal_True; + } + } + handle = UWinQueryClipbrdData( hAB, UCLIP_CF_BITMAP); + if (handle) { + if (handle != hBitmap) { + hBitmap = handle; + fireChanged = sal_True; + } + } + UWinCloseClipbrd( hAB); + if (fireChanged) + { + // notify listener for clipboard change + debug_printf("Os2Clipboard::getContents notify change\n"); + notifyAllClipboardListener(); + } + } + + if( ! m_aContents.is() ) + m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) ); + + return m_aContents; +} + +void SAL_CALL Os2Clipboard::setContents( const Reference< XTransferable >& xTrans, const Reference< XClipboardOwner >& xClipboardOwner ) throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::setContents\n"); + // remember old values for callbacks before setting the new ones. + ClearableMutexGuard aGuard(m_aMutex); + + Reference< XClipboardOwner > oldOwner(m_aOwner); + m_aOwner = xClipboardOwner; + + Reference< XTransferable > oldContents(m_aContents); + m_aContents = xTrans; + + aGuard.clear(); + + // notify old owner on loss of ownership + if( oldOwner.is() ) + oldOwner->lostOwnership(static_cast < XClipboard * > (this), oldContents); + + // notify all listeners on content changes + OInterfaceContainerHelper *pContainer = + rBHelper.aLC.getContainer(getCppuType( (Reference < XClipboardListener > *) 0)); + if (pContainer) + { + ClipboardEvent aEvent(static_cast < XClipboard * > (this), m_aContents); + OInterfaceIteratorHelper aIterator(*pContainer); + + while (aIterator.hasMoreElements()) + { + Reference < XClipboardListener > xListener(aIterator.next(), UNO_QUERY); + if (xListener.is()) + xListener->changedContents(aEvent); + } + } + +#if OSL_DEBUG_LEVEL>0 + // dump list of available mimetypes + Sequence< DataFlavor > aFlavors( m_aContents->getTransferDataFlavors() ); + for( int i = 0; i < aFlavors.getLength(); i++ ) + debug_printf("Os2Clipboard::setContents available mimetype: %d %s\n", + i, CHAR_POINTER(aFlavors.getConstArray()[i].MimeType)); +#endif + + // we can only export text or bitmap + DataFlavor nFlavorText( OUString::createFromAscii( "text/plain;charset=utf-16" ), + OUString::createFromAscii( "Unicode-Text" ), CPPUTYPE_OUSTRING); + DataFlavor nFlavorBitmap( OUString::createFromAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ), + OUString::createFromAscii( "Bitmap" ), CPPUTYPE_DEFAULT); + + // try text transfer data (if any) + PSZ pSharedText = NULL; + HBITMAP hbm = NULL; + try + { + Any aAny = m_aContents->getTransferData( nFlavorText ); + if (aAny.hasValue()) + { + APIRET rc; + // copy unicode text to clipboard + OUString aString; + aAny >>= aString; + // share text + rc = DosAllocSharedMem( (PPVOID) &pSharedText, NULL, + aString.getLength() * 2 + 2, + PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE | OBJ_ANY); + if (!rc) + memcpy( pSharedText, aString.getStr(), aString.getLength() * 2 + 2 ); + else + pSharedText = NULL; + debug_printf("Os2Clipboard::setContents SetClipbrdData text done\n"); + } + } catch ( UnsupportedFlavorException&) { + debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no text)\n"); + } + + // try bitmap transfer data (if any) + try + { + Any aAnyB = m_aContents->getTransferData( nFlavorBitmap ); + if (aAnyB.hasValue()) + { + hbm = OOoBmpToOS2Handle( aAnyB); + debug_printf("Os2Clipboard::setContents SetClipbrdData bitmap done\n"); + } + } catch ( UnsupportedFlavorException&) { + debug_printf("Os2Clipboard::setContents UnsupportedFlavorException (no bitmap)\n"); + } + + // copy to clipboard + if ( UWinOpenClipbrd( hAB) && (pSharedText || hbm)) + { + // set the flag, so we will ignore the next WM_DRAWCLIPBOARD + // since we generate it with following code. + m_bInSetClipboardData = sal_True; + UWinEmptyClipbrd( hAB); + // give pointer to clipboard (it will become owner of pSharedText!) + if (pSharedText) { + UWinSetClipbrdData( hAB, (ULONG) pSharedText, UCLIP_CF_UNICODETEXT, CFI_POINTER); + // update internal handle to avoid detection of this text as new data + hText = (ULONG)pSharedText; + } + // give bitmap to clipboard + if (hbm) { + UWinSetClipbrdData( hAB, (ULONG) hbm, UCLIP_CF_BITMAP, CFI_HANDLE); + // update internal handle to avoid detection of this bitmap as new data + hBitmap = hbm; + } + // reset the flag, so we will not ignore next WM_DRAWCLIPBOARD + m_bInSetClipboardData = sal_False; + UWinCloseClipbrd( hAB); + } + +} + +OUString SAL_CALL Os2Clipboard::getName() throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::getName\n"); + return m_aName; +} + +sal_Int8 SAL_CALL Os2Clipboard::getRenderingCapabilities() throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::getRenderingCapabilities\n"); + return Delayed; +} + +//======================================================================== +// XClipboardNotifier +//======================================================================== + +void SAL_CALL Os2Clipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::addClipboardListener\n"); + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSURE( !rBHelper.bInDispose, "do not add listeners in the dispose call" ); + OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); + if (!rBHelper.bInDispose && !rBHelper.bDisposed) + rBHelper.aLC.addInterface( getCppuType( (const ::com::sun::star::uno::Reference< XClipboardListener > *) 0), listener ); +} + +void SAL_CALL Os2Clipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) throw( RuntimeException ) +{ + debug_printf("Os2Clipboard::removeClipboardListener\n"); + MutexGuard aGuard( rBHelper.rMutex ); + OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); + if (!rBHelper.bInDispose && !rBHelper.bDisposed) + rBHelper.aLC.removeInterface( getCppuType( (const Reference< XClipboardListener > *) 0 ), listener ); \ +} + +// ------------------------------------------------------------------------ + +void SAL_CALL Os2Clipboard::notifyAllClipboardListener( ) +{ + if ( !rBHelper.bDisposed ) + { + ClearableMutexGuard aGuard( rBHelper.rMutex ); + if ( !rBHelper.bDisposed ) + { + aGuard.clear( ); + + ClearableMutexGuard aGuard(m_aMutex); + // copy member references on stack so they can be called + // without having the mutex + Reference< XClipboardOwner > xOwner( m_aOwner ); + Reference< XTransferable > xTrans( m_aContents ); + // clear members + m_aOwner.clear(); + m_aContents.clear(); + // release the mutex + aGuard.clear(); + + // inform previous owner of lost ownership + if ( xOwner.is() ) + xOwner->lostOwnership(static_cast < XClipboard * > (this), m_aContents); + + OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer( + getCppuType( ( Reference< XClipboardListener > * ) 0 ) ); + + if ( pICHelper ) + { + try + { + OInterfaceIteratorHelper iter(*pICHelper); + m_aContents = 0; + m_aContents = new Os2Transferable( static_cast< OWeakObject* >(this) ); + ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), m_aContents); + + while(iter.hasMoreElements()) + { + try + { + Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY); + if (xCBListener.is()) + xCBListener->changedContents(aClipbEvent); + } + catch(RuntimeException&) + { + OSL_ENSURE( false, "RuntimeException caught" ); + debug_printf( "RuntimeException caught" ); + } + } + } + catch(const ::com::sun::star::lang::DisposedException&) + { + OSL_ENSURE(false, "Service Manager disposed"); + debug_printf( "Service Manager disposed"); + + // no further clipboard changed notifications + //m_pImpl->unregisterClipboardViewer(); + } + + } // end if + } // end if + } // end if +} + +// ------------------------------------------------------------------------ + +Sequence< OUString > SAL_CALL Os2Clipboard_getSupportedServiceNames() +{ + Sequence< OUString > aRet(1); + aRet[0] = OUString::createFromAscii( OS2_CLIPBOARD_SERVICE_NAME ); + return aRet; +} + +// ------------------------------------------------------------------------ + +Reference< XInterface > SAL_CALL Os2Clipboard_createInstance( + const Reference< XMultiServiceFactory > & xMultiServiceFactory) +{ + return Reference < XInterface >( ( OWeakObject * ) new Os2Clipboard()); +} + diff --git a/dtrans/source/os2/clipb/Os2Clipboard.hxx b/dtrans/source/os2/clipb/Os2Clipboard.hxx new file mode 100644 index 000000000000..0a9f4d117464 --- /dev/null +++ b/dtrans/source/os2/clipb/Os2Clipboard.hxx @@ -0,0 +1,136 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _OS2CLIPBOARD_HXX_ +#define _OS2CLIPBOARD_HXX_ + +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <cppuhelper/compbase4.hxx> +#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> +#include "Os2Transferable.hxx" + +// the service names +#define OS2_CLIPBOARD_SERVICE_NAME "com.sun.star.datatransfer.clipboard.SystemClipboard" + +// the implementation names +#define OS2_CLIPBOARD_IMPL_NAME "com.sun.star.datatransfer.clipboard.Os2Clipboard" + +// the registry key names +#define OS2_CLIPBOARD_REGKEY_NAME "/com.sun.star.datatransfer.clipboard.Os2Clipboard/UNO/SERVICES/com.sun.star.datatransfer.clipboard.SystemClipboard" + +namespace os2 { + +class Os2Clipboard : + //public cppu::WeakComponentImplHelper3< ::com::sun::star::datatransfer::clipboard::XClipboardEx, ::com::sun::star::datatransfer::clipboard::XClipboardNotifier, ::com::sun::star::lang::XServiceInfo > + public ::cppu::WeakComponentImplHelper4 < \ + ::com::sun::star::datatransfer::clipboard::XClipboardEx, \ + ::com::sun::star::datatransfer::clipboard::XClipboardNotifier, \ + ::com::sun::star::lang::XServiceInfo, \ + ::com::sun::star::lang::XInitialization > +{ + +public: + Os2Clipboard(); + ~Os2Clipboard(); + + /* + * XInitialization + */ + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + /* + * XServiceInfo + */ + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); + + /* + * XClipboard + */ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > SAL_CALL getContents() + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL setContents( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& xTransferable, const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) + throw( ::com::sun::star::uno::RuntimeException ); + virtual ::rtl::OUString SAL_CALL getName() + throw( ::com::sun::star::uno::RuntimeException ); + + /* + * XClipboardEx + */ + virtual sal_Int8 SAL_CALL getRenderingCapabilities() + throw( ::com::sun::star::uno::RuntimeException ); + + /* + * XClipboardNotifier + */ + virtual void SAL_CALL addClipboardListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener ) + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL removeClipboardListener( const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener ) + throw( ::com::sun::star::uno::RuntimeException ); + void SAL_CALL notifyAllClipboardListener( ); + +public: + sal_Bool m_bInSetClipboardData; + +private: + HAB hAB; + HWND hObjWnd; + ULONG hText, hBitmap; // handles to previous clipboard data + + ::osl::Mutex m_aMutex; + ::rtl::OUString m_aName; + + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > m_aContents; + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner > m_aOwner; + + sal_Bool m_bInitialized; + +}; + +} // namespace Os2 + +// ------------------------------------------------------------------------ + +::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL Os2Clipboard_getSupportedServiceNames(); +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Os2Clipboard_createInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xMultiServiceFactory); + +#endif + diff --git a/dtrans/source/os2/clipb/Os2Service.cxx b/dtrans/source/os2/clipb/Os2Service.cxx new file mode 100644 index 000000000000..0c3e299f0299 --- /dev/null +++ b/dtrans/source/os2/clipb/Os2Service.cxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "Os2Clipboard.hxx" +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> + +using namespace rtl; +using namespace com::sun::star::uno; +using namespace com::sun::star::registry; +using namespace cppu; +using namespace com::sun::star::lang; +using namespace com::sun::star::datatransfer::clipboard; +using namespace os2; + +namespace os2 { + +Reference< XInterface > SAL_CALL createInstance( const Reference< XMultiServiceFactory >& rServiceManager ) +{ + return Reference< XInterface >( static_cast< XClipboard* >( new Os2Clipboard() ) ); +} + +} // namespace os2 + +extern "C" +{ + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* pRegistryKey ) +{ + void* pRet = 0; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, OS2_CLIPBOARD_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( OS2_CLIPBOARD_SERVICE_NAME ) ); + + //OUString( RTL_CONSTASCII_USTRINGPARAM( FPS_IMPL_NAME ) ) + Reference< XSingleServiceFactory > xFactory ( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createInstance, + aSNS ) ); + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +} // extern "C" diff --git a/dtrans/source/os2/clipb/Os2Transferable.cxx b/dtrans/source/os2/clipb/Os2Transferable.cxx new file mode 100644 index 000000000000..fe8c77105e90 --- /dev/null +++ b/dtrans/source/os2/clipb/Os2Transferable.cxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +#define INCL_WIN +#include <svpm.h> + +#include <string.h> +#include <com/sun/star/io/IOException.hpp> +#include "Os2Transferable.hxx" + +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::lang; +using namespace com::sun::star::io; +using namespace com::sun::star::uno; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace os2; + +// ======================================================================= + +Os2Transferable::Os2Transferable( + const Reference< XInterface >& xCreator ) : + m_xCreator( xCreator ) +{ + debug_printf("Os2Transferable::Os2Transferable %08x\n", this); + hAB = WinQueryAnchorBlock( HWND_DESKTOP ); + + // query clipboard data to get mimetype + if( UWinOpenClipbrd( hAB ) ) + { + ULONG handle = UWinQueryClipbrdData( hAB, UCLIP_CF_UNICODETEXT); + if (handle) { + aFlavor.MimeType = OUString::createFromAscii( "text/plain;charset=utf-16" ); + aFlavor.DataType = getCppuType( (OUString*)0 ); + //debug_printf("Os2Transferable::Os2Transferable pszText %s\n", pszText); + } + handle = UWinQueryClipbrdData( hAB, UCLIP_CF_BITMAP); + if (handle) { + aFlavor.MimeType = OUString::createFromAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ); + aFlavor.DataType = getCppuType( (OUString*)0 ); + //debug_printf("Os2Transferable::Os2Transferable pszText %s\n", pszText); + } + UWinCloseClipbrd( hAB); + } + else + { + debug_printf("Os2Transferable::Os2Transferable failed to open clipboard\n"); + } + +} + +//================================================================================================== + +Os2Transferable::~Os2Transferable() +{ + debug_printf("Os2Transferable::~Os2Transferable %08x\n", this); +} + +//================================================================================================== + +Any SAL_CALL Os2Transferable::getTransferData( const DataFlavor& rFlavor ) + throw(UnsupportedFlavorException, IOException, RuntimeException) +{ + debug_printf("Os2Transferable::getTransferData %08x\n", this); + debug_printf("Os2Transferable::getTransferData mimetype: %s\n", CHAR_POINTER(rFlavor.MimeType)); + Any aRet; + Sequence< sal_Int8 > aData; + + // retrieve unicode text + if( rFlavor.MimeType.equalsIgnoreAsciiCase( OUString::createFromAscii( "text/plain;charset=utf-16" ) ) ) + { + if( UWinOpenClipbrd( hAB ) ) + { + // check if clipboard has text format + sal_Unicode* pszText = (sal_Unicode*) UWinQueryClipbrdData( hAB, UCLIP_CF_UNICODETEXT); + if (pszText) { + // convert to oustring and return it + OUString aString( pszText); + aRet <<= aString; + } + UWinCloseClipbrd( hAB ); + if (pszText) + return aRet; + } + } + + // retrieve bitmap + if( rFlavor.MimeType.equalsIgnoreAsciiCase( OUString::createFromAscii( "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"" ) ) ) + { + if( UWinOpenClipbrd( hAB ) ) + { + // check if clipboard has text format + ULONG handle = UWinQueryClipbrdData( hAB, UCLIP_CF_BITMAP); + if (handle) { + Sequence< sal_Int8 > winDIBStream; + // convert to oustring and return it + if (OS2HandleToOOoBmp( handle, &winDIBStream)) + aRet <<= winDIBStream; + else + handle = 0; + } + UWinCloseClipbrd( hAB ); + if (handle) + return aRet; + } + } + + // clipboard format unsupported, throw exception + throw UnsupportedFlavorException( rFlavor.MimeType, static_cast < XTransferable * > ( this ) ); +} + +//================================================================================================== + +Sequence< DataFlavor > SAL_CALL Os2Transferable::getTransferDataFlavors() + throw(RuntimeException) +{ + debug_printf("Os2Transferable::getTransferDataFlavors %08x\n", this); + Sequence< DataFlavor > aFlavorList(1); + aFlavorList[0] = aFlavor; + debug_printf("Os2Transferable::getTransferDataFlavors mimetype: %s\n", CHAR_POINTER(aFlavor.MimeType)); + return aFlavorList; +} + +//================================================================================================== + +sal_Bool SAL_CALL Os2Transferable::isDataFlavorSupported( const DataFlavor& aFlavor ) + throw(RuntimeException) +{ + debug_printf("Os2Transferable::isDataFlavorSupported %08x\n", this); + debug_printf("Os2Transferable::isDataFlavorSupported %s\n", CHAR_POINTER(aFlavor.MimeType)); + + if( aFlavor.DataType != getCppuType( (Sequence< sal_Int8 >*)0 ) ) + { + if( ! aFlavor.MimeType.equalsIgnoreAsciiCase( OUString::createFromAscii( "text/plain;charset=utf-16" ) ) && + aFlavor.DataType == getCppuType( (OUString*)0 ) ) + return false; + } + + Sequence< DataFlavor > aFlavors( getTransferDataFlavors() ); + for( int i = 0; i < aFlavors.getLength(); i++ ) + if( aFlavor.MimeType.equalsIgnoreAsciiCase( aFlavors.getConstArray()[i].MimeType ) && + aFlavor.DataType == aFlavors.getConstArray()[i].DataType ) + return sal_True; + + return sal_False; +} + diff --git a/dtrans/source/os2/clipb/Os2Transferable.hxx b/dtrans/source/os2/clipb/Os2Transferable.hxx new file mode 100644 index 000000000000..833aa2680a8a --- /dev/null +++ b/dtrans/source/os2/clipb/Os2Transferable.hxx @@ -0,0 +1,99 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DTRANS_OS2_TRANSFERABLE_HXX_ +#define _DTRANS_OS2_TRANSFERABLE_HXX_ + +#include <com/sun/star/datatransfer/XTransferable.hpp> + +#ifndef _COM_SUN_STAR_LANG_XEVENTLISTENER_HDL_ +#include <com/sun/star/lang/XEventListener.hpp> +#endif +#include <cppuhelper/implbase1.hxx> +#include <osl/thread.h> + +#include <errno.h> + +#include <uclip.h> + +#define CHAR_POINTER(THE_OUSTRING) ::rtl::OUStringToOString (THE_OUSTRING, RTL_TEXTENCODING_UTF8).pData->buffer + +#if OSL_DEBUG_LEVEL>1 +//extern "C" int debug_printf(const char *f, ...); +#define debug_printf( ...) { 1; } +#else +#define debug_printf( ...) { 1; } +#endif + +#define CPPUTYPE_SEQSALINT8 getCppuType( (const Sequence< sal_Int8 >*) 0 ) +#define CPPUTYPE_DEFAULT CPPUTYPE_SEQSALINT8 + +#ifdef OOO_VENDOR +using namespace com::sun::star::uno; +HBITMAP OOoBmpToOS2Handle( Any &aAnyB); +int OS2HandleToOOoBmp( HBITMAP hbm, Sequence< sal_Int8 >* winDIBStream); +#else +#define OOoBmpToOS2Handle(a) 0 +#define OS2HandleToOOoBmp(a,b) 0 +#endif + +namespace os2 { + + class Os2Transferable : public ::cppu::WeakImplHelper1 < + ::com::sun::star::datatransfer::XTransferable > + { + HAB hAB; + ::rtl::OUString clipText; + ::com::sun::star::datatransfer::DataFlavor aFlavor; + ::osl::Mutex m_aMutex; + ::com::sun::star::uno::Reference< XInterface > m_xCreator; + + public: + Os2Transferable( const ::com::sun::star::uno::Reference< XInterface >& xCreator); + virtual ~Os2Transferable(); + + /* + * XTransferable + */ + + virtual ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) + throw(::com::sun::star::datatransfer::UnsupportedFlavorException, + ::com::sun::star::io::IOException, + ::com::sun::star::uno::RuntimeException + ); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) + throw(::com::sun::star::uno::RuntimeException); + }; + +} // namespace + +#endif + diff --git a/dtrans/source/os2/clipb/exports.dxp b/dtrans/source/os2/clipb/exports.dxp new file mode 100644 index 000000000000..926e49f5f1a5 --- /dev/null +++ b/dtrans/source/os2/clipb/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_getFactory + diff --git a/dtrans/source/os2/clipb/makefile.mk b/dtrans/source/os2/clipb/makefile.mk new file mode 100644 index 000000000000..a1ccc1ae87ec --- /dev/null +++ b/dtrans/source/os2/clipb/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=dtrans +TARGET=sysdtrans +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +COMPRDB=$(SOLARBINDIR)$/types.rdb +USE_BOUNDCHK= + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES= $(SLO)$/Os2Clipboard.obj \ + $(SLO)$/Os2Service.obj \ + $(SLO)$/Os2Transferable.obj + +.IF "$(OOO_VENDOR)"=="Serenity Systems Intl" +SLOFILES+= $(SLO)$/OS2Bitmap.obj +CDEFS+=-DOOO_VENDOR +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/dtrans/source/os2/clipb/sysdtrans.xml b/dtrans/source/os2/clipb/sysdtrans.xml new file mode 100644 index 000000000000..a6dec8a03a42 --- /dev/null +++ b/dtrans/source/os2/clipb/sysdtrans.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> sysdtrans </module-name> + <component-description> + <author> Tino Rachui </author> + <name> com.sun.star.comp.datatransfer.SystemClipboard </name> + <description> + The win32 implementation of the datatransfer service. +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.datatransfer.clipboard.SystemClipboard </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.datatransfer.clipboard.XClipboardEx </type> + <type> com.sun.star.datatransfer.XTransferable </type> + <type> com.sun.star.datatransfer.XTransferableEx </type> + <type> com.sun.star.datatransfer.clipboard.XClipboardOwner</type> + <type> com.sun.star.datatransfer.clipboard.XClipboardListener</type> + <type> com.sun.star.datatransfer.clipboard.XClipboardNotifier</type> + <type> com.sun.star.datatransfer.clipboard.XFlushableClipboard</type> + <type> com.sun.star.datatransfer.clipboard.RenderingCapabilities</type> + <type> com.sun.star.datatransfer.XTransferDataAccess </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.container.XSet </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/dtrans/source/test/makefile.mk b/dtrans/source/test/makefile.mk new file mode 100644 index 000000000000..4048797813ab --- /dev/null +++ b/dtrans/source/test/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME= dtrans +TARGET= test_dtrans + +LIBTARGET=NO +TARGETTYPE=CUI +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +APP1TARGET= $(TARGET) +APP1OBJS= \ + $(OBJ)$/test_dtrans.obj + +APP1STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) + +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk + diff --git a/dtrans/source/test/test_dtrans.cxx b/dtrans/source/test/test_dtrans.cxx new file mode 100644 index 000000000000..41d5bfb4f32f --- /dev/null +++ b/dtrans/source/test/test_dtrans.cxx @@ -0,0 +1,512 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +//------------------------------------------------------------------------ +// interface includes +//------------------------------------------------------------------------ +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardManager.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#include <com/sun/star/lang/XComponent.hpp> + +//------------------------------------------------------------------------ +// other includes +//------------------------------------------------------------------------ + + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <rtl/ustring.hxx> +#include <osl/diagnose.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +//#include <memory> + +//#include <process.h> + +//------------------------------------------------------------------------ +// my defines +//------------------------------------------------------------------------ + +#ifdef UNX +#define PATH_SEPERATOR '/' +#else +#define PATH_SEPERATOR '\\' +#endif + +#define ENSURE( a, b ) if( !a ) { fprintf( stderr, b "\n" ); exit( -1 ); } +#define TEST( a, b ) fprintf( stderr, "Testing " a ); fprintf( stderr, b ? "passed\n" : "FAILED\n" ) +#define PERFORM( a, b ) fprintf( stderr, "Performing " a); b; fprintf( stderr, "done\n" ) +#define TRACE( a ) fprintf( stderr, a ) + +//------------------------------------------------------------------------ +// namespaces +//------------------------------------------------------------------------ + +using namespace ::rtl; +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::clipboard; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; + +//------------------------------------------------------------------------ +// globals +//------------------------------------------------------------------------ + +const char * app = NULL; + +//------------------------------------------------------------------------ +// ClipboardOwner +//------------------------------------------------------------------------ + +class ClipboardOwner : public WeakImplHelper1< XClipboardOwner > +{ + Reference< XClipboard > m_xClipboard; + Reference< XTransferable > m_xTransferable; + + sal_uInt32 m_nReceivedLostOwnerships; + +public: + ClipboardOwner(); + + //-------------------------------------------------------------------- + // XClipboardOwner + //-------------------------------------------------------------------- + + virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) throw(RuntimeException); + + sal_uInt32 receivedLostOwnerships() { return m_nReceivedLostOwnerships; }; + Reference< XClipboard > lostOwnershipClipboardValue() { return m_xClipboard; } + Reference< XTransferable > lostOwnershipTransferableValue() { return m_xTransferable; }; +}; + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +ClipboardOwner::ClipboardOwner(): + m_nReceivedLostOwnerships( 0 ) +{ +} + +//------------------------------------------------------------------------ +// lostOwnership +//------------------------------------------------------------------------ + +void SAL_CALL ClipboardOwner::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) + throw(RuntimeException) +{ + m_nReceivedLostOwnerships++; + m_xClipboard = xClipboard; + m_xTransferable = xTrans; +} + +//------------------------------------------------------------------------ +// ClipboardListener +//------------------------------------------------------------------------ + +class ClipboardListener : public WeakImplHelper1< XClipboardListener > +{ + Reference< XClipboard > m_xClipboard; + Reference< XTransferable > m_xTransferable; + + sal_uInt32 m_nReceivedChangedContentsEvents; + +public: + ClipboardListener(); + + //-------------------------------------------------------------------- + // XClipboardOwner + //-------------------------------------------------------------------- + + virtual void SAL_CALL changedContents( const ClipboardEvent& event ) throw(RuntimeException); + + //-------------------------------------------------------------------- + // XEventListener + //-------------------------------------------------------------------- + + virtual void SAL_CALL disposing( const EventObject& event ) throw(RuntimeException); + + sal_uInt32 receivedChangedContentsEvents() { return m_nReceivedChangedContentsEvents; }; + Reference< XClipboard > changedContentsEventClipboardValue() { return m_xClipboard; } + Reference< XTransferable > changedContentsEventTransferableValue() { return m_xTransferable; }; +}; + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +ClipboardListener::ClipboardListener(): + m_nReceivedChangedContentsEvents( 0 ) +{ +} + +//------------------------------------------------------------------------ +// changedContents +//------------------------------------------------------------------------ + +void SAL_CALL ClipboardListener::changedContents( const ClipboardEvent& event ) + throw(RuntimeException) +{ + m_nReceivedChangedContentsEvents++; + m_xClipboard = Reference< XClipboard > (event.Source, UNO_QUERY); + m_xTransferable = event.Contents; +} + +//------------------------------------------------------------------------ +// disposing +//------------------------------------------------------------------------ + +void SAL_CALL ClipboardListener::disposing( const EventObject& event ) + throw(RuntimeException) +{ +} + +//------------------------------------------------------------------------ +// StringTransferable +//------------------------------------------------------------------------ + +class StringTransferable : public WeakImplHelper2< XClipboardOwner, XTransferable > +{ +public: + StringTransferable( ); + + //-------------------------------------------------------------------- + // XTransferable + //-------------------------------------------------------------------- + + virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor ) throw(UnsupportedFlavorException, IOException, RuntimeException); + virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor ) throw(RuntimeException); + + //-------------------------------------------------------------------- + // XClipboardOwner + //-------------------------------------------------------------------- + + virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) throw(RuntimeException); + + sal_Bool receivedLostOwnership() { return m_receivedLostOwnership; }; + void clearReceivedLostOwnership() { m_receivedLostOwnership = sal_False; }; + +private: + Sequence< DataFlavor > m_seqDFlv; + OUString m_Data; + sal_Bool m_receivedLostOwnership; +}; + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +StringTransferable::StringTransferable( ) : + m_seqDFlv( 1 ), + m_receivedLostOwnership( sal_False ), + m_Data( OUString::createFromAscii("clipboard test content") ) +{ + DataFlavor df; + + /* + df.MimeType = L"text/plain; charset=unicode"; + df.DataType = getCppuType( ( OUString* )0 ); + + m_seqDFlv[0] = df; + */ + + //df.MimeType = L"text/plain; charset=windows1252"; + df.MimeType = OUString::createFromAscii( "text/html" ); + df.DataType = getCppuType( ( Sequence< sal_Int8 >* )0 ); + + m_seqDFlv[0] = df; +} + +//------------------------------------------------------------------------ +// getTransferData +//------------------------------------------------------------------------ + +Any SAL_CALL StringTransferable::getTransferData( const DataFlavor& aFlavor ) + throw(UnsupportedFlavorException, IOException, RuntimeException) +{ + Any anyData; + + /*if ( aFlavor == m_seqDFlv[0] ) + { + anyData = makeAny( m_Data ); + } */ +#if 0 + else if ( aFlavor == m_seqDFlv[0] ) + { + OString aStr( m_Data.getStr( ), m_Data.getLength( ), 1252 ); + Sequence< sal_Int8 > sOfChars( aStr.getLength( ) ); + sal_Int32 lenStr = aStr.getLength( ); + + for ( sal_Int32 i = 0; i < lenStr; ++i ) + sOfChars[i] = aStr[i]; + + anyData = makeAny( sOfChars ); + } +#endif + + return anyData; +} + +//------------------------------------------------------------------------ +// getTransferDataFlavors +//------------------------------------------------------------------------ + +Sequence< DataFlavor > SAL_CALL StringTransferable::getTransferDataFlavors( ) + throw(RuntimeException) +{ + return m_seqDFlv; +} + +//------------------------------------------------------------------------ +// isDataFlavorSupported +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL StringTransferable::isDataFlavorSupported( const DataFlavor& aFlavor ) + throw(RuntimeException) +{ + sal_Int32 nLength = m_seqDFlv.getLength( ); + sal_Bool bRet = sal_False; + +// for ( sal_Int32 i = 0; i < nLength; ++i ) +// { +// if ( m_seqDFlv[i] == aFlavor ) +// { +// bRet = sal_True; +// break; +// } +// } + + return bRet; +} + +//------------------------------------------------------------------------ +// lostOwnership +//------------------------------------------------------------------------ + +void SAL_CALL StringTransferable::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) + throw(RuntimeException) +{ + m_receivedLostOwnership = sal_True; +} + +//------------------------------------------------------------------------ +// main +//------------------------------------------------------------------------ + +int SAL_CALL main( int argc, const char* argv[] ) +{ + OUString aRegistry; + + //------------------------------------------------------------------ + // check command line parameters + //------------------------------------------------------------------ + + if ( NULL == ( app = strrchr( argv[0], PATH_SEPERATOR ) ) ) + app = argv[0]; + else + app++; + + for( int n = 1; n < argc; n++ ) + { + if( strncmp( argv[n], "-r", 2 ) == 0 ) + { + if( strlen( argv[n] ) > 2 ) + aRegistry = OUString::createFromAscii( argv[n] + 2 ); + else if ( n + 1 < argc ) + aRegistry = OUString::createFromAscii( argv[++n] ); + } + } + + if( aRegistry.getLength() == 0 ) + fprintf( stderr, "Usage: %s -r full-path-to-applicat.rdb\n", app ); + + //------------------------------------------------------------------ + // create service manager + //------------------------------------------------------------------ + Reference< XMultiServiceFactory > xServiceManager; + + try + { + xServiceManager = createRegistryServiceFactory( aRegistry, sal_True ); + ENSURE( xServiceManager.is(), "*** ERROR *** service manager could not be created." ); + + //-------------------------------------------------------------- + // create an instance of GenericClipboard service + //-------------------------------------------------------------- + + Sequence< Any > arguments(1); + arguments[0] = makeAny( OUString::createFromAscii( "generic" ) ); + + Reference< XClipboard > xClipboard( xServiceManager->createInstanceWithArguments( + OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.GenericClipboard" ), + arguments ), UNO_QUERY ); + + ENSURE( xClipboard.is(), "*** ERROR *** generic clipboard service could not be created." ); + + Reference< XClipboardNotifier > xClipboardNotifier( xClipboard, UNO_QUERY ); + Reference< XClipboardListener > xClipboardListener = new ClipboardListener(); + ClipboardListener * pListener = (ClipboardListener *) xClipboardListener.get(); + + if( xClipboardNotifier.is() ) + xClipboardNotifier->addClipboardListener( xClipboardListener ); + + //-------------------------------------------------------------- + // run various tests on clipboard implementation + //-------------------------------------------------------------- + + TRACE( "\n*** testing generic clipboard service ***\n" ); + + Reference< XTransferable > xContents = new StringTransferable(); + Reference< XClipboardOwner > xOwner = new ClipboardOwner(); + ClipboardOwner *pOwner = (ClipboardOwner *) xOwner.get(); + + TEST( "initial contents (none): ", xClipboard->getContents().is() == sal_False ); + + PERFORM( "update on contents with clipboard owner: ", xClipboard->setContents( xContents, xOwner ) ); + TEST( "current clipboard contents: ", xContents == xClipboard->getContents() ); + + if( xClipboardNotifier.is() ) + { + TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 0 ); + TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 1 ); + TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard ); + TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventTransferableValue() == xContents ); + } + + PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) ); + TEST( "if received lostOwnership message(s): ", pOwner->receivedLostOwnerships() > 0 ); + TEST( "if received exactly 1 lostOwnership message: ", pOwner->receivedLostOwnerships() == 1 ); + TEST( "if received lostOwnership message for the correct clipboard: ", pOwner->lostOwnershipClipboardValue() == xClipboard ); + TEST( "if received lostOwnership message for the correct transferable: ", pOwner->lostOwnershipTransferableValue() == xContents ); + TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False ); + + if( xClipboardNotifier.is() ) + { + TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 1 ); + TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 2 ); + TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard ); + TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() ); + } + + PERFORM( "update on contents without clipboard owner: ", xClipboard->setContents( xContents, Reference< XClipboardOwner >() ) ); + TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 ); + TEST( "current clipboard contents: ", xContents == xClipboard->getContents() ); + + if( xClipboardNotifier.is() ) + { + TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 2 ); + TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 3 ); + TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard ); + TEST( "if received changedContents notification for correct transferable: ", pListener->changedContentsEventTransferableValue() == xContents ); + } + + + PERFORM( "update on contents without data (clear): ", xClipboard->setContents( Reference< XTransferable >(), Reference< XClipboardOwner >() ) ); + TEST( "that no further lostOwnership messages were received: ", pOwner->receivedLostOwnerships() == 1 ); + TEST( "current clipboard contents (none): ", xClipboard->getContents().is() == sal_False ); + + if( xClipboardNotifier.is() ) + { + TEST( "if received changedContents notifications: ", pListener->receivedChangedContentsEvents() > 3 ); + TEST( "if received exactly 1 changedContents notification: ", pListener->receivedChangedContentsEvents() == 4 ); + TEST( "if received changedContents notification for correct clipboard: ", pListener->changedContentsEventClipboardValue() == xClipboard ); + TEST( "if received changedContents notification for correct transferable: ", ! pListener->changedContentsEventTransferableValue().is() ); + } + + //-------------------------------------------------------------- + // create an instance of ClipboardManager service + //-------------------------------------------------------------- + + Reference< XClipboardManager > xClipboardManager( xServiceManager->createInstance( + OUString::createFromAscii( "com.sun.star.datatransfer.clipboard.ClipboardManager" ) ), UNO_QUERY ); + + ENSURE( xClipboardManager.is(), "*** ERROR *** clipboard manager service could not be created." ); + + //-------------------------------------------------------------- + // run various tests on clipboard manager implementation + //-------------------------------------------------------------- + + TRACE( "\n*** testing clipboard manager service ***\n" ); + + TEST( "initial number of clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 ); + PERFORM( "insertion of generic clipboard: ", xClipboardManager->addClipboard( xClipboard ) ); + TEST( "number of inserted clipboards (1): ", xClipboardManager->listClipboardNames().getLength() == 1 ); + TEST( "name of inserted clipboard (generic): ", xClipboardManager->listClipboardNames()[0] == OUString::createFromAscii( "generic" ) ); + TEST( "inserted clipboard instance: ", xClipboardManager->getClipboard( OUString::createFromAscii( "generic" ) ) == xClipboard ); + PERFORM( "removal of generic clipboard: ", xClipboardManager->removeClipboard( OUString::createFromAscii( "generic" ) ) ); + TEST( "number of inserted clipboards (0): ", xClipboardManager->listClipboardNames().getLength() == 0 ); + TRACE( "Testing inserted clipboard instance (none): " ); + try + { + xClipboardManager->getClipboard( OUString::createFromAscii( "generic" ) ); + TRACE( "FAILED\n" ); + } + catch( NoSuchElementException e ) + { + TRACE( "passed\n" ); + } + } + + catch ( Exception aException ) + { + ENSURE( sal_False, "*** ERROR *** exception caught." ); + } + + //-------------------------------------------------------------------- + // shutdown the service manager + //-------------------------------------------------------------------- + + // query XComponent interface + Reference< XComponent > xComponent( xServiceManager, UNO_QUERY ); + + ENSURE( xComponent.is(), "*** ERROR *** service manager does not support XComponent." ); + + // Dispose and clear factory + xComponent->dispose(); + xServiceManager.clear(); + + fprintf( stderr, "Done.\n" ); + return 0; +} + + diff --git a/dtrans/source/win32/clipb/APNDataObject.hxx b/dtrans/source/win32/clipb/APNDataObject.hxx new file mode 100644 index 000000000000..5a5bf1fa3547 --- /dev/null +++ b/dtrans/source/win32/clipb/APNDataObject.hxx @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _APNDATAOBJECT_HXX_ +#define _APNDATAOBJECT_HXX_ + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +/* + an APartment Neutral dataobject wrapper; this wrapper of a IDataObject + pointer can be used from any apartment without RPC_E_WRONG_THREAD + which normally occurs if an apartment tries to use an interface + pointer of another apartment; we use containment to hold the original + DataObject +*/ +class CAPNDataObject : public IDataObject +{ +public: + CAPNDataObject( IDataObjectPtr rIDataObject ); + ~CAPNDataObject( ); + + //----------------------------------------------------------------- + //IUnknown interface methods + //----------------------------------------------------------------- + + STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); + STDMETHODIMP_( ULONG ) AddRef( ); + STDMETHODIMP_( ULONG ) Release( ); + + //----------------------------------------------------------------- + // IDataObject interface methods + //----------------------------------------------------------------- + + STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc ); + STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut ); + STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease ); + STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ); + STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection ); + STDMETHODIMP DUnadvise( DWORD dwConnection ); + STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise ); + + operator IDataObject*( ); + +private: + HRESULT MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj ); + +private: + IDataObjectPtr m_rIDataObjectOrg; + HGLOBAL m_hGlobal; + LONG m_nRefCnt; + +// prevent copy and assignment +private: + CAPNDataObject( const CAPNDataObject& theOther ); + CAPNDataObject& operator=( const CAPNDataObject& theOther ); +}; + +#endif diff --git a/dtrans/source/win32/clipb/WinClipbImpl.cxx b/dtrans/source/win32/clipb/WinClipbImpl.cxx new file mode 100644 index 000000000000..30b35a48d391 --- /dev/null +++ b/dtrans/source/win32/clipb/WinClipbImpl.cxx @@ -0,0 +1,273 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "WinClipbImpl.hxx" + +#include <systools/win32/comtools.hxx> +#include "..\..\inc\DtObjFactory.hxx" +#include "..\dtobj\APNDataObject.hxx" +#include "WinClipboard.hxx" +#include <com/sun/star/datatransfer/clipboard/RenderingCapabilities.hpp> +#include "..\dtobj\XNotifyingDataObject.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <ole2.h> +#include <objidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace rtl; +using namespace osl; +using namespace std; +using namespace cppu; + +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using namespace com::sun::star::datatransfer::clipboard::RenderingCapabilities; + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +// definition of static members +CWinClipbImpl* CWinClipbImpl::s_pCWinClipbImpl = NULL; +osl::Mutex CWinClipbImpl::s_aMutex; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CWinClipbImpl::CWinClipbImpl( const OUString& aClipboardName, CWinClipboard* theWinClipboard ) : + m_itsName( aClipboardName ), + m_pWinClipboard( theWinClipboard ), + m_pCurrentClipContent( NULL ) +{ + OSL_ASSERT( NULL != m_pWinClipboard ); + + // necessary to reassociate from + // the static callback function + s_pCWinClipbImpl = this; + registerClipboardViewer( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CWinClipbImpl::~CWinClipbImpl( ) +{ + ClearableMutexGuard aGuard( s_aMutex ); + s_pCWinClipbImpl = NULL; + aGuard.clear( ); + + unregisterClipboardViewer( ); +} + +//------------------------------------------------------------------------ +// getContent +//------------------------------------------------------------------------ + +Reference< XTransferable > SAL_CALL CWinClipbImpl::getContents( ) throw( RuntimeException ) +{ + // use the shotcut or create a transferable from + // system clipboard + ClearableMutexGuard aGuard( m_ClipContentMutex ); + + if ( NULL != m_pCurrentClipContent ) + { + return m_pCurrentClipContent->m_XTransferable; + } + + // release the mutex, so that the variable may be + // changed by other threads + aGuard.clear( ); + + Reference< XTransferable > rClipContent; + + // get the current dataobject from clipboard + IDataObjectPtr pIDataObject; + HRESULT hr = m_MtaOleClipboard.getClipboard( &pIDataObject ); + + if ( SUCCEEDED( hr ) ) + { + // create an apartment neutral dataobject and initialize it with a + // com smart pointer to the IDataObject from clipboard + IDataObjectPtr pIDo( new CAPNDataObject( pIDataObject ) ); + + CDTransObjFactory objFactory; + + // remeber pIDo destroys itself due to the smart pointer + rClipContent = objFactory.createTransferableFromDataObj( m_pWinClipboard->m_SrvMgr, pIDo ); + } + + return rClipContent; +} + +//------------------------------------------------------------------------ +// setContent +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipbImpl::setContents( + const Reference< XTransferable >& xTransferable, + const Reference< XClipboardOwner >& xClipboardOwner ) + throw( RuntimeException ) +{ + CDTransObjFactory objFactory; + IDataObjectPtr pIDataObj; + + if ( xTransferable.is( ) ) + { + ClearableMutexGuard aGuard( m_ClipContentMutex ); + + m_pCurrentClipContent = new CXNotifyingDataObject( + objFactory.createDataObjFromTransferable( m_pWinClipboard->m_SrvMgr , xTransferable ), + xTransferable, + xClipboardOwner, + this ); + + aGuard.clear( ); + + pIDataObj = IDataObjectPtr( m_pCurrentClipContent ); + } + + m_MtaOleClipboard.setClipboard(pIDataObj.get()); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CWinClipbImpl::getName( ) throw( RuntimeException ) +{ + return m_itsName; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Int8 SAL_CALL CWinClipbImpl::getRenderingCapabilities( ) throw( RuntimeException ) +{ + return ( Delayed | Persistant ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipbImpl::flushClipboard( ) throw( RuntimeException ) +{ + // sollte eigentlich hier stehen: ClearableMutexGuard aGuard( m_ClipContentMutex ); + // geht aber nicht, da FlushClipboard zurückruft und das DataObject + // freigibt und damit würde es einen Deadlock in onReleaseDataObject geben + // FlushClipboard muß synchron sein, damit das runterfahren ggf. erst weitergeht, + // wenn alle Clipboard-Formate gerendert wurden + // die Abfrage ist nötig, damit nur geflusht wird, wenn wir wirklich Clipboardowner + // sind (ich weiss nicht genau was passiert, wenn man flusht und nicht Clipboard + // owner ist). + // eventuell kann man aber die Abfrage in den Clipboard STA Thread verlagern, indem + // man sich dort das DataObject merkt und vor dem flushen OleIsCurrentClipboard ruft + + if ( NULL != m_pCurrentClipContent ) + m_MtaOleClipboard.flushClipboard( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipbImpl::registerClipboardViewer( ) +{ + m_MtaOleClipboard.registerClipViewer( CWinClipbImpl::onClipboardContentChanged ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipbImpl::unregisterClipboardViewer( ) +{ + m_MtaOleClipboard.registerClipViewer( NULL ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipbImpl::dispose() throw( RuntimeException ) +{ + OSL_ENSURE( !m_pCurrentClipContent, "Clipboard was not flushed before shutdown!" ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void WINAPI CWinClipbImpl::onClipboardContentChanged( void ) +{ + MutexGuard aGuard( s_aMutex ); + + // reassocition to instance through static member + if ( NULL != s_pCWinClipbImpl ) + s_pCWinClipbImpl->m_pWinClipboard->notifyAllClipboardListener( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipbImpl::onReleaseDataObject( CXNotifyingDataObject* theCaller ) +{ + OSL_ASSERT( NULL != theCaller ); + + if ( theCaller ) + theCaller->lostOwnership( ); + + // if the current caller is the one we currently + // hold, then set it to NULL because an external + // source must be the clipboardowner now + MutexGuard aGuard( m_ClipContentMutex ); + + if ( m_pCurrentClipContent == theCaller ) + m_pCurrentClipContent = NULL; +} diff --git a/dtrans/source/win32/clipb/WinClipbImpl.hxx b/dtrans/source/win32/clipb/WinClipbImpl.hxx new file mode 100644 index 000000000000..c7b0a55a064a --- /dev/null +++ b/dtrans/source/win32/clipb/WinClipbImpl.hxx @@ -0,0 +1,125 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _WINCLIPBIMPL_HXX_ +#define _WINCLIPBIMPL_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <rtl/ustring.hxx> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include "..\..\inc\MtaOleClipb.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +class CWinClipboard; +class CXNotifyingDataObject; + +//--------------------------------------------------- +// impl class to avoid deadlocks between XTDataObject +// and the clipboard implementation +//--------------------------------------------------- + +class CWinClipbImpl +{ +public: + ~CWinClipbImpl( ); + +protected: + CWinClipbImpl( const ::rtl::OUString& aClipboardName, CWinClipboard* theWinClipboard ); + + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > SAL_CALL getContents( ) + throw( ::com::sun::star::uno::RuntimeException ); + + void SAL_CALL setContents( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& xTransferable, + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) + throw( ::com::sun::star::uno::RuntimeException ); + + ::rtl::OUString SAL_CALL getName( ) throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // XClipboardEx + //------------------------------------------------ + + sal_Int8 SAL_CALL getRenderingCapabilities( ) throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // XFlushableClipboard + //------------------------------------------------ + + void SAL_CALL flushClipboard( ) throw( com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // XComponent + //------------------------------------------------ + + void SAL_CALL dispose( ) throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // member functions + //------------------------------------------------ + + void SAL_CALL registerClipboardViewer( ); + void SAL_CALL unregisterClipboardViewer( ); + + static void WINAPI onClipboardContentChanged( void ); + +private: + void SAL_CALL onReleaseDataObject( CXNotifyingDataObject* theCaller ); + +private: + ::rtl::OUString m_itsName; + CMtaOleClipboard m_MtaOleClipboard; + CWinClipboard* m_pWinClipboard; + CXNotifyingDataObject* m_pCurrentClipContent; + osl::Mutex m_ClipContentMutex; + + static osl::Mutex s_aMutex; + static CWinClipbImpl* s_pCWinClipbImpl; + +private: + CWinClipbImpl( const CWinClipbImpl& ); + CWinClipbImpl& operator=( const CWinClipbImpl& ); + + friend class CWinClipboard; + friend class CXNotifyingDataObject; +}; + +#endif diff --git a/dtrans/source/win32/clipb/WinClipboard.cxx b/dtrans/source/win32/clipb/WinClipboard.cxx new file mode 100644 index 000000000000..0454460887e7 --- /dev/null +++ b/dtrans/source/win32/clipb/WinClipboard.cxx @@ -0,0 +1,322 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "WinClipboard.hxx" +#include <com/sun/star/datatransfer/clipboard/ClipboardEvent.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include "WinClipbImpl.hxx" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace rtl; +using namespace osl; +using namespace std; +using namespace cppu; + +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using namespace com::sun::star::lang; + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define WINCLIPBOARD_IMPL_NAME "com.sun.star.datatransfer.clipboard.ClipboardW32" + +//------------------------------------------------------------------------ +// helper functions +//------------------------------------------------------------------------ + +namespace +{ + Sequence< OUString > SAL_CALL WinClipboard_getSupportedServiceNames() + { + Sequence< OUString > aRet(1); + aRet[0] = OUString::createFromAscii("com.sun.star.datatransfer.clipboard.SystemClipboard"); + return aRet; + } +} + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ +/*XEventListener,*/ +CWinClipboard::CWinClipboard( const Reference< XMultiServiceFactory >& rServiceManager, const OUString& aClipboardName ) : + WeakComponentImplHelper4< XClipboardEx, XFlushableClipboard, XClipboardNotifier, XServiceInfo >( m_aCbListenerMutex ), + m_SrvMgr( rServiceManager ) +{ + m_pImpl.reset( new CWinClipbImpl( aClipboardName, this ) ); +} + +//======================================================================== +// XClipboard +//======================================================================== + +//------------------------------------------------------------------------ +// getContent +// to avoid unecessary traffic we check first if there is a clipboard +// content which was set via setContent, in this case we don't need +// to query the content from the clipboard, create a new wrapper object +// and so on, we simply return the orignial XTransferable instead of our +// DOTransferable +//------------------------------------------------------------------------ + +Reference< XTransferable > SAL_CALL CWinClipboard::getContents( ) throw( RuntimeException ) +{ + MutexGuard aGuard( m_aMutex ); + + if ( rBHelper.bDisposed ) + throw DisposedException( OUString::createFromAscii( "object is already disposed" ), + static_cast< XClipboardEx* >( this ) ); + + if ( NULL != m_pImpl.get( ) ) + return m_pImpl->getContents( ); + + return Reference< XTransferable >( ); +} + +//------------------------------------------------------------------------ +// setContent +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipboard::setContents( const Reference< XTransferable >& xTransferable, + const Reference< XClipboardOwner >& xClipboardOwner ) + throw( RuntimeException ) +{ + MutexGuard aGuard( m_aMutex ); + + if ( rBHelper.bDisposed ) + throw DisposedException( OUString::createFromAscii( "object is already disposed" ), + static_cast< XClipboardEx* >( this ) ); + + if ( NULL != m_pImpl.get( ) ) + m_pImpl->setContents( xTransferable, xClipboardOwner ); +} + +//------------------------------------------------------------------------ +// getName +//------------------------------------------------------------------------ + +OUString SAL_CALL CWinClipboard::getName( ) throw( RuntimeException ) +{ + if ( rBHelper.bDisposed ) + throw DisposedException( OUString::createFromAscii( "object is already disposed" ), + static_cast< XClipboardEx* >( this ) ); + + if ( NULL != m_pImpl.get( ) ) + return m_pImpl->getName( ); + + return OUString::createFromAscii( "" ); +} + +//======================================================================== +// XFlushableClipboard +//======================================================================== + +void SAL_CALL CWinClipboard::flushClipboard( ) throw( RuntimeException ) +{ + MutexGuard aGuard( m_aMutex ); + + if ( rBHelper.bDisposed ) + throw DisposedException( OUString::createFromAscii( "object is already disposed" ), + static_cast< XClipboardEx* >( this ) ); + + if ( NULL != m_pImpl.get( ) ) + m_pImpl->flushClipboard( ); +} + +//======================================================================== +// XClipboardEx +//======================================================================== + +sal_Int8 SAL_CALL CWinClipboard::getRenderingCapabilities( ) throw( RuntimeException ) +{ + if ( rBHelper.bDisposed ) + throw DisposedException( OUString::createFromAscii( "object is already disposed" ), + static_cast< XClipboardEx* >( this ) ); + + if ( NULL != m_pImpl.get( ) ) + return m_pImpl->getRenderingCapabilities( ); + + return 0; +} + +//======================================================================== +// XClipboardNotifier +//======================================================================== + +//------------------------------------------------------------------------ +// getName +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipboard::addClipboardListener( const Reference< XClipboardListener >& listener ) + throw( RuntimeException ) +{ + if ( rBHelper.bDisposed ) + throw DisposedException( OUString::createFromAscii( "object is already disposed" ), + static_cast< XClipboardEx* >( this ) ); + + // check input parameter + if ( !listener.is( ) ) + throw IllegalArgumentException( OUString::createFromAscii( "empty reference" ), + static_cast< XClipboardEx* >( this ), + 1 ); + + rBHelper.aLC.addInterface( getCppuType( &listener ), listener ); +} + +//------------------------------------------------------------------------ +// getName +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipboard::removeClipboardListener( const Reference< XClipboardListener >& listener ) + throw( RuntimeException ) +{ + if ( rBHelper.bDisposed ) + throw DisposedException( OUString::createFromAscii( "object is already disposed" ), + static_cast< XClipboardEx* >( this ) ); + + // check input parameter + if ( !listener.is( ) ) + throw IllegalArgumentException( OUString::createFromAscii( "empty reference" ), + static_cast< XClipboardEx* >( this ), + 1 ); + + rBHelper.aLC.removeInterface( getCppuType( &listener ), listener ); +} + +//------------------------------------------------------------------------ +// getName +//------------------------------------------------------------------------ + +void SAL_CALL CWinClipboard::notifyAllClipboardListener( ) +{ + if ( !rBHelper.bDisposed ) + { + ClearableMutexGuard aGuard( rBHelper.rMutex ); + if ( !rBHelper.bDisposed ) + { + aGuard.clear( ); + + OInterfaceContainerHelper* pICHelper = rBHelper.aLC.getContainer( + getCppuType( ( Reference< XClipboardListener > * ) 0 ) ); + + if ( pICHelper ) + { + try + { + OInterfaceIteratorHelper iter(*pICHelper); + Reference<XTransferable> rXTransf(m_pImpl->getContents()); + ClipboardEvent aClipbEvent(static_cast<XClipboard*>(this), rXTransf); + + while(iter.hasMoreElements()) + { + try + { + Reference<XClipboardListener> xCBListener(iter.next(), UNO_QUERY); + if (xCBListener.is()) + xCBListener->changedContents(aClipbEvent); + } + catch(RuntimeException&) + { + OSL_ENSURE( false, "RuntimeException caught" ); + } + } + } + catch(const ::com::sun::star::lang::DisposedException&) + { + OSL_ENSURE(false, "Service Manager disposed"); + + // no further clipboard changed notifications + m_pImpl->unregisterClipboardViewer(); + } + + } // end if + } // end if + } // end if +} + +//------------------------------------------------ +// overwritten base class method which will be +// called by the base class dispose method +//------------------------------------------------ + +void SAL_CALL CWinClipboard::disposing() +{ + // do my own stuff + m_pImpl->dispose( ); + + // force destruction of the impl class + m_pImpl.reset( NULL ); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +OUString SAL_CALL CWinClipboard::getImplementationName( ) + throw(RuntimeException) +{ + return OUString::createFromAscii( WINCLIPBOARD_IMPL_NAME ); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +sal_Bool SAL_CALL CWinClipboard::supportsService( const OUString& ServiceName ) + throw(RuntimeException) +{ + Sequence < OUString > SupportedServicesNames = WinClipboard_getSupportedServiceNames(); + + for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +Sequence< OUString > SAL_CALL CWinClipboard::getSupportedServiceNames( ) + throw(RuntimeException) +{ + return WinClipboard_getSupportedServiceNames(); +} diff --git a/dtrans/source/win32/clipb/WinClipboard.hxx b/dtrans/source/win32/clipb/WinClipboard.hxx new file mode 100644 index 000000000000..a8b48a246eb2 --- /dev/null +++ b/dtrans/source/win32/clipb/WinClipboard.hxx @@ -0,0 +1,157 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _WINCLIPBOARD_HXX_ +#define _WINCLIPBOARD_HXX_ + + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <cppuhelper/compbase4.hxx> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardListener.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <osl/conditn.hxx> + +#include <memory> + +// forward +class CWinClipbImpl; + +//------------------------------------------------------------------------ +// implements the XClipboard[Ex] ... interfaces +// for the clipboard viewer mechanism we need a static callback function +// and a static member to reasocciate from this static function to the +// class instance +// watch out: we are using only one static member variable and not a list +// because we assume to be instanciated only once +// this will be asured by an OneInstanceFactory of the service and not +// by this class! +//------------------------------------------------------------------------ + +// helper class, so that the mutex is constructed +// before the constructor of WeakComponentImplHelper +// will be called and initialized with this mutex +class CWinClipboardDummy +{ +protected: + osl::Mutex m_aMutex; + osl::Mutex m_aCbListenerMutex; +}; + +class CWinClipboard : + public CWinClipboardDummy, + public cppu::WeakComponentImplHelper4< + ::com::sun::star::datatransfer::clipboard::XClipboardEx, \ + ::com::sun::star::datatransfer::clipboard::XFlushableClipboard, + ::com::sun::star::datatransfer::clipboard::XClipboardNotifier, + ::com::sun::star::lang::XServiceInfo > +{ +public: + CWinClipboard( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager, + const ::rtl::OUString& aClipboardName ); + + //------------------------------------------------ + // XClipboard + //------------------------------------------------ + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > SAL_CALL getContents( ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setContents( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& xTransferable, + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL getName( ) + throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // XFlushableClipboard + //------------------------------------------------ + + virtual void SAL_CALL flushClipboard( ) throw( com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // XClipboardEx + //------------------------------------------------ + + virtual sal_Int8 SAL_CALL getRenderingCapabilities( ) throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // XClipboardNotifier + //------------------------------------------------ + + virtual void SAL_CALL addClipboardListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL removeClipboardListener( + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboardListener >& listener ) + throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // overwrite base class method, which is called + // by base class dispose function + //------------------------------------------------ + + virtual void SAL_CALL disposing(); + + //------------------------------------------------ + // XServiceInfo + //------------------------------------------------ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException); + +private: + void SAL_CALL notifyAllClipboardListener( ); + +private: + ::std::auto_ptr< CWinClipbImpl > m_pImpl; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr; + + friend class CWinClipbImpl; +}; + + +#endif diff --git a/dtrans/source/win32/clipb/exports.dxp b/dtrans/source/win32/clipb/exports.dxp new file mode 100644 index 000000000000..926e49f5f1a5 --- /dev/null +++ b/dtrans/source/win32/clipb/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_getFactory + diff --git a/dtrans/source/win32/clipb/makefile.mk b/dtrans/source/win32/clipb/makefile.mk new file mode 100644 index 000000000000..28f426d9296e --- /dev/null +++ b/dtrans/source/win32/clipb/makefile.mk @@ -0,0 +1,59 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=dtrans +TARGET=sysdtrans +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +USE_BOUNDCHK= + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +.IF "$(COM)" != "GCC" +CFLAGS+=-GR +.ENDIF +CFLAGS+=-DUNICODE -D_UNICODE + +SLOFILES=$(SLO)$/WinClipboard.obj \ + $(SLO)$/WinClipbImpl.obj \ + $(SLO)$/wcbentry.obj + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/dtrans/source/win32/clipb/sysdtrans.xml b/dtrans/source/win32/clipb/sysdtrans.xml new file mode 100644 index 000000000000..a6dec8a03a42 --- /dev/null +++ b/dtrans/source/win32/clipb/sysdtrans.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> sysdtrans </module-name> + <component-description> + <author> Tino Rachui </author> + <name> com.sun.star.comp.datatransfer.SystemClipboard </name> + <description> + The win32 implementation of the datatransfer service. +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.datatransfer.clipboard.SystemClipboard </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.datatransfer.clipboard.XClipboardEx </type> + <type> com.sun.star.datatransfer.XTransferable </type> + <type> com.sun.star.datatransfer.XTransferableEx </type> + <type> com.sun.star.datatransfer.clipboard.XClipboardOwner</type> + <type> com.sun.star.datatransfer.clipboard.XClipboardListener</type> + <type> com.sun.star.datatransfer.clipboard.XClipboardNotifier</type> + <type> com.sun.star.datatransfer.clipboard.XFlushableClipboard</type> + <type> com.sun.star.datatransfer.clipboard.RenderingCapabilities</type> + <type> com.sun.star.datatransfer.XTransferDataAccess </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.container.XSet </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/dtrans/source/win32/clipb/wcbentry.cxx b/dtrans/source/win32/clipb/wcbentry.cxx new file mode 100644 index 000000000000..653d97194efc --- /dev/null +++ b/dtrans/source/win32/clipb/wcbentry.cxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +//______________________________________________________________________________________________________________ +// includes of other projects +//______________________________________________________________________________________________________________ +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> +#include "WinClipboard.hxx" + +//----------------------------------------------------------------- +// some defines +//----------------------------------------------------------------- + +// the service names +#define WINCLIPBOARD_SERVICE_NAME "com.sun.star.datatransfer.clipboard.SystemClipboard" + +// the implementation names +#define WINCLIPBOARD_IMPL_NAME "com.sun.star.datatransfer.clipboard.ClipboardW32" + +// the registry key names +// a key under which this service will be registered, Format: -> "/ImplName/UNO/SERVICES/ServiceName" +// < Implementation-Name ></UNO/SERVICES/>< Service-Name > +#define WINCLIPBOARD_REGKEY_NAME "/com.sun.star.datatransfer.clipboard.ClipboardW32/UNO/SERVICES/com.sun.star.datatransfer.clipboard.SystemClipboard" + +//----------------------------------------------------------------------------------------------------------- +// namespace directives +//----------------------------------------------------------------------------------------------------------- + +using namespace ::rtl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::registry ; +using namespace ::cppu ; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::datatransfer::clipboard; + +//----------------------------------------------------------------- +// create a static object to initialize the shell9x library +//----------------------------------------------------------------- + +namespace +{ + + //----------------------------------------------------------------------------------------------------------- + // functions to create a new Clipboad instance; is needed by factory helper implementation + // @param rServiceManager - service manager, useful if the component needs other uno services + // so we should give it to every UNO-Implementation component + //----------------------------------------------------------------------------------------------------------- + + Reference< XInterface > SAL_CALL createInstance( const Reference< XMultiServiceFactory >& rServiceManager ) + { + return Reference< XInterface >( static_cast< XClipboard* >( new CWinClipboard( rServiceManager, rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" ) ) ) ) ); + } +} + +//----------------------------------------------------------------------------------------------------------- +// the 3 important functions which will be exported +//----------------------------------------------------------------------------------------------------------- + +extern "C" +{ + +//---------------------------------------------------------------------- +// component_getImplementationEnvironment +//---------------------------------------------------------------------- + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//---------------------------------------------------------------------- +// component_getFactory +// returns a factory to create XFilePicker-Services +//---------------------------------------------------------------------- + +void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* /*pRegistryKey*/ ) +{ + void* pRet = 0; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, WINCLIPBOARD_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( WINCLIPBOARD_SERVICE_NAME ) ); + + //OUString( RTL_CONSTASCII_USTRINGPARAM( FPS_IMPL_NAME ) ) + Reference< XSingleServiceFactory > xFactory ( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createInstance, + aSNS ) ); + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +} // extern "C" diff --git a/dtrans/source/win32/dnd/dnd.xml b/dtrans/source/win32/dnd/dnd.xml new file mode 100644 index 000000000000..10db2ddb2326 --- /dev/null +++ b/dtrans/source/win32/dnd/dnd.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> dnd </module-name> + <component-description> + <author> Joachim Lingner </author> + <name> com.sun.star.comp.datatransfer.dnd.OleDragAndDrop </name> + <description> + The win32 implementation of the drop target service. +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.datatransfer.dnd.OleDragSource</supported-service> + <supported-service> com.sun.star.datatransfer.dnd.OleDropTarget</supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.datatransfer.dnd.DNDConstants </type> + <type> com.sun.star.datatransfer.dnd.XDropTarget </type> + <type> com.sun.star.datatransfer.dnd.XDropTargetDragContext </type> + <type> com.sun.star.datatransfer.dnd.XDropTargetListener </type> + <type> com.sun.star.datatransfer.dnd.XDropTargetDropContext </type> + <type> com.sun.star.datatransfer.dnd.XDragSourceContext </type> + <type> com.sun.star.datatransfer.dnd.XDragSource </type> + <type> com.sun.star.datatransfer.XTransferable </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.lang.XInitialization </type> + <type> com.sun.star.lang.XUnoTunnel </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.awt.MouseButton </type> + <type> com.sun.star.awt.MouseEvent </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/dtrans/source/win32/dnd/dndentry.cxx b/dtrans/source/win32/dnd/dndentry.cxx new file mode 100644 index 000000000000..d37fa07ba3bd --- /dev/null +++ b/dtrans/source/win32/dnd/dndentry.cxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> + +#include "source.hxx" +#include "target.hxx" + +using namespace ::rtl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::registry ; +using namespace ::cppu ; +using namespace ::com::sun::star::lang; + +rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; + +Reference< XInterface > SAL_CALL createDragSource( const Reference< XMultiServiceFactory >& rServiceManager ) +{ + DragSource* pSource= new DragSource( rServiceManager ); + return Reference<XInterface>( static_cast<XInitialization*>(pSource), UNO_QUERY); +} + +Reference< XInterface > SAL_CALL createDropTarget( const Reference< XMultiServiceFactory >& rServiceManager ) +{ + DropTarget* pTarget= new DropTarget( rServiceManager ); + return Reference<XInterface>( static_cast<XInitialization*>(pTarget), UNO_QUERY); +} + + +extern "C" +{ +sal_Bool SAL_CALL component_canUnload( TimeValue *pTime ) +{ + return g_moduleCount.canUnload( &g_moduleCount , pTime ); +} + +//---------------------------------------------------------------------- +// component_getImplementationEnvironment +//---------------------------------------------------------------------- + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//---------------------------------------------------------------------- +// component_getFactory +// returns a factory to create XFilePicker-Services +//---------------------------------------------------------------------- + +void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* /*pRegistryKey*/ ) +{ + void* pRet = 0; + Reference< XSingleServiceFactory > xFactory; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, DNDSOURCE_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( DNDSOURCE_SERVICE_NAME ) ); + + xFactory= createSingleFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createDragSource, + aSNS, + &g_moduleCount.modCnt); + + } + else if( pSrvManager && ( 0 == rtl_str_compare( pImplName, DNDTARGET_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( DNDTARGET_SERVICE_NAME ) ); + + xFactory= createSingleFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createDropTarget, + aSNS); + + } + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + +} // extern "C" diff --git a/dtrans/source/win32/dnd/exports.dxp b/dtrans/source/win32/dnd/exports.dxp new file mode 100644 index 000000000000..f0e1c69934bc --- /dev/null +++ b/dtrans/source/win32/dnd/exports.dxp @@ -0,0 +1,2 @@ +component_getImplementationEnvironment +component_getFactory diff --git a/dtrans/source/win32/dnd/globals.cxx b/dtrans/source/win32/dnd/globals.cxx new file mode 100644 index 000000000000..9c6bdba5c024 --- /dev/null +++ b/dtrans/source/win32/dnd/globals.cxx @@ -0,0 +1,139 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> + +#include "globals.hxx" + +//--> TRA +#include <com/sun/star/datatransfer/XTransferable.hpp> + +// used as shortcut when drag-source and drop-target are the same +::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > g_XTransferable; + +//<-- TRA + +using namespace com::sun::star::datatransfer::dnd::DNDConstants; + +sal_Int8 dndOleKeysToAction( DWORD grfKeyState, sal_Int8 nSourceActions) +{ + sal_Int8 ret= 0; + + // no MK_ALT, MK_CONTROL, MK_SHIFT + if( !(grfKeyState & MK_CONTROL) && + !(grfKeyState & MK_ALT) && + !(grfKeyState & MK_RBUTTON) && + !(grfKeyState & MK_SHIFT)) + { + if( nSourceActions & ACTION_MOVE ) + { + ret= ACTION_DEFAULT | ACTION_MOVE; + } + + else if( nSourceActions & ACTION_COPY ) + { + ret= ACTION_COPY; + } + + else if( nSourceActions & ACTION_LINK ) + { + ret= ACTION_LINK; + } + + else + ret = 0; + } + else if( grfKeyState & MK_SHIFT && + !(grfKeyState & MK_CONTROL)) + { + ret= ACTION_MOVE; + } + else if ( grfKeyState & MK_CONTROL && + !(grfKeyState & MK_SHIFT) ) + { + ret= ACTION_COPY; + } + else if ( grfKeyState & MK_CONTROL && + grfKeyState & MK_SHIFT) + { + ret= ACTION_LINK; + } + else if ( grfKeyState & MK_RBUTTON | + grfKeyState & MK_ALT) + { + ret= ACTION_COPY_OR_MOVE | ACTION_LINK; + } + return ret; +} + + +sal_Int8 dndOleDropEffectsToActions( DWORD dwEffect) +{ + sal_Int8 ret= ACTION_NONE; + if( dwEffect & DROPEFFECT_COPY) + ret |= ACTION_COPY; + if( dwEffect & DROPEFFECT_MOVE) + ret |= ACTION_MOVE; + if( dwEffect & DROPEFFECT_LINK) + ret |= ACTION_LINK; + + return ret; +} + +DWORD dndActionsToDropEffects( sal_Int8 actions) +{ + DWORD ret= DROPEFFECT_NONE; + if( actions & ACTION_MOVE) + ret |= DROPEFFECT_MOVE; + if( actions & ACTION_COPY) + ret |= DROPEFFECT_COPY; + if( actions & ACTION_LINK) + ret |= DROPEFFECT_LINK; + if( actions & ACTION_DEFAULT) + ret |= DROPEFFECT_COPY; + return ret; +} + +DWORD dndActionsToSingleDropEffect( sal_Int8 actions) +{ + DWORD effects= dndActionsToDropEffects( actions); + + sal_Int8 countEffect= 0; + + if( effects & DROPEFFECT_MOVE) + countEffect++; + if( effects & DROPEFFECT_COPY) + countEffect++; + if( effects & DROPEFFECT_LINK) + countEffect++; + + // DROPEFFECT_MOVE is the default effect + DWORD retVal= countEffect > 1 ? DROPEFFECT_MOVE : effects; + return retVal; +} diff --git a/dtrans/source/win32/dnd/globals.hxx b/dtrans/source/win32/dnd/globals.hxx new file mode 100644 index 000000000000..0f21d00d7371 --- /dev/null +++ b/dtrans/source/win32/dnd/globals.hxx @@ -0,0 +1,94 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _GLOBALS_HXX_ +#define _GLOBALS_HXX_ + +#ifndef _OSL_MUTEX_H_ +#include <osl/mutex.hxx> +#endif + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <wtypes.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <sal/types.h> + + +#define DNDSOURCE_SERVICE_NAME "com.sun.star.datatransfer.dnd.OleDragSource" +#define DNDSOURCE_IMPL_NAME "com.sun.star.comp.datatransfer.dnd.OleDragSource_V1" +#define DNDSOURCE_REGKEY_NAME "/com.sun.star.comp.datatransfer.dnd.OleDragSource_V1/UNO/SERVICES/com.sun.star.datatransfer.dnd.OleDragSource" + +#define DNDTARGET_SERVICE_NAME "com.sun.star.datatransfer.dnd.OleDropTarget" +#define DNDTARGET_IMPL_NAME "com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1" +#define DNDTARGET_REGKEY_NAME "/com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1/UNO/SERVICES/com.sun.star.datatransfer.dnd.OleDropTarget" + +// This maps key states as occur as parameter, e.g. in IDropTarget::DragEnter, +// IDropSource::QueryContinueDrag, to actions as are declared in +// com::sun::star::datatransfer::dnd::DNDConstants ( ACTION_MOVE etc). +// If the grfKeyState indicates the ALt or right mousebutton then the returned +// values combines all possible actions. This is because those key and button are +// used when the user expect a menu to appear when he drops. The menu then +// contains entries, such as move, copy, link, cancel. +// An odd fact is that the argument grfKeyState in IDropTarget::Drop does not +// contain mouse buttons (winnt 4 SP6). That indicates that the right mouse button +// is not considered relevant in a drag operation. Contrarily the file explorer +// gives that button a special meaning: the user has to select the effect from +// a context menu on drop. +sal_Int8 dndOleKeysToAction( DWORD grfKeyState, sal_Int8 sourceActions); + +// The function maps a windows DROPEFFECTs to actions +// ( com::sun::star::datatransfer::dnd::DNDConstants). +// The argument can be a combination of different DROPEFFECTS, +// In that case the return value is also a combination of the +// appropriate actions. +sal_Int8 dndOleDropEffectsToActions( DWORD dwEffect); + +// The function maps actions ( com::sun::star::datatransfer::dnd::DNDConstants) +// to window DROPEFFECTs. +// The argument can be a combination of different actions +// In that case the return value is also a combination of the +// appropriate DROPEFFECTS. +DWORD dndActionsToDropEffects( sal_Int8 actions); + +// If the argument constitutes only one action then it is mapped to the +// corresponding DROPEFFECT otherwise DROPEFFECT_MOVE is returned. This is +// why move is the default effect (no modifiers pressed, or right mouse button +// or Alt). +DWORD dndActionsToSingleDropEffect( sal_Int8 actions); + + + +struct MutexDummy +{ + osl::Mutex m_mutex; +}; + + +#endif diff --git a/dtrans/source/win32/dnd/idroptarget.cxx b/dtrans/source/win32/dnd/idroptarget.cxx new file mode 100644 index 000000000000..702c9a3e567e --- /dev/null +++ b/dtrans/source/win32/dnd/idroptarget.cxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include "idroptarget.hxx" +#include <rtl/unload.h> + +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +extern rtl_StandardModuleCount g_moduleCount; + +IDropTargetImpl::IDropTargetImpl( DropTarget& pTarget): m_nRefCount( 0), + m_rDropTarget( pTarget) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +} + +IDropTargetImpl::~IDropTargetImpl() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + + +//IDropTarget +HRESULT STDMETHODCALLTYPE IDropTargetImpl::QueryInterface( REFIID riid, void **ppvObject) +{ + if( !ppvObject) + return E_POINTER; + *ppvObject= NULL; + + if( riid == __uuidof( IUnknown)) + *ppvObject= static_cast<IUnknown*>( this); + else if ( riid == __uuidof( IDropTarget)) + *ppvObject= static_cast<IDropTarget*>( this); + + if(*ppvObject) + { + AddRef(); + return S_OK; + } + else + return E_NOINTERFACE; + +} + +ULONG STDMETHODCALLTYPE IDropTargetImpl::AddRef( void) +{ + return InterlockedIncrement( &m_nRefCount); +} + +ULONG STDMETHODCALLTYPE IDropTargetImpl::Release( void) +{ + LONG count= InterlockedDecrement( &m_nRefCount); + if( m_nRefCount == 0 ) + delete this; + return count; +} + +STDMETHODIMP IDropTargetImpl::DragEnter( IDataObject __RPC_FAR *pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ + return m_rDropTarget.DragEnter( pDataObj, grfKeyState, + pt, pdwEffect); +} + +STDMETHODIMP IDropTargetImpl::DragOver( DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ + return m_rDropTarget.DragOver( grfKeyState, pt, pdwEffect); +} + +STDMETHODIMP IDropTargetImpl::DragLeave( void) +{ + return m_rDropTarget.DragLeave(); +} + +STDMETHODIMP IDropTargetImpl::Drop( IDataObject *pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD __RPC_FAR *pdwEffect) +{ + return m_rDropTarget.Drop( pDataObj, grfKeyState, + pt, pdwEffect); +} diff --git a/dtrans/source/win32/dnd/idroptarget.hxx b/dtrans/source/win32/dnd/idroptarget.hxx new file mode 100644 index 000000000000..dd3cbed3d893 --- /dev/null +++ b/dtrans/source/win32/dnd/idroptarget.hxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _IDROPTARGET_HXX_ +#define _IDROPTARGET_HXX_ + +#include "target.hxx" + +class IDropTargetImpl: public IDropTarget +{ + LONG m_nRefCount; + // Calls to IDropTarget functions are delegated to a DropTarget. + DropTarget& m_rDropTarget; + + virtual ~IDropTargetImpl(); // delete is only called by IUnknown::Release + IDropTargetImpl( const IDropTargetImpl& ); + IDropTargetImpl& operator=( const IDropTargetImpl& ); +public: + IDropTargetImpl( DropTarget& pTarget); + + // IDropTarget + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + virtual ULONG STDMETHODCALLTYPE AddRef( ); + + virtual ULONG STDMETHODCALLTYPE Release( ); + + virtual HRESULT STDMETHODCALLTYPE DragEnter( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragOver( + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragLeave( ) ; + + virtual HRESULT STDMETHODCALLTYPE Drop( + /* [unique][in] */ IDataObject __RPC_FAR *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD __RPC_FAR *pdwEffect); + + +}; +#endif diff --git a/dtrans/source/win32/dnd/makefile.mk b/dtrans/source/win32/dnd/makefile.mk new file mode 100644 index 000000000000..54fd748a0889 --- /dev/null +++ b/dtrans/source/win32/dnd/makefile.mk @@ -0,0 +1,66 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=dtrans +TARGET=dnd +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +USE_BOUNDCHK= + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +#CFLAGS+=-GR -DUNICODE -D_UNICODE + +#DBG_CONSOLE_OUT: when IDropTarget or IDropSource are called we write to a console +#DBG_CLIPBOARD_DATA: To provide DoDragDrop with an data object we call OleGetClipboard +#CFLAGS+= -DDBG_CONSOLE_OUT -DDBG_CLIPBOARD_DATA + + +SLOFILES= $(SLO)$/dndentry.obj \ + $(SLO)$/target.obj \ + $(SLO)$/idroptarget.obj \ + $(SLO)$/source.obj \ + $(SLO)$/globals.obj \ + $(SLO)$/targetdropcontext.obj \ + $(SLO)$/targetdragcontext.obj \ + $(SLO)$/sourcecontext.obj + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/dtrans/source/win32/dnd/source.cxx b/dtrans/source/win32/dnd/source.cxx new file mode 100644 index 000000000000..8c05d8806601 --- /dev/null +++ b/dtrans/source/win32/dnd/source.cxx @@ -0,0 +1,431 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/awt/MouseEvent.hpp> +#include <rtl/unload.h> + +#include <process.h> +#include <memory> + +#include "source.hxx" +#include "globals.hxx" +#include "sourcecontext.hxx" +#include "../../inc/DtObjFactory.hxx" +#include <rtl/ustring.h> +#include <process.h> +#include <winuser.h> +#include <stdio.h> + +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +using namespace com::sun::star::uno; +using namespace com::sun::star::awt::MouseButton; +using namespace com::sun::star::awt; +using namespace com::sun::star::lang; + +extern rtl_StandardModuleCount g_moduleCount; + +//--> TRA + +extern Reference< XTransferable > g_XTransferable; + +//<-- TRA + +unsigned __stdcall DndOleSTAFunc(LPVOID pParams); + +//---------------------------------------------------- +/** Ctor +*/ +DragSource::DragSource( const Reference<XMultiServiceFactory>& sf): + m_serviceFactory( sf), + WeakComponentImplHelper3< XDragSource, XInitialization, XServiceInfo >(m_mutex), +// m_pcurrentContext_impl(0), + m_hAppWindow(0), + m_MouseButton(0), + m_RunningDndOperationCount(0) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +} + +//---------------------------------------------------- +/** Dtor +*/ +DragSource::~DragSource() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +//---------------------------------------------------- +/** First start a new drag and drop thread if + the last one has finished + + ???? + Do we really need a separate thread for + every Dnd opeartion or only if the source + thread is an MTA thread + ???? +*/ +void DragSource::StartDragImpl( + const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 /*cursor*/, + sal_Int32 /*image*/, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener ) +{ + // The actions supported by the drag source + m_sourceActions= sourceActions; + // We need to know which mouse button triggered the operation. + // If it was the left one, then the drop occurs when that button + // has been released and if it was the right one then the drop + // occurs when the right button has been released. If the event is not + // set then we assume that the left button is pressed. + MouseEvent evtMouse; + trigger.Event >>= evtMouse; + m_MouseButton= evtMouse.Buttons; + + // The SourceContext class administers the XDragSourceListener s and + // fires events to them. An instance only exists in the scope of this + // functions. However, the drag and drop operation causes callbacks + // to the IDropSource interface implemented in this class (but only + // while this function executes). The source context is also used + // in DragSource::QueryContinueDrag. + m_currentContext= static_cast<XDragSourceContext*>( new SourceContext( + static_cast<DragSource*>(this), listener ) ); + + // Convert the XTransferable data object into an IDataObject object; + + //--> TRA + g_XTransferable = trans; + //<-- TRA + + m_spDataObject= m_aDataConverter.createDataObjFromTransferable( + m_serviceFactory, trans); + + // Obtain the id of the thread that created the window + DWORD processId; + m_threadIdWindow= GetWindowThreadProcessId( m_hAppWindow, &processId); + + // hold the instance for the DnD thread, it's to late + // to acquire at the start of the thread procedure + // the thread procedure is responsible for the release + acquire(); + + // The thread acccesses members of this instance but does not call acquire. + // Hopefully this instance is not destroyed before the thread has terminated. + unsigned threadId; + HANDLE hThread= reinterpret_cast<HANDLE>(_beginthreadex( + 0, 0, DndOleSTAFunc, reinterpret_cast<void*>(this), 0, &threadId)); + + // detach from thread + CloseHandle(hThread); +} + +// XInitialization + +//---------------------------------------------------- +/** aArguments contains a machine id +*/ +void SAL_CALL DragSource::initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException) +{ + if( aArguments.getLength() >=2) + m_hAppWindow= *(HWND*)aArguments[1].getValue(); + OSL_ASSERT( IsWindow( m_hAppWindow) ); +} + +//---------------------------------------------------- +/** XDragSource +*/ +sal_Bool SAL_CALL DragSource::isDragImageSupported( ) + throw(RuntimeException) +{ + return 0; +} + +//---------------------------------------------------- +/** +*/ +sal_Int32 SAL_CALL DragSource::getDefaultCursor( sal_Int8 /*dragAction*/ ) + throw( IllegalArgumentException, RuntimeException) +{ + return 0; +} + +//---------------------------------------------------- +/** Notifies the XDragSourceListener by + calling dragDropEnd +*/ +void SAL_CALL DragSource::startDrag( + const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 cursor, + sal_Int32 image, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener ) throw( RuntimeException) +{ + // Allow only one running dnd operation at a time, + // see XDragSource documentation + + long cnt = InterlockedIncrement(&m_RunningDndOperationCount); + + if (1 == cnt) + { + StartDragImpl(trigger, sourceActions, cursor, image, trans, listener); + } + else + { + //OSL_ENSURE(false, "Overlapping Drag&Drop operation rejected!"); + + cnt = InterlockedDecrement(&m_RunningDndOperationCount); + + DragSourceDropEvent dsde; + + dsde.DropAction = ACTION_NONE; + dsde.DropSuccess = false; + + try + { + listener->dragDropEnd(dsde); + } + catch(RuntimeException&) + { + OSL_ENSURE(false, "Runtime exception during event dispatching"); + } + } +} + +//---------------------------------------------------- +/**IDropTarget +*/ +HRESULT STDMETHODCALLTYPE DragSource::QueryInterface( REFIID riid, void **ppvObject) +{ + if( !ppvObject) + return E_POINTER; + *ppvObject= NULL; + + if( riid == __uuidof( IUnknown) ) + *ppvObject= static_cast<IUnknown*>( this); + else if ( riid == __uuidof( IDropSource) ) + *ppvObject= static_cast<IDropSource*>( this); + + if(*ppvObject) + { + AddRef(); + return S_OK; + } + else + return E_NOINTERFACE; + +} + +//---------------------------------------------------- +/** +*/ +ULONG STDMETHODCALLTYPE DragSource::AddRef( void) +{ + acquire(); + return (ULONG) m_refCount; +} + +//---------------------------------------------------- +/** +*/ +ULONG STDMETHODCALLTYPE DragSource::Release( void) +{ + ULONG ref= m_refCount; + release(); + return --ref; +} + +//---------------------------------------------------- +/** IDropSource +*/ +HRESULT STDMETHODCALLTYPE DragSource::QueryContinueDrag( +/* [in] */ BOOL fEscapePressed, +/* [in] */ DWORD grfKeyState) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDragSource::QueryContinueDrag"); +#endif + + HRESULT retVal= S_OK; // default continue DnD + + if (fEscapePressed) + { + retVal= DRAGDROP_S_CANCEL; + } + else + { + if( ( m_MouseButton == MouseButton::RIGHT && !(grfKeyState & MK_RBUTTON) ) || + ( m_MouseButton == MouseButton::MIDDLE && !(grfKeyState & MK_MBUTTON) ) || + ( m_MouseButton == MouseButton::LEFT && !(grfKeyState & MK_LBUTTON) ) || + ( m_MouseButton == 0 && !(grfKeyState & MK_LBUTTON) ) ) + { + retVal= DRAGDROP_S_DROP; + } + } + + // fire dropActionChanged event. + // this is actually done by the context, which also detects whether the action + // changed at all + sal_Int8 dropAction= fEscapePressed ? ACTION_NONE : + dndOleKeysToAction( grfKeyState, m_sourceActions); + + sal_Int8 userAction= fEscapePressed ? ACTION_NONE : + dndOleKeysToAction( grfKeyState, -1 ); + + static_cast<SourceContext*>(m_currentContext.get())->fire_dropActionChanged( + dropAction, userAction); + + return retVal; +} + +//---------------------------------------------------- +/** +*/ +HRESULT STDMETHODCALLTYPE DragSource::GiveFeedback( +/* [in] */ DWORD +#if defined DBG_CONSOLE_OUT +dwEffect +#endif +) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDragSource::GiveFeedback %d", dwEffect); +#endif + + return DRAGDROP_S_USEDEFAULTCURSORS; +} + +// XServiceInfo +OUString SAL_CALL DragSource::getImplementationName( ) throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_IMPL_NAME));; +} +// XServiceInfo +sal_Bool SAL_CALL DragSource::supportsService( const OUString& ServiceName ) throw (RuntimeException) +{ + if( ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_SERVICE_NAME )))) + return sal_True; + return sal_False; +} + +Sequence< OUString > SAL_CALL DragSource::getSupportedServiceNames( ) throw (RuntimeException) +{ + OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM(DNDSOURCE_SERVICE_NAME))}; + + return Sequence<OUString>(names, 1); +} + +//---------------------------------------------------- +/**This function is called as extra thread from + DragSource::executeDrag. The function + carries out a drag and drop operation by calling + DoDragDrop. The thread also notifies all + XSourceListener. +*/ +unsigned __stdcall DndOleSTAFunc(LPVOID pParams) +{ + // The structure contains all arguments for DoDragDrop and other + DragSource *pSource= (DragSource*)pParams; + + // Drag and drop only works in a thread in which OleInitialize is called. + HRESULT hr= OleInitialize( NULL); + + if(SUCCEEDED(hr)) + { + // We force the creation of a thread message queue. This is necessary + // for a later call to AttachThreadInput + MSG msgtemp; + PeekMessage( &msgtemp, NULL, WM_USER, WM_USER, PM_NOREMOVE); + + DWORD threadId= GetCurrentThreadId(); + + // This thread is attached to the thread that created the window. Hence + // this thread also receives all mouse and keyboard messages which are + // needed by DoDragDrop + AttachThreadInput( threadId , pSource->m_threadIdWindow, TRUE ); + + DWORD dwEffect= 0; + hr= DoDragDrop( + pSource->m_spDataObject.get(), + static_cast<IDropSource*>(pSource), + dndActionsToDropEffects( pSource->m_sourceActions), + &dwEffect); + + // #105428 detach my message queue from the other threads + // message queue before calling fire_dragDropEnd else + // the office may appear to hang sometimes + AttachThreadInput( threadId, pSource->m_threadIdWindow, FALSE); + + //--> TRA + // clear the global transferable again + g_XTransferable = Reference< XTransferable >( ); + //<-- TRA + + OSL_ENSURE( hr != E_INVALIDARG, "IDataObject impl does not contain valid data"); + + //Fire event + sal_Int8 action= hr == DRAGDROP_S_DROP ? dndOleDropEffectsToActions( dwEffect) : ACTION_NONE; + + static_cast<SourceContext*>(pSource->m_currentContext.get())->fire_dragDropEnd( + hr == DRAGDROP_S_DROP ? sal_True : sal_False, action); + + // Destroy SourceContextslkfgj + pSource->m_currentContext= 0; + // Destroy the XTransferable wrapper + pSource->m_spDataObject=0; + + OleUninitialize(); + } + + InterlockedDecrement(&pSource->m_RunningDndOperationCount); + + // the DragSource was manually acquired by + // thread starting method DelayedStartDrag + pSource->release(); + + return 0; +} + + + + diff --git a/dtrans/source/win32/dnd/source.hxx b/dtrans/source/win32/dnd/source.hxx new file mode 100644 index 000000000000..decf3f61368f --- /dev/null +++ b/dtrans/source/win32/dnd/source.hxx @@ -0,0 +1,151 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SOURCE_HXX_ +#define _SOURCE_HXX_ + +#include <com/sun/star/datatransfer/dnd/XDragSource.hpp> +#include <com/sun/star/datatransfer/dnd/XDragSourceContext.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#ifndef _OSL_MUTEX_H_ +#include <osl/mutex.hxx> +#endif +#ifndef _CPPUHELPER_COMPBASE2_HXX_ +#include <cppuhelper/compbase3.hxx> +#endif +#include <com/sun/star/lang/XServiceInfo.hpp> +#include "../../inc/DtObjFactory.hxx" +#include "globals.hxx" +#include <oleidl.h> + +#include <systools/win32/comtools.hxx> + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; + + + +class SourceContext; +// RIGHT MOUSE BUTTON drag and drop not supportet currently. +// ALT modifier is considered to effect a user selection of effects +class DragSource: + public MutexDummy, + public WeakComponentImplHelper3<XDragSource, XInitialization, XServiceInfo>, + public IDropSource + +{ + Reference<XMultiServiceFactory> m_serviceFactory; + HWND m_hAppWindow; + + // The mouse button that set off the drag and drop operation + short m_MouseButton; + // Converts XTransferable objects to IDataObject objects. + CDTransObjFactory m_aDataConverter; + + DragSource(); + DragSource(const DragSource&); + DragSource &operator= ( const DragSource&); + + // First starting a new drag and drop thread if + // the last one has finished + void StartDragImpl( + const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 cursor, + sal_Int32 image, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener); + +public: + long m_RunningDndOperationCount; + +public: + // only valid for one dnd operation + // the thread ID of the thread which created the window + DWORD m_threadIdWindow; + // The context notifies the XDragSourceListener s + Reference<XDragSourceContext> m_currentContext; + + // the wrapper for the Transferable ( startDrag) + IDataObjectPtr m_spDataObject; + + sal_Int8 m_sourceActions; + +public: + DragSource(const Reference<XMultiServiceFactory>& sf); + virtual ~DragSource(); + + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException); + + + // XDragSource + virtual sal_Bool SAL_CALL isDragImageSupported( ) throw(RuntimeException); + virtual sal_Int32 SAL_CALL getDefaultCursor( sal_Int8 dragAction ) + throw( IllegalArgumentException, RuntimeException); + virtual void SAL_CALL startDrag( const DragGestureEvent& trigger, + sal_Int8 sourceActions, + sal_Int32 cursor, + sal_Int32 image, + const Reference<XTransferable >& trans, + const Reference<XDragSourceListener >& listener ) + throw( RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + + + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + virtual ULONG STDMETHODCALLTYPE AddRef( ); + + virtual ULONG STDMETHODCALLTYPE Release( ); + + + // IDropSource + virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag( + /* [in] */ BOOL fEscapePressed, + /* [in] */ DWORD grfKeyState); + + virtual HRESULT STDMETHODCALLTYPE GiveFeedback( + /* [in] */ DWORD dwEffect); + +}; + + +#endif diff --git a/dtrans/source/win32/dnd/sourcecontext.cxx b/dtrans/source/win32/dnd/sourcecontext.cxx new file mode 100644 index 000000000000..da4d5c06eefb --- /dev/null +++ b/dtrans/source/win32/dnd/sourcecontext.cxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> + +#include "sourcecontext.hxx" +#include <rtl/unload.h> + +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +extern rtl_StandardModuleCount g_moduleCount; + +SourceContext::SourceContext( DragSource* pSource, + const Reference<XDragSourceListener>& listener): + WeakComponentImplHelper1<XDragSourceContext>(m_mutex), + m_pDragSource( pSource), + m_dragSource( static_cast<XDragSource*>( m_pDragSource) ) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +#if OSL_DEBUG_LEVEL > 1 + if( listener.is()) +#endif + rBHelper.addListener( ::getCppuType( &listener ), listener ); +} + +SourceContext::~SourceContext() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +void SAL_CALL SourceContext::addDragSourceListener( + const Reference<XDragSourceListener >& ) + throw( RuntimeException) +{ +} + +void SAL_CALL SourceContext::removeDragSourceListener( + const Reference<XDragSourceListener >& ) + throw( RuntimeException) +{ +} + +sal_Int32 SAL_CALL SourceContext::getCurrentCursor( ) + throw( RuntimeException) +{ + return 0; +} + +void SAL_CALL SourceContext::setCursor( sal_Int32 /*cursorId*/ ) + throw( RuntimeException) +{ +} + +void SAL_CALL SourceContext::setImage( sal_Int32 /*imageId*/ ) + throw( RuntimeException) +{ +} + +void SAL_CALL SourceContext::transferablesFlavorsChanged( ) + throw( RuntimeException) +{ +} + + +// non -interface functions +// Fires XDragSourceListener::dragDropEnd events. +void SourceContext::fire_dragDropEnd( sal_Bool success, sal_Int8 effect) +{ + + DragSourceDropEvent e; + + if( success == sal_True) + { + e.DropAction= effect; + e.DropSuccess= sal_True; + } + else + { + e.DropAction= ACTION_NONE; + e.DropSuccess= sal_False; + } + e.DragSource= m_dragSource; + e.DragSourceContext= static_cast<XDragSourceContext*>( this); + e.Source= Reference<XInterface>( static_cast<XDragSourceContext*>( this), UNO_QUERY); + + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( + getCppuType( (Reference<XDragSourceListener>* )0 ) ); + + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDragSourceListener> listener( + static_cast<XDragSourceListener*>( iter.next())); + listener->dragDropEnd( e); + } + } +} + + +void SourceContext::fire_dropActionChanged( sal_Int8 dropAction, sal_Int8 userAction) +{ + if( m_currentAction != dropAction) + { + m_currentAction= dropAction; + DragSourceDragEvent e; + e.DropAction= dropAction; + e.UserAction= userAction; + e.DragSource= m_dragSource; + e.DragSourceContext= static_cast<XDragSourceContext*>( this); + e.Source= Reference<XInterface>( static_cast<XDragSourceContext*>( this), UNO_QUERY); + + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( + getCppuType( (Reference<XDragSourceListener>* )0 ) ); + + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDragSourceListener> listener( + static_cast<XDragSourceListener*>( iter.next())); + listener->dropActionChanged( e); + } + } + } +} diff --git a/dtrans/source/win32/dnd/sourcecontext.hxx b/dtrans/source/win32/dnd/sourcecontext.hxx new file mode 100644 index 000000000000..db3f093b21a9 --- /dev/null +++ b/dtrans/source/win32/dnd/sourcecontext.hxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _SOURCECONTEXT_HXX_ +#define _SOURCECONTEXT_HXX_ + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDragSourceContext.hpp> +#include <cppuhelper/compbase1.hxx> + + +#include "source.hxx" + +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + + +// This class fires events to XDragSourceListener implementations. +// Of that interface only dragDropEnd and dropActionChanged are called. +// The functions dragEnter, dragExit and dragOver are not supported +// currently. +// An instance of SourceContext only lives as long as the drag and drop +// operation lasts. +class SourceContext: public MutexDummy, + public WeakComponentImplHelper1<XDragSourceContext> +{ + DragSource* m_pDragSource; + Reference<XDragSource> m_dragSource; + // the action ( copy, move etc) + sal_Int8 m_currentAction; + + SourceContext(); + SourceContext( const SourceContext&); + SourceContext &operator= (const SourceContext& ); + +public: + SourceContext( DragSource* pSource, const Reference<XDragSourceListener>& listener); + ~SourceContext(); + + virtual void SAL_CALL addDragSourceListener( const Reference<XDragSourceListener >& dsl ) + throw( RuntimeException); + virtual void SAL_CALL removeDragSourceListener( const Reference<XDragSourceListener >& dsl ) + throw( RuntimeException); + virtual sal_Int32 SAL_CALL getCurrentCursor( ) + throw( RuntimeException); + virtual void SAL_CALL setCursor( sal_Int32 cursorId ) + throw( RuntimeException); + virtual void SAL_CALL setImage( sal_Int32 imageId ) + throw( RuntimeException); + virtual void SAL_CALL transferablesFlavorsChanged( ) + throw( RuntimeException); + + + + // non - interface functions + void fire_dragDropEnd( sal_Bool success, sal_Int8 byte); + void fire_dropActionChanged( sal_Int8 dropAction, sal_Int8 userAction); + +}; + + + +#endif diff --git a/dtrans/source/win32/dnd/target.cxx b/dtrans/source/win32/dnd/target.cxx new file mode 100644 index 000000000000..6e2e28bcfc39 --- /dev/null +++ b/dtrans/source/win32/dnd/target.cxx @@ -0,0 +1,661 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <rtl/unload.h> + +#include <stdio.h> +#include "target.hxx" +#include "idroptarget.hxx" +#include "globals.hxx" +#include "targetdropcontext.hxx" +#include "targetdragcontext.hxx" +#include <rtl/ustring.h> +using namespace rtl; +using namespace cppu; +using namespace osl; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; + +#define WM_REGISTERDRAGDROP WM_USER + 1 +#define WM_REVOKEDRAGDROP WM_USER + 2 +//--> TRA +extern Reference< XTransferable > g_XTransferable; + +//<-- TRA + +extern rtl_StandardModuleCount g_moduleCount; +DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams); + +DropTarget::DropTarget( const Reference<XMultiServiceFactory>& sf): + m_hWnd( NULL), + m_serviceFactory( sf), + WeakComponentImplHelper3<XInitialization,XDropTarget, XServiceInfo>(m_mutex), + m_bActive(sal_True), + m_nDefaultActions(ACTION_COPY|ACTION_MOVE|ACTION_LINK|ACTION_DEFAULT), + m_nCurrentDropAction( ACTION_NONE), + m_oleThreadId( 0), + m_pDropTarget( NULL), + m_threadIdWindow(0), + m_threadIdTarget(0), + m_hOleThread(0), + m_nLastDropAction(0) + + +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); +} + + +DropTarget::~DropTarget() +{ + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); + +} +// called from WeakComponentImplHelperX::dispose +// WeakComponentImplHelper calls disposing before it destroys +// itself. +// NOTE: RevokeDragDrop decrements the ref count on the IDropTarget +// interface. (m_pDropTarget) +// If the HWND is invalid then it doesn't decrement and +// the IDropTarget object will live on. MEMORY LEAK +void SAL_CALL DropTarget::disposing() +{ + HRESULT hr= S_OK; + if( m_threadIdTarget) + { + // Call RevokeDragDrop and wait for the OLE thread to die; + PostThreadMessage( m_threadIdTarget, WM_REVOKEDRAGDROP, (WPARAM)this, 0); + WaitForSingleObject( m_hOleThread, INFINITE); + CloseHandle( m_hOleThread); + //OSL_ENSURE( SUCCEEDED( hr), "HWND not valid!" ); + } + else + { + hr= RevokeDragDrop( m_hWnd); + m_hWnd= 0; + } + if( m_pDropTarget) + { + CoLockObjectExternal( m_pDropTarget, FALSE, TRUE); + m_pDropTarget->Release(); + } + + if( m_oleThreadId) + { + if( m_oleThreadId == CoGetCurrentProcess() ) + OleUninitialize(); + } + +} + +void SAL_CALL DropTarget::initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException) +{ + // The window must be registered for Dnd by RegisterDragDrop. We must ensure + // that RegisterDragDrop is called from an STA ( OleInitialize) thread. + // As long as the window is registered we need to receive OLE messages in + // an OLE thread. That is to say, if DropTarget::initialize was called from an + // MTA thread then we create an OLE thread in which the window is registered. + // The thread will stay alive until aver RevokeDragDrop has been called. + + // Additionally even if RegisterDragDrop is called from an STA thread we have + // to ensure that it is called from the same thread that created the Window + // otherwise meesages sent during DND won't reach the windows message queue. + // Calling AttachThreadInput first would resolve this problem but would block + // the message queue of the calling thread. So if the current thread + // (even if it's an STA thread) and the thread that created the window are not + // identical we need to create a new thread as we do when the calling thread is + // an MTA thread. + + if( aArguments.getLength() > 0) + { + // Get the window handle from aArgument. It is needed for RegisterDragDrop. + m_hWnd= *(HWND*)aArguments[0].getValue(); + OSL_ASSERT( IsWindow( m_hWnd) ); + + // Obtain the id of the thread that created the window + m_threadIdWindow= GetWindowThreadProcessId( m_hWnd, NULL); + + HRESULT hr= OleInitialize( NULL); + + // Current thread is MTA or Current thread and Window thread are not identical + if( hr == RPC_E_CHANGED_MODE || GetCurrentThreadId() != m_threadIdWindow ) + { + OSL_ENSURE( ! m_threadIdTarget,"initialize was called twice"); + // create the IDropTargetImplementation + m_pDropTarget= new IDropTargetImpl( *static_cast<DropTarget*>( this) ); + m_pDropTarget->AddRef(); + + + // Obtain the id of the thread that created the window + m_threadIdWindow= GetWindowThreadProcessId( m_hWnd, NULL); + // The event is set by the thread that we will create momentarily. + // It indicates that the thread is ready to receive messages. + HANDLE m_evtThreadReady= CreateEvent( NULL, FALSE, FALSE, NULL); + + m_hOleThread= CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DndTargetOleSTAFunc, + &m_evtThreadReady, 0, &m_threadIdTarget); + WaitForSingleObject( m_evtThreadReady, INFINITE); + CloseHandle( m_evtThreadReady); + PostThreadMessage( m_threadIdTarget, WM_REGISTERDRAGDROP, (WPARAM)static_cast<DropTarget*>(this), 0); + } + else if( hr == S_OK || hr == S_FALSE) + { + // current thread is STA + // If OleInitialize has been called by the caller then we must not call + // OleUninitialize + if( hr == S_OK) + { + // caller did not call OleInitialize, so we call OleUninitialize + // remember the thread that will call OleUninitialize + m_oleThreadId= CoGetCurrentProcess(); // get a unique thread id + } + + // Get the window handle from aArgument. It is needed for RegisterDragDrop. + // create the IDropTargetImplementation + m_pDropTarget= new IDropTargetImpl( *static_cast<DropTarget*>( this) ); + m_pDropTarget->AddRef(); + // CoLockObjectExternal is prescribed by the protocol. It bumps up the ref count + if( SUCCEEDED( CoLockObjectExternal( m_pDropTarget, TRUE, FALSE))) + { + if( FAILED( RegisterDragDrop( m_hWnd, m_pDropTarget) ) ) + { + // do clean up if drag and drop is not possible + CoLockObjectExternal( m_pDropTarget, FALSE, FALSE); + m_pDropTarget->Release(); + m_hWnd= NULL; + } + } + } + else + throw Exception(); + + } +} + +// This function is called as extra thread from DragSource::startDrag. +// The function carries out a drag and drop operation by calling +// DoDragDrop. The thread also notifies all XSourceListener. +DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams) +{ + HRESULT hr= OleInitialize( NULL); + if( SUCCEEDED( hr) ) + { + MSG msg; + // force the creation of a message queue + PeekMessage( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE); + // Signal the creator ( DropTarget::initialize) that the thread is + // ready to receive messages. + SetEvent( *(HANDLE*) pParams); + // Thread id is needed for attaching this message queue to the one of the + // thread where the window was created. + DWORD threadId= GetCurrentThreadId(); + // We force the creation of a thread message queue. This is necessary + // for a later call to AttachThreadInput + while( GetMessage(&msg, (HWND)NULL, 0, 0) ) + { + if( msg.message == WM_REGISTERDRAGDROP) + { + DropTarget *pTarget= (DropTarget*)msg.wParam; + // This thread is attached to the thread that created the window. Hence + // this thread also receives all mouse and keyboard messages which are + // needed + AttachThreadInput( threadId , pTarget->m_threadIdWindow, TRUE ); + + if( SUCCEEDED( CoLockObjectExternal(pTarget-> m_pDropTarget, TRUE, FALSE))) + { + if( FAILED( RegisterDragDrop( pTarget-> m_hWnd, pTarget-> m_pDropTarget) ) ) + { + // do clean up if drag and drop is not possible + CoLockObjectExternal( pTarget->m_pDropTarget, FALSE, FALSE); + pTarget->m_pDropTarget->Release(); + pTarget->m_hWnd= NULL; + } + } + } + else if( msg.message == WM_REVOKEDRAGDROP) + { + DropTarget *pTarget= (DropTarget*)msg.wParam; + RevokeDragDrop( pTarget-> m_hWnd); + // Detach this thread from the window thread + AttachThreadInput( threadId, pTarget->m_threadIdWindow, FALSE); + pTarget->m_hWnd= 0; + break; + } + TranslateMessage( &msg); + DispatchMessage( &msg); + } + OleUninitialize(); + } + return 0; +} + + + + +// XServiceInfo +OUString SAL_CALL DropTarget::getImplementationName( ) throw (RuntimeException) +{ + return OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_IMPL_NAME));; +} +// XServiceInfo +sal_Bool SAL_CALL DropTarget::supportsService( const OUString& ServiceName ) throw (RuntimeException) +{ + if( ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_SERVICE_NAME )))) + return sal_True; + return sal_False; +} + +Sequence< OUString > SAL_CALL DropTarget::getSupportedServiceNames( ) throw (RuntimeException) +{ + OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_SERVICE_NAME))}; + return Sequence<OUString>(names, 1); +} + + +// XDropTarget ---------------------------------------------------------------- +void SAL_CALL DropTarget::addDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException) +{ + rBHelper.addListener( ::getCppuType( &dtl ), dtl ); +} + +void SAL_CALL DropTarget::removeDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException) +{ + rBHelper.removeListener( ::getCppuType( &dtl ), dtl ); +} + +sal_Bool SAL_CALL DropTarget::isActive( ) throw(RuntimeException) +{ + return m_bActive; //m_bDropTargetRegistered; +} + + +void SAL_CALL DropTarget::setActive( sal_Bool _b ) throw(RuntimeException) +{ + MutexGuard g(m_mutex); + m_bActive= _b; +} + + +sal_Int8 SAL_CALL DropTarget::getDefaultActions( ) throw(RuntimeException) +{ + return m_nDefaultActions; +} + +void SAL_CALL DropTarget::setDefaultActions( sal_Int8 actions ) throw(RuntimeException) +{ + OSL_ENSURE( actions < 8, "No valid default actions"); + m_nDefaultActions= actions; +} + + +HRESULT DropTarget::DragEnter( IDataObject *pDataObj, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::DragEnter state: %x effect %d", grfKeyState, *pdwEffect); +#endif + if( m_bActive ) + { + // Intersection of pdwEffect and the allowed actions ( setDefaultActions) + m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect); + // m_nLastDropAction has to be set by a listener. If no listener calls + //XDropTargetDragContext::acceptDrag and specifies an action then pdwEffect + // will be DROPEFFECT_NONE throughout + m_nLastDropAction= ACTION_DEFAULT | ACTION_MOVE; + + m_currentDragContext= static_cast<XDropTargetDragContext*>( new TargetDragContext( + static_cast<DropTarget*>(this) ) ); + + //--> TRA + + // shortcut + if ( g_XTransferable.is( ) ) + m_currentData = g_XTransferable; + else + { + // Convert the IDataObject to a XTransferable + m_currentData= m_aDataConverter.createTransferableFromDataObj( + m_serviceFactory, IDataObjectPtr(pDataObj)); + } + + //<-- TRA + + if( m_nCurrentDropAction != ACTION_NONE) + { + DropTargetDragEnterEvent e; + e.SupportedDataFlavors= m_currentData->getTransferDataFlavors(); + e.DropAction= m_nCurrentDropAction; + e.Source= Reference<XInterface>( static_cast<XDropTarget*>(this),UNO_QUERY); + e.Context= m_currentDragContext; + POINT point={ pt.x, pt.y}; + ScreenToClient( m_hWnd, &point); + e.LocationX= point.x; + e.LocationY= point.y; + e.SourceActions= dndOleDropEffectsToActions( *pdwEffect); + + fire_dragEnter( e); + // Check if the action derived from grfKeyState (m_nCurrentDropAction) or the action set + // by the listener (m_nCurrentDropAction) is allowed by the source. Only a allowed action is set + // in pdwEffect. The listener notification is asynchron, that is we cannot expext that the listener + // has already reacted to the notification. + // If there is more then one valid action which is the case when ALT or RIGHT MOUSE BUTTON is pressed + // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed. + // On drop the target should present the user a dialog from which the user may change the action. + sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect); + *pdwEffect= dndActionsToSingleDropEffect( m_nLastDropAction & allowedActions); + } + else + { + *pdwEffect= DROPEFFECT_NONE; + } + } + return S_OK; +} + +HRESULT DropTarget::DragOver( DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ + if( m_bActive) + { + m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect); + + if( m_nCurrentDropAction) + { + DropTargetDragEvent e; + e.DropAction= m_nCurrentDropAction; + e.Source= Reference<XInterface>(static_cast<XDropTarget*>(this),UNO_QUERY); + e.Context= m_currentDragContext; + POINT point={ pt.x, pt.y}; + ScreenToClient( m_hWnd, &point); + e.LocationX= point.x; + e.LocationY= point.y; + e.SourceActions= dndOleDropEffectsToActions( *pdwEffect); + + // if grfKeyState has changed since the last DragOver then fire events. + // A listener might change m_nCurrentDropAction by calling the + // XDropTargetDragContext::acceptDrag function. But this is not important + // because in the afterwards fired dragOver event the action reflects + // grgKeyState again. + if( m_nLastDropAction != m_nCurrentDropAction) + fire_dropActionChanged( e); + + // The Event contains a XDropTargetDragContext implementation. + fire_dragOver( e); + // Check if the action derived from grfKeyState (m_nCurrentDropAction) or the action set + // by the listener (m_nCurrentDropAction) is allowed by the source. Only a allowed action is set + // in pdwEffect. The listener notification is asynchron, that is we cannot expext that the listener + // has already reacted to the notification. + // If there is more then one valid action which is the case when ALT or RIGHT MOUSE BUTTON is pressed + // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed. + // On drop the target should present the user a dialog from which the user may change the action. + sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect); + // set the last action to the current if listener has not changed the value yet + *pdwEffect= dndActionsToSingleDropEffect( m_nLastDropAction & allowedActions); + } + else + { + *pdwEffect= DROPEFFECT_NONE; + } + } +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::DragOver %d", *pdwEffect ); +#endif + return S_OK; +} + +HRESULT DropTarget::DragLeave( void) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::DragLeave"); +#endif + if( m_bActive) + { + + m_currentData=0; + m_currentDragContext= 0; + m_currentDropContext= 0; + m_nLastDropAction= 0; + + if( m_nDefaultActions != ACTION_NONE) + { + DropTargetEvent e; + e.Source= static_cast<XDropTarget*>(this); + + fire_dragExit( e); + } + } + return S_OK; +} + +HRESULT DropTarget::Drop( IDataObject * /*pDataObj*/, + DWORD grfKeyState, + POINTL pt, + DWORD *pdwEffect) +{ +#if defined DBG_CONSOLE_OUT + printf("\nDropTarget::Drop"); +#endif + if( m_bActive) + { + + m_bDropComplete= sal_False; + + m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect); + m_currentDropContext= static_cast<XDropTargetDropContext*>( new TargetDropContext( static_cast<DropTarget*>(this )) ); + if( m_nCurrentDropAction) + { + DropTargetDropEvent e; + e.DropAction= m_nCurrentDropAction; + e.Source= Reference<XInterface>( static_cast<XDropTarget*>(this), UNO_QUERY); + e.Context= m_currentDropContext; + POINT point={ pt.x, pt.y}; + ScreenToClient( m_hWnd, &point); + e.LocationX= point.x; + e.LocationY= point.y; + e.SourceActions= dndOleDropEffectsToActions( *pdwEffect); + e.Transferable= m_currentData; + fire_drop( e); + + //if fire_drop returns than a listener might have modified m_nCurrentDropAction + if( m_bDropComplete == sal_True) + { + sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect); + *pdwEffect= dndActionsToSingleDropEffect( m_nCurrentDropAction & allowedActions); + } + else + *pdwEffect= DROPEFFECT_NONE; + } + else + *pdwEffect= DROPEFFECT_NONE; + + m_currentData= 0; + m_currentDragContext= 0; + m_currentDropContext= 0; + m_nLastDropAction= 0; + } + return S_OK; +} + + + +void DropTarget::fire_drop( const DropTargetDropEvent& dte) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->drop( dte); + } + } +} + +void DropTarget::fire_dragEnter( const DropTargetDragEnterEvent& e ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dragEnter( e); + } + } +} + +void DropTarget::fire_dragExit( const DropTargetEvent& dte ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dragExit( dte); + } + } +} + +void DropTarget::fire_dragOver( const DropTargetDragEvent& dtde ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer ); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dragOver( dtde); + } + } +} + +void DropTarget::fire_dropActionChanged( const DropTargetDragEvent& dtde ) +{ + OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) ); + if( pContainer) + { + OInterfaceIteratorHelper iter( *pContainer); + while( iter.hasMoreElements()) + { + Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next())); + listener->dropActionChanged( dtde); + } + } +} + +// Non - interface functions ============================================================ +// DropTarget fires events to XDropTargetListeners. The event object contains an +// XDropTargetDropContext implementaion. When the listener calls on that interface +// then the calls are delegated from DropContext (XDropTargetDropContext) to these +// functions. +// Only one listener which visible area is affected is allowed to call on +// XDropTargetDropContext +// Returning sal_False would cause the XDropTargetDropContext or ..DragContext implementation +// to throw an InvalidDNDOperationException, meaning that a Drag is not currently performed. +// return sal_False results in throwing a InvalidDNDOperationException in the caller. + +void DropTarget::_acceptDrop(sal_Int8 dropOperation, const Reference<XDropTargetDropContext>& context) +{ + if( context == m_currentDropContext) + { + m_nCurrentDropAction= dropOperation; + } +} + +void DropTarget::_rejectDrop( const Reference<XDropTargetDropContext>& context) +{ + if( context == m_currentDropContext) + { + m_nCurrentDropAction= ACTION_NONE; + } +} + +void DropTarget::_dropComplete(sal_Bool success, const Reference<XDropTargetDropContext>& context) +{ + if(context == m_currentDropContext) + { + m_bDropComplete= success; + } +} +// -------------------------------------------------------------------------------------- +// DropTarget fires events to XDropTargetListeners. The event object can contains an +// XDropTargetDragContext implementaion. When the listener calls on that interface +// then the calls are delegated from DragContext (XDropTargetDragContext) to these +// functions. +// Only one listener which visible area is affected is allowed to call on +// XDropTargetDragContext +void DropTarget::_acceptDrag( sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context) +{ + if( context == m_currentDragContext) + { + m_nLastDropAction= dragOperation; + } +} + +void DropTarget::_rejectDrag( const Reference<XDropTargetDragContext>& context) +{ + if(context == m_currentDragContext) + { + m_nLastDropAction= ACTION_NONE; + } +} + + +//-------------------------------------------------------------------------------------- + + +// This function determines the action dependend on the pressed +// key modifiers ( CTRL, SHIFT, ALT, Right Mouse Button). The result +// is then checked against the allowed actions which can be set through +// XDropTarget::setDefaultActions. Only those values which are also +// default actions are returned. If setDefaultActions has not been called +// beforehand the the default actions comprise all possible actions. +// params: grfKeyState - the modifier keys and mouse buttons currently pressed +inline sal_Int8 DropTarget::getFilteredActions( DWORD grfKeyState, DWORD dwEffect) +{ + sal_Int8 actions= dndOleKeysToAction( grfKeyState, dndOleDropEffectsToActions( dwEffect)); + return actions & m_nDefaultActions; +} + + diff --git a/dtrans/source/win32/dnd/target.hxx b/dtrans/source/win32/dnd/target.hxx new file mode 100644 index 000000000000..94982b54818f --- /dev/null +++ b/dtrans/source/win32/dnd/target.hxx @@ -0,0 +1,213 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _TARGET_HXX_ +#define _TARGET_HXX_ + +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#ifndef _CPPUHELPER_COMPBASE2_HXX_ +#include <cppuhelper/compbase3.hxx> +#endif +#include <cppuhelper/interfacecontainer.hxx> +#ifndef _OSL_MUTEX_H_ +#include <osl/mutex.hxx> +#endif + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <oleidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include "globals.hxx" +#include "../../inc/DtObjFactory.hxx" + + +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace cppu; +using namespace osl; +using namespace rtl; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; + + +// The client +// has to call XComponent::dispose. The thread that calls initialize +// must also execute the destruction of the instance. This is because +// initialize calls OleInitialize and the destructor calls OleUninitialize. +// If the service calls OleInitialize then it also calls OleUnitialize when +// it is destroyed. Therefore no second instance may exist which was +// created in the same thread and still needs OLE. +class DropTarget: public MutexDummy, + public WeakComponentImplHelper3< XInitialization, XDropTarget, XServiceInfo> + +{ +private: + friend DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams); + // The native window which acts as drop target. + // It is set in initialize. In case RegisterDragDrop fails it is set + // to NULL + HWND m_hWnd; // set by initialize + // Holds the thread id of the thread which created the window that is the + // drop target. Only used when DropTarget::initialize is called from an MTA + // thread + DWORD m_threadIdWindow; + // This is the thread id of the OLE thread that is created in DropTarget::initialize + // when the calling thread is an MTA + DWORD m_threadIdTarget; + // The handle of the thread that is created in DropTarget::initialize + // when the calling thread is an MTA + HANDLE m_hOleThread; + // The thread id of the thread which called initialize. When the service dies + // than m_oleThreadId is used to determine if the service successfully called + // OleInitialize. If so then OleUninitialize has to be called. + DWORD m_oleThreadId; + // An Instance of IDropTargetImpl which receives calls from the system's drag + // and drop implementation. It delegate the calls to name alike functions in + // this class. + IDropTarget* m_pDropTarget; + + Reference<XMultiServiceFactory> m_serviceFactory; + // If m_bActive == sal_True then events are fired to XDropTargetListener s, + // none otherwise. The default value is sal_True. + sal_Bool m_bActive; + sal_Int8 m_nDefaultActions; + + // This value is set when a XDropTargetListener calls accept or reject on + // the XDropTargetDropContext or XDropTargetDragContext. + // The values are from the DNDConstants group. + sal_Int8 m_nCurrentDropAction; + // This value is manipulated by the XDropTargetListener + sal_Int8 m_nLastDropAction; + + Reference<XTransferable> m_currentData; + // The current action is used to determine if the USER + // action has changed (dropActionChanged) +// sal_Int8 m_userAction; + // Set by listeners when they call XDropTargetDropContext::dropComplete + sal_Bool m_bDropComplete; + // converts IDataObject objects to XTransferable objects. + CDTransObjFactory m_aDataConverter; + Reference<XDropTargetDragContext> m_currentDragContext; + Reference<XDropTargetDropContext> m_currentDropContext; + + +private: + DropTarget(); + DropTarget(DropTarget&); + DropTarget &operator= (DropTarget&); + +public: + DropTarget(const Reference<XMultiServiceFactory>& sf); + virtual ~DropTarget(); + + // Overrides WeakComponentImplHelper::disposing which is called by + // WeakComponentImplHelper::dispose + // Must be called. + virtual void SAL_CALL disposing(); + // XInitialization + virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) + throw(Exception, RuntimeException); + + // XDropTarget + virtual void SAL_CALL addDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException); + virtual void SAL_CALL removeDropTargetListener( const Reference< XDropTargetListener >& dtl ) + throw(RuntimeException); + // Default is not active + virtual sal_Bool SAL_CALL isActive( ) throw(RuntimeException); + virtual void SAL_CALL setActive( sal_Bool isActive ) throw(RuntimeException); + virtual sal_Int8 SAL_CALL getDefaultActions( ) throw(RuntimeException); + virtual void SAL_CALL setDefaultActions( sal_Int8 actions ) throw(RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); + + + // Functions called from the IDropTarget implementation ( m_pDropTarget) + virtual HRESULT DragEnter( + /* [unique][in] */ IDataObject *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragOver( + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD *pdwEffect); + + virtual HRESULT STDMETHODCALLTYPE DragLeave( ) ; + + virtual HRESULT STDMETHODCALLTYPE Drop( + /* [unique][in] */ IDataObject *pDataObj, + /* [in] */ DWORD grfKeyState, + /* [in] */ POINTL pt, + /* [out][in] */ DWORD *pdwEffect); + + +// Non - interface functions -------------------------------------------------- +// XDropTargetDropContext delegated from DropContext + + void _acceptDrop( sal_Int8 dropOperation, const Reference<XDropTargetDropContext>& context); + void _rejectDrop( const Reference<XDropTargetDropContext>& context); + void _dropComplete( sal_Bool success, const Reference<XDropTargetDropContext>& context); + +// XDropTargetDragContext delegated from DragContext + void _acceptDrag( sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context); + void _rejectDrag( const Reference<XDropTargetDragContext>& context); + + +protected: + // Gets the current action dependend on the pressed modifiers, the effects + // supported by the drop source (IDropSource) and the default actions of the + // drop target (XDropTarget, this class)) + inline sal_Int8 getFilteredActions( DWORD grfKeyState, DWORD sourceActions); + // Only filters with the default actions + inline sal_Int8 getFilteredActions( DWORD grfKeyState); + + + + void fire_drop( const DropTargetDropEvent& dte); + void fire_dragEnter( const DropTargetDragEnterEvent& dtde ); + void fire_dragExit( const DropTargetEvent& dte ); + void fire_dragOver( const DropTargetDragEvent& dtde ); + void fire_dropActionChanged( const DropTargetDragEvent& dtde ); + + + + +}; + + +#endif diff --git a/dtrans/source/win32/dnd/targetdragcontext.cxx b/dtrans/source/win32/dnd/targetdragcontext.cxx new file mode 100644 index 000000000000..15f7ea32a1ef --- /dev/null +++ b/dtrans/source/win32/dnd/targetdragcontext.cxx @@ -0,0 +1,59 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <rtl/unload.h> + +#include "targetdragcontext.hxx" + +extern rtl_StandardModuleCount g_moduleCount; +TargetDragContext::TargetDragContext( DropTarget* p) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + m_pDropTarget= p; + p->acquire(); +} + +TargetDragContext::~TargetDragContext() +{ + m_pDropTarget->release(); + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +void SAL_CALL TargetDragContext::acceptDrag( sal_Int8 dragOperation ) + throw( RuntimeException) +{ + m_pDropTarget->_acceptDrag( dragOperation, static_cast<XDropTargetDragContext*>( this) ); + +} +void SAL_CALL TargetDragContext::rejectDrag( ) + throw( RuntimeException) +{ + m_pDropTarget->_rejectDrag( static_cast<XDropTargetDragContext*>( this) ); +} + diff --git a/dtrans/source/win32/dnd/targetdragcontext.hxx b/dtrans/source/win32/dnd/targetdragcontext.hxx new file mode 100644 index 000000000000..e4b24b95b0a0 --- /dev/null +++ b/dtrans/source/win32/dnd/targetdragcontext.hxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TARGETDRAGCONTEXT_HXX_ +#define _TARGETDRAGCONTEXT_HXX_ + + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDropTargetDragContext.hpp> +#include <com/sun/star/datatransfer/DataFlavor.hpp> + +#include "target.hxx" +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +class TargetDragContext: public WeakImplHelper1<XDropTargetDragContext> +{ + // some calls to the functions of XDropTargetDragContext are delegated + // to non-interface functions of m_pDropTarget + DropTarget* m_pDropTarget; + + TargetDragContext(); + TargetDragContext( const TargetDragContext&); + TargetDragContext &operator= ( const TargetDragContext&); +public: + TargetDragContext( DropTarget* pTarget); + ~TargetDragContext(); + + virtual void SAL_CALL acceptDrag( sal_Int8 dragOperation ) + throw( RuntimeException); + virtual void SAL_CALL rejectDrag( ) + throw( RuntimeException); +}; + +#endif diff --git a/dtrans/source/win32/dnd/targetdropcontext.cxx b/dtrans/source/win32/dnd/targetdropcontext.cxx new file mode 100644 index 000000000000..a009b8df7527 --- /dev/null +++ b/dtrans/source/win32/dnd/targetdropcontext.cxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <rtl/unload.h> + +#include "targetdropcontext.hxx" + +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +extern rtl_StandardModuleCount g_moduleCount; +TargetDropContext::TargetDropContext( DropTarget* p) +{ + g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); + m_pDropTarget= p; + p->acquire(); +} + +TargetDropContext::~TargetDropContext() +{ + m_pDropTarget->release(); + g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); +} + +void SAL_CALL TargetDropContext::acceptDrop( sal_Int8 dropOperation ) + throw( RuntimeException) +{ + m_pDropTarget->_acceptDrop( dropOperation, static_cast<XDropTargetDropContext*>( this) ); +} + +void SAL_CALL TargetDropContext::rejectDrop( ) + throw( RuntimeException) +{ + m_pDropTarget->_rejectDrop( static_cast<XDropTargetDropContext*>( this) ); +} + +void SAL_CALL TargetDropContext::dropComplete( sal_Bool success ) + throw( RuntimeException) +{ + m_pDropTarget->_dropComplete( success, static_cast<XDropTargetDropContext*>( this) ); +} diff --git a/dtrans/source/win32/dnd/targetdropcontext.hxx b/dtrans/source/win32/dnd/targetdropcontext.hxx new file mode 100644 index 000000000000..6ae6f0182a36 --- /dev/null +++ b/dtrans/source/win32/dnd/targetdropcontext.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TARGETDROPCONTEXT_HXX_ +#define _TARGETDROPCONTEXT_HXX_ + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDropTargetDropContext.hpp> + +#include "target.hxx" + +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +class TargetDropContext: public WeakImplHelper1<XDropTargetDropContext> +{ + // calls to the functions of XDropTargetDropContext are delegated + // to non-interface functions of m_pDropTarget + DropTarget* m_pDropTarget; + + TargetDropContext(); + TargetDropContext( const TargetDropContext&); + TargetDropContext &operator= ( const TargetDropContext&); +public: + TargetDropContext( DropTarget* pTarget); + ~TargetDropContext(); + + + // XDropTargetDragContext + virtual void SAL_CALL acceptDrop( sal_Int8 dropOperation ) + throw( RuntimeException); + virtual void SAL_CALL rejectDrop( ) + throw( RuntimeException); + + +/* virtual Sequence< DataFlavor > SAL_CALL getCurrentDataFlavors( ) + throw( RuntimeException); + virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& df ) + throw( RuntimeException); +*/ + + // XDropTargetDropContext (inherits XDropTargetDragContext) + virtual void SAL_CALL dropComplete( sal_Bool success ) + throw( RuntimeException); +}; +#endif diff --git a/dtrans/source/win32/dtobj/APNDataObject.cxx b/dtrans/source/win32/dtobj/APNDataObject.cxx new file mode 100644 index 000000000000..775e952ac885 --- /dev/null +++ b/dtrans/source/win32/dtobj/APNDataObject.cxx @@ -0,0 +1,378 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include "APNDataObject.hxx" +#include <osl/diagnose.h> + +#include <systools/win32/comtools.hxx> +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define FREE_HGLOB_ON_RELEASE TRUE +#define KEEP_HGLOB_ON_RELEASE FALSE + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +CAPNDataObject::CAPNDataObject( IDataObjectPtr rIDataObject ) : + m_rIDataObjectOrg( rIDataObject ), + m_hGlobal( NULL ), + m_nRefCnt( 0 ) +{ + + OSL_ENSURE( m_rIDataObjectOrg.get( ), "constructing CAPNDataObject with empty data object" ); + + // we marshal the IDataObject interface pointer here so + // that it can be unmarshaled multiple times when this + // class will be used from another apartment + IStreamPtr pStm; + HRESULT hr = CreateStreamOnHGlobal( 0, KEEP_HGLOB_ON_RELEASE, &pStm ); + + OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" ); + + if ( SUCCEEDED( hr ) ) + { + HRESULT hr_marshal = CoMarshalInterface( + pStm.get(), + __uuidof(IDataObject), + static_cast<LPUNKNOWN>(m_rIDataObjectOrg.get()), + MSHCTX_LOCAL, + NULL, + MSHLFLAGS_TABLEWEAK ); + + OSL_ENSURE( CO_E_NOTINITIALIZED != hr_marshal, "COM is not initialized" ); + + // marshalling may fail if COM is not initialized + // for the calling thread which is a program time + // error or because of stream errors which are runtime + // errors for instance E_OUTOFMEMORY etc. + + hr = GetHGlobalFromStream(pStm.get(), &m_hGlobal ); + + OSL_ENSURE( E_INVALIDARG != hr, "invalid stream passed to GetHGlobalFromStream" ); + + // if the marshalling failed we free the + // global memory again and set m_hGlobal + // to a defined value + if (FAILED(hr_marshal)) + { + OSL_ENSURE(sal_False, "marshalling failed"); + + #if OSL_DEBUG_LEVEL > 0 + HGLOBAL hGlobal = + #endif + GlobalFree(m_hGlobal); + OSL_ENSURE(NULL == hGlobal, "GlobalFree failed"); + m_hGlobal = NULL; + } + } +} + +CAPNDataObject::~CAPNDataObject( ) +{ + if (m_hGlobal) + { + IStreamPtr pStm; + HRESULT hr = CreateStreamOnHGlobal(m_hGlobal, FREE_HGLOB_ON_RELEASE, &pStm); + + OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" ); + + if (SUCCEEDED(hr)) + { + hr = CoReleaseMarshalData(pStm.get()); + OSL_ENSURE(SUCCEEDED(hr), "CoReleaseMarshalData failed"); + } + } +} + +//------------------------------------------------------------------------ +// IUnknown->QueryInterface +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject ) +{ + OSL_ASSERT( NULL != ppvObject ); + + if ( NULL == ppvObject ) + return E_INVALIDARG; + + HRESULT hr = E_NOINTERFACE; + *ppvObject = NULL; + + if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) ) + { + *ppvObject = static_cast< IUnknown* >( this ); + ( (LPUNKNOWN)*ppvObject )->AddRef( ); + hr = S_OK; + } + + return hr; +} + +//------------------------------------------------------------------------ +// IUnknown->AddRef +//------------------------------------------------------------------------ + +STDMETHODIMP_(ULONG) CAPNDataObject::AddRef( ) +{ + return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) ); +} + +//------------------------------------------------------------------------ +// IUnknown->Release +//------------------------------------------------------------------------ + +STDMETHODIMP_(ULONG) CAPNDataObject::Release( ) +{ + // we need a helper variable because it's not allowed to access + // a member variable after an object is destroyed + ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) ); + + if ( 0 == nRefCnt ) + delete this; + + return nRefCnt; +} + +//------------------------------------------------------------------------ +// IDataObject->GetData +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ) +{ + HRESULT hr = m_rIDataObjectOrg->GetData( pFormatetc, pmedium ); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->GetData(pFormatetc, pmedium); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->EnumFormatEtc +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ) +{ + HRESULT hr = m_rIDataObjectOrg->EnumFormatEtc(dwDirection, ppenumFormatetc); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->EnumFormatEtc(dwDirection, ppenumFormatetc); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->QueryGetData +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::QueryGetData( LPFORMATETC pFormatetc ) +{ + HRESULT hr = m_rIDataObjectOrg->QueryGetData( pFormatetc ); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment( &pIDOTmp ); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->QueryGetData(pFormatetc); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->GetDataHere +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ) +{ + HRESULT hr = m_rIDataObjectOrg->GetDataHere(pFormatetc, pmedium); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->GetDataHere(pFormatetc, pmedium); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->GetCanonicalFormatEtc +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut) +{ + HRESULT hr = m_rIDataObjectOrg->GetCanonicalFormatEtc( pFormatectIn, pFormatetcOut ); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->GetCanonicalFormatEtc(pFormatectIn, pFormatetcOut); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->SetData +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease ) +{ + HRESULT hr = m_rIDataObjectOrg->SetData( pFormatetc, pmedium, fRelease ); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->SetData(pFormatetc, pmedium, fRelease); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->DAdvise +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD * pdwConnection ) +{ + HRESULT hr = m_rIDataObjectOrg->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->DUnadvise +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::DUnadvise( DWORD dwConnection ) +{ + HRESULT hr = m_rIDataObjectOrg->DUnadvise( dwConnection ); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->DUnadvise(dwConnection); + } + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->EnumDAdvise +//------------------------------------------------------------------------ + +STDMETHODIMP CAPNDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise ) +{ + HRESULT hr = m_rIDataObjectOrg->EnumDAdvise(ppenumAdvise); + + if (RPC_E_WRONG_THREAD == hr) + { + IDataObjectPtr pIDOTmp; + hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp); + + if (SUCCEEDED(hr)) + hr = pIDOTmp->EnumDAdvise(ppenumAdvise); + } + return hr; +} + +//------------------------------------------------------------------------ +// for our convenience +//------------------------------------------------------------------------ + +CAPNDataObject::operator IDataObject*( ) +{ + return static_cast< IDataObject* >( this ); +} + +//------------------------------------------------------------------------ +// helper function +//------------------------------------------------------------------------ + +HRESULT CAPNDataObject::MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj ) +{ + OSL_ASSERT(NULL != ppIDataObj); + + *ppIDataObj = NULL; + HRESULT hr = E_FAIL; + + if (m_hGlobal) + { + IStreamPtr pStm; + hr = CreateStreamOnHGlobal(m_hGlobal, KEEP_HGLOB_ON_RELEASE, &pStm); + + OSL_ENSURE(E_INVALIDARG != hr, "CreateStreamOnHGlobal with invalid args called"); + + if (SUCCEEDED(hr)) + { + hr = CoUnmarshalInterface(pStm.get(), __uuidof(IDataObject), (void**)ppIDataObj); + OSL_ENSURE(CO_E_NOTINITIALIZED != hr, "COM is not initialized"); + } + } + return hr; +} diff --git a/dtrans/source/win32/dtobj/APNDataObject.hxx b/dtrans/source/win32/dtobj/APNDataObject.hxx new file mode 100644 index 000000000000..990e38236e66 --- /dev/null +++ b/dtrans/source/win32/dtobj/APNDataObject.hxx @@ -0,0 +1,89 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _APNDATAOBJECT_HXX_ +#define _APNDATAOBJECT_HXX_ + +#include <systools/win32/comtools.hxx> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +/* + an APartment Neutral dataobject wrapper; this wrapper of a IDataObject + pointer can be used from any apartment without RPC_E_WRONG_THREAD + which normally occurs if an apartment tries to use an interface + pointer of another apartment; we use containment to hold the original + DataObject +*/ +class CAPNDataObject : public IDataObject +{ +public: + CAPNDataObject( IDataObjectPtr rIDataObject ); + virtual ~CAPNDataObject( ); + + //----------------------------------------------------------------- + //IUnknown interface methods + //----------------------------------------------------------------- + + STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); + STDMETHODIMP_( ULONG ) AddRef( ); + STDMETHODIMP_( ULONG ) Release( ); + + //----------------------------------------------------------------- + // IDataObject interface methods + //----------------------------------------------------------------- + + STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc ); + STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut ); + STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease ); + STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ); + STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection ); + STDMETHODIMP DUnadvise( DWORD dwConnection ); + STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise ); + + operator IDataObject*( ); + +private: + HRESULT MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj ); + +private: + IDataObjectPtr m_rIDataObjectOrg; + HGLOBAL m_hGlobal; + LONG m_nRefCnt; + +// prevent copy and assignment +private: + CAPNDataObject( const CAPNDataObject& theOther ); + CAPNDataObject& operator=( const CAPNDataObject& theOther ); +}; + +#endif diff --git a/dtrans/source/win32/dtobj/DOTransferable.cxx b/dtrans/source/win32/dtobj/DOTransferable.cxx new file mode 100755 index 000000000000..c590bf0e6a80 --- /dev/null +++ b/dtrans/source/win32/dtobj/DOTransferable.cxx @@ -0,0 +1,614 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <sal/types.h> +#include <rtl/process.h> + +#ifndef _DOWRAPPERTRANSFERABLE_HXX_ +#include "DOTransferable.hxx" +#endif +#include "..\misc\ImplHelper.hxx" +#include "..\misc\WinClip.hxx" +#include "DTransHelper.hxx" +#include "..\misc\ImplHelper.hxx" +#include "TxtCnvtHlp.hxx" +#include "MimeAttrib.hxx" +#include "FmtFilter.hxx" +#include "Fetc.hxx" + + +#if(_MSC_VER < 1300) && !defined(__MINGW32__) +#include <olestd.h> +#endif + +#define STR2(x) #x +#define STR(x) STR2(x) +#define PRAGMA_MSG( msg ) message( __FILE__ "(" STR(__LINE__) "): " #msg ) + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace rtl; +using namespace std; +using namespace osl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::io; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +namespace +{ + const Type CPPUTYPE_SEQINT8 = getCppuType( ( Sequence< sal_Int8 >* )0 ); + const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 ); + + inline + sal_Bool isValidFlavor( const DataFlavor& aFlavor ) + { + return ( aFlavor.MimeType.getLength( ) && + ( ( aFlavor.DataType == CPPUTYPE_SEQINT8 ) || + ( aFlavor.DataType == CPPUTYPE_OUSTRING ) ) ); + } + +} // end namespace + + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +CDOTransferable::CDOTransferable( + const Reference< XMultiServiceFactory >& ServiceManager, IDataObjectPtr rDataObject ) : + m_rDataObject( rDataObject ), + m_SrvMgr( ServiceManager ), + m_DataFormatTranslator( m_SrvMgr ), + m_bUnicodeRegistered( sal_False ), + m_TxtFormatOnClipboard( CF_INVALID ) +{ +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +Any SAL_CALL CDOTransferable::getTransferData( const DataFlavor& aFlavor ) + throw( UnsupportedFlavorException, IOException, RuntimeException ) +{ + OSL_ASSERT( isValidFlavor( aFlavor ) ); + + MutexGuard aGuard( m_aMutex ); + + //------------------------------------------------ + // convert dataflavor to formatetc + //------------------------------------------------ + + CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcFromDataFlavor( aFlavor ); + OSL_ASSERT( CF_INVALID != fetc.getClipformat() ); + + //------------------------------------------------ + // get the data from clipboard in a byte stream + //------------------------------------------------ + + ByteSequence_t clipDataStream; + + try + { + clipDataStream = getClipboardData( fetc ); + } + catch( UnsupportedFlavorException& ) + { + if ( m_DataFormatTranslator.isUnicodeTextFormat( fetc.getClipformat( ) ) && + m_bUnicodeRegistered ) + { + OUString aUnicodeText = synthesizeUnicodeText( ); + Any aAny = makeAny( aUnicodeText ); + return aAny; + } + else + throw; // pass through exception + } + + //------------------------------------------------ + // return the data as any + //------------------------------------------------ + + return byteStreamToAny( clipDataStream, aFlavor.DataType ); +} + +//------------------------------------------------------------------------ +// getTransferDataFlavors +//------------------------------------------------------------------------ + +Sequence< DataFlavor > SAL_CALL CDOTransferable::getTransferDataFlavors( ) + throw( RuntimeException ) +{ + return m_FlavorList; +} + +//------------------------------------------------------------------------ +// isDataFlavorSupported +// returns true if we find a DataFlavor with the same MimeType and +// DataType +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDOTransferable::isDataFlavorSupported( const DataFlavor& aFlavor ) + throw( RuntimeException ) +{ + OSL_ASSERT( isValidFlavor( aFlavor ) ); + + for ( sal_Int32 i = 0; i < m_FlavorList.getLength( ); i++ ) + if ( compareDataFlavors( aFlavor, m_FlavorList[i] ) ) + return sal_True; + + return sal_False; +} + +//------------------------------------------------------------------------ +// helper function +// the list of datafalvors currently on the clipboard will be initialized +// only once; if the client of this Transferable will hold a reference +// to it und the underlying clipboard content changes, the client does +// possible operate on a invalid list +// if there is only text on the clipboard we will also offer unicode text +// an synthesize this format on the fly if requested, to accomplish this +// we save the first offered text format which we will later use for the +// conversion +//------------------------------------------------------------------------ + +void SAL_CALL CDOTransferable::initFlavorList( ) +{ + IEnumFORMATETCPtr pEnumFormatEtc; + HRESULT hr = m_rDataObject->EnumFormatEtc( DATADIR_GET, &pEnumFormatEtc ); + if ( SUCCEEDED( hr ) ) + { + pEnumFormatEtc->Reset( ); + + FORMATETC fetc; + while ( S_FALSE != pEnumFormatEtc->Next( 1, &fetc, NULL ) ) + { + // we use locales only to determine the + // charset if there is text on the cliboard + // we don't offer this format + if ( CF_LOCALE == fetc.cfFormat ) + continue; + + DataFlavor aFlavor = formatEtcToDataFlavor( fetc ); + + // if text or oemtext is offered we also pretend to have unicode text + if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) && + !m_bUnicodeRegistered ) + { + addSupportedFlavor( aFlavor ); + + m_TxtFormatOnClipboard = fetc.cfFormat; + m_bUnicodeRegistered = sal_True; + + // register unicode text as accompany format + aFlavor = formatEtcToDataFlavor( + m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) ); + addSupportedFlavor( aFlavor ); + } + else if ( (CF_UNICODETEXT == fetc.cfFormat) && !m_bUnicodeRegistered ) + { + addSupportedFlavor( aFlavor ); + m_bUnicodeRegistered = sal_True; + } + else + addSupportedFlavor( aFlavor ); + + // see MSDN IEnumFORMATETC + CoTaskMemFree( fetc.ptd ); + } + } +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +void SAL_CALL CDOTransferable::addSupportedFlavor( const DataFlavor& aFlavor ) +{ + // we ignore all formats that couldn't be translated + if ( aFlavor.MimeType.getLength( ) ) + { + OSL_ASSERT( isValidFlavor( aFlavor ) ); + + m_FlavorList.realloc( m_FlavorList.getLength( ) + 1 ); + m_FlavorList[m_FlavorList.getLength( ) - 1] = aFlavor; + } +} + +//------------------------------------------------------------------------ +// helper function +//------------------------------------------------------------------------ + +//inline +DataFlavor SAL_CALL CDOTransferable::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) +{ + DataFlavor aFlavor; + LCID lcid = 0; + + // for non-unicode text format we must provid a locale to get + // the character-set of the text, if there is no locale on the + // clipboard we assume the text is in a charset appropriate for + // the current thread locale + if ( (CF_TEXT == aFormatEtc.cfFormat) || (CF_OEMTEXT == aFormatEtc.cfFormat) ) + lcid = getLocaleFromClipboard( ); + + return m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, lcid ); +} + +//------------------------------------------------------------------------ +// returns the current locale on clipboard; if there is no locale on +// clipboard the function returns the current thread locale +//------------------------------------------------------------------------ + +LCID SAL_CALL CDOTransferable::getLocaleFromClipboard( ) +{ + LCID lcid = GetThreadLocale( ); + + try + { + CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_LOCALE ); + ByteSequence_t aLCIDSeq = getClipboardData( fetc ); + lcid = *(reinterpret_cast<LCID*>( aLCIDSeq.getArray( ) ) ); + + // because of a Win95/98 Bug; there the high word + // of a locale has the same value as the + // low word e.g. 0x07040704 that's not right + // correct is 0x00000704 + lcid &= 0x0000FFFF; + } + catch(...) + { + // we take the default locale + } + + return lcid; +} + +//------------------------------------------------------------------------ +// i think it's not necessary to call ReleaseStgMedium +// in case of failures because nothing should have been +// allocated etc. +//------------------------------------------------------------------------ + +CDOTransferable::ByteSequence_t SAL_CALL CDOTransferable::getClipboardData( CFormatEtc& aFormatEtc ) +{ + STGMEDIUM stgmedium; + HRESULT hr = m_rDataObject->GetData( aFormatEtc, &stgmedium ); + + // in case of failure to get a WMF metafile handle, try to get a memory block + if( FAILED( hr ) && + ( CF_METAFILEPICT == aFormatEtc.getClipformat() ) && + ( TYMED_MFPICT == aFormatEtc.getTymed() ) ) + { + CFormatEtc aTempFormat( aFormatEtc ); + aTempFormat.setTymed( TYMED_HGLOBAL ); + hr = m_rDataObject->GetData( aTempFormat, &stgmedium ); + } + + if ( FAILED( hr ) ) + { + OSL_ASSERT( (hr != E_INVALIDARG) && + (hr != DV_E_DVASPECT) && + (hr != DV_E_LINDEX) && + (hr != DV_E_TYMED) ); + + if ( DV_E_FORMATETC == hr ) + throw UnsupportedFlavorException( ); + else if ( STG_E_MEDIUMFULL == hr ) + throw IOException( ); + else + throw RuntimeException( ); + } + + ByteSequence_t byteStream; + + try + { + if ( CF_ENHMETAFILE == aFormatEtc.getClipformat() ) + byteStream = WinENHMFPictToOOMFPict( stgmedium.hEnhMetaFile ); + else if (CF_HDROP == aFormatEtc.getClipformat()) + byteStream = CF_HDROPToFileList(stgmedium.hGlobal); + else if ( CF_BITMAP == aFormatEtc.getClipformat() ) + { + byteStream = WinBITMAPToOOBMP(stgmedium.hBitmap); + if( aFormatEtc.getTymed() == TYMED_GDI && + ! stgmedium.pUnkForRelease ) + { + DeleteObject(stgmedium.hBitmap); + } + } + else + { + clipDataToByteStream( aFormatEtc.getClipformat( ), stgmedium, byteStream ); + + // format conversion if necessary + if ( CF_DIB == aFormatEtc.getClipformat() ) + byteStream = WinDIBToOOBMP( byteStream ); + else if ( CF_METAFILEPICT == aFormatEtc.getClipformat() ) + byteStream = WinMFPictToOOMFPict( byteStream ); + } + + ReleaseStgMedium( &stgmedium ); + } + catch( CStgTransferHelper::CStgTransferException& ) + { + ReleaseStgMedium( &stgmedium ); + throw IOException( ); + } + + return byteStream; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CDOTransferable::synthesizeUnicodeText( ) +{ + ByteSequence_t aTextSequence; + CFormatEtc fetc; + LCID lcid = getLocaleFromClipboard( ); + sal_uInt32 cpForTxtCnvt = 0; + + if ( CF_TEXT == m_TxtFormatOnClipboard ) + { + fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT ); + aTextSequence = getClipboardData( fetc ); + + // determine the codepage used for text conversion + cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTANSICODEPAGE ).toInt32( ); + } + else if ( CF_OEMTEXT == m_TxtFormatOnClipboard ) + { + fetc = m_DataFormatTranslator.getFormatEtcForClipformat( CF_OEMTEXT ); + aTextSequence = getClipboardData( fetc ); + + // determine the codepage used for text conversion + cpForTxtCnvt = getWinCPFromLocaleId( lcid, LOCALE_IDEFAULTCODEPAGE ).toInt32( ); + } + else + OSL_ASSERT( sal_False ); + + CStgTransferHelper stgTransferHelper; + + // convert the text + MultiByteToWideCharEx( cpForTxtCnvt, + reinterpret_cast<char*>( aTextSequence.getArray( ) ), + sal::static_int_cast<sal_uInt32>(-1), // Huh ? + stgTransferHelper, + sal_False); + + CRawHGlobalPtr ptrHGlob(stgTransferHelper); + sal_Unicode* pWChar = reinterpret_cast<sal_Unicode*>(ptrHGlob.GetMemPtr()); + + return OUString(pWChar); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CDOTransferable::clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, ByteSequence_t& aByteSequence ) +{ + CStgTransferHelper memTransferHelper; + + switch( stgmedium.tymed ) + { + case TYMED_HGLOBAL: + memTransferHelper.init( stgmedium.hGlobal ); + break; + + case TYMED_MFPICT: + memTransferHelper.init( stgmedium.hMetaFilePict ); + break; + + case TYMED_ENHMF: + memTransferHelper.init( stgmedium.hEnhMetaFile ); + break; + + case TYMED_ISTREAM: + #ifdef _MSC_VER + #pragma PRAGMA_MSG( Has to be implemented ) + #endif + break; + + default: + throw UnsupportedFlavorException( ); + break; + } + + int nMemSize = memTransferHelper.memSize( cf ); + aByteSequence.realloc( nMemSize ); + memTransferHelper.read( aByteSequence.getArray( ), nMemSize ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +Any CDOTransferable::byteStreamToAny( ByteSequence_t& aByteStream, const Type& aRequestedDataType ) +{ + Any aAny; + + if ( aRequestedDataType == CPPUTYPE_OUSTRING ) + { + OUString str = byteStreamToOUString( aByteStream ); + aAny = makeAny( str ); + } + else + aAny = makeAny( aByteStream ); + + return aAny; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +OUString CDOTransferable::byteStreamToOUString( ByteSequence_t& aByteStream ) +{ + sal_Int32 nWChars; + sal_Int32 nMemSize = aByteStream.getLength( ); + + // if there is a trailing L"\0" substract 1 from length + if ( 0 == aByteStream[ aByteStream.getLength( ) - 2 ] && + 0 == aByteStream[ aByteStream.getLength( ) - 1 ] ) + nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) ) - 1; + else + nWChars = static_cast< sal_Int32 >( nMemSize / sizeof( sal_Unicode ) ); + + return OUString( reinterpret_cast< sal_Unicode* >( aByteStream.getArray( ) ), nWChars ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDOTransferable::compareDataFlavors( + const DataFlavor& lhs, const DataFlavor& rhs ) +{ + if ( !m_rXMimeCntFactory.is( ) ) + { + m_rXMimeCntFactory = Reference< XMimeContentTypeFactory >( m_SrvMgr->createInstance( + OUString::createFromAscii( "com.sun.star.datatransfer.MimeContentTypeFactory" ) ), UNO_QUERY ); + } + OSL_ASSERT( m_rXMimeCntFactory.is( ) ); + + sal_Bool bRet = sal_False; + + try + { + Reference< XMimeContentType > xLhs( m_rXMimeCntFactory->createMimeContentType( lhs.MimeType ) ); + Reference< XMimeContentType > xRhs( m_rXMimeCntFactory->createMimeContentType( rhs.MimeType ) ); + + if ( cmpFullMediaType( xLhs, xRhs ) ) + { + bRet = cmpAllContentTypeParameter( xLhs, xRhs ); + } + } + catch( IllegalArgumentException& ) + { + OSL_ENSURE( sal_False, "Invalid content type detected" ); + bRet = sal_False; + } + + return bRet; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDOTransferable::cmpFullMediaType( + const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const +{ + return xLhs->getFullMediaType().equalsIgnoreAsciiCase( xRhs->getFullMediaType( ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDOTransferable::cmpAllContentTypeParameter( + const Reference< XMimeContentType >& xLhs, const Reference< XMimeContentType >& xRhs ) const +{ + Sequence< OUString > xLhsFlavors = xLhs->getParameters( ); + Sequence< OUString > xRhsFlavors = xRhs->getParameters( ); + sal_Bool bRet = sal_True; + + try + { + if ( xLhsFlavors.getLength( ) == xRhsFlavors.getLength( ) ) + { + OUString pLhs; + OUString pRhs; + + for ( sal_Int32 i = 0; i < xLhsFlavors.getLength( ); i++ ) + { + pLhs = xLhs->getParameterValue( xLhsFlavors[i] ); + pRhs = xRhs->getParameterValue( xLhsFlavors[i] ); + + if ( !pLhs.equalsIgnoreAsciiCase( pRhs ) ) + { + bRet = sal_False; + break; + } + } + } + else + bRet = sal_False; + } + catch( NoSuchElementException& ) + { + bRet = sal_False; + } + catch( IllegalArgumentException& ) + { + bRet = sal_False; + } + + return bRet; +} + +::com::sun::star::uno::Any SAL_CALL CDOTransferable::getData( const Sequence< sal_Int8>& aProcessId ) + throw (::com::sun::star::uno::RuntimeException) +{ + Any retVal; + + sal_uInt8 * arProcCaller= (sal_uInt8*)(sal_Int8*) aProcessId.getConstArray(); + sal_uInt8 arId[16]; + rtl_getGlobalProcessId(arId); + if( ! memcmp( arId, arProcCaller,16)) + { + if (m_rDataObject.is()) + { + IDataObject* pObj= m_rDataObject.get(); + pObj->AddRef(); + retVal.setValue( &pObj, getCppuType((sal_uInt32*)0)); + } + } + return retVal; +} + diff --git a/dtrans/source/win32/dtobj/DOTransferable.hxx b/dtrans/source/win32/dtobj/DOTransferable.hxx new file mode 100644 index 000000000000..dd99e857b908 --- /dev/null +++ b/dtrans/source/win32/dtobj/DOTransferable.hxx @@ -0,0 +1,133 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _DOTRANSFERABLE_HXX_ +#define _DOTRANSFERABLE_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <com/sun/star/datatransfer/XTransferable.hpp> + +#ifndef _CPPUHELPER_IMPLBASE1_HXX_ +#include <cppuhelper/implbase2.hxx> +#endif +#include "DataFmtTransl.hxx" +#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp> +#include <com/sun/star/datatransfer/XMimeContentType.hpp> +#include <com/sun/star/datatransfer/XSystemTransferable.hpp> + +#include <systools/win32/comtools.hxx> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +// forward +class CDTransObjFactory; +class CFormatEtc; + +class CDOTransferable : public ::cppu::WeakImplHelper2< ::com::sun::star::datatransfer::XTransferable, + ::com::sun::star::datatransfer::XSystemTransferable> +{ +public: + typedef com::sun::star::uno::Sequence< sal_Int8 > ByteSequence_t; + + //------------------------------------------------------------------------ + // XTransferable + //------------------------------------------------------------------------ + + virtual ::com::sun::star::uno::Any SAL_CALL getTransferData( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) + throw( ::com::sun::star::datatransfer::UnsupportedFlavorException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::datatransfer::DataFlavor > SAL_CALL getTransferDataFlavors( ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL isDataFlavorSupported( const ::com::sun::star::datatransfer::DataFlavor& aFlavor ) + throw( ::com::sun::star::uno::RuntimeException ); + //------------------------------------------------------------------------ + // XSystemTransferable + //------------------------------------------------------------------------ + virtual ::com::sun::star::uno::Any SAL_CALL getData( const com::sun::star::uno::Sequence<sal_Int8>& aProcessId ) throw + (::com::sun::star::uno::RuntimeException); + + +private: + // should be created only by CDTransObjFactory + explicit CDOTransferable( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ServiceManager, + IDataObjectPtr rDataObject ); + + //------------------------------------------------------------------------ + // some helper functions + //------------------------------------------------------------------------ + + void SAL_CALL initFlavorList( ); + + void SAL_CALL addSupportedFlavor( const com::sun::star::datatransfer::DataFlavor& aFlavor ); + com::sun::star::datatransfer::DataFlavor SAL_CALL formatEtcToDataFlavor( const FORMATETC& aFormatEtc ); + + ByteSequence_t SAL_CALL getClipboardData( CFormatEtc& aFormatEtc ); + rtl::OUString SAL_CALL synthesizeUnicodeText( ); + + void SAL_CALL clipDataToByteStream( CLIPFORMAT cf, STGMEDIUM stgmedium, ByteSequence_t& aByteSequence ); + + ::com::sun::star::uno::Any SAL_CALL byteStreamToAny( ByteSequence_t& aByteStream, const com::sun::star::uno::Type& aRequestedDataType ); + rtl::OUString SAL_CALL byteStreamToOUString( ByteSequence_t& aByteStream ); + + LCID SAL_CALL getLocaleFromClipboard( ); + + sal_Bool SAL_CALL compareDataFlavors( const com::sun::star::datatransfer::DataFlavor& lhs, + const com::sun::star::datatransfer::DataFlavor& rhs ); + + sal_Bool SAL_CALL cmpFullMediaType( const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xLhs, + const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xRhs ) const; + + sal_Bool SAL_CALL cmpAllContentTypeParameter( const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xLhs, + const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentType >& xRhs ) const; + +private: + IDataObjectPtr m_rDataObject; + com::sun::star::uno::Sequence< com::sun::star::datatransfer::DataFlavor > m_FlavorList; + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr; + CDataFormatTranslator m_DataFormatTranslator; + com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentTypeFactory > m_rXMimeCntFactory; + ::osl::Mutex m_aMutex; + sal_Bool m_bUnicodeRegistered; + CLIPFORMAT m_TxtFormatOnClipboard; + +// non supported operations +private: + CDOTransferable( const CDOTransferable& ); + CDOTransferable& operator=( const CDOTransferable& ); + + friend class CDTransObjFactory; +}; + +#endif diff --git a/dtrans/source/win32/dtobj/DTransHelper.cxx b/dtrans/source/win32/dtobj/DTransHelper.cxx new file mode 100644 index 000000000000..30370fdaf3c8 --- /dev/null +++ b/dtrans/source/win32/dtobj/DTransHelper.cxx @@ -0,0 +1,239 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <rtl/ustring.h> +#include <osl/diagnose.h> +#include "DTransHelper.hxx" + +//------------------------------------------------------------------------ +// implementation +//------------------------------------------------------------------------ + +CStgTransferHelper::CStgTransferHelper( sal_Bool bAutoInit, + HGLOBAL hGlob, + sal_Bool bDelStgOnRelease ) : + m_lpStream( NULL ), + m_bDelStgOnRelease( bDelStgOnRelease ) +{ + if ( bAutoInit ) + init( hGlob, m_bDelStgOnRelease ); +} + +//------------------------------------------------------------------------ +// dtor +//------------------------------------------------------------------------ + + +CStgTransferHelper::~CStgTransferHelper( ) +{ + if ( m_lpStream ) + m_lpStream->Release( ); +} + +//------------------------------------------------------------------------ +// TransferData into the +//------------------------------------------------------------------------ + +void SAL_CALL CStgTransferHelper::write( const void* lpData, ULONG cb, ULONG* cbWritten ) +{ + HRESULT hr = E_FAIL; + + if ( m_lpStream ) + hr = m_lpStream->Write( lpData, cb, cbWritten ); + + if ( FAILED( hr ) ) + throw CStgTransferException( hr ); + +#if OSL_DEBUG_LEVEL > 0 + HGLOBAL hGlob; + hr = GetHGlobalFromStream( m_lpStream, &hGlob ); + OSL_ASSERT( SUCCEEDED( hr ) ); + + /*DWORD dwSize =*/ GlobalSize( hGlob ); + /*LPVOID lpdbgData =*/ GlobalLock( hGlob ); + GlobalUnlock( hGlob ); +#endif +} + +//------------------------------------------------------------------------ +// read +//------------------------------------------------------------------------ + +void SAL_CALL CStgTransferHelper::read( LPVOID pv, ULONG cb, ULONG* pcbRead ) +{ + HRESULT hr = E_FAIL; + + if ( m_lpStream ) + hr = m_lpStream->Read( pv, cb , pcbRead ); + + if ( FAILED( hr ) ) + throw CStgTransferException( hr ); +} + +//------------------------------------------------------------------------ +// GetHGlobal +//------------------------------------------------------------------------ + +HGLOBAL SAL_CALL CStgTransferHelper::getHGlobal( ) const +{ + OSL_ASSERT( m_lpStream ); + + HGLOBAL hGlob = NULL; + + if ( m_lpStream ) + { + HRESULT hr = GetHGlobalFromStream( m_lpStream, &hGlob ); + if ( FAILED( hr ) ) + hGlob = NULL; + } + + return hGlob; +} + +//------------------------------------------------------------------------ +// getIStream +//------------------------------------------------------------------------ + +void SAL_CALL CStgTransferHelper::getIStream( LPSTREAM* ppStream ) +{ + OSL_ASSERT( ppStream ); + *ppStream = m_lpStream; + if ( *ppStream ) + static_cast< LPUNKNOWN >( *ppStream )->AddRef( ); +} + +//------------------------------------------------------------------------ +// Init +//------------------------------------------------------------------------ + +void SAL_CALL CStgTransferHelper::init( SIZE_T newSize, + sal_uInt32 uiFlags, + sal_Bool bDelStgOnRelease ) +{ + cleanup( ); + + m_bDelStgOnRelease = bDelStgOnRelease; + + HGLOBAL hGlob = GlobalAlloc( uiFlags, newSize ); + if ( NULL == hGlob ) + throw CStgTransferException( STG_E_MEDIUMFULL ); + + HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream ); + if ( FAILED( hr ) ) + { + GlobalFree( hGlob ); + m_lpStream = NULL; + throw CStgTransferException( hr ); + } + +#if OSL_DEBUG_LEVEL > 0 + STATSTG statstg; + hr = m_lpStream->Stat( &statstg, STATFLAG_DEFAULT ); + OSL_ASSERT( SUCCEEDED( hr ) ); +#endif +} + +//------------------------------------------------------------------------ +// Init +//------------------------------------------------------------------------ + +void SAL_CALL CStgTransferHelper::init( HGLOBAL hGlob, + sal_Bool bDelStgOnRelease ) +{ + cleanup( ); + + m_bDelStgOnRelease = bDelStgOnRelease; + + HRESULT hr = CreateStreamOnHGlobal( hGlob, m_bDelStgOnRelease, &m_lpStream ); + if ( FAILED( hr ) ) + throw CStgTransferException( hr ); +} + +//------------------------------------------------------------------------ +// free the global memory and invalidate the stream pointer +//------------------------------------------------------------------------ + +void SAL_CALL CStgTransferHelper::cleanup( ) +{ + if ( m_lpStream && !m_bDelStgOnRelease ) + { + HGLOBAL hGlob; + GetHGlobalFromStream( m_lpStream, &hGlob ); + GlobalFree( hGlob ); + } + + if ( m_lpStream ) + { + m_lpStream->Release( ); + m_lpStream = NULL; + } +} + +//------------------------------------------------------------------------ +// return the size of memory we point to +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CStgTransferHelper::memSize( CLIPFORMAT cf ) const +{ + DWORD dwSize = 0; + + if ( NULL != m_lpStream ) + { + HGLOBAL hGlob; + GetHGlobalFromStream( m_lpStream, &hGlob ); + + if ( CF_TEXT == cf || RegisterClipboardFormat( "HTML Format" ) == cf ) + { + sal_Char* pText = static_cast< sal_Char* >( GlobalLock( hGlob ) ); + if ( pText ) + { + dwSize = strlen(pText) + 1; // strlen + trailing '\0' + GlobalUnlock( hGlob ); + } + } + else if ( CF_UNICODETEXT == cf ) + { + sal_Unicode* pText = static_cast< sal_Unicode* >( GlobalLock( hGlob ) ); + if ( pText ) + { + dwSize = rtl_ustr_getLength( pText ) * sizeof( sal_Unicode ); + GlobalUnlock( hGlob ); + } + } + else + dwSize = GlobalSize( hGlob ); + } + + return dwSize; +} + diff --git a/dtrans/source/win32/dtobj/DTransHelper.hxx b/dtrans/source/win32/dtobj/DTransHelper.hxx new file mode 100644 index 000000000000..7975b84eec57 --- /dev/null +++ b/dtrans/source/win32/dtobj/DTransHelper.hxx @@ -0,0 +1,214 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _DTRANSHELPER_HXX_ +#define _DTRANSHELPER_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include "..\misc\WinClip.hxx" + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define AUTO_INIT TRUE +#define NO_AUTO_INIT FALSE +#define MEM_DESTROY_ON_RELEASE TRUE +#define NO_MEM_DESTROY_ON_RELEASE FALSE + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + + +//------------------------------------------------------------------------- +// a helper class to manage a global memory area, the clients can write +// into the global memory area and extract the handle to the global mem +// note: not thread-safe +//------------------------------------------------------------------------- + +class CStgTransferHelper +{ +public: + // will be thrown in case of failures + class CStgTransferException + { + public: + HRESULT m_hr; + CStgTransferException( HRESULT hr ) : m_hr( hr ) {}; + }; + +public: + CStgTransferHelper( + sal_Bool bAutoInit = sal_False, + HGLOBAL hGlob = NULL, + sal_Bool bDelStgOnRelease = sal_False ); + + ~CStgTransferHelper( ); + + void SAL_CALL write( const void* lpData, ULONG cb, ULONG* cbWritten = NULL ); + void SAL_CALL read( LPVOID pv, ULONG cb, ULONG* pcbRead = NULL ); + + HGLOBAL SAL_CALL getHGlobal( ) const; + void SAL_CALL getIStream( LPSTREAM* ppStream ); + + void SAL_CALL init( + SIZE_T newSize, + sal_uInt32 uiFlags = GHND, + sal_Bool bDelStgOnRelease = sal_False ); + + void SAL_CALL init( + HGLOBAL hGlob, + sal_Bool bDelStgOnRelease = sal_False ); + + // returns the size of the managed memory + sal_uInt32 SAL_CALL memSize( CLIPFORMAT cf = CF_INVALID ) const; + + // free the global memory and necessary + // release the internal stream pointer + void SAL_CALL cleanup( ); + +private: + LPSTREAM m_lpStream; + sal_Bool m_bDelStgOnRelease; + +private: + CStgTransferHelper( const CStgTransferHelper& ); + CStgTransferHelper& operator=( const CStgTransferHelper& ); +}; + +//------------------------------------------------------------------------- +// something like an auto-pointer - allows access to the memory belonging +// to a HGLOBAL and automatically unlocks a global memory at destruction +// time +//------------------------------------------------------------------------- + +class CRawHGlobalPtr +{ +public: + + //--------------------------------------------- + // ctor + //--------------------------------------------- + + CRawHGlobalPtr( HGLOBAL hGlob ) : + m_hGlob( hGlob ), + m_bIsLocked( FALSE ), + m_pGlobMem( NULL ) + { + } + + + //--------------------------------------------- + // ctor + //--------------------------------------------- + + CRawHGlobalPtr( const CStgTransferHelper& theHGlobalHelper ) : + m_hGlob( theHGlobalHelper.getHGlobal( ) ), + m_bIsLocked( FALSE ), + m_pGlobMem( NULL ) + { + } + + //--------------------------------------------- + // dtor + //--------------------------------------------- + + ~CRawHGlobalPtr( ) + { + if ( m_bIsLocked ) + GlobalUnlock( m_hGlob ); + } + + //--------------------------------------------- + // lock the global memory (initializes a + // pointer to this memory) + //--------------------------------------------- + + BOOL Lock( ) + { + if ( !m_bIsLocked && ( NULL != m_hGlob ) ) + { + m_pGlobMem = GlobalLock( m_hGlob ); + m_bIsLocked = ( NULL != m_pGlobMem ); + } + + return m_bIsLocked; + } + + //--------------------------------------------- + // unlock the global memory (invalidates the + // pointer to this memory) + //--------------------------------------------- + + BOOL Unlock( ) + { + GlobalUnlock( m_hGlob ); + m_bIsLocked = FALSE; + m_pGlobMem = NULL; + + return ( NO_ERROR == GetLastError( ) ); + } + + //--------------------------------------------- + // locks the global memory and returns a + // pointer to this memory + //--------------------------------------------- + + LPVOID GetMemPtr( ) + { + Lock( ); + return m_pGlobMem; + } + + //--------------------------------------------- + // size of mem we point to + //--------------------------------------------- + + int MemSize( ) const + { + return GlobalSize( m_hGlob ); + } + +private: + HGLOBAL m_hGlob; + BOOL m_bIsLocked; + LPVOID m_pGlobMem; +}; + +#endif diff --git a/dtrans/source/win32/dtobj/DataFmtTransl.cxx b/dtrans/source/win32/dtobj/DataFmtTransl.cxx new file mode 100644 index 000000000000..f72e8bb714a7 --- /dev/null +++ b/dtrans/source/win32/dtobj/DataFmtTransl.cxx @@ -0,0 +1,336 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include "DataFmtTransl.hxx" +#include <rtl/string.hxx> +#include <osl/diagnose.h> +#include <rtl/tencinfo.h> +#include "..\misc\ImplHelper.hxx" +#include "..\misc\WinClip.hxx" +#include "MimeAttrib.hxx" +#include "DTransHelper.hxx" +#include <rtl/string.h> +#include "Fetc.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#pragma warning(disable:4917) +#endif +#include <windows.h> +#if (_MSC_VER < 1300) && !defined(__MINGW32__) +#include <olestd.h> +#endif +#include <shlobj.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace rtl; +using namespace std; +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::lang; + +//------------------------------------------------------------------------ +// const +//------------------------------------------------------------------------ + +const Type CPPUTYPE_SALINT32 = getCppuType((sal_Int32*)0); +const Type CPPUTYPE_SALINT8 = getCppuType((sal_Int8*)0); +const Type CPPUTYPE_OUSTRING = getCppuType((OUString*)0); +const Type CPPUTYPE_SEQSALINT8 = getCppuType((Sequence< sal_Int8>*)0); +const sal_Int32 MAX_CLIPFORMAT_NAME = 256; + +const OUString TEXT_PLAIN_CHARSET = OUString::createFromAscii( "text/plain;charset=" ); +const OUString HPNAME_OEM_ANSI_TEXT = OUString::createFromAscii( "OEM/ANSI Text" ); + +const OUString HTML_FORMAT_NAME_WINDOWS = OUString::createFromAscii( "HTML Format" ); +const OUString HTML_FORMAT_NAME_SOFFICE = OUString::createFromAscii( "HTML (HyperText Markup Language)" ); + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CDataFormatTranslator::CDataFormatTranslator( const Reference< XMultiServiceFactory >& aServiceManager ) : + m_SrvMgr( aServiceManager ) +{ + m_XDataFormatTranslator = Reference< XDataFormatTranslator >( + m_SrvMgr->createInstance( OUString::createFromAscii( "com.sun.star.datatransfer.DataFormatTranslator" ) ), UNO_QUERY ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc CDataFormatTranslator::getFormatEtcFromDataFlavor( const DataFlavor& aDataFlavor ) const +{ + sal_Int32 cf = CF_INVALID; + + try + { + if( m_XDataFormatTranslator.is( ) ) + { + Any aFormat = m_XDataFormatTranslator->getSystemDataTypeFromDataFlavor( aDataFlavor ); + + if ( aFormat.hasValue( ) ) + { + if ( aFormat.getValueType( ) == CPPUTYPE_SALINT32 ) + { + aFormat >>= cf; + OSL_ENSURE( CF_INVALID != cf, "Invalid Clipboard format delivered" ); + } + else if ( aFormat.getValueType( ) == CPPUTYPE_OUSTRING ) + { + OUString aClipFmtName; + aFormat >>= aClipFmtName; + + OSL_ASSERT( aClipFmtName.getLength( ) ); + cf = RegisterClipboardFormatW( reinterpret_cast<LPCWSTR>(aClipFmtName.getStr( )) ); + + OSL_ENSURE( CF_INVALID != cf, "RegisterClipboardFormat failed" ); + } + else + OSL_ENSURE( sal_False, "Wrong Any-Type detected" ); + } + } + } + catch( ... ) + { + OSL_ENSURE( sal_False, "Unexpected error" ); + } + + return sal::static_int_cast<CFormatEtc>(getFormatEtcForClipformat( sal::static_int_cast<CLIPFORMAT>(cf) )); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +DataFlavor CDataFormatTranslator::getDataFlavorFromFormatEtc( const FORMATETC& aFormatEtc, LCID lcid ) const +{ + DataFlavor aFlavor; + + try + { + CLIPFORMAT aClipformat = aFormatEtc.cfFormat; + + Any aAny; + aAny <<= static_cast< sal_Int32 >( aClipformat ); + + if ( isOemOrAnsiTextFormat( aClipformat ) ) + { + aFlavor.MimeType = TEXT_PLAIN_CHARSET; + aFlavor.MimeType += getTextCharsetFromLCID( lcid, aClipformat ); + + aFlavor.HumanPresentableName = HPNAME_OEM_ANSI_TEXT; + aFlavor.DataType = CPPUTYPE_SEQSALINT8; + } + else if ( CF_INVALID != aClipformat ) + { + if ( m_XDataFormatTranslator.is( ) ) + { + aFlavor = m_XDataFormatTranslator->getDataFlavorFromSystemDataType( aAny ); + + if ( !aFlavor.MimeType.getLength( ) ) + { + // lookup of DataFlavor from clipboard format id + // failed, so we try to resolve via clipboard + // format name + OUString clipFormatName = getClipboardFormatName( aClipformat ); + + // if we could not get a clipboard format name an + // error must have occured or it is a standard + // clipboard format that we don't translate, e.g. + // CF_BITMAP (the office only uses CF_DIB) + if ( clipFormatName.getLength( ) ) + { + aAny <<= clipFormatName; + aFlavor = m_XDataFormatTranslator->getDataFlavorFromSystemDataType( aAny ); + } + } + } + } + } + catch( ... ) + { + OSL_ENSURE( sal_False, "Unexpected error" ); + } + + return aFlavor; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc SAL_CALL CDataFormatTranslator::getFormatEtcForClipformatName( const OUString& aClipFmtName ) const +{ + // check parameter + if ( !aClipFmtName.getLength( ) ) + return CFormatEtc( CF_INVALID ); + + CLIPFORMAT cf = sal::static_int_cast<CLIPFORMAT>(RegisterClipboardFormatW( reinterpret_cast<LPCWSTR>(aClipFmtName.getStr( )) )); + return getFormatEtcForClipformat( cf ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString CDataFormatTranslator::getClipboardFormatName( CLIPFORMAT aClipformat ) const +{ + OSL_PRECOND( CF_INVALID != aClipformat, "Invalid clipboard format" ); + + sal_Unicode wBuff[ MAX_CLIPFORMAT_NAME ]; + sal_Int32 nLen = GetClipboardFormatNameW( aClipformat, reinterpret_cast<LPWSTR>(wBuff), MAX_CLIPFORMAT_NAME ); + + return OUString( wBuff, nLen ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc SAL_CALL CDataFormatTranslator::getFormatEtcForClipformat( CLIPFORMAT cf ) const +{ + CFormatEtc fetc( cf, TYMED_NULL, NULL, DVASPECT_CONTENT ); + + switch( cf ) + { + case CF_METAFILEPICT: + fetc.setTymed( TYMED_MFPICT ); + break; + + case CF_ENHMETAFILE: + fetc.setTymed( TYMED_ENHMF ); + break; + + default: + fetc.setTymed( TYMED_HGLOBAL /*| TYMED_ISTREAM*/ ); + } + + /* + hack: in order to paste urls copied by Internet Explorer + with "copy link" we set the lindex member to 0 + but if we really want to support CFSTR_FILECONTENT and + the accompany format CFSTR_FILEDESCRIPTOR (FileGroupDescriptor) + the client of the clipboard service has to provide a id + of which FileContents it wants to paste + see MSDN: "Handling Shell Data Transfer Scenarios" + */ + if ( cf == RegisterClipboardFormatA( CFSTR_FILECONTENTS ) ) + fetc.setLindex( 0 ); + + return fetc; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDataFormatTranslator::isOemOrAnsiTextFormat( CLIPFORMAT cf ) const +{ + return ( (cf == CF_TEXT) || (cf == CF_OEMTEXT) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDataFormatTranslator::isUnicodeTextFormat( CLIPFORMAT cf ) const +{ + return ( cf == CF_UNICODETEXT ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDataFormatTranslator::isTextFormat( CLIPFORMAT cf ) const +{ + return ( isOemOrAnsiTextFormat( cf ) || isUnicodeTextFormat( cf ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDataFormatTranslator::isHTMLFormat( CLIPFORMAT cf ) const +{ + OUString clipFormatName = getClipboardFormatName( cf ); + return ( clipFormatName == HTML_FORMAT_NAME_WINDOWS ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CDataFormatTranslator::isTextHtmlFormat( CLIPFORMAT cf ) const +{ + OUString clipFormatName = getClipboardFormatName( cf ); + return ( clipFormatName.equalsIgnoreAsciiCase( HTML_FORMAT_NAME_SOFFICE ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CDataFormatTranslator::getTextCharsetFromLCID( LCID lcid, CLIPFORMAT aClipformat ) const +{ + OSL_ASSERT( isOemOrAnsiTextFormat( aClipformat ) ); + + OUString charset; + if ( CF_TEXT == aClipformat ) + { + charset = getMimeCharsetFromLocaleId( + lcid, + LOCALE_IDEFAULTANSICODEPAGE, + PRE_WINDOWS_CODEPAGE ); + } + else if ( CF_OEMTEXT == aClipformat ) + { + charset = getMimeCharsetFromLocaleId( + lcid, + LOCALE_IDEFAULTCODEPAGE, + PRE_OEM_CODEPAGE ); + } + else // CF_UNICODE + OSL_ASSERT( sal_False ); + + return charset; +} diff --git a/dtrans/source/win32/dtobj/DataFmtTransl.hxx b/dtrans/source/win32/dtobj/DataFmtTransl.hxx new file mode 100644 index 000000000000..70982ccaf6b9 --- /dev/null +++ b/dtrans/source/win32/dtobj/DataFmtTransl.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _DATAFMTTRANSL_HXX_ +#define _DATAFMTTRANSL_HXX_ + +//----------------------------------------------- +// includes +//----------------------------------------------- + +#include <cppuhelper/servicefactory.hxx> +#include <com/sun/star/datatransfer/XDataFormatTranslator.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <sal/types.h> +#include <rtl/ustring.hxx> + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//----------------------------------------------- +// declaration +//----------------------------------------------- + +class CFormatEtc; + +class CDataFormatTranslator +{ +public: + CDataFormatTranslator( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager ); + + CFormatEtc getFormatEtcFromDataFlavor( const com::sun::star::datatransfer::DataFlavor& aDataFlavor ) const; + com::sun::star::datatransfer::DataFlavor getDataFlavorFromFormatEtc( + const FORMATETC& aFormatEtc, LCID lcid = GetThreadLocale( ) ) const; + + CFormatEtc SAL_CALL getFormatEtcForClipformat( CLIPFORMAT cf ) const; + CFormatEtc SAL_CALL getFormatEtcForClipformatName( const rtl::OUString& aClipFmtName ) const; + rtl::OUString SAL_CALL getClipboardFormatName( CLIPFORMAT aClipformat ) const; + + sal_Bool SAL_CALL isHTMLFormat( CLIPFORMAT cf ) const; + sal_Bool SAL_CALL isTextHtmlFormat( CLIPFORMAT cf ) const; + sal_Bool SAL_CALL isOemOrAnsiTextFormat( CLIPFORMAT cf ) const; + sal_Bool SAL_CALL isUnicodeTextFormat( CLIPFORMAT cf ) const; + sal_Bool SAL_CALL isTextFormat( CLIPFORMAT cf ) const; + +private: + rtl::OUString SAL_CALL getTextCharsetFromLCID( LCID lcid, CLIPFORMAT aClipformat ) const; + +private: + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr; + com::sun::star::uno::Reference< com::sun::star::datatransfer::XDataFormatTranslator > m_XDataFormatTranslator; +}; + +#endif diff --git a/dtrans/source/win32/dtobj/DtObjFactory.cxx b/dtrans/source/win32/dtobj/DtObjFactory.cxx new file mode 100644 index 000000000000..e6cadec92983 --- /dev/null +++ b/dtrans/source/win32/dtobj/DtObjFactory.cxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include "..\..\inc\DtObjFactory.hxx" + +#ifndef _TWRAPPERDATAOBJECT_HXX_ +#include "XTDataObject.hxx" +#endif + +#ifndef _DOWRAPPERTRANSFERABLE_HXX_ +#include "DOTransferable.hxx" +#endif + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::lang; + +//------------------------------------------------------------------------ +// implementation +//------------------------------------------------------------------------ + +IDataObjectPtr SAL_CALL CDTransObjFactory::createDataObjFromTransferable(const Reference<XMultiServiceFactory>& aServiceManager, + const Reference< XTransferable >& refXTransferable) +{ + return (IDataObjectPtr(new CXTDataObject(aServiceManager, refXTransferable))); +} + +Reference< XTransferable > SAL_CALL CDTransObjFactory::createTransferableFromDataObj( const Reference< XMultiServiceFactory >& aServiceManager, + IDataObjectPtr pIDataObject ) +{ + CDOTransferable* pTransf = new CDOTransferable(aServiceManager, pIDataObject); + Reference<XTransferable> refDOTransf(pTransf); + + pTransf->acquire(); + pTransf->initFlavorList(); + pTransf->release(); + + return refDOTransf; +} + diff --git a/dtrans/source/win32/dtobj/Fetc.cxx b/dtrans/source/win32/dtobj/Fetc.cxx new file mode 100644 index 000000000000..525bfd58be4d --- /dev/null +++ b/dtrans/source/win32/dtobj/Fetc.cxx @@ -0,0 +1,259 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "Fetc.hxx" +#include "..\misc\ImplHelper.hxx" + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc::CFormatEtc( ) +{ + m_FormatEtc.cfFormat = 0; + m_FormatEtc.ptd = NULL; + m_FormatEtc.dwAspect = 0; + m_FormatEtc.lindex = -1; + m_FormatEtc.tymed = TYMED_NULL; +} + +//------------------------------------------------------------------------ +// transfer of ownership +//------------------------------------------------------------------------ + +CFormatEtc::CFormatEtc( const FORMATETC& aFormatEtc ) +{ + CopyFormatEtc( &m_FormatEtc, &const_cast< FORMATETC& >( aFormatEtc ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc::~CFormatEtc( ) +{ + DeleteTargetDevice( m_FormatEtc.ptd ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc::CFormatEtc( CLIPFORMAT cf, DWORD tymed, DVTARGETDEVICE* ptd, DWORD dwAspect, LONG lindex ) +{ + m_FormatEtc.cfFormat = cf; + m_FormatEtc.ptd = CopyTargetDevice( ptd ); + m_FormatEtc.dwAspect = dwAspect; + m_FormatEtc.lindex = lindex; + m_FormatEtc.tymed = tymed; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc::CFormatEtc( const CFormatEtc& theOther ) +{ + m_FormatEtc.cfFormat = theOther.m_FormatEtc.cfFormat; + m_FormatEtc.ptd = CopyTargetDevice( theOther.m_FormatEtc.ptd ); + m_FormatEtc.dwAspect = theOther.m_FormatEtc.dwAspect; + m_FormatEtc.lindex = theOther.m_FormatEtc.lindex; + m_FormatEtc.tymed = theOther.m_FormatEtc.tymed; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc& CFormatEtc::operator=( const CFormatEtc& theOther ) +{ + if ( this != &theOther ) + { + DeleteTargetDevice( m_FormatEtc.ptd ); + + m_FormatEtc.cfFormat = theOther.m_FormatEtc.cfFormat; + m_FormatEtc.ptd = CopyTargetDevice( theOther.m_FormatEtc.ptd ); + m_FormatEtc.dwAspect = theOther.m_FormatEtc.dwAspect; + m_FormatEtc.lindex = theOther.m_FormatEtc.lindex; + m_FormatEtc.tymed = theOther.m_FormatEtc.tymed; + } + + return *this; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc::operator FORMATETC*( ) +{ + return &m_FormatEtc; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtc::operator FORMATETC( ) +{ + return m_FormatEtc; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtc::getFORMATETC( LPFORMATETC lpFormatEtc ) +{ + OSL_ASSERT( lpFormatEtc ); + OSL_ASSERT( !IsBadWritePtr( lpFormatEtc, sizeof( FORMATETC ) ) ); + + CopyFormatEtc( lpFormatEtc, &m_FormatEtc ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CLIPFORMAT CFormatEtc::getClipformat( ) const +{ + return m_FormatEtc.cfFormat; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +DWORD CFormatEtc::getTymed( ) const +{ + return m_FormatEtc.tymed; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtc::getTargetDevice( DVTARGETDEVICE** lpDvTargetDevice ) const +{ + OSL_ASSERT( lpDvTargetDevice ); + OSL_ASSERT( !IsBadWritePtr( lpDvTargetDevice, sizeof( DVTARGETDEVICE ) ) ); + + *lpDvTargetDevice = NULL; + + if ( m_FormatEtc.ptd ) + *lpDvTargetDevice = CopyTargetDevice( m_FormatEtc.ptd ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +DWORD CFormatEtc::getDvAspect( ) const +{ + return m_FormatEtc.dwAspect; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +LONG CFormatEtc::getLindex( ) const +{ + return m_FormatEtc.lindex; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtc::setClipformat( CLIPFORMAT cf ) +{ + m_FormatEtc.cfFormat = cf; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtc::setTymed( DWORD tymed ) +{ + m_FormatEtc.tymed = tymed; +} + +//------------------------------------------------------------------------ +// transfer of ownership! +//------------------------------------------------------------------------ + +void CFormatEtc::setTargetDevice( DVTARGETDEVICE* ptd ) +{ + DeleteTargetDevice( m_FormatEtc.ptd ); + m_FormatEtc.ptd = ptd; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtc::setDvAspect( DWORD dwAspect ) +{ + m_FormatEtc.dwAspect = dwAspect; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtc::setLindex( LONG lindex ) +{ + m_FormatEtc.lindex = lindex; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Int32 operator==( const CFormatEtc& lhs, const CFormatEtc& rhs ) +{ + return CompareFormatEtc( &lhs.m_FormatEtc, &rhs.m_FormatEtc ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Int32 operator!=( const CFormatEtc& lhs, const CFormatEtc& rhs ) +{ + return ( ( lhs == rhs ) != 1 ); +} + diff --git a/dtrans/source/win32/dtobj/Fetc.hxx b/dtrans/source/win32/dtobj/Fetc.hxx new file mode 100644 index 000000000000..a0af6dead8c1 --- /dev/null +++ b/dtrans/source/win32/dtobj/Fetc.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _FETC_HXX_ +#define _FETC_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +/********************************************************************** + stl container elements must fulfill the following requirements: + 1. they need a copy ctor and assignement operator(?) + 2. they must be compareable + because the FORMATETC structure has a pointer to a TARGETDEVICE + structure we need a simple wrapper class to fulfill these needs +***********************************************************************/ + +class CFormatEtc +{ +public: + CFormatEtc( ); + CFormatEtc( const FORMATETC& aFormatEtc ); + CFormatEtc( CLIPFORMAT cf, DWORD tymed = TYMED_HGLOBAL, DVTARGETDEVICE* ptd = NULL, DWORD dwAspect = DVASPECT_CONTENT, LONG lindex = -1 ); + CFormatEtc( const CFormatEtc& theOther ); + + ~CFormatEtc( ); + + CFormatEtc& operator=( const CFormatEtc& theOther ); + operator FORMATETC*( ); + operator FORMATETC( ); + + void getFORMATETC( LPFORMATETC lpFormatEtc ); + + CLIPFORMAT getClipformat( ) const; + DWORD getTymed( ) const; + void getTargetDevice( DVTARGETDEVICE** ptd ) const; + DWORD getDvAspect( ) const; + LONG getLindex( ) const; + + void setClipformat( CLIPFORMAT cf ); + void setTymed( DWORD tymed ); + void setTargetDevice( DVTARGETDEVICE* ptd ); + void setDvAspect( DWORD dwAspect ); + void setLindex( LONG lindex ); + +private: + FORMATETC m_FormatEtc; + + friend sal_Int32 operator==( const CFormatEtc& lhs, const CFormatEtc& rhs ); + friend sal_Int32 operator!=( const CFormatEtc& lhs, const CFormatEtc& rhs ); +}; + +sal_Int32 operator==( const CFormatEtc& lhs, const CFormatEtc& rhs ); +sal_Int32 operator!=( const CFormatEtc& lhs, const CFormatEtc& rhs ); + + +#endif diff --git a/dtrans/source/win32/dtobj/FetcList.cxx b/dtrans/source/win32/dtobj/FetcList.cxx new file mode 100644 index 000000000000..8deb2296ad80 --- /dev/null +++ b/dtrans/source/win32/dtobj/FetcList.cxx @@ -0,0 +1,480 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "FetcList.hxx" +#include "Fetc.hxx" +#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp> +#include <com/sun/star/datatransfer/XMimeContentType.hpp> + +#ifndef _DATAFORMATTRANSLATOR_HXX_ +#include "DataFmtTransl.hxx" +#endif +#include "..\misc\ImplHelper.hxx" +#include "..\misc\WinClip.hxx" + +#include <algorithm> + +#include "MimeAttrib.hxx" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace rtl; +using namespace std; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +LCID CFormatRegistrar::m_TxtLocale = 0; +sal_uInt32 CFormatRegistrar::m_TxtCodePage = GetACP( ); + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatEtcContainer::CFormatEtcContainer( ) +{ + m_EnumIterator = m_FormatMap.begin( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtcContainer::addFormatEtc( const CFormatEtc& fetc ) +{ + m_FormatMap.push_back( CFormatEtc( fetc ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFormatEtcContainer::removeFormatEtc( const CFormatEtc& fetc ) +{ + FormatEtcMap_t::iterator iter = + find( m_FormatMap.begin(), m_FormatMap.end(), fetc ); + + if ( iter != m_FormatMap.end( ) ) + m_FormatMap.erase( iter ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFormatEtcContainer::removeAllFormatEtc( ) +{ + m_FormatMap.clear( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool CFormatEtcContainer::hasFormatEtc( const CFormatEtc& fetc ) const +{ + FormatEtcMap_t::const_iterator iter = + find( m_FormatMap.begin(), m_FormatMap.end(), fetc ); + + return ( iter != m_FormatMap.end( ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool CFormatEtcContainer::hasElements( ) const +{ + return ( m_FormatMap.size( ) > 0 ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFormatEtcContainer::beginEnumFormatEtc( ) +{ + m_EnumIterator = m_FormatMap.begin( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CFormatEtcContainer::nextFormatEtc( LPFORMATETC lpFetc, + sal_uInt32 aNum ) +{ + OSL_ASSERT( lpFetc ); + OSL_ASSERT( !IsBadWritePtr( lpFetc, sizeof( FORMATETC ) * aNum ) ); + + sal_uInt32 nFetched = 0; + + if ( m_EnumIterator != m_FormatMap.end( ) ) + { + for ( sal_uInt32 i = 0; i < aNum; i++, nFetched++, lpFetc++, ++m_EnumIterator ) + CopyFormatEtc( lpFetc, *m_EnumIterator ); + } + + return nFetched; +} + + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFormatEtcContainer::skipFormatEtc( sal_uInt32 aNum ) +{ + FormatEtcMap_t::const_iterator iter_end = m_FormatMap.end( ); + for ( sal_uInt32 i = 0; + (i < aNum) && (m_EnumIterator != iter_end); + i++, ++m_EnumIterator ) + ;/* intentionally left empty */ + + return ( m_EnumIterator != m_FormatMap.end( ) ); +} + + +//######################################################################### + + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFormatRegistrar::CFormatRegistrar( const Reference< XMultiServiceFactory >& ServiceManager, + const CDataFormatTranslator& aDataFormatTranslator ) : + m_DataFormatTranslator( aDataFormatTranslator ), + m_bHasSynthesizedLocale( sal_False ), + m_SrvMgr( ServiceManager ) +{ +} + +// ---------------------------------------------------------------------------------------- +// this function converts all DataFlavors of the given FlavorList into +// an appropriate FORMATETC structure, for some formats like unicodetext, +// text and text/html we will offer an accompany format e.g.: +// +// DataFlavor | Registered Clipformat | Registered accompany clipformat +// -------------------------|---------------------------|----------------------------------- +// text/plain;charset=ansi | CF_TEXT | CF_UNICODETEXT +// | | CF_LOCALE (if charset != GetACP() +// | | +// text/plain;charset=oem | CF_OEMTEXT | CF_UNICODETEXT +// | | CF_LOCALE (if charset != GetOEMCP() +// | | +// text/plain;charset=utf-16| CF_UNICODETEXT | CF_TEXT +// | | +// text/html | HTML (Hypertext ...) | HTML Format +// | | +// +// if some tries to register different text formats with different charsets the last +// registered wins and the others are ignored +// ---------------------------------------------------------------------------------------- + +void SAL_CALL CFormatRegistrar::RegisterFormats( + const Reference< XTransferable >& aXTransferable, CFormatEtcContainer& aFormatEtcContainer ) +{ + Sequence< DataFlavor > aFlavorList = aXTransferable->getTransferDataFlavors( ); + sal_Int32 nFlavors = aFlavorList.getLength( ); + sal_Bool bUnicodeRegistered = sal_False; + DataFlavor aFlavor; + + for( sal_Int32 i = 0; i < nFlavors; i++ ) + { + aFlavor = aFlavorList[i]; + CFormatEtc fetc = m_DataFormatTranslator.getFormatEtcFromDataFlavor( aFlavor ); + + // maybe an internal format so we ignore it + if ( CF_INVALID == fetc.getClipformat( ) ) + continue; + + if ( !needsToSynthesizeAccompanyFormats( fetc ) ) + aFormatEtcContainer.addFormatEtc( fetc ); + else + { + // if we haven't registered any text format up to now + if ( m_DataFormatTranslator.isTextFormat( fetc.getClipformat() ) && !bUnicodeRegistered ) + { + // if the transferable supports unicode text we ignore + // any further text format the transferable offers + // because we can create it from Unicode text in addition + // we register CF_TEXT for non unicode clients + if ( m_DataFormatTranslator.isUnicodeTextFormat( fetc.getClipformat() ) ) + { + aFormatEtcContainer.addFormatEtc( fetc ); // add CF_UNICODE + aFormatEtcContainer.addFormatEtc( + m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT ) ); // add CF_TEXT + bUnicodeRegistered = sal_True; + } + else if ( !hasUnicodeFlavor( aXTransferable ) ) + { + // we try to investigate the charset and make a valid + // windows codepage from this charset the default + // return value is the result of GetACP( ) + OUString charset = getCharsetFromDataFlavor( aFlavor ); + sal_uInt32 txtCP = getWinCPFromMimeCharset( charset ); + + // we try to get a Locale appropriate for this codepage + if ( findLocaleForTextCodePage( ) ) + { + m_TxtCodePage = txtCP; + + aFormatEtcContainer.addFormatEtc( + m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) ); + + if ( !IsOEMCP( m_TxtCodePage ) ) + aFormatEtcContainer.addFormatEtc( + m_DataFormatTranslator.getFormatEtcForClipformat( CF_TEXT ) ); + else + aFormatEtcContainer.addFormatEtc( + m_DataFormatTranslator.getFormatEtcForClipformat( CF_OEMTEXT ) ); + + aFormatEtcContainer.addFormatEtc( + m_DataFormatTranslator.getFormatEtcForClipformat( CF_LOCALE ) ); + + // we save the flavor so it's easier when + // queried for it in XTDataObject::GetData(...) + m_RegisteredTextFlavor = aFlavor; + m_bHasSynthesizedLocale = sal_True; + } + } + } + else if ( m_DataFormatTranslator.isTextHtmlFormat( fetc.getClipformat( ) ) ) // Html (Hyper Text...) + { + // we add text/html ( HTML (HyperText Markup Language) ) + aFormatEtcContainer.addFormatEtc( fetc ); + + // and HTML Format + OUString htmlFormat( OUString::createFromAscii( "HTML Format" ) ); + aFormatEtcContainer.addFormatEtc( + m_DataFormatTranslator.getFormatEtcForClipformatName( htmlFormat ) ); + } + } + } +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFormatRegistrar::hasSynthesizedLocale( ) const +{ + return m_bHasSynthesizedLocale; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +LCID SAL_CALL CFormatRegistrar::getSynthesizedLocale( ) const +{ + return m_TxtLocale; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CFormatRegistrar::getRegisteredTextCodePage( ) const +{ + return m_TxtCodePage; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +DataFlavor SAL_CALL CFormatRegistrar::getRegisteredTextFlavor( ) const +{ + return m_RegisteredTextFlavor; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFormatRegistrar::isSynthesizeableFormat( const CFormatEtc& aFormatEtc ) const +{ + return ( m_DataFormatTranslator.isOemOrAnsiTextFormat( aFormatEtc.getClipformat() ) || + m_DataFormatTranslator.isUnicodeTextFormat( aFormatEtc.getClipformat() ) || + m_DataFormatTranslator.isHTMLFormat( aFormatEtc.getClipformat() ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +sal_Bool SAL_CALL CFormatRegistrar::needsToSynthesizeAccompanyFormats( const CFormatEtc& aFormatEtc ) const +{ + return ( m_DataFormatTranslator.isOemOrAnsiTextFormat( aFormatEtc.getClipformat() ) || + m_DataFormatTranslator.isUnicodeTextFormat( aFormatEtc.getClipformat() ) || + m_DataFormatTranslator.isTextHtmlFormat( aFormatEtc.getClipformat( ) ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CFormatRegistrar::getCharsetFromDataFlavor( const DataFlavor& aFlavor ) +{ + OUString charset; + + try + { + Reference< XMimeContentTypeFactory > xMimeFac( + m_SrvMgr->createInstance( OUString::createFromAscii( \ + "com.sun.star.datatransfer.MimeContentTypeFactory" ) ), UNO_QUERY ); + + if( xMimeFac.is( ) ) + { + Reference< XMimeContentType > xMimeType( xMimeFac->createMimeContentType( aFlavor.MimeType ) ); + if ( xMimeType->hasParameter( TEXTPLAIN_PARAM_CHARSET ) ) + charset = xMimeType->getParameterValue( TEXTPLAIN_PARAM_CHARSET ); + else + charset = getMimeCharsetFromWinCP( GetACP( ), PRE_WINDOWS_CODEPAGE ); + } + } + catch(NoSuchElementException&) + { + OSL_ENSURE( sal_False, "Unexpected" ); + } + catch(...) + { + OSL_ENSURE( sal_False, "Invalid data flavor" ); + } + + return charset; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFormatRegistrar::hasUnicodeFlavor( const Reference< XTransferable >& aXTransferable ) const +{ + CFormatEtc fetc( CF_UNICODETEXT ); + + DataFlavor aFlavor = + m_DataFormatTranslator.getDataFlavorFromFormatEtc( fetc ); + + return aXTransferable->isDataFlavorSupported( aFlavor ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +sal_Bool CFormatRegistrar::isEqualCurrentSystemCodePage( sal_uInt32 aCodePage ) const +{ + return ( (aCodePage == GetOEMCP()) || (aCodePage == GetACP()) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFormatRegistrar::findLocaleForTextCodePage( ) +{ + m_TxtLocale = 0; + EnumSystemLocalesA( CFormatRegistrar::EnumLocalesProc, LCID_INSTALLED ); + return ( IsValidLocale( m_TxtLocale, LCID_INSTALLED ) ) ? sal_True : sal_False; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFormatRegistrar::isLocaleCodePage( LCID lcid, LCTYPE lctype, sal_uInt32 codepage ) +{ + char buff[6]; + sal_uInt32 localeCodePage; + + OSL_ASSERT( IsValidLocale( lcid, LCID_INSTALLED ) ); + + // get the ansi codepage of the current locale + GetLocaleInfoA( lcid, lctype, buff, sizeof( buff ) ); + localeCodePage = atol( buff ); + + return ( localeCodePage == codepage ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +sal_Bool SAL_CALL CFormatRegistrar::isLocaleOemCodePage( LCID lcid, sal_uInt32 codepage ) +{ + return isLocaleCodePage( lcid, LOCALE_IDEFAULTCODEPAGE, codepage ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +sal_Bool SAL_CALL CFormatRegistrar::isLocaleAnsiCodePage( LCID lcid, sal_uInt32 codepage ) +{ + return isLocaleCodePage( lcid, LOCALE_IDEFAULTANSICODEPAGE, codepage ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +BOOL CALLBACK CFormatRegistrar::EnumLocalesProc( LPSTR lpLocaleStr ) +{ + // the lpLocaleStr parametere is hexadecimal + LCID lcid = strtol( lpLocaleStr, NULL, 16 ); + + if ( isLocaleAnsiCodePage( lcid, CFormatRegistrar::m_TxtCodePage ) || + isLocaleOemCodePage( lcid, CFormatRegistrar::m_TxtCodePage ) ) + { + CFormatRegistrar::m_TxtLocale = lcid; + return sal_False; // stop enumerating + } + + return sal_True; +} + diff --git a/dtrans/source/win32/dtobj/FetcList.hxx b/dtrans/source/win32/dtobj/FetcList.hxx new file mode 100644 index 000000000000..c5105a8662b6 --- /dev/null +++ b/dtrans/source/win32/dtobj/FetcList.hxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _FETCLIST_HXX_ +#define _FETCLIST_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <cppuhelper/servicefactory.hxx> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include "Fetc.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <vector> + +/***************************************************************** + a simple container for FORMATECT structures + instances of this class are not thread-safe +*****************************************************************/ + +class CFormatEtcContainer +{ +public: + CFormatEtcContainer( ); + + // duplicates not allowed + void SAL_CALL addFormatEtc( const CFormatEtc& fetc ); + + // removes the specified formatetc + void SAL_CALL removeFormatEtc( const CFormatEtc& fetc ); + + // removes the formatetc at pos + void SAL_CALL removeAllFormatEtc( ); + + sal_Bool SAL_CALL hasFormatEtc( const CFormatEtc& fetc ) const; + + sal_Bool SAL_CALL hasElements( ) const; + + // begin enumeration + void SAL_CALL beginEnumFormatEtc( ); + + // copies the specified number of formatetc structures starting + // at the current enum position + // the return value is the number of copied elements; if the + // current enum position is at the end the return value is 0 + sal_uInt32 SAL_CALL nextFormatEtc( LPFORMATETC lpFetc, sal_uInt32 aNum = 1 ); + + // skips the specified number of elements in the container + sal_Bool SAL_CALL skipFormatEtc( sal_uInt32 aNum ); + +protected: + typedef std::vector< CFormatEtc > FormatEtcMap_t; + +private: + FormatEtcMap_t m_FormatMap; + FormatEtcMap_t::iterator m_EnumIterator; +}; + +/***************************************************************** + a helper class which converts data flavors to clipformats, + creates an appropriate formatetc structures and if possible + synthesizes clipboard formats if necessary, e.g. if text + is provided a locale will also be provided; + the class registers the formatetc within a CFormatEtcContainer + + instances of this class are not thread-safe and multiple + instances of this class would use the same static variables + that's why this class should not be used by multiple threads, + only one thread of a process should use it +*****************************************************************/ + +// forward +class CDataFormatTranslator; + +class CFormatRegistrar +{ +public: + CFormatRegistrar( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ServiceManager, + const CDataFormatTranslator& aDataFormatTranslator ); + + void SAL_CALL RegisterFormats( const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& aXTransferable, + CFormatEtcContainer& aFormatEtcContainer ); + + sal_Bool SAL_CALL hasSynthesizedLocale( ) const; + LCID SAL_CALL getSynthesizedLocale( ) const; + sal_uInt32 SAL_CALL getRegisteredTextCodePage( ) const; + com::sun::star::datatransfer::DataFlavor SAL_CALL getRegisteredTextFlavor( ) const; + + sal_Bool SAL_CALL isSynthesizeableFormat( const CFormatEtc& aFormatEtc ) const; + sal_Bool SAL_CALL needsToSynthesizeAccompanyFormats( const CFormatEtc& aFormatEtc ) const; + +private: + sal_Bool SAL_CALL isEqualCurrentSystemCodePage( sal_uInt32 aCodePage ) const; + rtl::OUString SAL_CALL getCharsetFromDataFlavor( const com::sun::star::datatransfer::DataFlavor& aFlavor ); + + sal_Bool SAL_CALL hasUnicodeFlavor( + const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& aXTransferable ) const; + + sal_Bool SAL_CALL findLocaleForTextCodePage( ); + + static sal_Bool SAL_CALL isLocaleOemCodePage( LCID lcid, sal_uInt32 codepage ); + static sal_Bool SAL_CALL isLocaleAnsiCodePage( LCID lcid, sal_uInt32 codepage ); + static sal_Bool SAL_CALL isLocaleCodePage( LCID lcid, LCTYPE lctype, sal_uInt32 codepage ); + + static BOOL CALLBACK EnumLocalesProc( LPSTR lpLocaleStr ); + +private: + const CDataFormatTranslator& m_DataFormatTranslator; + sal_Bool m_bHasSynthesizedLocale; + com::sun::star::datatransfer::DataFlavor m_RegisteredTextFlavor; + + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr; + + static LCID m_TxtLocale; + static sal_uInt32 m_TxtCodePage; + +private: + CFormatRegistrar( const CFormatRegistrar& ); + CFormatRegistrar& operator=( const CFormatRegistrar& ); +}; + +#endif diff --git a/dtrans/source/win32/dtobj/FmtFilter.cxx b/dtrans/source/win32/dtobj/FmtFilter.cxx new file mode 100755 index 000000000000..c4f73977d92d --- /dev/null +++ b/dtrans/source/win32/dtobj/FmtFilter.cxx @@ -0,0 +1,579 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include "FmtFilter.hxx" +#include <osl/diagnose.h> +#include <comphelper/sequence.hxx> + +#if defined _MSC_VER +#pragma warning(push,1) +#pragma warning(disable:4917) +#endif +#include <Shobjidl.h> +#include <shlguid.h> +#include <ObjIdl.h> +#include <shellapi.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <string> +#include <sstream> +#include <vector> +#include <iomanip> + +#include <systools/win32/comtools.hxx> + +using namespace com::sun::star::uno; +using rtl::OString; + +#pragma pack(2) +struct METAFILEHEADER +{ + DWORD key; + short hmf; + SMALL_RECT bbox; + WORD inch; + DWORD reserved; + WORD checksum; +}; +#pragma pack() + +//------------------------------------------------------------------------ +// convert a windows metafile picture to a openoffice metafile picture +//------------------------------------------------------------------------ + +Sequence< sal_Int8 > SAL_CALL WinMFPictToOOMFPict( Sequence< sal_Int8 >& aMetaFilePict ) +{ + OSL_ASSERT( aMetaFilePict.getLength( ) == sizeof( METAFILEPICT ) ); + + Sequence< sal_Int8 > mfpictStream; + METAFILEPICT* pMFPict = reinterpret_cast< METAFILEPICT* >( aMetaFilePict.getArray( ) ); + HMETAFILE hMf = pMFPict->hMF; + sal_uInt32 nCount = GetMetaFileBitsEx( hMf, 0, NULL ); + + if ( nCount > 0 ) + { + mfpictStream.realloc( nCount + sizeof( METAFILEHEADER ) ); + + METAFILEHEADER* pMFHeader = reinterpret_cast< METAFILEHEADER* >( mfpictStream.getArray( ) ); + SMALL_RECT aRect = { 0, + 0, + static_cast< short >( pMFPict->xExt ), + static_cast< short >( pMFPict->yExt ) }; + USHORT nInch; + + switch( pMFPict->mm ) + { + case MM_TEXT: + nInch = 72; + break; + + case MM_LOMETRIC: + nInch = 100; + break; + + case MM_HIMETRIC: + nInch = 1000; + break; + + case MM_LOENGLISH: + nInch = 254; + break; + + case MM_HIENGLISH: + case MM_ISOTROPIC: + case MM_ANISOTROPIC: + nInch = 2540; + break; + + case MM_TWIPS: + nInch = 1440; + break; + + default: + nInch = 576; + } + + pMFHeader->key = 0x9AC6CDD7L; + pMFHeader->hmf = 0; + pMFHeader->bbox = aRect; + pMFHeader->inch = nInch; + pMFHeader->reserved = 0; + pMFHeader->checksum = 0; + + char* pMFBuff = reinterpret_cast< char* >( mfpictStream.getArray( ) ); + + nCount = GetMetaFileBitsEx( pMFPict->hMF, nCount, pMFBuff + sizeof( METAFILEHEADER ) ); + OSL_ASSERT( nCount > 0 ); + } + + return mfpictStream; +} + +//------------------------------------------------------------- +// convert a windows enhanced metafile to a openoffice metafile +//------------------------------------------------------------- + +Sequence< sal_Int8 > SAL_CALL WinENHMFPictToOOMFPict( HENHMETAFILE hEnhMetaFile ) +{ + Sequence< sal_Int8 > aRet; + UINT nSize = 0; + + if( hEnhMetaFile && + ( ( nSize = GetEnhMetaFileBits( hEnhMetaFile, 0, NULL ) ) != 0 ) ) + { + aRet.realloc( nSize ); + + if( GetEnhMetaFileBits( hEnhMetaFile, nSize, (sal_uChar*) aRet.getArray() ) != nSize ) + aRet.realloc( 0 ); + } + + return aRet; +} + +//------------------------------------------------------------------------ +// convert a openoffice metafile picture to a windows metafile picture +//------------------------------------------------------------------------ + +HMETAFILEPICT SAL_CALL OOMFPictToWinMFPict( Sequence< sal_Int8 >& aOOMetaFilePict ) +{ + HMETAFILEPICT hPict = NULL; + HMETAFILE hMtf = SetMetaFileBitsEx( aOOMetaFilePict.getLength(), (sal_uChar*) aOOMetaFilePict.getConstArray() ); + + if( hMtf ) + { + METAFILEPICT* pPict = (METAFILEPICT*) GlobalLock( hPict = GlobalAlloc( GHND, sizeof( METAFILEPICT ) ) ); + + pPict->mm = 8; + pPict->xExt = 0; + pPict->yExt = 0; + pPict->hMF = hMtf; + + GlobalUnlock( hPict ); + } + + return hPict; +} + +//----------------------------------------------------------------------------- +// convert a openoffice metafile picture to a windows enhanced metafile picture +//----------------------------------------------------------------------------- + +HENHMETAFILE SAL_CALL OOMFPictToWinENHMFPict( Sequence< sal_Int8 >& aOOMetaFilePict ) +{ + HENHMETAFILE hEnhMtf = SetEnhMetaFileBits( aOOMetaFilePict.getLength(), (sal_uChar*) aOOMetaFilePict.getConstArray() ); + + return hEnhMtf; +} + +//------------------------------------------------------------------------ +// convert a windows device independent bitmap into a openoffice bitmap +//------------------------------------------------------------------------ + +Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const Sequence< sal_Int8 >& aWinDIB ) +{ + OSL_ASSERT( aWinDIB.getLength( ) > sizeof( BITMAPINFOHEADER ) ); + + Sequence< sal_Int8 > ooBmpStream; + + ooBmpStream.realloc( aWinDIB.getLength( ) + sizeof(BITMAPFILEHEADER) ); + + const BITMAPINFOHEADER *pBmpInfoHdr = (const BITMAPINFOHEADER*)aWinDIB.getConstArray(); + BITMAPFILEHEADER *pBmpFileHdr = reinterpret_cast< BITMAPFILEHEADER* >( ooBmpStream.getArray() ); + DWORD nOffset = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ); + + rtl_copyMemory( pBmpFileHdr + 1, pBmpInfoHdr, aWinDIB.getLength( ) ); + + if( pBmpInfoHdr->biBitCount <= 8 ) + nOffset += ( pBmpInfoHdr->biClrUsed ? pBmpInfoHdr->biClrUsed : ( 1 << pBmpInfoHdr->biBitCount ) ) << 2; + else if( ( BI_BITFIELDS == pBmpInfoHdr->biCompression ) && ( ( 16 == pBmpInfoHdr->biBitCount ) || ( 32 == pBmpInfoHdr->biBitCount ) ) ) + nOffset += 12; + + pBmpFileHdr->bfType = 'MB'; + pBmpFileHdr->bfSize = 0; // maybe: nMemSize + sizeof(BITMAPFILEHEADER) + pBmpFileHdr->bfReserved1 = 0; + pBmpFileHdr->bfReserved2 = 0; + pBmpFileHdr->bfOffBits = nOffset; + + return ooBmpStream; +} + +//------------------------------------------------------------------------ +// convert a openoffice bitmap into a windows device independent bitmap +//------------------------------------------------------------------------ + +Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( Sequence< sal_Int8 >& aOOBmp ) +{ + OSL_ASSERT( aOOBmp.getLength( ) > + ( sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) ) ); + + Sequence< sal_Int8 > winDIBStream( aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) ); + + rtl_copyMemory( winDIBStream.getArray( ), + aOOBmp.getArray( ) + sizeof( BITMAPFILEHEADER ), + aOOBmp.getLength( ) - sizeof( BITMAPFILEHEADER ) ); + + return winDIBStream; +} + +//------------------------------------------------------------------------------ +// converts the openoffice text/html clipboard format to the HTML Format +// well known under MS Windows +// the MS HTML Format has a header before the real html data +// +// Version:1.0 Version number of the clipboard. Staring is 0.9 +// StartHTML: Byte count from the beginning of the clipboard to the start +// of the context, or -1 if no context +// EndHTML: Byte count from the beginning of the clipboard to the end +// of the context, or -1 if no context +// StartFragment: Byte count from the beginning of the clipboard to the +// start of the fragment +// EndFragment: Byte count from the beginning of the clipboard to the +// end of the fragment +// StartSelection: Byte count from the beginning of the clipboard to the +// start of the selection +// EndSelection: Byte count from the beginning of the clipboard to the +// end of the selection +// +// StartSelection and EndSelection are optional +// The fragment should be preceded and followed by the HTML comments +// <!--StartFragment--> and <!--EndFragment--> (no space between !-- and the +// text +//------------------------------------------------------------------------------ +/* +Sequence< sal_Int8 > SAL_CALL TextHtmlToHTMLFormat( Sequence< sal_Int8 >& aTextHtml ) +{ + OSL_ASSERT( aTextHtml.getLength( ) > 0 ); + + // check parameter + if ( !(aTextHtml.getLength( ) > 0) ) + return Sequence< sal_Int8 >( ); + + // we create a buffer with the approximated size of + // the HTML Format header + char aHTMLFmtHdr[120]; + + rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) ); + + // fill the buffer with dummy values to calc the + // exact length + + wsprintf( + aHTMLFmtHdr, + "Version:1.0\nStartHTML:%010d\r\nnEndHTML:%010d\r\nStartFragment:%010\r\nnEndFragment:%010d\r\n", 0, 0, 0, 0 ); + + sal_uInt32 lHTMLFmtHdr = rtl_str_getLength( aHTMLFmtHdr ); + + // the office allways writes the start + // and end html tag in upper cases and + // without spaces + // both tags don't allow parameters + OString startHtmlTag( "<HTML>" ); + OString endHtmlTag( "</HTML>" ); + + // we don't include '>' into the search + // because the body tag allows parameters + // e.g. <BODY param> + // #92840# + OString startBodyTag( "<BODY" ); + OString endBodyTag( "</BODY" ); + + OString textHtml( + reinterpret_cast< const sal_Char* >( aTextHtml.getConstArray( ) ), + aTextHtml.getLength( ) ); + + sal_Int32 nStartHtml = textHtml.indexOf( startHtmlTag ); + sal_Int32 nEndHtml = textHtml.indexOf( endHtmlTag ); + sal_Int32 nStartFrgmt = textHtml.indexOf( startBodyTag ); + sal_Int32 nEndFrgmt = textHtml.indexOf( endBodyTag ); + + OSL_ASSERT( (nStartHtml >= 0) && (nEndHtml > nStartHtml) && (nStartFrgmt > nStartHtml) && (nEndFrgmt > nStartFrgmt) ); + + Sequence< sal_Int8 > aHTMLFmtSequence; + + if ( (nStartHtml > -1) && (nEndHtml > -1) && (nStartFrgmt > -1) && (nEndFrgmt > -1) ) + { + nStartHtml = nStartHtml + lHTMLFmtHdr - 1; // we start one before <HTML> Word 2000 does also so + nEndHtml = nEndHtml + lHTMLFmtHdr + endHtmlTag.getLength( ) + 1; // our SOffice 5.2 wants 2 behind </HTML>? + nStartFrgmt = nStartFrgmt + startBodyTag.getLength( ) + lHTMLFmtHdr; // after the <BODY> tag + nEndFrgmt = nEndFrgmt + lHTMLFmtHdr; + + // fill the html header + rtl_zeroMemory( aHTMLFmtHdr, sizeof( aHTMLFmtHdr ) ); + + wsprintf( + aHTMLFmtHdr, + "Version:1.0\nStartHTML:%010d\r\nEndHTML:%010d\r\nStartFragment:%010d\r\nEndFragment:%010d\r\n", + nStartHtml, nEndHtml, nStartFrgmt, nEndFrgmt ); + + // we add space for a trailing \0 + aHTMLFmtSequence.realloc( lHTMLFmtHdr + aTextHtml.getLength( ) + 1 ); + rtl_zeroMemory( aHTMLFmtSequence.getArray( ), aHTMLFmtSequence.getLength( ) ); + + // copy the HTML Format header + rtl_copyMemory( + static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) ), + static_cast< LPVOID >( aHTMLFmtHdr ), lHTMLFmtHdr ); + + // concat the text/html + rtl_copyMemory( + static_cast< LPVOID >( aHTMLFmtSequence.getArray( ) + lHTMLFmtHdr ), + static_cast< LPVOID >( aTextHtml.getArray( ) ), + aTextHtml.getLength( ) ); + } + + return aHTMLFmtSequence; +} +*/ + +std::string GetHtmlFormatHeader(size_t startHtml, size_t endHtml, size_t startFragment, size_t endFragment) +{ + std::ostringstream htmlHeader; + htmlHeader << "Version:1.0" << '\r' << '\n'; + htmlHeader << "StartHTML:" << std::setw(10) << std::setfill('0') << std::dec << startHtml << '\r' << '\n'; + htmlHeader << "EndHTML:" << std::setw(10) << std::setfill('0') << std::dec << endHtml << '\r' << '\n'; + htmlHeader << "StartFragment:" << std::setw(10) << std::setfill('0') << std::dec << startFragment << '\r' << '\n'; + htmlHeader << "EndFragment:" << std::setw(10) << std::setfill('0') << std::dec << endFragment << '\r' << '\n'; + return htmlHeader.str(); +} + +// the office allways writes the start and end html tag in upper cases and +// without spaces both tags don't allow parameters +const std::string TAG_HTML = std::string("<HTML>"); +const std::string TAG_END_HTML = std::string("</HTML>"); + +// The body tag may have parameters so we need to search for the +// closing '>' manually e.g. <BODY param> #92840# +const std::string TAG_BODY = std::string("<BODY"); +const std::string TAG_END_BODY = std::string("</BODY"); + +Sequence<sal_Int8> SAL_CALL TextHtmlToHTMLFormat(Sequence<sal_Int8>& aTextHtml) +{ + OSL_ASSERT(aTextHtml.getLength() > 0); + + if (!(aTextHtml.getLength() > 0)) + return Sequence<sal_Int8>(); + + // fill the buffer with dummy values to calc the exact length + std::string dummyHtmlHeader = GetHtmlFormatHeader(0, 0, 0, 0); + size_t lHtmlFormatHeader = dummyHtmlHeader.length(); + + std::string textHtml( + reinterpret_cast<const sal_Char*>(aTextHtml.getConstArray()), + reinterpret_cast<const sal_Char*>(aTextHtml.getConstArray()) + aTextHtml.getLength()); + + std::string::size_type nStartHtml = textHtml.find(TAG_HTML) + lHtmlFormatHeader - 1; // we start one before '<HTML>' Word 2000 does also so + std::string::size_type nEndHtml = textHtml.find(TAG_END_HTML) + lHtmlFormatHeader + TAG_END_HTML.length() + 1; // our SOffice 5.2 wants 2 behind </HTML>? + + // The body tag may have parameters so we need to search for the + // closing '>' manually e.g. <BODY param> #92840# + std::string::size_type nStartFragment = textHtml.find(">", textHtml.find(TAG_BODY)) + lHtmlFormatHeader + 1; + std::string::size_type nEndFragment = textHtml.find(TAG_END_BODY) + lHtmlFormatHeader; + + std::string htmlFormat = GetHtmlFormatHeader(nStartHtml, nEndHtml, nStartFragment, nEndFragment); + htmlFormat += textHtml; + + Sequence<sal_Int8> byteSequence(htmlFormat.length() + 1); // space the trailing '\0' + rtl_zeroMemory(byteSequence.getArray(), byteSequence.getLength()); + + rtl_copyMemory( + static_cast<void*>(byteSequence.getArray()), + static_cast<const void*>(htmlFormat.c_str()), + htmlFormat.length()); + + return byteSequence; +} + +std::wstring getFileExtension(const std::wstring& aFilename) +{ + std::wstring::size_type idx = aFilename.rfind(L"."); + if ((idx != std::wstring::npos)) + { + return std::wstring(aFilename, idx); + } + return std::wstring(); +} + +const std::wstring SHELL_LINK_FILE_EXTENSION = L".lnk"; + +bool isShellLink(const std::wstring& aFilename) +{ + std::wstring ext = getFileExtension(aFilename); + return (_wcsicmp(ext.c_str(), SHELL_LINK_FILE_EXTENSION.c_str()) == 0); +} + +/** Resolve a Windows Shell Link (lnk) file. If a resolution + is not possible simply return the provided name of the + lnk file. */ +std::wstring getShellLinkTarget(const std::wstring& aLnkFile) +{ + OSL_ASSERT(isShellLink(aLnkFile)); + + std::wstring target = aLnkFile; + + try + { + sal::systools::COMReference<IShellLinkA> pIShellLink; + HRESULT hr = CoCreateInstance( + CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, reinterpret_cast<LPVOID*>(&pIShellLink)); + if (FAILED(hr)) + return target; + + sal::systools::COMReference<IPersistFile> pIPersistFile = + pIShellLink.QueryInterface<IPersistFile>(IID_IPersistFile); + + hr = pIPersistFile->Load(aLnkFile.c_str(), STGM_READ); + if (FAILED(hr)) + return target; + + hr = pIShellLink->Resolve(NULL, SLR_UPDATE | SLR_NO_UI); + if (FAILED(hr)) + return target; + + char pathA[MAX_PATH]; + WIN32_FIND_DATA wfd; + hr = pIShellLink->GetPath(pathA, MAX_PATH, &wfd, SLGP_RAWPATH); + if (FAILED(hr)) + return target; + + wchar_t pathW[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, pathA, -1, pathW, MAX_PATH); + target = pathW; + } + catch(sal::systools::ComError& ex) + { + OSL_ENSURE(false, ex.what()); + ex = ex; + } + return target; +} + +typedef std::vector<std::wstring> FileList_t; +typedef FileList_t::value_type FileList_ValueType_t; +typedef Sequence<sal_Int8> ByteSequence_t; + +/* Calculate the size required for turning a string list into + a double '\0' terminated string buffer */ +size_t CalcSizeForStringListBuffer(const FileList_t& fileList) +{ + if (fileList.size() == 0) + return 0; + + size_t size = 1; // one for the very final '\0' + FileList_t::const_iterator iter_end = fileList.end(); + for (FileList_t::const_iterator iter = fileList.begin(); iter != iter_end; ++iter) + { + size += iter->length() + 1; // length including terminating '\0' + } + return (size * sizeof(FileList_ValueType_t::value_type)); +} + +ByteSequence_t FileListToByteSequence(const FileList_t& fileList) +{ + ByteSequence_t bseq; + size_t size = CalcSizeForStringListBuffer(fileList); + + if (size > 0) + { + bseq.realloc(size); + wchar_t* p = reinterpret_cast<wchar_t*>(bseq.getArray()); + ZeroMemory(p, size); + + FileList_t::const_iterator iter; + FileList_t::const_iterator iter_end = fileList.end(); + for (iter = fileList.begin(); iter != iter_end; ++iter) + { + wcsncpy(p, iter->c_str(), iter->length()); + p += (iter->length() + 1); + } + } + return bseq; +} + +ByteSequence_t CF_HDROPToFileList(HGLOBAL hGlobal) +{ + UINT nFiles = DragQueryFileW((HDROP)hGlobal, 0xFFFFFFFF, NULL, 0); + FileList_t files; + + for (UINT i = 0; i < nFiles; i++) + { + wchar_t buff[MAX_PATH]; + /*UINT size =*/ DragQueryFileW((HDROP)hGlobal, i, buff, MAX_PATH); + std::wstring filename = buff; + if (isShellLink(filename)) + filename = getShellLinkTarget(filename); + files.push_back(filename); + } + return FileListToByteSequence(files); +} + +//------------------------------------------------------------------------ +// convert a windows bitmap handle into a openoffice bitmap +//------------------------------------------------------------------------ + +Sequence< sal_Int8 > SAL_CALL WinBITMAPToOOBMP( HBITMAP aHBMP ) +{ + Sequence< sal_Int8 > ooBmpStream; + + SIZE aBmpSize; + if( GetBitmapDimensionEx( aHBMP, &aBmpSize ) ) + { + // fill bitmap info header + size_t nDataBytes = 4 * aBmpSize.cy * aBmpSize.cy; + Sequence< sal_Int8 > aBitmapStream( + sizeof(BITMAPINFO) + + nDataBytes + ); + PBITMAPINFOHEADER pBmp = (PBITMAPINFOHEADER)aBitmapStream.getArray(); + pBmp->biSize = sizeof( BITMAPINFOHEADER ); + pBmp->biWidth = aBmpSize.cx; + pBmp->biHeight = aBmpSize.cy; + pBmp->biPlanes = 1; + pBmp->biBitCount = 32; + pBmp->biCompression = BI_RGB; + pBmp->biSizeImage = (DWORD)nDataBytes; + pBmp->biXPelsPerMeter = 1000; + pBmp->biYPelsPerMeter = 1000; + pBmp->biClrUsed = 0; + pBmp->biClrImportant = 0; + if( GetDIBits( 0, // DC, 0 is a default GC, basically that of the desktop + aHBMP, + 0, aBmpSize.cy, + aBitmapStream.getArray() + sizeof(BITMAPINFO), + (LPBITMAPINFO)pBmp, + DIB_RGB_COLORS ) ) + { + ooBmpStream = WinDIBToOOBMP( aBitmapStream ); + } + } + + return ooBmpStream; +} + diff --git a/dtrans/source/win32/dtobj/FmtFilter.hxx b/dtrans/source/win32/dtobj/FmtFilter.hxx new file mode 100755 index 000000000000..84f764c9769b --- /dev/null +++ b/dtrans/source/win32/dtobj/FmtFilter.hxx @@ -0,0 +1,96 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _FMTFILTER_HXX_ +#define _FMTFILTER_HXX_ + +#include <sal/types.h> + +#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_ +#include <com/sun/star/uno/Sequence.hxx> +#endif + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +/*------------------------------------------------------------------------ + input: + aMetaFilePict - a sequence of bytes containing a METAFILEPICT struct +------------------------------------------------------------------------*/ +com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinMFPictToOOMFPict( com::sun::star::uno::Sequence< sal_Int8 >& aMetaFilePict ); +com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinENHMFPictToOOMFPict( HENHMETAFILE hEnhMetaFile ); + +/*------------------------------------------------------------------------ + input: + aByteStream - a sequence of bytes containing a openoffice metafile + picture with a leading METAFILEHEADER +------------------------------------------------------------------------*/ +HMETAFILEPICT SAL_CALL OOMFPictToWinMFPict( com::sun::star::uno::Sequence< sal_Int8 >& aOOMetaFilePict ); +HENHMETAFILE SAL_CALL OOMFPictToWinENHMFPict( com::sun::star::uno::Sequence< sal_Int8 >& aOOMetaFilePict ); + +/*------------------------------------------------------------------------ + input: + aWinDIB - sequence of bytes containing a windows device independent + bitmap +------------------------------------------------------------------------*/ +com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinDIBToOOBMP( const com::sun::star::uno::Sequence< sal_Int8 >& aWinDIB ); + +/*------------------------------------------------------------------------ + input: + aWinDIB - sequence of bytes containing a windows bitmap handle +------------------------------------------------------------------------*/ +com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL WinBITMAPToOOBMP( HBITMAP ); + +/*------------------------------------------------------------------------ + input: + aOOBmp - sequence of bytes containing a openoffice bitmap +------------------------------------------------------------------------*/ +com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL OOBmpToWinDIB( com::sun::star::uno::Sequence< sal_Int8 >& aOOBmp ); + +/*------------------------------------------------------------------------ + input: + aTextHtml - a sequence of text/html which will be converted to the + HTML Format; the HTML Format has header before the real html data + the Format is described in the MSDN Library under HTML Clipboard + Format +------------------------------------------------------------------------*/ +com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL TextHtmlToHTMLFormat( com::sun::star::uno::Sequence< sal_Int8 >& aTextHtml ); + +/** + Return a FileList in which Windows Shell Links (lnk) are resolved. + If for what ever reason a resolution is not possible leave the + original lnk file. +*/ +com::sun::star::uno::Sequence< sal_Int8 > CF_HDROPToFileList(HGLOBAL hGlobal); + +#endif diff --git a/dtrans/source/win32/dtobj/MimeAttrib.hxx b/dtrans/source/win32/dtobj/MimeAttrib.hxx new file mode 100644 index 000000000000..7bd631cc79d5 --- /dev/null +++ b/dtrans/source/win32/dtobj/MimeAttrib.hxx @@ -0,0 +1,50 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _MIMEATTRIB_HXX_ +#define _MIMEATTRIB_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <rtl/ustring.hxx> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +const rtl::OUString TEXTPLAIN_PARAM_CHARSET = rtl::OUString::createFromAscii( "charset" ); + +const rtl::OUString PRE_WINDOWS_CODEPAGE = rtl::OUString::createFromAscii( "windows" ); +const rtl::OUString PRE_OEM_CODEPAGE = rtl::OUString::createFromAscii( "cp" ); +const rtl::OUString CHARSET_UTF16 = rtl::OUString::createFromAscii( "utf-16" ); +const rtl::OUString CHARSET_UNICODE = rtl::OUString::createFromAscii( "unicode" ); + + +#endif diff --git a/dtrans/source/win32/dtobj/TxtCnvtHlp.cxx b/dtrans/source/win32/dtobj/TxtCnvtHlp.cxx new file mode 100644 index 000000000000..3eecad271567 --- /dev/null +++ b/dtrans/source/win32/dtobj/TxtCnvtHlp.cxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "TxtCnvtHlp.hxx" +#include "DTransHelper.hxx" +#include "..\misc\ImplHelper.hxx" + +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::uno; + +//------------------------------------------------------------------ +// assuming a '\0' terminated string if no length specified +//------------------------------------------------------------------ + +int CalcBuffSizeForTextConversion( UINT code_page, LPCSTR lpMultiByteString, int nLen = -1 ) +{ + return ( MultiByteToWideChar( code_page, + 0, + lpMultiByteString, + nLen, + NULL, + 0 ) * sizeof( sal_Unicode ) ); +} + +//------------------------------------------------------------------ +// assuming a '\0' terminated string if no length specified +//------------------------------------------------------------------ + +int CalcBuffSizeForTextConversion( UINT code_page, LPCWSTR lpWideCharString, int nLen = -1 ) +{ + return WideCharToMultiByte( code_page, + 0, + lpWideCharString, + nLen, + NULL, + 0, + NULL, + NULL ); +} + +//------------------------------------------------------------------ +// converts text in one code page into unicode text +// automatically calculates the necessary buffer size and allocates +// the buffer +//------------------------------------------------------------------ + +int MultiByteToWideCharEx( UINT cp_src, + LPCSTR lpMultiByteString, + sal_uInt32 lenStr, + CStgTransferHelper& refDTransHelper, + BOOL bEnsureTrailingZero ) +{ + OSL_ASSERT( IsValidCodePage( cp_src ) ); + OSL_ASSERT( NULL != lpMultiByteString ); + + // calculate the required buff size + int reqSize = CalcBuffSizeForTextConversion( cp_src, lpMultiByteString, lenStr ); + + if ( bEnsureTrailingZero ) + reqSize += sizeof( sal_Unicode ); + + // initialize the data-transfer helper + refDTransHelper.init( reqSize ); + + // setup a global memory pointer + CRawHGlobalPtr ptrHGlob( refDTransHelper ); + + // do the converssion an return + return MultiByteToWideChar( cp_src, + 0, + lpMultiByteString, + lenStr, + static_cast< LPWSTR >( ptrHGlob.GetMemPtr( ) ), + ptrHGlob.MemSize( ) ); +} + +//------------------------------------------------------------------ +// converts unicode text into text of the specified code page +// automatically calculates the necessary buffer size and allocates +// the buffer +//------------------------------------------------------------------ + +int WideCharToMultiByteEx( UINT cp_dest, + LPCWSTR lpWideCharString, + sal_uInt32 lenStr, + CStgTransferHelper& refDTransHelper, + BOOL bEnsureTrailingZero ) +{ + OSL_ASSERT( IsValidCodePage( cp_dest ) ); + OSL_ASSERT( NULL != lpWideCharString ); + + // calculate the required buff size + int reqSize = CalcBuffSizeForTextConversion( cp_dest, lpWideCharString, lenStr ); + + if ( bEnsureTrailingZero ) + reqSize += sizeof( sal_Int8 ); + + // initialize the data-transfer helper + refDTransHelper.init( reqSize ); + + // setup a global memory pointer + CRawHGlobalPtr ptrHGlob( refDTransHelper ); + + // do the converssion an return + return WideCharToMultiByte( cp_dest, + 0, + lpWideCharString, + lenStr, + static_cast< LPSTR >( ptrHGlob.GetMemPtr( ) ), + ptrHGlob.MemSize( ), + NULL, + NULL ); +} + diff --git a/dtrans/source/win32/dtobj/TxtCnvtHlp.hxx b/dtrans/source/win32/dtobj/TxtCnvtHlp.hxx new file mode 100644 index 000000000000..a4d59a69284e --- /dev/null +++ b/dtrans/source/win32/dtobj/TxtCnvtHlp.hxx @@ -0,0 +1,63 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _TXTCNVTHLP_HXX_ +#define _TXTCNVTHLP_HXX_ + +#include <com/sun/star/datatransfer/DataFlavor.hpp> + +#ifndef _COM_SUN_STAR_UNO_SEQUENCE_HPP_ +#include <com/sun/star/uno/Sequence.h> +#endif +#include "DTransHelper.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +int MultiByteToWideCharEx( UINT cp_src, + LPCSTR lpMultiByteString, + sal_uInt32 lenStr, + CStgTransferHelper& refDTransHelper, + BOOL bEnsureTrailingZero = TRUE ); + +int WideCharToMultiByteEx( UINT cp_dest, + LPCWSTR lpWideCharString, + sal_uInt32 lenStr, + CStgTransferHelper& refDTransHelper, + BOOL bEnsureTrailingZero = TRUE ); + +#endif diff --git a/dtrans/source/win32/dtobj/XNotifyingDataObject.cxx b/dtrans/source/win32/dtobj/XNotifyingDataObject.cxx new file mode 100644 index 000000000000..25e3fab3a702 --- /dev/null +++ b/dtrans/source/win32/dtobj/XNotifyingDataObject.cxx @@ -0,0 +1,163 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include <osl/diagnose.h> +#include "XNotifyingDataObject.hxx" +#include "..\clipb\WinClipbImpl.hxx" +#include "..\clipb\WinClipboard.hxx" +#include "..\..\inc\DtObjFactory.hxx" + +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Reference; + + +CXNotifyingDataObject::CXNotifyingDataObject( + const IDataObjectPtr& aIDataObject, + const Reference< XTransferable >& aXTransferable, + const Reference< XClipboardOwner >& aXClipOwner, + CWinClipbImpl* theWinClipImpl ) : + m_nRefCnt( 0 ), + m_aIDataObject( aIDataObject ), + m_XTransferable( aXTransferable ), + m_XClipboardOwner( aXClipOwner ), + m_pWinClipImpl( theWinClipImpl ) +{ +} + +STDMETHODIMP CXNotifyingDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject ) +{ + if ( NULL == ppvObject ) + return E_INVALIDARG; + + HRESULT hr = E_NOINTERFACE; + + *ppvObject = NULL; + if ( ( __uuidof( IUnknown ) == iid ) || + ( __uuidof( IDataObject ) == iid ) ) + { + *ppvObject = static_cast< IUnknown* >( this ); + ( (LPUNKNOWN)*ppvObject )->AddRef( ); + hr = S_OK; + } + + return hr; +} + +STDMETHODIMP_(ULONG) CXNotifyingDataObject::AddRef( ) +{ + return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) ); +} + +STDMETHODIMP_(ULONG) CXNotifyingDataObject::Release( ) +{ + ULONG nRefCnt = + static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) ); + + if ( 0 == nRefCnt ) + { + if ( m_pWinClipImpl ) + m_pWinClipImpl->onReleaseDataObject( this ); + + delete this; + } + + return nRefCnt; +} + +STDMETHODIMP CXNotifyingDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ) +{ + return m_aIDataObject->GetData(pFormatetc, pmedium); +} + +STDMETHODIMP CXNotifyingDataObject::EnumFormatEtc( + DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ) +{ + return m_aIDataObject->EnumFormatEtc(dwDirection, ppenumFormatetc); +} + +STDMETHODIMP CXNotifyingDataObject::QueryGetData( LPFORMATETC pFormatetc ) +{ + return m_aIDataObject->QueryGetData(pFormatetc); +} + +STDMETHODIMP CXNotifyingDataObject::GetDataHere( LPFORMATETC lpFetc, LPSTGMEDIUM lpStgMedium ) +{ + return m_aIDataObject->GetDataHere(lpFetc, lpStgMedium); +} + +STDMETHODIMP CXNotifyingDataObject::GetCanonicalFormatEtc( LPFORMATETC lpFetc, LPFORMATETC lpCanonicalFetc ) +{ + return m_aIDataObject->GetCanonicalFormatEtc(lpFetc, lpCanonicalFetc); +} + +STDMETHODIMP CXNotifyingDataObject::SetData( LPFORMATETC lpFetc, LPSTGMEDIUM lpStgMedium, BOOL bRelease ) +{ + return m_aIDataObject->SetData( lpFetc, lpStgMedium, bRelease ); +} + +STDMETHODIMP CXNotifyingDataObject::DAdvise( + LPFORMATETC lpFetc, DWORD advf, LPADVISESINK lpAdvSink, DWORD* pdwConnection ) +{ + return m_aIDataObject->DAdvise( lpFetc, advf, lpAdvSink, pdwConnection ); +} + +STDMETHODIMP CXNotifyingDataObject::DUnadvise( DWORD dwConnection ) +{ + return m_aIDataObject->DUnadvise( dwConnection ); +} + +STDMETHODIMP CXNotifyingDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise ) +{ + return m_aIDataObject->EnumDAdvise( ppenumAdvise ); +} + +CXNotifyingDataObject::operator IDataObject*( ) +{ + return static_cast< IDataObject* >( this ); +} + +void SAL_CALL CXNotifyingDataObject::lostOwnership( ) +{ + try + { + if (m_XClipboardOwner.is()) + m_XClipboardOwner->lostOwnership( + static_cast<XClipboardEx*>(m_pWinClipImpl->m_pWinClipboard ), m_XTransferable); + } + catch(RuntimeException&) + { + OSL_ENSURE( sal_False, "RuntimeException caught" ); + } +} diff --git a/dtrans/source/win32/dtobj/XNotifyingDataObject.hxx b/dtrans/source/win32/dtobj/XNotifyingDataObject.hxx new file mode 100644 index 000000000000..394b835c3612 --- /dev/null +++ b/dtrans/source/win32/dtobj/XNotifyingDataObject.hxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _XNOTIFYINGDATAOBJECT_HXX_ +#define _XNOTIFYINGDATAOBJECT_HXX_ + + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <objidl.h> +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <systools/win32/comtools.hxx> + +/*-------------------------------------------------------------------------- + To implement the lostOwnership mechanism cleanly we need this wrapper + object +----------------------------------------------------------------------------*/ + +// forward +class CWinClipbImpl; + +class CXNotifyingDataObject : public IDataObject +{ +public: + CXNotifyingDataObject( + const IDataObjectPtr& aIDataObject, + const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable >& aXTransferable, + const com::sun::star::uno::Reference< com::sun::star::datatransfer::clipboard::XClipboardOwner >& aXClipOwner, + CWinClipbImpl* theWinClipImpl ); + + virtual ~CXNotifyingDataObject() {} + + //----------------------------------------------------------------- + // ole interface implementation + //----------------------------------------------------------------- + + //IUnknown interface methods + STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); + STDMETHODIMP_( ULONG ) AddRef( ); + STDMETHODIMP_( ULONG ) Release( ); + + // IDataObject interface methods + STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc ); + STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut ); + STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease ); + STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ); + STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection ); + STDMETHODIMP DUnadvise( DWORD dwConnection ); + STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise ); + + operator IDataObject*( ); + +private: + void SAL_CALL lostOwnership( ); + +private: + sal_Int32 m_nRefCnt; + IDataObjectPtr m_aIDataObject; + const com::sun::star::uno::Reference< com::sun::star::datatransfer::XTransferable > m_XTransferable; + const com::sun::star::uno::Reference< com::sun::star::datatransfer::clipboard::XClipboardOwner > m_XClipboardOwner; + CWinClipbImpl* m_pWinClipImpl; + + friend class CWinClipbImpl; +}; + +#endif diff --git a/dtrans/source/win32/dtobj/XTDataObject.cxx b/dtrans/source/win32/dtobj/XTDataObject.cxx new file mode 100644 index 000000000000..e17a931d7380 --- /dev/null +++ b/dtrans/source/win32/dtobj/XTDataObject.cxx @@ -0,0 +1,848 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> + +#ifndef _TXDATAOBJECT_HXX_ +#include "XTDataObject.hxx" +#endif +#include <com/sun/star/datatransfer/dataflavor.hpp> +#include "..\misc\ImplHelper.hxx" +#include "DTransHelper.hxx" +#include "TxtCnvtHlp.hxx" +#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#include "FmtFilter.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#pragma warning(disable:4917) +#endif +#include <windows.h> +#include <shlobj.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::datatransfer::clipboard; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace rtl; + +//------------------------------------------------------------------------ +// a helper class that will be thrown by the function validateFormatEtc +//------------------------------------------------------------------------ + +class CInvalidFormatEtcException +{ +public: + HRESULT m_hr; + CInvalidFormatEtcException( HRESULT hr ) : m_hr( hr ) {}; +}; + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +CXTDataObject::CXTDataObject( const Reference< XMultiServiceFactory >& aServiceManager, + const Reference< XTransferable >& aXTransferable ) : + m_nRefCnt( 0 ), + m_SrvMgr( aServiceManager ), + m_XTransferable( aXTransferable ), + m_DataFormatTranslator( aServiceManager ), + m_bFormatEtcContainerInitialized( sal_False ), + m_FormatRegistrar( m_SrvMgr, m_DataFormatTranslator ) +{ +} + +//------------------------------------------------------------------------ +// IUnknown->QueryInterface +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject ) +{ + if ( NULL == ppvObject ) + return E_INVALIDARG; + + HRESULT hr = E_NOINTERFACE; + + *ppvObject = NULL; + if ( ( __uuidof( IUnknown ) == iid ) || + ( __uuidof( IDataObject ) == iid ) ) + { + *ppvObject = static_cast< IUnknown* >( this ); + ( (LPUNKNOWN)*ppvObject )->AddRef( ); + hr = S_OK; + } + + return hr; +} + +//------------------------------------------------------------------------ +// IUnknown->AddRef +//------------------------------------------------------------------------ + +STDMETHODIMP_(ULONG) CXTDataObject::AddRef( ) +{ + return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) ); +} + +//------------------------------------------------------------------------ +// IUnknown->Release +//------------------------------------------------------------------------ + +STDMETHODIMP_(ULONG) CXTDataObject::Release( ) +{ + ULONG nRefCnt = + static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) ); + + if ( 0 == nRefCnt ) + delete this; + + return nRefCnt; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ) +{ + if ( !(pFormatetc && pmedium) ) + return E_INVALIDARG; + + try + { + // prepare data transfer + invalidateStgMedium( *pmedium ); + validateFormatEtc( pFormatetc ); + + // handle locale request, because locale is a artificial format for us + if ( CF_LOCALE == pFormatetc->cfFormat ) + renderLocaleAndSetupStgMedium( *pFormatetc, *pmedium ); + else if ( CF_UNICODETEXT == pFormatetc->cfFormat ) + renderUnicodeAndSetupStgMedium( *pFormatetc, *pmedium ); + else + renderAnyDataAndSetupStgMedium( *pFormatetc, *pmedium ); + } + catch(UnsupportedFlavorException&) + { + HRESULT hr = DV_E_FORMATETC; + + if ( m_FormatRegistrar.isSynthesizeableFormat( *pFormatetc ) ) + hr = renderSynthesizedFormatAndSetupStgMedium( *pFormatetc, *pmedium ); + + return hr; + } + catch( CInvalidFormatEtcException& ex ) + { + return ex.m_hr; + } + catch( CStgTransferHelper::CStgTransferException& ex ) + { + return translateStgExceptionCode( ex.m_hr ); + } + catch(...) + { + return E_UNEXPECTED; + } + + return S_OK; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +// inline +void SAL_CALL CXTDataObject::renderDataAndSetupStgMedium( + const sal_Int8* lpStorage, const FORMATETC& fetc, sal_uInt32 nInitStgSize, + sal_uInt32 nBytesToTransfer, STGMEDIUM& stgmedium ) +{ + OSL_PRECOND( !nInitStgSize || nInitStgSize && (nInitStgSize >= nBytesToTransfer), + "Memory size less than number of bytes to transfer" ); + + CStgTransferHelper stgTransfHelper( AUTO_INIT ); + + // setup storage size + if ( nInitStgSize > 0 ) + stgTransfHelper.init( nInitStgSize, GHND ); + +#if OSL_DEBUG_LEVEL > 0 + sal_uInt32 nBytesWritten = 0; + stgTransfHelper.write( lpStorage, nBytesToTransfer, &nBytesWritten ); + OSL_ASSERT( nBytesWritten == nBytesToTransfer ); +#else + stgTransfHelper.write( lpStorage, nBytesToTransfer ); +#endif + + setupStgMedium( fetc, stgTransfHelper, stgmedium ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +//inline +void SAL_CALL CXTDataObject::renderLocaleAndSetupStgMedium( + FORMATETC& fetc, STGMEDIUM& stgmedium ) +{ + if ( m_FormatRegistrar.hasSynthesizedLocale( ) ) + { + LCID lcid = m_FormatRegistrar.getSynthesizedLocale( ); + renderDataAndSetupStgMedium( + reinterpret_cast< sal_Int8* >( &lcid ), + fetc, + 0, + sizeof( LCID ), + stgmedium ); + } + else + throw CInvalidFormatEtcException( DV_E_FORMATETC ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +//inline +void SAL_CALL CXTDataObject::renderUnicodeAndSetupStgMedium( + FORMATETC& fetc, STGMEDIUM& stgmedium ) +{ + DataFlavor aFlavor = formatEtcToDataFlavor( fetc ); + + Any aAny = m_XTransferable->getTransferData( aFlavor ); + + // unfortunately not all transferables fulfill the + // spec. an do throw an UnsupportedFlavorException + // so we must check the any + if ( !aAny.hasValue( ) ) + { + OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); + throw UnsupportedFlavorException( ); + } + + OUString aText; + aAny >>= aText; + + sal_uInt32 nBytesToTransfer = aText.getLength( ) * sizeof( sal_Unicode ); + + // to be sure there is an ending 0 + sal_uInt32 nRequiredMemSize = nBytesToTransfer + sizeof( sal_Unicode ); + + renderDataAndSetupStgMedium( + reinterpret_cast< const sal_Int8* >( aText.getStr( ) ), + fetc, + nRequiredMemSize, + nBytesToTransfer, + stgmedium ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +//inline +void SAL_CALL CXTDataObject::renderAnyDataAndSetupStgMedium( + FORMATETC& fetc, STGMEDIUM& stgmedium ) +{ + DataFlavor aFlavor = formatEtcToDataFlavor( fetc ); + + Any aAny = m_XTransferable->getTransferData( aFlavor ); + + // unfortunately not all transferables fulfill the + // spec. an do throw an UnsupportedFlavorException + // so we must check the any + if ( !aAny.hasValue( ) ) + { + OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); + throw UnsupportedFlavorException( ); + } + + // unfortunately not all transferables fulfill the + // spec. an do throw an UnsupportedFlavorException + // so we must check the any + if ( !aAny.hasValue( ) ) + throw UnsupportedFlavorException( ); + + Sequence< sal_Int8 > clipDataStream; + aAny >>= clipDataStream; + + sal_uInt32 nRequiredMemSize = 0; + if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) ) + nRequiredMemSize = sizeof( sal_Int8 ) * clipDataStream.getLength( ) + 1; + + // prepare data for transmision + if ( CF_DIB == fetc.cfFormat ) + clipDataStream = OOBmpToWinDIB( clipDataStream ); + + if ( CF_METAFILEPICT == fetc.cfFormat ) + { + stgmedium.tymed = TYMED_MFPICT; + stgmedium.hMetaFilePict = OOMFPictToWinMFPict( clipDataStream ); + stgmedium.pUnkForRelease = NULL; + } + else if( CF_ENHMETAFILE == fetc.cfFormat ) + { + stgmedium.tymed = TYMED_ENHMF; + stgmedium.hMetaFilePict = OOMFPictToWinENHMFPict( clipDataStream ); + stgmedium.pUnkForRelease = NULL; + } + else + renderDataAndSetupStgMedium( + clipDataStream.getArray( ), + fetc, + nRequiredMemSize, + clipDataStream.getLength( ), + stgmedium ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +HRESULT SAL_CALL CXTDataObject::renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) +{ + HRESULT hr = S_OK; + + try + { + if ( CF_UNICODETEXT == fetc.cfFormat ) + // the transferable seems to have only text + renderSynthesizedUnicodeAndSetupStgMedium( fetc, stgmedium ); + else if ( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) ) + // the transferable seems to have only unicode text + renderSynthesizedTextAndSetupStgMedium( fetc, stgmedium ); + else + // the transferable seems to have only text/html + renderSynthesizedHtmlAndSetupStgMedium( fetc, stgmedium ); + } + catch(UnsupportedFlavorException&) + { + hr = DV_E_FORMATETC; + } + catch( CInvalidFormatEtcException& ) + { + OSL_ENSURE( sal_False, "Unexpected exception" ); + } + catch( CStgTransferHelper::CStgTransferException& ex ) + { + return translateStgExceptionCode( ex.m_hr ); + } + catch(...) + { + hr = E_UNEXPECTED; + } + + return hr; +} + +//------------------------------------------------------------------------ +// the transferable must have only text, so we will synthesize unicode text +//------------------------------------------------------------------------ + +void SAL_CALL CXTDataObject::renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) +{ + OSL_ASSERT( CF_UNICODETEXT == fetc.cfFormat ); + + Any aAny = m_XTransferable->getTransferData( m_FormatRegistrar.getRegisteredTextFlavor( ) ); + + // unfortunately not all transferables fulfill the + // spec. an do throw an UnsupportedFlavorException + // so we must check the any + if ( !aAny.hasValue( ) ) + { + OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); + throw UnsupportedFlavorException( ); + } + + Sequence< sal_Int8 > aText; + aAny >>= aText; + + CStgTransferHelper stgTransfHelper; + + MultiByteToWideCharEx( + m_FormatRegistrar.getRegisteredTextCodePage( ), + reinterpret_cast< char* >( aText.getArray( ) ), + aText.getLength( ), + stgTransfHelper ); + + setupStgMedium( fetc, stgTransfHelper, stgmedium ); +} + +//------------------------------------------------------------------------ +// the transferable must have only unicode text so we will sythesize text +//------------------------------------------------------------------------ + +void SAL_CALL CXTDataObject::renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) +{ + OSL_ASSERT( m_DataFormatTranslator.isOemOrAnsiTextFormat( fetc.cfFormat ) ); + + DataFlavor aFlavor = formatEtcToDataFlavor( + m_DataFormatTranslator.getFormatEtcForClipformat( CF_UNICODETEXT ) ); + + Any aAny = m_XTransferable->getTransferData( aFlavor ); + + // unfortunately not all transferables fulfill the + // spec. an do throw an UnsupportedFlavorException + // so we must check the any + if ( !aAny.hasValue( ) ) + { + OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); + throw UnsupportedFlavorException( ); + } + + OUString aUnicodeText; + aAny >>= aUnicodeText; + + CStgTransferHelper stgTransfHelper; + + WideCharToMultiByteEx( + GetACP( ), + reinterpret_cast<LPCWSTR>( aUnicodeText.getStr( ) ), + aUnicodeText.getLength( ), + stgTransfHelper ); + + setupStgMedium( fetc, stgTransfHelper, stgmedium ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CXTDataObject::renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ) +{ + OSL_ASSERT( m_DataFormatTranslator.isHTMLFormat( fetc.cfFormat ) ); + + DataFlavor aFlavor; + + // creating a DataFlavor on the fly + aFlavor.MimeType = OUString::createFromAscii( "text/html" ); + aFlavor.DataType = getCppuType( (Sequence< sal_Int8 >*)0 ); + + Any aAny = m_XTransferable->getTransferData( aFlavor ); + + // unfortunately not all transferables fulfill the + // spec. an do throw an UnsupportedFlavorException + // so we must check the any + if ( !aAny.hasValue( ) ) + { + OSL_ENSURE( sal_False, "XTransferable should throw an exception if ask for an unsupported flavor" ); + throw UnsupportedFlavorException( ); + } + + Sequence< sal_Int8 > aTextHtmlSequence; + aAny >>= aTextHtmlSequence; + + Sequence< sal_Int8 > aHTMLFormatSequence = TextHtmlToHTMLFormat( aTextHtmlSequence ); + + sal_uInt32 nBytesToTransfer = aHTMLFormatSequence.getLength( ); + + renderDataAndSetupStgMedium( + reinterpret_cast< const sal_Int8* >( aHTMLFormatSequence.getArray( ) ), + fetc, + 0, + nBytesToTransfer, + stgmedium ); +} + +//------------------------------------------------------------------------ +// IDataObject->EnumFormatEtc +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::EnumFormatEtc( + DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ) +{ + if ( NULL == ppenumFormatetc ) + return E_INVALIDARG; + + if ( DATADIR_SET == dwDirection ) + return E_NOTIMPL; + + *ppenumFormatetc = NULL; + + InitializeFormatEtcContainer( ); + + HRESULT hr; + if ( DATADIR_GET == dwDirection ) + { + *ppenumFormatetc = new CEnumFormatEtc( this, m_FormatEtcContainer ); + if ( NULL != *ppenumFormatetc ) + static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( ); + + hr = ( NULL != *ppenumFormatetc ) ? S_OK : E_OUTOFMEMORY; + } + else + hr = E_INVALIDARG; + + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->QueryGetData +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc ) +{ + if ( (NULL == pFormatetc) || IsBadReadPtr( pFormatetc, sizeof( FORMATETC ) ) ) + return E_INVALIDARG; + + InitializeFormatEtcContainer( ); + + return m_FormatEtcContainer.hasFormatEtc( *pFormatetc ) ? S_OK : S_FALSE; +} + +//------------------------------------------------------------------------ +// IDataObject->GetDataHere +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->GetCanonicalFormatEtc +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->SetData +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->DAdvise +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->DUnadvise +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::DUnadvise( DWORD ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->EnumDAdvise +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// for our convenience +//------------------------------------------------------------------------ + +CXTDataObject::operator IDataObject*( ) +{ + return static_cast< IDataObject* >( this ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +DataFlavor SAL_CALL CXTDataObject::formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const +{ + DataFlavor aFlavor; + + if ( m_FormatRegistrar.hasSynthesizedLocale( ) ) + aFlavor = + m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc, m_FormatRegistrar.getSynthesizedLocale( ) ); + else + aFlavor = m_DataFormatTranslator.getDataFlavorFromFormatEtc( aFormatEtc ); + + if ( !aFlavor.MimeType.getLength( ) ) + throw UnsupportedFlavorException( ); + + return aFlavor; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +void CXTDataObject::validateFormatEtc( LPFORMATETC lpFormatEtc ) const +{ + OSL_ASSERT( lpFormatEtc ); + + if ( lpFormatEtc->lindex != -1 ) + throw CInvalidFormatEtcException( DV_E_LINDEX ); + + if ( !(lpFormatEtc->dwAspect & DVASPECT_CONTENT) && + !(lpFormatEtc->dwAspect & DVASPECT_SHORTNAME) ) + throw CInvalidFormatEtcException( DV_E_DVASPECT ); + + if ( !(lpFormatEtc->tymed & TYMED_HGLOBAL) && + !(lpFormatEtc->tymed & TYMED_ISTREAM) && + !(lpFormatEtc->tymed & TYMED_MFPICT) && + !(lpFormatEtc->tymed & TYMED_ENHMF) ) + throw CInvalidFormatEtcException( DV_E_TYMED ); + + if ( lpFormatEtc->cfFormat == CF_METAFILEPICT && + !(lpFormatEtc->tymed & TYMED_MFPICT) ) + throw CInvalidFormatEtcException( DV_E_TYMED ); + + if ( lpFormatEtc->cfFormat == CF_ENHMETAFILE && + !(lpFormatEtc->tymed & TYMED_ENHMF) ) + throw CInvalidFormatEtcException( DV_E_TYMED ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +//inline +void SAL_CALL CXTDataObject::setupStgMedium( const FORMATETC& fetc, + CStgTransferHelper& stgTransHlp, + STGMEDIUM& stgmedium ) +{ + stgmedium.pUnkForRelease = NULL; + + if ( fetc.cfFormat == CF_METAFILEPICT ) + { + stgmedium.tymed = TYMED_MFPICT; + stgmedium.hMetaFilePict = static_cast< HMETAFILEPICT >( stgTransHlp.getHGlobal( ) ); + } + else if ( fetc.cfFormat == CF_ENHMETAFILE ) + { + stgmedium.tymed = TYMED_ENHMF; + stgmedium.hEnhMetaFile = static_cast< HENHMETAFILE >( stgTransHlp.getHGlobal( ) ); + } + else if ( fetc.tymed & TYMED_HGLOBAL ) + { + stgmedium.tymed = TYMED_HGLOBAL; + stgmedium.hGlobal = stgTransHlp.getHGlobal( ); + } + else if ( fetc.tymed & TYMED_ISTREAM ) + { + stgmedium.tymed = TYMED_ISTREAM; + stgTransHlp.getIStream( &stgmedium.pstm ); + } + else + OSL_ASSERT( sal_False ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +void SAL_CALL CXTDataObject::invalidateStgMedium( STGMEDIUM& stgmedium ) const +{ + stgmedium.tymed = TYMED_NULL; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline +HRESULT SAL_CALL CXTDataObject::translateStgExceptionCode( HRESULT hr ) const +{ + HRESULT hrTransl; + + switch( hr ) + { + case STG_E_MEDIUMFULL: + hrTransl = hr; + break; + + default: + hrTransl = E_UNEXPECTED; + break; + } + + return hrTransl; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +inline void SAL_CALL CXTDataObject::InitializeFormatEtcContainer( ) +{ + if ( !m_bFormatEtcContainerInitialized ) + { + m_FormatRegistrar.RegisterFormats( m_XTransferable, m_FormatEtcContainer ); + m_bFormatEtcContainerInitialized = sal_True; + } +} + +//============================================================================ +// CEnumFormatEtc +//============================================================================ + +//---------------------------------------------------------------------------- +// ctor +//---------------------------------------------------------------------------- + +CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ) : + m_nRefCnt( 0 ), + m_lpUnkOuter( lpUnkOuter ), + m_FormatEtcContainer( aFormatEtcContainer ) +{ + Reset( ); +} + +//---------------------------------------------------------------------------- +// IUnknown->QueryInterface +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject ) +{ + if ( NULL == ppvObject ) + return E_INVALIDARG; + + HRESULT hr = E_NOINTERFACE; + + *ppvObject = NULL; + + if ( ( __uuidof( IUnknown ) == iid ) || + ( __uuidof( IEnumFORMATETC ) == iid ) ) + { + *ppvObject = static_cast< IUnknown* >( this ); + static_cast< LPUNKNOWN >( *ppvObject )->AddRef( ); + hr = S_OK; + } + + return hr; +} + +//---------------------------------------------------------------------------- +// IUnknown->AddRef +//---------------------------------------------------------------------------- + +STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( ) +{ + // keep the dataobject alive + m_lpUnkOuter->AddRef( ); + return InterlockedIncrement( &m_nRefCnt ); +} + +//---------------------------------------------------------------------------- +// IUnknown->Release +//---------------------------------------------------------------------------- + +STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( ) +{ + // release the outer dataobject + m_lpUnkOuter->Release( ); + + ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt ); + if ( 0 == nRefCnt ) + delete this; + + return nRefCnt; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Next +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched ) +{ + if ( ( nRequested < 1 ) || + (( nRequested > 1 ) && ( NULL == lpFetched )) || + IsBadWritePtr( lpDest, sizeof( FORMATETC ) * nRequested ) ) + return E_INVALIDARG; + + sal_uInt32 nFetched = m_FormatEtcContainer.nextFormatEtc( lpDest, nRequested ); + + if ( NULL != lpFetched ) + *lpFetched = nFetched; + + return (nFetched == nRequested) ? S_OK : S_FALSE; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Skip +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt ) +{ + return m_FormatEtcContainer.skipFormatEtc( celt ) ? S_OK : S_FALSE; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Reset +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Reset( ) +{ + m_FormatEtcContainer.beginEnumFormatEtc( ); + return S_OK; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Clone +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum ) +{ + if ( NULL == ppenum ) + return E_INVALIDARG; + + *ppenum = new CEnumFormatEtc( m_lpUnkOuter, m_FormatEtcContainer ); + if ( NULL != ppenum ) + static_cast< LPUNKNOWN >( *ppenum )->AddRef( ); + + return ( NULL != *ppenum ) ? S_OK : E_OUTOFMEMORY; +} diff --git a/dtrans/source/win32/dtobj/XTDataObject.hxx b/dtrans/source/win32/dtobj/XTDataObject.hxx new file mode 100644 index 000000000000..b7b20af56ac7 --- /dev/null +++ b/dtrans/source/win32/dtobj/XTDataObject.hxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _XTDATAOBJECT_HXX_ +#define _XTDATAOBJECT_HXX_ + + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> + +#ifndef _DATAFORMATTRANSLATOR_HXX_ +#include "DataFmtTransl.hxx" +#endif + +#ifndef _FETCLIST_HXX_ +#include "FEtcList.hxx" +#endif + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <ole2.h> +#include <objidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +/*-------------------------------------------------------------------------- + - the function principle of the windows clipboard: + a data provider offers all formats he can deliver on the clipboard + a clipboard client ask for the available formats on the clipboard + and decides if there is a format he can use + if there is one, he requests the data in this format + + - This class inherits from IDataObject an so can be placed on the + OleClipboard. The class wrapps a transferable object which is the + original DataSource + - DataFlavors offerd by this transferable will be translated into + appropriate clipboard formats + - if the transferable contains text data always text and unicodetext + will be offered or vice versa + - text data will be automaticaly converted between text und unicode text + - although the transferable may support text in different charsets + (codepages) only text in one codepage can be offered by the clipboard + +----------------------------------------------------------------------------*/ + +class CStgTransferHelper; + +class CXTDataObject : public IDataObject +{ +public: + CXTDataObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& aServiceManager, + const ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable >& aXTransferable ); + virtual ~CXTDataObject() {} + + //----------------------------------------------------------------- + // ole interface implementation + //----------------------------------------------------------------- + + //IUnknown interface methods + STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); + STDMETHODIMP_( ULONG ) AddRef( ); + STDMETHODIMP_( ULONG ) Release( ); + + // IDataObject interface methods + STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc ); + STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut ); + STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease ); + STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ); + STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection ); + STDMETHODIMP DUnadvise( DWORD dwConnection ); + STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise ); + + operator IDataObject*( ); + +private: + com::sun::star::datatransfer::DataFlavor SAL_CALL formatEtcToDataFlavor( const FORMATETC& aFormatEtc ) const; + + void SAL_CALL renderDataAndSetupStgMedium( const sal_Int8* lpStorage, + const FORMATETC& fetc, + sal_uInt32 nInitStgSize, + sal_uInt32 nBytesToTransfer, + STGMEDIUM& stgmedium ); + + void SAL_CALL renderLocaleAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ); + void SAL_CALL renderUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ); + void SAL_CALL renderAnyDataAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ); + + HRESULT SAL_CALL renderSynthesizedFormatAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ); + void SAL_CALL renderSynthesizedUnicodeAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ); + void SAL_CALL renderSynthesizedTextAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ); + void SAL_CALL renderSynthesizedHtmlAndSetupStgMedium( FORMATETC& fetc, STGMEDIUM& stgmedium ); + + void SAL_CALL setupStgMedium( const FORMATETC& fetc, + CStgTransferHelper& stgTransHlp, + STGMEDIUM& stgmedium ); + + void validateFormatEtc( LPFORMATETC lpFormatEtc ) const; + void SAL_CALL invalidateStgMedium( STGMEDIUM& stgmedium ) const; + + HRESULT SAL_CALL translateStgExceptionCode( HRESULT hr ) const; + + inline void SAL_CALL InitializeFormatEtcContainer( ); + +private: + LONG m_nRefCnt; + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr; + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > m_XTransferable; + CFormatEtcContainer m_FormatEtcContainer; + sal_Bool m_bFormatEtcContainerInitialized; + CDataFormatTranslator m_DataFormatTranslator; + CFormatRegistrar m_FormatRegistrar; +}; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +class CEnumFormatEtc : public IEnumFORMATETC +{ +public: + CEnumFormatEtc( LPUNKNOWN lpUnkOuter, const CFormatEtcContainer& aFormatEtcContainer ); + virtual ~CEnumFormatEtc() {} + + // IUnknown + STDMETHODIMP QueryInterface( REFIID iid, LPVOID* ppvObject ); + STDMETHODIMP_( ULONG ) AddRef( ); + STDMETHODIMP_( ULONG ) Release( ); + + //IEnumFORMATETC + STDMETHODIMP Next( ULONG nRequested, LPFORMATETC lpDest, ULONG* lpFetched ); + STDMETHODIMP Skip( ULONG celt ); + STDMETHODIMP Reset( ); + STDMETHODIMP Clone( IEnumFORMATETC** ppenum ); + +private: + LONG m_nRefCnt; + LPUNKNOWN m_lpUnkOuter; + CFormatEtcContainer m_FormatEtcContainer; +}; + +typedef CEnumFormatEtc *PCEnumFormatEtc; + +#endif diff --git a/dtrans/source/win32/dtobj/makefile.mk b/dtrans/source/win32/dtobj/makefile.mk new file mode 100644 index 000000000000..5aea2b133dc1 --- /dev/null +++ b/dtrans/source/win32/dtobj/makefile.mk @@ -0,0 +1,76 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=dtrans +TARGET=dtobjfact +ENABLE_EXCEPTIONS=TRUE +LIBTARGET=NO + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +#-DUNICODE -D_UNICODE +.IF "$(COM)"!="GCC" +CFLAGS+=-GR -Ob0 +.ENDIF + +SLOFILES=$(SLO)$/DtObjFactory.obj\ + $(SLO)$/APNDataObject.obj\ + $(SLO)$/DOTransferable.obj\ + $(SLO)$/DTransHelper.obj\ + $(SLO)$/XTDataObject.obj\ + $(SLO)$/TxtCnvtHlp.obj\ + $(SLO)$/DataFmtTransl.obj\ + $(SLO)$/FmtFilter.obj\ + $(SLO)$/FetcList.obj\ + $(SLO)$/Fetc.obj\ + $(SLO)$/XNotifyingDataObject.obj + +LIB1TARGET=$(SLB)$/$(TARGET).lib +.IF "$(COM)"!="GCC" +LIB1OBJFILES=$(SLOFILES) +.ELSE +LIB1OBJFILES=$(SLO)$/DtObjFactory.obj\ + $(SLO)$/APNDataObject.obj\ + $(SLO)$/DOTransferable.obj\ + $(SLO)$/DTransHelper.obj\ + $(SLO)$/XTDataObject.obj\ + $(SLO)$/TxtCnvtHlp.obj\ + $(SLO)$/DataFmtTransl.obj\ + $(SLO)$/FmtFilter.obj\ + $(SLO)$/FetcList.obj\ + $(SLO)$/Fetc.obj +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/dtrans/source/win32/ftransl/exports.dxp b/dtrans/source/win32/ftransl/exports.dxp new file mode 100644 index 000000000000..f0e1c69934bc --- /dev/null +++ b/dtrans/source/win32/ftransl/exports.dxp @@ -0,0 +1,2 @@ +component_getImplementationEnvironment +component_getFactory diff --git a/dtrans/source/win32/ftransl/ftransl.cxx b/dtrans/source/win32/ftransl/ftransl.cxx new file mode 100755 index 000000000000..98c6625bb33e --- /dev/null +++ b/dtrans/source/win32/ftransl/ftransl.cxx @@ -0,0 +1,649 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> + +#ifndef _DFLVCONT_HXX_ +#include "ftransl.hxx" +#endif +#include <com/sun/star/datatransfer/XMimeContentType.hpp> +#include "..\misc\ImplHelper.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#pragma warning(disable:4917) +#endif +#include <shlobj.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define IMPL_NAME "com.sun.star.datatransfer.DataFormatTranslator" + +#define MODULE_PRIVATE +#define CPPUTYPE_SEQSALINT8 getCppuType( (const Sequence< sal_Int8 >*) 0 ) +#define CPPUTYPE_DEFAULT CPPUTYPE_SEQSALINT8 +#define CPPUTYPE_OUSTR getCppuType( (const ::rtl::OUString*) 0 ) +#define CPPUTYPE_SALINT32 getCppuType( ( sal_Int32 * ) 0 ) +#define OUSTR( str ) OUString::createFromAscii( #str ) +#define OUSTR_( str ) OUString::createFromAscii( str ) +#define EMPTY_OUSTR OUString::createFromAscii( "" ) +//#define PRIVATE_OO OUString::createFromAscii( "application/x-openoffice;" "windows_formatname=" ) + +const rtl::OUString Windows_FormatName = rtl::OUString::createFromAscii("windows_formatname"); +const com::sun::star::uno::Type CppuType_ByteSequence = ::getCppuType((const com::sun::star::uno::Sequence<sal_Int8>*)0); +const com::sun::star::uno::Type CppuType_String = ::getCppuType((const ::rtl::OUString*)0); + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace rtl; +using namespace osl; +using namespace cppu; +using namespace std; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::container; + +//------------------------------------------------------------------------ +// helper functions +//------------------------------------------------------------------------ + +namespace MODULE_PRIVATE +{ + Sequence< OUString > SAL_CALL DataFormatTranslator_getSupportedServiceNames( ) + { + Sequence< OUString > aRet(1); + aRet[0] = OUString::createFromAscii("com.sun.star.datatransfer.DataFormatTranslator"); + return aRet; + } +} + +//------------------------------------------------ +// +//------------------------------------------------ + +FormatEntry::FormatEntry() +{ +} + +//------------------------------------------------ +// +//------------------------------------------------ + +FormatEntry::FormatEntry( + const char* mime_content_type, + const char* human_presentable_name, + const char* native_format_name, + CLIPFORMAT std_clipboard_format_id, + ::com::sun::star::uno::Type const & cppu_type) +{ + aDataFlavor.MimeType = rtl::OUString::createFromAscii(mime_content_type); + aDataFlavor.HumanPresentableName = rtl::OUString::createFromAscii(human_presentable_name); + aDataFlavor.DataType = cppu_type; + + if (native_format_name) + aNativeFormatName = rtl::OUString::createFromAscii(native_format_name); + else + aNativeFormatName = rtl::OUString::createFromAscii(human_presentable_name); + + aStandardFormatId = std_clipboard_format_id; +} + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +CDataFormatTranslator::CDataFormatTranslator( const Reference< XMultiServiceFactory >& rSrvMgr ) : + m_SrvMgr( rSrvMgr ) +{ + initTranslationTable( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +Any SAL_CALL CDataFormatTranslator::getSystemDataTypeFromDataFlavor( const DataFlavor& aDataFlavor ) + throw( RuntimeException ) +{ + Any aAny; + + try + { + Reference< XMimeContentTypeFactory > refXMimeCntFactory( m_SrvMgr->createInstance( + OUSTR( com.sun.star.datatransfer.MimeContentTypeFactory ) ), UNO_QUERY ); + + if ( !refXMimeCntFactory.is( ) ) + throw RuntimeException( ); + + Reference< XMimeContentType > + refXMimeCntType( refXMimeCntFactory->createMimeContentType( aDataFlavor.MimeType ) ); + + OUString fullMediaType = refXMimeCntType->getFullMediaType( ); + if ( isTextPlainMediaType( fullMediaType ) ) + { + // default is CF_TEXT + aAny <<= static_cast< sal_Int32 >( CF_TEXT ); + + if ( refXMimeCntType->hasParameter( OUSTR( charset ) ) ) + { + // but maybe it is unicode text or oem text + OUString charset = refXMimeCntType->getParameterValue( OUSTR( charset ) ); + findStandardFormatIdForCharset( charset, aAny ); + } + } + else + { + if (refXMimeCntType->hasParameter(Windows_FormatName)) + { + OUString winfmtname = refXMimeCntType->getParameterValue(Windows_FormatName); + aAny <<= winfmtname; + + setStandardFormatIdForNativeFormatName( winfmtname, aAny ); + } + else + findStdFormatIdOrNativeFormatNameForFullMediaType( refXMimeCntFactory, fullMediaType, aAny ); + } + } + catch( IllegalArgumentException& ) + { + OSL_ENSURE( sal_False, "Invalid content-type detected!" ); + } + catch( NoSuchElementException& ) + { + OSL_ENSURE( sal_False, "Illegal content-type parameter" ); + } + catch( ... ) + { + OSL_ENSURE( sal_False, "Unexpected error" ); + throw; + } + + return aAny; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +DataFlavor SAL_CALL CDataFormatTranslator::getDataFlavorFromSystemDataType( const Any& aSysDataType ) + throw( RuntimeException ) +{ + OSL_PRECOND( aSysDataType.hasValue( ), "Empty system data type delivered" ); + + DataFlavor aFlavor = mkDataFlv( EMPTY_OUSTR, EMPTY_OUSTR, CPPUTYPE_SEQSALINT8 ); + + if ( aSysDataType.getValueType( ) == CPPUTYPE_SALINT32 ) + { + sal_Int32 clipformat; + aSysDataType >>= clipformat; + if ( CF_INVALID != clipformat ) + findDataFlavorForStandardFormatId( clipformat, aFlavor ); + } + else if ( aSysDataType.getValueType( ) == CPPUTYPE_OUSTR ) + { + OUString nativeFormatName; + aSysDataType >>= nativeFormatName; + + findDataFlavorForNativeFormatName( nativeFormatName, aFlavor ); + } + else + OSL_ENSURE( sal_False, "Invalid data type received" ); + + return aFlavor; +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +OUString SAL_CALL CDataFormatTranslator::getImplementationName( ) + throw( RuntimeException ) +{ + return OUString::createFromAscii( IMPL_NAME ); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +sal_Bool SAL_CALL CDataFormatTranslator::supportsService( const OUString& ServiceName ) + throw( RuntimeException ) +{ + Sequence < OUString > SupportedServicesNames = DataFormatTranslator_getSupportedServiceNames(); + + for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +Sequence< OUString > SAL_CALL CDataFormatTranslator::getSupportedServiceNames( ) + throw( RuntimeException ) +{ + return DataFormatTranslator_getSupportedServiceNames( ); +} + +// ------------------------------------------------- +// to optimize searching we add all entries with a +// standard clipboard format number first, in the +// table before the entries with CF_INVALID +// if we are searching for a standard clipboard +// format number we can stop if we find the first +// CF_INVALID +// ------------------------------------------------- + +void SAL_CALL CDataFormatTranslator::initTranslationTable() +{ + //SOT_FORMATSTR_ID_DIF + m_TranslTable.push_back(FormatEntry("application/x-openoffice-dif;windows_formatname=\"DIF\"", "DIF", "DIF", CF_DIF, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_BITMAP + m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_DIB, CPPUTYPE_DEFAULT)); + m_TranslTable.push_back(FormatEntry("application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"", "Bitmap", "Bitmap", CF_BITMAP, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_STRING + m_TranslTable.push_back(FormatEntry("text/plain;charset=utf-16", "Unicode-Text", "", CF_UNICODETEXT, CppuType_String)); + // Format Locale - for internal use + m_TranslTable.push_back(FormatEntry("application/x-openoffice-locale;windows_formatname=\"Locale\"", "Locale", "Locale", CF_LOCALE, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_WMF + m_TranslTable.push_back(FormatEntry("application/x-openoffice-wmf;windows_formatname=\"Image WMF\"", "Windows MetaFile", "Image WMF", CF_METAFILEPICT, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_EMF + m_TranslTable.push_back(FormatEntry("application/x-openoffice-emf;windows_formatname=\"Image EMF\"", "Windows Enhanced MetaFile", "Image EMF", CF_ENHMETAFILE, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_FILE_LIST + m_TranslTable.push_back(FormatEntry("application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", "FileList", CF_HDROP, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SYLK + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sylk;windows_formatname=\"Sylk\"", "Sylk", "Sylk", CF_SYLK, CPPUTYPE_DEFAULT ) ); + // SOT_FORMAT_GDIMETAFILE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"", "GDIMetaFile", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_PRIVATE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-private;windows_formatname=\"Private\"", "Private", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_FILE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-file;windows_formatname=\"FileName\"", "FileName", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMAT_RTF + m_TranslTable.push_back(FormatEntry("text/richtext", "Rich Text Format", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_DRAWING + m_TranslTable.push_back(FormatEntry("application/x-openoffice-drawing;windows_formatname=\"Drawing Format\"", "Drawing Format", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_SVXB + m_TranslTable.push_back(FormatEntry("application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"", "SVXB (StarView Bitmap/Animation)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_SVIM + m_TranslTable.push_back(FormatEntry("application/x-openoffice-svim;windows_formatname=\"SVIM (StarView ImageMap)\"", "SVIM (StarView ImageMap)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_XFA + m_TranslTable.push_back(FormatEntry("application/x-openoffice-xfa;windows_formatname=\"XFA (XOutDev FillAttr)\"", "XFA (XOutDev FillAttr)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_EDITENGINE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-editengine;windows_formatname=\"EditEngineFormat\"", "EditEngineFormat", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_INTERNALLINK_STATE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-internallink-state;windows_formatname=\"StatusInfo vom SvxInternalLink\"", "StatusInfo vom SvxInternalLink", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_SOLK + m_TranslTable.push_back(FormatEntry("application/x-openoffice-solk;windows_formatname=\"SOLK (StarOffice Link)\"", "SOLK (StarOffice Link)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_NETSCAPE_BOOKMARK + m_TranslTable.push_back(FormatEntry("application/x-openoffice-netscape-bookmark;windows_formatname=\"Netscape Bookmark\"", "Netscape Bookmark", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_TREELISTBOX + m_TranslTable.push_back(FormatEntry("application/x-openoffice-treelistbox;windows_formatname=\"SV_LBOX_DD_FORMAT\"", "SV_LBOX_DD_FORMAT", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_NATIVE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-native;windows_formatname=\"Native\"", "Native", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_OWNERLINK + m_TranslTable.push_back(FormatEntry("application/x-openoffice-ownerlink;windows_formatname=\"OwnerLink\"", "OwnerLink", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARSERVER + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starserver;windows_formatname=\"StarServerFormat\"", "StarServerFormat", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STAROBJECT + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starobject;windows_formatname=\"StarObjectFormat\"", "StarObjectFormat", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_APPLETOBJECT + m_TranslTable.push_back(FormatEntry("application/x-openoffice-appletobject;windows_formatname=\"Applet Object\"", "Applet Object", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_PLUGIN_OBJECT + m_TranslTable.push_back(FormatEntry("application/x-openoffice-plugin-object;windows_formatname=\"PlugIn Object\"", "PlugIn Object", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARWRITER_30 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starwriter-30;windows_formatname=\"StarWriter 3.0\"", "StarWriter 3.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITER_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starwriter-40;windows_formatname=\"StarWriter 4.0\"", "StarWriter 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITER_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starwriter-50;windows_formatname=\"StarWriter 5.0\"", "StarWriter 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITERWEB_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starwriterweb-40;windows_formatname=\"StarWriter/Web 4.0\"", "StarWriter/Web 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITERWEB_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starwriterweb-50;windows_formatname=\"StarWriter/Web 5.0\"", "StarWriter/Web 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITERGLOB_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starwriterglob-40;windows_formatname=\"StarWriter/Global 4.0\"", "StarWriter/Global 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARWRITERGLOB_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starwriterglob-50;windows_formatname=\"StarWriter/Global 5.0\"", "StarWriter/Global 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARDRAW + m_TranslTable.push_back(FormatEntry("application/x-openoffice-stardraw;windows_formatname=\"StarDrawDocument\"", "StarDrawDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARDRAW_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-stardraw-40;windows_formatname=\"StarDrawDocument 4.0\"", "StarDrawDocument 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARIMPRESS_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starimpress-50;windows_formatname=\"StarImpress 5.0\"", "StarImpress 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARDRAW_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-stardraw-50;windows_formatname=\"StarDraw 5.0\"", "StarDraw 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARCALC + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starcalc;windows_formatname=\"StarCalcDocument\"", "StarCalcDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARCALC_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starcalc-40;windows_formatname=\"StarCalc 4.0\"", "StarCalc 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARCALC_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starcalc-50;windows_formatname=\"StarCalc 5.0\"", "StarCalc 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARCHART + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starchart;windows_formatname=\"StarChartDocument\"", "StarChartDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARCHART_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starchart-40;windows_formatname=\"StarChartDocument 4.0\"", "StarChartDocument 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + // SOT_FORMATSTR_ID_STARCHART_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starchart-50;windows_formatname=\"StarChart 5.0\"", "StarChart 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARIMAGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starimage;windows_formatname=\"StarImageDocument\"", "StarImageDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARIMAGE_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starimage-40;windows_formatname=\"StarImageDocument 4.0\"", "StarImageDocument 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARIMAGE_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starimage-50;windows_formatname=\"StarImage 5.0\"", "StarImage 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARMATH + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starmath;windows_formatname=\"StarMath\"", "StarMath", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARMATH_40 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starmath-40;windows_formatname=\"StarMathDocument 4.0\"", "StarMathDocument 4.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARMATH_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starmath-50;windows_formatname=\"StarMath 5.0\"", "StarMath 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STAROBJECT_PAINTDOC + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starobject-paintdoc;windows_formatname=\"StarObjectPaintDocument\"", "StarObjectPaintDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_FILLED_AREA + m_TranslTable.push_back(FormatEntry("application/x-openoffice-filled-area;windows_formatname=\"FilledArea\"", "FilledArea", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_HTML + m_TranslTable.push_back(FormatEntry("text/html", "HTML (HyperText Markup Language)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_HTML_SIMPLE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-html-simple;windows_formatname=\"HTML Format\"", "HTML Format", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_CHAOS + m_TranslTable.push_back(FormatEntry("application/x-openoffice-chaos;windows_formatname=\"FORMAT_CHAOS\"", "FORMAT_CHAOS", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_CNT_MSGATTACHFILE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-msgattachfile;windows_formatname=\"CNT_MSGATTACHFILE_FORMAT\"", "CNT_MSGATTACHFILE_FORMAT", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_BIFF_5 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-biff5;windows_formatname=\"Biff5\"", "Biff5", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_BIFF__5 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-biff-5;windows_formatname=\"Biff 5\"", "Biff 5", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_BIFF_8 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-biff-8;windows_formatname=\"Biff8\"", "Biff8", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SYLK_BIGCAPS + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sylk-bigcaps;windows_formatname=\"SYLK\"", "SYLK", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_LINK + m_TranslTable.push_back(FormatEntry("application/x-openoffice-link;windows_formatname=\"Link\"", "Link", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARDRAW_TABBAR + m_TranslTable.push_back(FormatEntry("application/x-openoffice-stardraw-tabbar;windows_formatname=\"StarDraw TabBar\"", "StarDraw TabBar", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SONLK + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sonlk;windows_formatname=\"SONLK (StarOffice Navi Link)\"", "SONLK (StarOffice Navi Link)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_MSWORD_DOC + m_TranslTable.push_back(FormatEntry("application/msword", "MSWordDoc", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STAR_FRAMESET_DOC + m_TranslTable.push_back(FormatEntry("application/x-openoffice-star-frameset-doc;windows_formatname=\"StarFrameSetDocument\"", "StarFrameSetDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_OFFICE_DOC + m_TranslTable.push_back(FormatEntry("application/x-openoffice-office-doc;windows_formatname=\"OfficeDocument\"", "OfficeDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_NOTES_DOCINFO + m_TranslTable.push_back(FormatEntry("application/x-openoffice-notes-docinfo;windows_formatname=\"NotesDocInfo\"", "NotesDocInfo", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_NOTES_HNOTE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-notes-hnote;windows_formatname=\"NoteshNote\"", "NoteshNote", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_NOTES_NATIVE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-notes-native;windows_formatname=\"Native\"", "Native", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SFX_DOC + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sfx-doc;windows_formatname=\"SfxDocument\"", "SfxDocument", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EVDF + m_TranslTable.push_back(FormatEntry("application/x-openoffice-evdf;windows_formatname=\"EVDF (Explorer View Dummy Format)\"", "EVDF (Explorer View Dummy Format)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_ESDF + m_TranslTable.push_back(FormatEntry("application/x-openoffice-esdf;windows_formatname=\"ESDF (Explorer Search Dummy Format)\"", "ESDF (Explorer Search Dummy Format)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_IDF + m_TranslTable.push_back(FormatEntry("application/x-openoffice-idf;windows_formatname=\"IDF (Iconview Dummy Format)\"", "IDF (Iconview Dummy Format)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EFTP + m_TranslTable.push_back(FormatEntry("application/x-openoffice-eftp;windows_formatname=\"EFTP (Explorer Ftp File)\"", "EFTP (Explorer Ftp File)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EFD + m_TranslTable.push_back(FormatEntry("application/x-openoffice-efd;windows_formatname=\"EFD (Explorer Ftp Dir)\"", "EFD (Explorer Ftp Dir)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SVX_FORMFIELDEXCH + m_TranslTable.push_back(FormatEntry("application/x-openoffice-svx-formfieldexch;windows_formatname=\"SvxFormFieldExch\"", "SvxFormFieldExch", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EXTENDED_TABBAR + m_TranslTable.push_back(FormatEntry("application/x-openoffice-extended-tabbar;windows_formatname=\"ExtendedTabBar\"", "ExtendedTabBar", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_DATAEXCHANGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-dataexchange;windows_formatname=\"SBA-DATAFORMAT\"", "SBA-DATAFORMAT", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-fielddataexchange;windows_formatname=\"SBA-FIELDFORMAT\"", "SBA-FIELDFORMAT", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_PRIVATE_URL + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-private-url;windows_formatname=\"SBA-PRIVATEURLFORMAT\"", "SBA-PRIVATEURLFORMAT", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_TABED + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-tabed;windows_formatname=\"Tabed\"", "Tabed", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_TABID + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-tabid;windows_formatname=\"Tabid\"", "Tabid", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_JOIN + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-join;windows_formatname=\"SBA-JOINFORMAT\"", "SBA-JOINFORMAT", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_OBJECTDESCRIPTOR + m_TranslTable.push_back(FormatEntry("application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"", "Star Object Descriptor (XML)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR + m_TranslTable.push_back(FormatEntry("application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"", "Star Link Source Descriptor (XML)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EMBED_SOURCE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"", "Star Embed Source (XML)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_LINK_SOURCE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"", "Star Link Source (XML)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EMBEDDED_OBJ + m_TranslTable.push_back(FormatEntry("application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"", "Star Embedded Object (XML)", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_FILECONTENT + m_TranslTable.push_back(FormatEntry("application/x-openoffice-filecontent;windows_formatname=\"" CFSTR_FILECONTENTS "\"", CFSTR_FILECONTENTS, NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_FILEGRPDESCRIPTOR + m_TranslTable.push_back(FormatEntry("application/x-openoffice-filegrpdescriptor;windows_formatname=\"" CFSTR_FILEDESCRIPTOR "\"", CFSTR_FILEDESCRIPTOR, NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_FILENAME + m_TranslTable.push_back(FormatEntry("application/x-openoffice-filename;windows_formatname=\"" CFSTR_FILENAME "\"", CFSTR_FILENAME, NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SD_OLE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sd-ole;windows_formatname=\"SD-OLE\"", "SD-OLE", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EMBEDDED_OBJ_OLE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-embedded-obj-ole;windows_formatname=\"Embedded Object\"", "Embedded Object", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_EMBED_SOURCE_OLE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-embed-source-ole;windows_formatname=\"Embed Source\"", "Embed Source", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_OBJECTDESCRIPTOR_OLE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-objectdescriptor-ole;windows_formatname=\"Object Descriptor\"", "Object Descriptor", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_LINKSRCDESCRIPTOR_OLE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-linkdescriptor-ole;windows_formatname=\"Link Source Descriptor\"", "Link Source Descriptor", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_LINK_SOURCE_OLE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-link-source-ole;windows_formatname=\"Link Source\"", "Link Source", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-ctrldataexchange;windows_formatname=\"SBA-CTRLFORMAT\"", "SBA-CTRLFORMAT", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_OUTPLACE_OBJ + m_TranslTable.push_back(FormatEntry("application/x-openoffice-outplace-obj;windows_formatname=\"OutPlace Object\"", "OutPlace Object", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_CNT_OWN_CLIP + m_TranslTable.push_back(FormatEntry("application/x-openoffice-cnt-own-clip;windows_formatname=\"CntOwnClipboard\"", "CntOwnClipboard", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_INET_IMAGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-inet-image;windows_formatname=\"SO-INet-Image\"", "SO-INet-Image", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_NETSCAPE_IMAGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-netscape-image;windows_formatname=\"Netscape Image Format\"", "Netscape Image Format", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_SBA_FORMEXCHANGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-formexchange;windows_formatname=\"SBA_FORMEXCHANGE\"", "SBA_FORMEXCHANGE", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); //SOT_FORMATSTR_ID_SBA_REPORTEXCHANGE + m_TranslTable.push_back(FormatEntry("application/x-openoffice-sba-reportexchange;windows_formatname=\"SBA_REPORTEXCHANGE\"", "SBA_REPORTEXCHANGE", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_UNIFORMRESOURCELOCATOR + m_TranslTable.push_back(FormatEntry("application/x-openoffice-uniformresourcelocator;windows_formatname=\"UniformResourceLocator\"", "UniformResourceLocator", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARCHARTDOCUMENT_50 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-starchartdocument-50;windows_formatname=\"StarChartDocument 5.0\"", "StarChartDocument 5.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_GRAPHOBJ + m_TranslTable.push_back(FormatEntry("application/x-openoffice-graphobj;windows_formatname=\"Graphic Object\"", "Graphic Object", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITER_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.writer", "Writer 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITERWEB_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.writer.web", "Writer/Web 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWRITERGLOB_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.writer.global", "Writer/Global 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARWDRAW_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.draw", "Draw 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARIMPRESS_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.impress", "Impress 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARCALC_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.calc", "Calc 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARCHART_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.chart", "Chart 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_STARMATH_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.math", "Math 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_DIALOG_60 + m_TranslTable.push_back(FormatEntry("application/vnd.sun.xml.dialog", "Dialog 6.0", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_BMP + m_TranslTable.push_back(FormatEntry("image/bmp", "Windows Bitmap", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_DUMMY3 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-dummy3;windows_formatname=\"SO_DUMMYFORMAT_3\"", "SO_DUMMYFORMAT_3", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); + //SOT_FORMATSTR_ID_DUMMY4 + m_TranslTable.push_back(FormatEntry("application/x-openoffice-dummy4;windows_formatname=\"SO_DUMMYFORMAT_4\"", "SO_DUMMYFORMAT_4", NULL, CF_INVALID, CPPUTYPE_DEFAULT)); +} + +// ------------------------------------------------- +// +// ------------------------------------------------- + +void SAL_CALL CDataFormatTranslator::findDataFlavorForStandardFormatId( sal_Int32 aStandardFormatId, DataFlavor& aDataFlavor ) const +{ + /* + we break the for loop if we find the first CF_INVALID + because in the translation table the entries with a + standard clipboard format id appear before the other + entries with CF_INVALID + */ + vector< FormatEntry >::const_iterator citer_end = m_TranslTable.end( ); + for ( vector< FormatEntry >::const_iterator citer = m_TranslTable.begin( ); citer != citer_end; ++citer ) + { + sal_Int32 stdId = citer->aStandardFormatId; + if ( aStandardFormatId == stdId ) + { + aDataFlavor = citer->aDataFlavor; + break; + } + else if ( stdId == CF_INVALID ) + break; + } +} + +// ------------------------------------------------- +// +// ------------------------------------------------- + +void SAL_CALL CDataFormatTranslator::findDataFlavorForNativeFormatName( const OUString& aNativeFormatName, DataFlavor& aDataFlavor ) const +{ + vector< FormatEntry >::const_iterator citer_end = m_TranslTable.end( ); + for ( vector< FormatEntry >::const_iterator citer = m_TranslTable.begin( ); + citer != citer_end; + ++citer ) + { + if ( aNativeFormatName.equalsIgnoreAsciiCase( citer->aNativeFormatName ) ) + { + aDataFlavor = citer->aDataFlavor; + break; + } + } +} + +// ------------------------------------------------- +// +// ------------------------------------------------- + +void SAL_CALL CDataFormatTranslator::findStandardFormatIdForCharset( const OUString& aCharset, Any& aAny ) const +{ + if ( aCharset.equalsIgnoreAsciiCase( OUSTR( utf-16 ) ) ) + aAny <<= static_cast< sal_Int32 >( CF_UNICODETEXT ); + else + { + sal_Int32 wincp = getWinCPFromMimeCharset( aCharset ); + if ( IsOEMCP ( wincp ) ) + aAny <<= static_cast< sal_Int32 >( CF_OEMTEXT ); + } +} + +// ------------------------------------------------- +// +// ------------------------------------------------- + +void SAL_CALL CDataFormatTranslator::setStandardFormatIdForNativeFormatName( const OUString& aNativeFormatName, Any& aAny ) const +{ + vector< FormatEntry >::const_iterator citer_end = m_TranslTable.end( ); + for ( vector< FormatEntry >::const_iterator citer = m_TranslTable.begin( ); citer != citer_end; ++citer ) + { + if ( aNativeFormatName.equalsIgnoreAsciiCase( citer->aNativeFormatName ) && + (CF_INVALID != citer->aStandardFormatId) ) + { + aAny <<= citer->aStandardFormatId; + break; + } + } +} + +// ------------------------------------------------- +// +// ------------------------------------------------- + +void SAL_CALL CDataFormatTranslator::findStdFormatIdOrNativeFormatNameForFullMediaType( + const Reference< XMimeContentTypeFactory >& aRefXMimeFactory, + const OUString& aFullMediaType, + Any& aAny ) const +{ + vector< FormatEntry >::const_iterator citer_end = m_TranslTable.end( ); + for ( vector< FormatEntry >::const_iterator citer = m_TranslTable.begin( ); citer != citer_end; ++citer ) + { + Reference< XMimeContentType > + refXMime( aRefXMimeFactory->createMimeContentType( citer->aDataFlavor.MimeType ) ); + if ( aFullMediaType.equalsIgnoreAsciiCase( refXMime->getFullMediaType( ) ) ) + { + sal_Int32 cf = citer->aStandardFormatId; + if ( CF_INVALID != cf ) + aAny <<= cf; + else + { + OSL_ENSURE( citer->aNativeFormatName.getLength( ), + "Invalid standard format id and empty native format name in translation table" ); + aAny <<= citer->aNativeFormatName; + } + break; + } + } +} + +// ------------------------------------------------- +// +// ------------------------------------------------- + +inline sal_Bool CDataFormatTranslator::isTextPlainMediaType( const OUString& fullMediaType ) const +{ + return (fullMediaType.equalsIgnoreAsciiCase(OUSTR(text/plain))); +} + +// ------------------------------------------------- +// +// ------------------------------------------------- + +DataFlavor SAL_CALL CDataFormatTranslator::mkDataFlv(const OUString& cnttype, const OUString& hpname, Type dtype) +{ + DataFlavor dflv; + dflv.MimeType = cnttype; + dflv.HumanPresentableName = hpname; + dflv.DataType = dtype; + return dflv; +} diff --git a/dtrans/source/win32/ftransl/ftransl.hxx b/dtrans/source/win32/ftransl/ftransl.hxx new file mode 100644 index 000000000000..631ae89cc388 --- /dev/null +++ b/dtrans/source/win32/ftransl/ftransl.hxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _FTRANSL_HXX_ +#define _FTRANSL_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <cppuhelper/compbase2.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/datatransfer/XDataFormatTranslator.hpp> +#include <com/sun/star/datatransfer/XMimeContentTypeFactory.hpp> +#include "..\misc\WinClip.hxx" + +#include <vector> + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//------------------------------------------------------------------------ +// declarations +//------------------------------------------------------------------------ + +struct FormatEntry +{ + FormatEntry(); + + FormatEntry( + const char* mime_content_type, + const char* human_presentable_name, + const char* native_format_name, + CLIPFORMAT std_clipboard_format_id, + com::sun::star::uno::Type const & cppu_type + ); + + com::sun::star::datatransfer::DataFlavor aDataFlavor; + rtl::OUString aNativeFormatName; + sal_Int32 aStandardFormatId; +}; + +//------------------------------------------------ +// CDataFormatTranslator +//------------------------------------------------ + +class CDataFormatTranslator : public + cppu::WeakImplHelper2< com::sun::star::datatransfer::XDataFormatTranslator, \ + com::sun::star::lang::XServiceInfo > +{ + +public: + CDataFormatTranslator( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSrvMgr ); + + //------------------------------------------------ + // XDataFormatTranslator + //------------------------------------------------ + + virtual ::com::sun::star::uno::Any SAL_CALL getSystemDataTypeFromDataFlavor( const ::com::sun::star::datatransfer::DataFlavor& aDataFlavor ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::datatransfer::DataFlavor SAL_CALL getDataFlavorFromSystemDataType( const ::com::sun::star::uno::Any& aSysDataType ) + throw(::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XServiceInfo + //------------------------------------------------ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException); + +private: + void SAL_CALL initTranslationTable( ); + + void SAL_CALL findDataFlavorForStandardFormatId( sal_Int32 aStandardFormatId, com::sun::star::datatransfer::DataFlavor& aDataFlavor ) const; + void SAL_CALL findDataFlavorForNativeFormatName( const rtl::OUString& aNativeFormatName, com::sun::star::datatransfer::DataFlavor& aDataFlavor ) const; + void SAL_CALL findStandardFormatIdForCharset( const rtl::OUString& aCharset, com::sun::star::uno::Any& aAny ) const; + void SAL_CALL setStandardFormatIdForNativeFormatName( const rtl::OUString& aNativeFormatName, com::sun::star::uno::Any& aAny ) const; + void SAL_CALL findStdFormatIdOrNativeFormatNameForFullMediaType( + const com::sun::star::uno::Reference< com::sun::star::datatransfer::XMimeContentTypeFactory >& aRefXMimeFactory, + const rtl::OUString& aFullMediaType, com::sun::star::uno::Any& aAny ) const; + + sal_Bool isTextPlainMediaType( const rtl::OUString& fullMediaType ) const; + + com::sun::star::datatransfer::DataFlavor SAL_CALL mkDataFlv( const rtl::OUString& cnttype, const rtl::OUString& hpname, ::com::sun::star::uno::Type dtype ); + +private: + std::vector< FormatEntry > m_TranslTable; + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_SrvMgr; +}; + + +#endif + diff --git a/dtrans/source/win32/ftransl/ftransl.xml b/dtrans/source/win32/ftransl/ftransl.xml new file mode 100644 index 000000000000..28cddad4bbab --- /dev/null +++ b/dtrans/source/win32/ftransl/ftransl.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name> ftransl </module-name> + <component-description> + <author> Tino Rachui </author> + <name> com.sun.star.comp.datatransfer.DataFormatTranslator </name> + <description> + The win32 implementation of the datatransfer service. +</description> + <loader-name> com.sun.star.loader.SharedLibrary </loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.datatransfer.DataFormatTranslator </supported-service> + <service-dependency> ... </service-dependency> + <type> com.sun.star.datatransfer.XDataFormatTranslator </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.container.XSet </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/dtrans/source/win32/ftransl/ftranslentry.cxx b/dtrans/source/win32/ftransl/ftranslentry.cxx new file mode 100644 index 000000000000..abdd27ffcdae --- /dev/null +++ b/dtrans/source/win32/ftransl/ftranslentry.cxx @@ -0,0 +1,134 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//----------------------------------------------------------------- +// includes of other projects +//----------------------------------------------------------------- +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> + +#ifndef _COM_SUN_STAR_DATATRANSFER_XDATAFLAVORCONTAINER_HPP_ +#include <com/sun/star/datatransfer/XDataFormatTranslator.hpp> +#endif +#include "ftransl.hxx" + +//----------------------------------------------------------------- +// some defines +//----------------------------------------------------------------- + +// the service names +#define SERVICE_NAME "com.sun.star.datatransfer.DataFormatTranslator" + +// the implementation names +#define IMPL_NAME "com.sun.star.datatransfer.DataFormatTranslator" + +// the registry key names +// a key under which this service will be registered, Format: -> "/ImplName/UNO/SERVICES/ServiceName" +// < Implementation-Name ></UNO/SERVICES/>< Service-Name > +#define REGKEY_NAME "/com.sun.star.datatransfer.DataFormatTranslator/UNO/SERVICES/com.sun.star.datatransfer.DataFormatTranslator" + +//----------------------------------------------------------------------------------------------------------- +// namespace directives +//----------------------------------------------------------------------------------------------------------- + +using namespace ::rtl ; +using namespace ::cppu ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::registry ; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::datatransfer; + +//----------------------------------------------------------------- +// create a static object to initialize the shell9x library +//----------------------------------------------------------------- + +namespace +{ + + //----------------------------------------------------------------------------------------------------------- + // functions to create a new Clipboad instance; is needed by factory helper implementation + // @param rServiceManager - service manager, useful if the component needs other uno services + // so we should give it to every UNO-Implementation component + //----------------------------------------------------------------------------------------------------------- + + Reference< XInterface > SAL_CALL createInstance( const Reference< XMultiServiceFactory >& rServiceManager ) + { + return Reference< XInterface >( static_cast< XDataFormatTranslator* >( new CDataFormatTranslator( rServiceManager ) ) ); + } +} + +//----------------------------------------------------------------------------------------------------------- +// the 3 important functions which will be exported +//----------------------------------------------------------------------------------------------------------- + +extern "C" +{ + +//---------------------------------------------------------------------- +// component_getImplementationEnvironment +//---------------------------------------------------------------------- + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//---------------------------------------------------------------------- +// component_getFactory +// returns a factory to create XFilePicker-Services +//---------------------------------------------------------------------- + +void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* /*pRegistryKey*/ ) +{ + void* pRet = 0; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) ); + + Reference< XSingleServiceFactory > xFactory ( createOneInstanceFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createInstance, + aSNS ) ); + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +} // extern "C" diff --git a/dtrans/source/win32/ftransl/makefile.mk b/dtrans/source/win32/ftransl/makefile.mk new file mode 100644 index 000000000000..bc6294a90f93 --- /dev/null +++ b/dtrans/source/win32/ftransl/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=dtrans +TARGET=ftransl +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) +USE_BOUNDCHK= + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES=$(SLO)$/ftranslentry.obj \ + $(SLO)$/ftransl.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/dtrans/source/win32/misc/ImplHelper.cxx b/dtrans/source/win32/misc/ImplHelper.cxx new file mode 100644 index 000000000000..4bfb7f462fc2 --- /dev/null +++ b/dtrans/source/win32/misc/ImplHelper.cxx @@ -0,0 +1,489 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "ImplHelper.hxx" +#include <rtl/tencinfo.h> +#include <rtl/memory.h> + +#include <memory> +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#ifdef __MINGW32__ +#include <excpt.h> +#endif + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define FORMATETC_EXACT_MATCH 1 +#define FORMATETC_PARTIAL_MATCH -1 +#define FORMATETC_NO_MATCH 0 + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using ::rtl::OUString; +using ::rtl::OString; + +//------------------------------------------------------------------------ +// returns a windows codepage appropriate to the +// given mime charset parameter value +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL getWinCPFromMimeCharset( const OUString& charset ) +{ + sal_uInt32 winCP = GetACP( ); + + if ( charset.getLength( ) ) + { + OString osCharset( + charset.getStr( ), charset.getLength( ), RTL_TEXTENCODING_ASCII_US ); + + rtl_TextEncoding txtEnc = + rtl_getTextEncodingFromMimeCharset( osCharset.getStr( ) ); + + sal_uInt32 winChrs = rtl_getBestWindowsCharsetFromTextEncoding( txtEnc ); + + CHARSETINFO chrsInf; + sal_Bool bRet = TranslateCharsetInfo( (DWORD*)winChrs, &chrsInf, TCI_SRCCHARSET ) ? + sal_True : sal_False; + + // if one of the above functions fails + // we will return the current ANSI codepage + // of this thread + if ( bRet ) + winCP = chrsInf.ciACP; + } + + return winCP; +} + +//-------------------------------------------------- +// returns a windows codepage appropriate to the +// given locale and locale type +//-------------------------------------------------- + +OUString SAL_CALL getWinCPFromLocaleId( LCID lcid, LCTYPE lctype ) +{ + OSL_ASSERT( IsValidLocale( lcid, LCID_SUPPORTED ) ); + + // we set an default value + OUString winCP; + + // set an default value + if ( LOCALE_IDEFAULTCODEPAGE == lctype ) + { + winCP = OUString::valueOf( static_cast<sal_Int32>(GetOEMCP( )), 10 ); + } + else if ( LOCALE_IDEFAULTANSICODEPAGE == lctype ) + { + winCP = OUString::valueOf( static_cast<sal_Int32>(GetACP( )), 10 ); + } + else + OSL_ASSERT( sal_False ); + + // we use the GetLocaleInfoA because don't want to provide + // a unicode wrapper function for Win9x in sal/systools + char buff[6]; + sal_Int32 nResult = GetLocaleInfoA( + lcid, lctype | LOCALE_USE_CP_ACP, buff, sizeof( buff ) ); + + OSL_ASSERT( nResult ); + + if ( nResult ) + { + sal_Int32 len = MultiByteToWideChar( + CP_ACP, 0, buff, -1, NULL, 0 ); + + OSL_ASSERT( len > 0 ); + + std::auto_ptr< sal_Unicode > lpwchBuff( new sal_Unicode[len] ); + + if ( NULL != lpwchBuff.get( ) ) + { + len = MultiByteToWideChar( + CP_ACP, 0, buff, -1, reinterpret_cast<LPWSTR>(lpwchBuff.get( )), len ); + + winCP = OUString( lpwchBuff.get( ), (len - 1) ); + } + } + + return winCP; +} + +//-------------------------------------------------- +// returns a mime charset parameter value appropriate +// to the given codepage, optional a prefix can be +// given, e.g. "windows-" or "cp" +//-------------------------------------------------- + +OUString SAL_CALL getMimeCharsetFromWinCP( sal_uInt32 cp, const OUString& aPrefix ) +{ + return aPrefix + cptostr( cp ); +} + +//-------------------------------------------------- +// returns a mime charset parameter value appropriate +// to the given locale id and locale type, optional a +// prefix can be given, e.g. "windows-" or "cp" +//-------------------------------------------------- + +OUString SAL_CALL getMimeCharsetFromLocaleId( LCID lcid, LCTYPE lctype, const OUString& aPrefix ) +{ + OUString charset = getWinCPFromLocaleId( lcid, lctype ); + return aPrefix + charset; +} + +//------------------------------------------------------------------------ +// IsOEMCP +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage ) +{ + OSL_ASSERT( IsValidCodePage( codepage ) ); + + sal_uInt32 arrOEMCP[] = { 437, 708, 709, 710, 720, 737, + 775, 850, 852, 855, 857, 860, + 861, 862, 863, 864, 865, 866, + 869, 874, 932, 936, 949, 950, 1361 }; + + for ( sal_Int8 i = 0; i < ( sizeof( arrOEMCP )/sizeof( sal_uInt32 ) ); ++i ) + if ( arrOEMCP[i] == codepage ) + return sal_True; + + return sal_False; +} + +//------------------------------------------------------------------------ +// converts a codepage into its string representation +//------------------------------------------------------------------------ + +OUString SAL_CALL cptostr( sal_uInt32 codepage ) +{ + OSL_ASSERT( IsValidCodePage( codepage ) ); + + return OUString::valueOf( static_cast<sal_Int64>( codepage ), 10 ); +} + +//------------------------------------------------------------------------- +// OleStdDeleteTargetDevice() +// +// Purpose: +// +// Parameters: +// +// Return Value: +// SCODE - S_OK if successful +//------------------------------------------------------------------------- + +void SAL_CALL DeleteTargetDevice( DVTARGETDEVICE* ptd ) +{ +#ifdef __MINGW32__ + jmp_buf jmpbuf; + __SEHandler han; + if (__builtin_setjmp(jmpbuf) == 0) + { + han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); +#else + __try + { +#endif + CoTaskMemFree( ptd ); + } +#ifdef __MINGW32__ + else +#else + __except( EXCEPTION_EXECUTE_HANDLER ) +#endif + { + OSL_ENSURE( sal_False, "Error DeleteTargetDevice" ); + } +#ifdef __MINGW32__ + han.Reset(); +#endif +} + + + +//------------------------------------------------------------------------- +// OleStdCopyTargetDevice() +// +// Purpose: +// duplicate a TARGETDEVICE struct. this function allocates memory for +// the copy. the caller MUST free the allocated copy when done with it +// using the standard allocator returned from CoGetMalloc. +// (OleStdFree can be used to free the copy). +// +// Parameters: +// ptdSrc pointer to source TARGETDEVICE +// +// Return Value: +// pointer to allocated copy of ptdSrc +// if ptdSrc==NULL then retuns NULL is returned. +// if ptdSrc!=NULL and memory allocation fails, then NULL is returned +//------------------------------------------------------------------------- + +DVTARGETDEVICE* SAL_CALL CopyTargetDevice( DVTARGETDEVICE* ptdSrc ) +{ + DVTARGETDEVICE* ptdDest = NULL; + +#ifdef __MINGW32__ + jmp_buf jmpbuf; + __SEHandler han; + if (__builtin_setjmp(jmpbuf) == 0) + { + han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); +#else + __try + { +#endif + if ( NULL != ptdSrc ) + { + ptdDest = static_cast< DVTARGETDEVICE* >( CoTaskMemAlloc( ptdSrc->tdSize ) ); + rtl_copyMemory( ptdDest, ptdSrc, static_cast< size_t >( ptdSrc->tdSize ) ); + } + } +#ifdef __MINGW32__ + han.Reset(); +#else + __except( EXCEPTION_EXECUTE_HANDLER ) + { + } +#endif + + return ptdDest; +} + + +//------------------------------------------------------------------------- +// OleStdCopyFormatEtc() +// +// Purpose: +// Copies the contents of a FORMATETC structure. this function takes +// special care to copy correctly copying the pointer to the TARGETDEVICE +// contained within the source FORMATETC structure. +// if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy +// of the TARGETDEVICE will be allocated for the destination of the +// FORMATETC (petcDest). +// +// NOTE: the caller MUST free the allocated copy of the TARGETDEVICE +// within the destination FORMATETC when done with it +// using the standard allocator returned from CoGetMalloc. +// (OleStdFree can be used to free the copy). +// +// Parameters: +// petcDest pointer to destination FORMATETC +// petcSrc pointer to source FORMATETC +// +// Return Value: +// returns TRUE if copy was successful; +// retuns FALSE if not successful, e.g. one or both of the pointers +// were invalid or the pointers were equal +//------------------------------------------------------------------------- + +sal_Bool SAL_CALL CopyFormatEtc( LPFORMATETC petcDest, LPFORMATETC petcSrc ) +{ + sal_Bool bRet = sal_False; + +#ifdef __MINGW32__ + jmp_buf jmpbuf; + __SEHandler han; + if (__builtin_setjmp(jmpbuf) == 0) + { + han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); +#else + __try + { +#endif + if ( petcDest != petcSrc ) + { + + petcDest->cfFormat = petcSrc->cfFormat; + + petcDest->ptd = NULL; + if ( NULL != petcSrc->ptd ) + petcDest->ptd = CopyTargetDevice(petcSrc->ptd); + + petcDest->dwAspect = petcSrc->dwAspect; + petcDest->lindex = petcSrc->lindex; + petcDest->tymed = petcSrc->tymed; + + bRet = sal_True; + } + } +#ifdef __MINGW32__ + else +#else + __except( EXCEPTION_EXECUTE_HANDLER ) +#endif + { + OSL_ENSURE( sal_False, "Error CopyFormatEtc" ); + } +#ifdef __MINGW32__ + han.Reset(); +#endif + + return bRet; +} + +//------------------------------------------------------------------------- +// returns: +// 1 for exact match, +// 0 for no match, +// -1 for partial match (which is defined to mean the left is a subset +// of the right: fewer aspects, null target device, fewer medium). +//------------------------------------------------------------------------- + +sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLhs, const FORMATETC* pFetcRhs ) +{ + sal_Int32 nMatch = FORMATETC_EXACT_MATCH; + +#ifdef __MINGW32__ + jmp_buf jmpbuf; + __SEHandler han; + if (__builtin_setjmp(jmpbuf) == 0) + { + han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); +#else + __try + { +#endif + if ( pFetcLhs != pFetcRhs ) + + if ( ( pFetcLhs->cfFormat != pFetcRhs->cfFormat ) || + ( pFetcLhs->lindex != pFetcRhs->lindex ) || + !CompareTargetDevice( pFetcLhs->ptd, pFetcRhs->ptd ) ) + { + nMatch = FORMATETC_NO_MATCH; + } + + else if ( pFetcLhs->dwAspect == pFetcRhs->dwAspect ) + // same aspects; equal + ; + else if ( ( pFetcLhs->dwAspect & ~pFetcRhs->dwAspect ) != 0 ) + { + // left not subset of aspects of right; not equal + nMatch = FORMATETC_NO_MATCH; + } + else + // left subset of right + nMatch = FORMATETC_PARTIAL_MATCH; + + if ( nMatch == FORMATETC_EXACT_MATCH || nMatch == FORMATETC_PARTIAL_MATCH ) + { + if ( pFetcLhs->tymed == pFetcRhs->tymed ) + // same medium flags; equal + ; + else if ( ( pFetcLhs->tymed & ~pFetcRhs->tymed ) != 0 ) + { + // left not subset of medium flags of right; not equal + nMatch = FORMATETC_NO_MATCH; + } + else + // left subset of right + nMatch = FORMATETC_PARTIAL_MATCH; + } + } +#ifdef __MINGW32__ + else +#else + __except( EXCEPTION_EXECUTE_HANDLER ) +#endif + { + OSL_ENSURE( sal_False, "Error CompareFormatEtc" ); + nMatch = FORMATETC_NO_MATCH; + } +#ifdef __MINGW32__ + han.Reset(); +#endif + + return nMatch; +} + + +//------------------------------------------------------------------------- +// +//------------------------------------------------------------------------- + +sal_Bool SAL_CALL CompareTargetDevice( DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight ) +{ + sal_Bool bRet = sal_False; + +#ifdef __MINGW32__ + jmp_buf jmpbuf; + __SEHandler han; + if (__builtin_setjmp(jmpbuf) == 0) + { + han.Set(jmpbuf, NULL, (__SEHandler::PF)EXCEPTION_EXECUTE_HANDLER); +#else + __try + { +#endif + if ( ptdLeft == ptdRight ) + { + // same address of td; must be same (handles NULL case) + bRet = sal_True; + } + + // one ot the two is NULL + else if ( ( NULL != ptdRight ) && ( NULL != ptdLeft ) ) + + if ( ptdLeft->tdSize == ptdRight->tdSize ) + + if ( rtl_compareMemory( ptdLeft, ptdRight, ptdLeft->tdSize ) == 0 ) + bRet = sal_True; + } +#ifdef __MINGW32__ + else +#else + __except( EXCEPTION_EXECUTE_HANDLER ) +#endif + { + OSL_ENSURE( sal_False, "Error CompareTargetDevice" ); + bRet = sal_False; + } +#ifdef __MINGW32__ + han.Reset(); +#endif + + return bRet; +} diff --git a/dtrans/source/win32/misc/ImplHelper.hxx b/dtrans/source/win32/misc/ImplHelper.hxx new file mode 100644 index 000000000000..f410424c947f --- /dev/null +++ b/dtrans/source/win32/misc/ImplHelper.hxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _IMPLHELPER_HXX_ +#define _IMPLHELPER_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <rtl/ustring.hxx> + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +// target device and formatetc helper +void SAL_CALL DeleteTargetDevice(DVTARGETDEVICE* ptd); +sal_Bool SAL_CALL CopyFormatEtc(LPFORMATETC petcDest, LPFORMATETC petcSrc); +sal_Int32 SAL_CALL CompareFormatEtc( const FORMATETC* pFetcLeft, const FORMATETC* pFetcRight); +sal_Bool SAL_CALL CompareTargetDevice(DVTARGETDEVICE* ptdLeft, DVTARGETDEVICE* ptdRight); +DVTARGETDEVICE* SAL_CALL CopyTargetDevice(DVTARGETDEVICE* ptdSrc); + +// some codepage helper functions + +//-------------------------------------------------- +// returns a windows codepage appropriate to the +// given mime charset parameter value +//-------------------------------------------------- + +sal_uInt32 SAL_CALL getWinCPFromMimeCharset( + const rtl::OUString& charset ); + +//-------------------------------------------------- +// returns a windows codepage appropriate to the +// given locale and locale type +//-------------------------------------------------- + +rtl::OUString SAL_CALL getWinCPFromLocaleId( + LCID lcid, LCTYPE lctype ); + +//-------------------------------------------------- +// returns a mime charset parameter value appropriate +// to the given codepage, optional a prefix can be +// given, e.g. "windows-" or "cp" +//-------------------------------------------------- + +rtl::OUString SAL_CALL getMimeCharsetFromWinCP( + sal_uInt32 cp, const rtl::OUString& aPrefix ); + +//-------------------------------------------------- +// returns a mime charset parameter value appropriate +// to the given locale id and locale type, optional a +// prefix can be given, e.g. "windows-" or "cp" +//-------------------------------------------------- + +rtl::OUString SAL_CALL getMimeCharsetFromLocaleId( + LCID lcid, LCTYPE lctype, const rtl::OUString& aPrefix ); + +//----------------------------------------------------- +// returns true, if a given codepage is an oem codepage +//----------------------------------------------------- + +sal_Bool SAL_CALL IsOEMCP( sal_uInt32 codepage ); + +//-------------------------------------------------- +// converts a codepage into a string representation +//-------------------------------------------------- + +rtl::OUString SAL_CALL cptostr( sal_uInt32 codepage ); + +#endif diff --git a/dtrans/source/win32/misc/WinClip.hxx b/dtrans/source/win32/misc/WinClip.hxx new file mode 100644 index 000000000000..670fd70d97d6 --- /dev/null +++ b/dtrans/source/win32/misc/WinClip.hxx @@ -0,0 +1,45 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _WINCLIP_HXX_ +#define _WINCLIP_HXX_ + + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +const sal_Int32 CF_INVALID = 0; + +#endif diff --git a/dtrans/source/win32/misc/makefile.mk b/dtrans/source/win32/misc/makefile.mk new file mode 100644 index 000000000000..6e9ebb82ece1 --- /dev/null +++ b/dtrans/source/win32/misc/makefile.mk @@ -0,0 +1,60 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=dtrans +TARGET=dtutils +LIBTARGET=NO +USE_BOUNDCHK= +ENABLE_EXCEPTIONS=YES + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------- + +.INCLUDE : settings.mk + +#------------------------------------------- +# files to compile to obj's + +SLOFILES= $(SLO)$/ImplHelper.obj + +#------------------------------------------- +# build a static library + +LIB1TARGET= $(SLB)$/$(TARGET).lib +LIB1OBJFILES=$(SLOFILES) + + +# --- Targets ------------------------------ + +.INCLUDE : target.mk + diff --git a/dtrans/source/win32/mtaole/MtaOleClipb.cxx b/dtrans/source/win32/mtaole/MtaOleClipb.cxx new file mode 100644 index 000000000000..3d083b9e5735 --- /dev/null +++ b/dtrans/source/win32/mtaole/MtaOleClipb.cxx @@ -0,0 +1,893 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +/* + MtaOleClipb.cxx - documentation + + This class setup a single threaded apartment (sta) thread to deal with + the ole clipboard, which runs only in an sta thread. + The consequence is that callback from the ole clipboard are in the + context of this sta thread. In the soffice applications this may lead + to problems because they all use the one and only mutex called + SolarMutex. + In order to transfer clipboard requests to our sta thread we use a + hidden window an forward these requests via window messages. +*/ + +#ifdef _MSC_VER +#pragma warning( disable : 4786 ) // identifier was truncated to 'number' + // characters in the debug information +#endif + +//#define UNICODE +#include <osl/diagnose.h> + +#include "..\..\inc\MtaOleClipb.hxx" +#include <osl/conditn.hxx> + +#include <wchar.h> +#include <process.h> + +#include <systools/win32/comtools.hxx> +#ifdef __MINGW32__ +#define __uuidof(I) IID_##I +#endif + +//---------------------------------------------------------------- +// namespace directives +//---------------------------------------------------------------- + +using osl::Condition; +using osl::Mutex; +using osl::MutexGuard; +using osl::ClearableMutexGuard; + +//---------------------------------------------------------------- +// defines +//---------------------------------------------------------------- + +namespace /* private */ +{ + char CLIPSRV_DLL_NAME[] = "sysdtrans.dll"; + char g_szWndClsName[] = "MtaOleReqWnd###"; + + //-------------------------------------------------------- + // messages constants + //-------------------------------------------------------- + + const sal_uInt32 MSG_SETCLIPBOARD = WM_USER + 0x0001; + const sal_uInt32 MSG_GETCLIPBOARD = WM_USER + 0x0002; + const sal_uInt32 MSG_REGCLIPVIEWER = WM_USER + 0x0003; + const sal_uInt32 MSG_FLUSHCLIPBOARD = WM_USER + 0x0004; + const sal_uInt32 MSG_SHUTDOWN = WM_USER + 0x0005; + + const sal_uInt32 MAX_WAITTIME = 10000; // msec + const sal_uInt32 MAX_WAIT_SHUTDOWN = 10000; // msec + const sal_uInt32 MAX_CLIPEVENT_PROCESSING_TIME = 5000; // msec + + const sal_Bool MANUAL_RESET = sal_True; + const sal_Bool AUTO_RESET = sal_False; + const sal_Bool INIT_NONSIGNALED = sal_False; + + //------------------------------------------------------ + /* Cannot use osl conditions because they are blocking + without waking up on messages sent by another thread + this leads to deadlocks because we are blocking the + communication between inter-thread marshalled COM + pointers. + COM Proxy-Stub communication uses SendMessages for + synchronization purposes. + */ + class Win32Condition + { + public: + // ctor + Win32Condition() + { + m_hEvent = CreateEvent( + 0, /* no security */ + true, /* manual reset */ + false, /* initial state not signaled */ + 0); /* automatic name */ + } + + // dtor + ~Win32Condition() + { + CloseHandle(m_hEvent); + } + + // wait infinite for event be signaled + // leave messages sent through + void wait() + { + while(1) + { + DWORD dwResult = + MsgWaitForMultipleObjects(1, &m_hEvent, FALSE, INFINITE, QS_SENDMESSAGE); + + switch (dwResult) + { + case WAIT_OBJECT_0: + return; + + case WAIT_OBJECT_0 + 1: + { + /* PeekMessage processes all messages in the SendMessage + queue that's what we want, messages from the PostMessage + queue stay untouched */ + MSG msg; + PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); + + break; + } + } + } + } + + // reset the event + void set() + { + SetEvent(m_hEvent); + } + + private: + HANDLE m_hEvent; + + // prevent copy/assignment + private: + Win32Condition(const Win32Condition&); + Win32Condition& operator=(const Win32Condition&); + }; + + //------------------------------------------ + // we use one condition for every request + //------------------------------------------ + + struct MsgCtx + { + Win32Condition aCondition; + HRESULT hr; + }; + +} /* namespace private */ + +//---------------------------------------------------------------- +// static member initialization +//---------------------------------------------------------------- + +CMtaOleClipboard* CMtaOleClipboard::s_theMtaOleClipboardInst = NULL; + +//-------------------------------------------------------------------- +// marshal an IDataObject +//-------------------------------------------------------------------- + +//inline +HRESULT MarshalIDataObjectInStream( IDataObject* pIDataObject, LPSTREAM* ppStream ) +{ + OSL_ASSERT( NULL != pIDataObject ); + OSL_ASSERT( NULL != ppStream ); + + *ppStream = NULL; + return CoMarshalInterThreadInterfaceInStream( + __uuidof(IDataObject), //The IID of inteface to be marshaled + pIDataObject, //The interface pointer + ppStream //IStream pointer + ); +} + +//-------------------------------------------------------------------- +// unmarshal an IDataObject +//-------------------------------------------------------------------- + +//inline +HRESULT UnmarshalIDataObjectAndReleaseStream( LPSTREAM lpStream, IDataObject** ppIDataObject ) +{ + OSL_ASSERT( NULL != lpStream ); + OSL_ASSERT( NULL != ppIDataObject ); + + *ppIDataObject = NULL; + return CoGetInterfaceAndReleaseStream( + lpStream, + __uuidof(IDataObject), + reinterpret_cast<LPVOID*>(ppIDataObject)); +} + +//-------------------------------------------------------------------- +// helper class to ensure that the calling thread has com initialized +//-------------------------------------------------------------------- + +class CAutoComInit +{ +public: + CAutoComInit( ) + { + /* + to be safe we call CoInitialize + although it is not necessary if + the calling thread was created + using osl_CreateThread because + this function calls CoInitialize + for every thread it creates + */ + m_hResult = CoInitialize( NULL ); + + if ( S_OK == m_hResult ) + OSL_ENSURE( sal_False, \ + "com was not yet initialzed, the thread was not created using osl_createThread" ); + else if ( FAILED( m_hResult ) && !( RPC_E_CHANGED_MODE == m_hResult ) ) + OSL_ENSURE( sal_False, \ + "com could not be initialized, maybe the thread was not created using osl_createThread" ); + } + + ~CAutoComInit( ) + { + /* + we only call CoUninitialize when + CoInitailize returned S_FALSE, what + means that com was already initialize + for that thread so we keep the balance + if CoInitialize returned S_OK what means + com was not yet initialized we better + let com initialized or we may run into + the realm of undefined behaviour + */ + if ( m_hResult == S_FALSE ) + CoUninitialize( ); + } + +private: + HRESULT m_hResult; +}; + +//-------------------------------------------------------------------- +// ctor +//-------------------------------------------------------------------- + +CMtaOleClipboard::CMtaOleClipboard( ) : + m_hOleThread( NULL ), + m_uOleThreadId( 0 ), + m_hEvtThrdReady( NULL ), + m_hwndMtaOleReqWnd( NULL ), + m_MtaOleReqWndClassAtom( 0 ), + m_hwndNextClipViewer( NULL ), + m_pfncClipViewerCallback( NULL ), + m_bRunClipboardNotifierThread( sal_True ), + m_hClipboardChangedEvent( m_hClipboardChangedNotifierEvents[0] ), + m_hTerminateClipboardChangedNotifierEvent( m_hClipboardChangedNotifierEvents[1] ), + m_ClipboardChangedEventCount( 0 ) +{ + // signals that the thread was successfully setup + m_hEvtThrdReady = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL ); + + OSL_ASSERT( NULL != m_hEvtThrdReady ); + + s_theMtaOleClipboardInst = this; + + m_hOleThread = (HANDLE)_beginthreadex( + NULL, 0, CMtaOleClipboard::oleThreadProc, this, 0, &m_uOleThreadId ); + OSL_ASSERT( NULL != m_hOleThread ); + + //---------------------------------------------- + // setup the clipboard changed notifier thread + //---------------------------------------------- + + m_hClipboardChangedNotifierEvents[0] = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL ); + OSL_ASSERT( NULL != m_hClipboardChangedNotifierEvents[0] ); + + m_hClipboardChangedNotifierEvents[1] = CreateEventA( 0, MANUAL_RESET, INIT_NONSIGNALED, NULL ); + OSL_ASSERT( NULL != m_hClipboardChangedNotifierEvents[1] ); + + unsigned uThreadId; + m_hClipboardChangedNotifierThread = (HANDLE)_beginthreadex( + NULL, 0, CMtaOleClipboard::clipboardChangedNotifierThreadProc, this, 0, &uThreadId ); + + OSL_ASSERT( NULL != m_hClipboardChangedNotifierThread ); +} + +//-------------------------------------------------------------------- +// dtor +//-------------------------------------------------------------------- + +CMtaOleClipboard::~CMtaOleClipboard( ) +{ + // block calling threads out + if ( NULL != m_hEvtThrdReady ) + ResetEvent( m_hEvtThrdReady ); + + // terminate the clipboard changed notifier thread + m_bRunClipboardNotifierThread = sal_False; + SetEvent( m_hTerminateClipboardChangedNotifierEvent ); + + sal_uInt32 dwResult = WaitForSingleObject( + m_hClipboardChangedNotifierThread, MAX_WAIT_SHUTDOWN ); + + OSL_ENSURE( dwResult == WAIT_OBJECT_0, "clipboard notifier thread could not terminate" ); + + if ( NULL != m_hClipboardChangedNotifierThread ) + CloseHandle( m_hClipboardChangedNotifierThread ); + + if ( NULL != m_hClipboardChangedNotifierEvents[0] ) + CloseHandle( m_hClipboardChangedNotifierEvents[0] ); + + if ( NULL != m_hClipboardChangedNotifierEvents[1] ) + CloseHandle( m_hClipboardChangedNotifierEvents[1] ); + + // end the thread + // because DestroyWindow can only be called + // from within the thread that created the window + sendMessage( MSG_SHUTDOWN, + static_cast< WPARAM >( 0 ), + static_cast< LPARAM >( 0 ) ); + + // wait for thread shutdown + dwResult = WaitForSingleObject( m_hOleThread, MAX_WAIT_SHUTDOWN ); + OSL_ENSURE( dwResult == WAIT_OBJECT_0, "OleThread could not terminate" ); + + if ( NULL != m_hOleThread ) + CloseHandle( m_hOleThread ); + + if ( NULL != m_hEvtThrdReady ) + CloseHandle( m_hEvtThrdReady ); + + if ( m_MtaOleReqWndClassAtom ) + UnregisterClassA( g_szWndClsName, NULL ); + + OSL_ENSURE( ( NULL == m_pfncClipViewerCallback ) && + !IsWindow( m_hwndNextClipViewer ), \ + "Clipboard viewer not properly unregistered" ); +} + + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +HRESULT CMtaOleClipboard::flushClipboard( ) +{ + if ( !WaitForThreadReady( ) ) + { + OSL_ENSURE( sal_False, "clipboard sta thread not ready" ); + return E_FAIL; + } + + OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, \ + "flushClipboard from within clipboard sta thread called" ); + + MsgCtx aMsgCtx; + + postMessage( MSG_FLUSHCLIPBOARD, + static_cast< WPARAM >( 0 ), + reinterpret_cast< LPARAM >( &aMsgCtx ) ); + + aMsgCtx.aCondition.wait( /* infinite */ ); + + return aMsgCtx.hr; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +HRESULT CMtaOleClipboard::getClipboard( IDataObject** ppIDataObject ) +{ + OSL_PRECOND( NULL != ppIDataObject, "invalid parameter" ); + OSL_PRECOND( GetCurrentThreadId( ) != m_uOleThreadId, "getClipboard from within clipboard sta thread called" ); + + if ( !WaitForThreadReady( ) ) + { + OSL_ENSURE( sal_False, "clipboard sta thread not ready" ); + return E_FAIL; + } + + CAutoComInit comAutoInit; + + LPSTREAM lpStream; + HRESULT hr = E_FAIL; + + *ppIDataObject = NULL; + + MsgCtx aMsgCtx; + + postMessage( MSG_GETCLIPBOARD, + reinterpret_cast< WPARAM >( &lpStream ), + reinterpret_cast< LPARAM >( &aMsgCtx ) ); + + aMsgCtx.aCondition.wait( /* infinite */ ); + + hr = aMsgCtx.hr; + + if ( SUCCEEDED( hr ) ) + { + hr = UnmarshalIDataObjectAndReleaseStream( lpStream, ppIDataObject ); + OSL_ENSURE( SUCCEEDED( hr ), "unmarshalling clipboard data object failed" ); + } + + return hr; +} + +//-------------------------------------------------------------------- +// this is an asynchronous method that's why we don't wait until the +// request is completed +//-------------------------------------------------------------------- + +HRESULT CMtaOleClipboard::setClipboard( IDataObject* pIDataObject ) +{ + if ( !WaitForThreadReady( ) ) + { + OSL_ENSURE( sal_False, "clipboard sta thread not ready" ); + return E_FAIL; + } + + CAutoComInit comAutoInit; + + OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, "setClipboard from within the clipboard sta thread called" ); + + // because we marshall this request + // into the sta thread we better + // acquire the interface here so + // that the object will not be + // destroyed before the ole clipboard + // can acquire it + // remember: pIDataObject may be NULL + // which is an request to clear the + // current clipboard content + if ( pIDataObject ) + pIDataObject->AddRef( ); + + postMessage( + MSG_SETCLIPBOARD, + reinterpret_cast< WPARAM >( pIDataObject ), + 0 ); + + // because this is an asynchronous function + // the return value is useless + return S_OK; +} + +//-------------------------------------------------------------------- +// register a clipboard viewer +//-------------------------------------------------------------------- + +sal_Bool CMtaOleClipboard::registerClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback ) +{ + if ( !WaitForThreadReady( ) ) + { + OSL_ENSURE( sal_False, "clipboard sta thread not ready" ); + return sal_False; + } + + sal_Bool bRet = sal_False; + + OSL_ENSURE( GetCurrentThreadId( ) != m_uOleThreadId, "registerClipViewer from within the OleThread called" ); + + MsgCtx aMsgCtx; + + postMessage( MSG_REGCLIPVIEWER, + reinterpret_cast<WPARAM>( pfncClipViewerCallback ), + reinterpret_cast<LPARAM>( &aMsgCtx ) ); + + aMsgCtx.aCondition.wait( /* infinite */ ); + + return bRet; +} + +//-------------------------------------------------------------------- +// register a clipboard viewer +//-------------------------------------------------------------------- + +sal_Bool CMtaOleClipboard::onRegisterClipViewer( LPFNC_CLIPVIEWER_CALLBACK_t pfncClipViewerCallback ) +{ + sal_Bool bRet = sal_True; + + // we need exclusive access because the clipboard changed notifier + // thread also accesses this variable + MutexGuard aGuard( m_pfncClipViewerCallbackMutex ); + + // register if not yet done + if ( ( NULL != pfncClipViewerCallback ) && ( NULL == m_pfncClipViewerCallback ) ) + { + // SetClipboardViewer sends a WM_DRAWCLIPBOARD message we ignore + // this message if we register ourself as clip viewer + m_bInRegisterClipViewer = sal_True; + m_hwndNextClipViewer = SetClipboardViewer( m_hwndMtaOleReqWnd ); + m_bInRegisterClipViewer = sal_False; + + // if there is no other cb-viewer the + // return value is NULL!!! + bRet = IsWindow( m_hwndNextClipViewer ) ? sal_True : sal_False; + + // save the new callback function + m_pfncClipViewerCallback = pfncClipViewerCallback; + } + else if ( ( NULL == pfncClipViewerCallback ) && ( NULL != m_pfncClipViewerCallback ) ) + { + m_pfncClipViewerCallback = NULL; + + // unregister if input parameter is NULL and we previously registered + // as clipboard viewer + ChangeClipboardChain( m_hwndMtaOleReqWnd, m_hwndNextClipViewer ); + m_hwndNextClipViewer = NULL; + } + + return bRet; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +LRESULT CMtaOleClipboard::onSetClipboard( IDataObject* pIDataObject ) +{ + return static_cast<LRESULT>( OleSetClipboard( pIDataObject ) ); +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +LRESULT CMtaOleClipboard::onGetClipboard( LPSTREAM* ppStream ) +{ + OSL_ASSERT(NULL != ppStream); + + IDataObjectPtr pIDataObject; + + // forward the request to the OleClipboard + HRESULT hr = OleGetClipboard( &pIDataObject ); + if ( SUCCEEDED( hr ) ) + { + hr = MarshalIDataObjectInStream(pIDataObject.get(), ppStream); + OSL_ENSURE(SUCCEEDED(hr), "marshalling cliboard data object failed"); + } + return static_cast<LRESULT>(hr); +} + +//-------------------------------------------------------------------- +// flush the ole-clipboard +//-------------------------------------------------------------------- + +LRESULT CMtaOleClipboard::onFlushClipboard( ) +{ + return static_cast<LRESULT>( OleFlushClipboard( ) ); +} + +//-------------------------------------------------------------------- +// handle clipboard chain change event +//-------------------------------------------------------------------- + +LRESULT CMtaOleClipboard::onChangeCBChain( HWND hWndRemove, HWND hWndNext ) +{ + if ( hWndRemove == m_hwndNextClipViewer ) + m_hwndNextClipViewer = hWndNext; + else if ( IsWindow( m_hwndNextClipViewer ) ) + { + // forward the message to the next one + DWORD dwResult; + SendMessageTimeoutA( + m_hwndNextClipViewer, + WM_CHANGECBCHAIN, + reinterpret_cast<WPARAM>(hWndRemove), + reinterpret_cast<LPARAM>(hWndNext), + SMTO_BLOCK, + MAX_CLIPEVENT_PROCESSING_TIME, + &dwResult ); + } + + return 0; +} + +//-------------------------------------------------------------------- +// handle draw clipboard event +//-------------------------------------------------------------------- + +LRESULT CMtaOleClipboard::onDrawClipboard( ) +{ + // we don't send a notification if we are + // registering ourself as clipboard + if ( !m_bInRegisterClipViewer ) + { + ClearableMutexGuard aGuard( m_ClipboardChangedEventCountMutex ); + + m_ClipboardChangedEventCount++; + SetEvent( m_hClipboardChangedEvent ); + + aGuard.clear( ); + } + + // foward the message to the next viewer in the chain + if ( IsWindow( m_hwndNextClipViewer ) ) + { + DWORD dwResult; + SendMessageTimeoutA( + m_hwndNextClipViewer, + WM_DRAWCLIPBOARD, + static_cast< WPARAM >( 0 ), + static_cast< LPARAM >( 0 ), + SMTO_BLOCK, + MAX_CLIPEVENT_PROCESSING_TIME, + &dwResult ); + } + + return 0; +} + +//-------------------------------------------------------------------- +// SendMessage so we don't need to supply the HWND if we send +// something to our wrapped window +//-------------------------------------------------------------------- + +LRESULT CMtaOleClipboard::sendMessage( UINT msg, WPARAM wParam, LPARAM lParam ) +{ + return ::SendMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam ); +} + +//-------------------------------------------------------------------- +// PostMessage so we don't need to supply the HWND if we send +// something to our wrapped window +//-------------------------------------------------------------------- + +sal_Bool CMtaOleClipboard::postMessage( UINT msg, WPARAM wParam, LPARAM lParam ) +{ + return PostMessageA( m_hwndMtaOleReqWnd, msg, wParam, lParam ) ? sal_True : sal_False; +} + + +//-------------------------------------------------------------------- +// the window proc +//-------------------------------------------------------------------- + +LRESULT CALLBACK CMtaOleClipboard::mtaOleReqWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + LRESULT lResult = 0; + + // get a connection to the class-instance via the static member + CMtaOleClipboard* pImpl = CMtaOleClipboard::s_theMtaOleClipboardInst; + OSL_ASSERT( NULL != pImpl ); + + switch( uMsg ) + { + case MSG_SETCLIPBOARD: + { + IDataObject* pIDataObject = reinterpret_cast< IDataObject* >( wParam ); + pImpl->onSetClipboard( pIDataObject ); + + // in setClipboard we did acquire the + // interface pointer in order to prevent + // destruction of the object before the + // ole clipboard can acquire the interface + // now we release the interface so that + // our lostOwnership mechanism works + // remember: pIDataObject may be NULL + if ( pIDataObject ) + pIDataObject->Release( ); + } + break; + + case MSG_GETCLIPBOARD: + { + MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam ); + OSL_ASSERT( aMsgCtx ); + + aMsgCtx->hr = pImpl->onGetClipboard( reinterpret_cast< LPSTREAM* >(wParam) ); + aMsgCtx->aCondition.set( ); + } + break; + + case MSG_FLUSHCLIPBOARD: + { + MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam ); + OSL_ASSERT( aMsgCtx ); + + aMsgCtx->hr = pImpl->onFlushClipboard( ); + aMsgCtx->aCondition.set( ); + } + break; + + case MSG_REGCLIPVIEWER: + { + MsgCtx* aMsgCtx = reinterpret_cast< MsgCtx* >( lParam ); + OSL_ASSERT( aMsgCtx ); + + pImpl->onRegisterClipViewer( reinterpret_cast<CMtaOleClipboard::LPFNC_CLIPVIEWER_CALLBACK_t>(wParam) ); + aMsgCtx->aCondition.set( ); + } + break; + + case WM_CHANGECBCHAIN: + lResult = pImpl->onChangeCBChain( + reinterpret_cast< HWND >( wParam ), reinterpret_cast< HWND >( lParam ) ); + break; + + case WM_DRAWCLIPBOARD: + lResult = pImpl->onDrawClipboard( ); + break; + + case MSG_SHUTDOWN: + DestroyWindow( pImpl->m_hwndMtaOleReqWnd ); + break; + + // force the sta thread to end + case WM_DESTROY: + PostQuitMessage( 0 ); + break; + + default: + lResult = DefWindowProcA( hWnd, uMsg, wParam, lParam ); + break; + } + + return lResult; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void CMtaOleClipboard::createMtaOleReqWnd( ) +{ + WNDCLASSEXA wcex; + + HINSTANCE hInst = GetModuleHandleA( CLIPSRV_DLL_NAME ); + OSL_ENSURE( NULL != hInst, "The name of the clipboard service dll must have changed" ); + + ZeroMemory( &wcex, sizeof( WNDCLASSEXA ) ); + + wcex.cbSize = sizeof(WNDCLASSEXA); + wcex.style = 0; + wcex.lpfnWndProc = static_cast< WNDPROC >( CMtaOleClipboard::mtaOleReqWndProc ); + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInst; + wcex.hIcon = NULL; + wcex.hCursor = NULL; + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = g_szWndClsName; + wcex.hIconSm = NULL; + + m_MtaOleReqWndClassAtom = RegisterClassExA( &wcex ); + + if ( 0 != m_MtaOleReqWndClassAtom ) + m_hwndMtaOleReqWnd = CreateWindowA( + g_szWndClsName, NULL, 0, 0, 0, 0, 0, NULL, NULL, hInst, NULL ); +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +unsigned int CMtaOleClipboard::run( ) +{ + #if OSL_DEBUG_LEVEL > 0 + HRESULT hr = + #endif + OleInitialize( NULL ); + OSL_ASSERT( SUCCEEDED( hr ) ); + + createMtaOleReqWnd( ); + + unsigned int nRet; + + if ( IsWindow( m_hwndMtaOleReqWnd ) ) + { + if ( NULL != m_hEvtThrdReady ) + SetEvent( m_hEvtThrdReady ); + + // pumping messages + MSG msg; + while( GetMessageA( &msg, NULL, 0, 0 ) ) + DispatchMessageA( &msg ); + + nRet = 0; + } + else + nRet = ~0U; + + OleUninitialize( ); + + return nRet; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +unsigned int WINAPI CMtaOleClipboard::oleThreadProc( LPVOID pParam ) +{ + CMtaOleClipboard* pInst = + reinterpret_cast<CMtaOleClipboard*>( pParam ); + OSL_ASSERT( NULL != pInst ); + + return pInst->run( ); +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +unsigned int WINAPI CMtaOleClipboard::clipboardChangedNotifierThreadProc( LPVOID pParam ) +{ + CMtaOleClipboard* pInst = reinterpret_cast< CMtaOleClipboard* >( pParam ); + OSL_ASSERT( NULL != pInst ); + + CoInitialize( NULL ); + + // assuming we don't need a lock for + // a boolean variable like m_bRun... + while ( pInst->m_bRunClipboardNotifierThread ) + { + // wait for clipboard changed or terminate event + WaitForMultipleObjects( 2, pInst->m_hClipboardChangedNotifierEvents, false, INFINITE ); + + ClearableMutexGuard aGuard( pInst->m_ClipboardChangedEventCountMutex ); + + if ( pInst->m_ClipboardChangedEventCount > 0 ) + { + pInst->m_ClipboardChangedEventCount--; + if ( 0 == pInst->m_ClipboardChangedEventCount ) + ResetEvent( pInst->m_hClipboardChangedEvent ); + + aGuard.clear( ); + + // nobody should touch m_pfncClipViewerCallback while we do + MutexGuard aClipViewerGuard( pInst->m_pfncClipViewerCallbackMutex ); + + // notify all clipboard listener + if ( pInst->m_pfncClipViewerCallback ) + pInst->m_pfncClipViewerCallback( ); + } + else + aGuard.clear( ); + } + + CoUninitialize( ); + + return ( 0 ); +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +inline +sal_Bool CMtaOleClipboard::WaitForThreadReady( ) const +{ + sal_Bool bRet = sal_False; + + if ( NULL != m_hEvtThrdReady ) + { + DWORD dwResult = WaitForSingleObject( + m_hEvtThrdReady, MAX_WAITTIME ); + bRet = ( dwResult == WAIT_OBJECT_0 ); + } + + return bRet; +} + diff --git a/dtrans/source/win32/mtaole/makefile.mk b/dtrans/source/win32/mtaole/makefile.mk new file mode 100644 index 000000000000..3316f1a190fe --- /dev/null +++ b/dtrans/source/win32/mtaole/makefile.mk @@ -0,0 +1,54 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=dtrans +TARGET=mtaolecb +LIBTARGET=NO +ENABLE_EXCEPTIONS=YES + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk + +# --- Targets ---------------------------------- + +.IF "$(GUI)"=="WNT" + +# --- static lib -------------------------- + +# don't do this in the source file. breaks pch +CDEFS+=-DUNICODE + +SLOFILES=$(SLO)$/MtaOleClipb.obj + +LIB1TARGET=$(SLB)$/$(TARGET).lib +LIB1OBJFILES=$(SLOFILES) + +.ENDIF + +.INCLUDE : target.mk diff --git a/dtrans/source/win32/workbench/XTDo.cxx b/dtrans/source/win32/workbench/XTDo.cxx new file mode 100644 index 000000000000..c3209429cf21 --- /dev/null +++ b/dtrans/source/win32/workbench/XTDo.cxx @@ -0,0 +1,431 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> + +#include "..\DTransHelper.hxx" + +#ifndef _TWRAPPERDATAOBJECT_HXX_ +#include "XTDo.hxx" +#endif + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <ole2.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <memory> +#include <tchar.h> + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace ::std; + +//============================================================================ +// OTWrapperDataObject +//============================================================================ + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ +/* + in the constructor we enumerate all formats offered by the transferable + and convert the formats into formatetc structures + if the transferable supports text in different charsets we use either + the charset equal to the charset of the current thread or an arbitrary + charset supported by the transferable and the system + if the transferable supports only unicodetext we offer in addition to + this text in the charset of the current thread + in order to allow the consumer of the clipboard to query for the charset + of the text in the clipboard we offer a CF_LOCALE +*/ +CXTDataObject::CXTDataObject( ) : + m_nRefCnt( 0 ) +{ + +} + +//------------------------------------------------------------------------ +// IUnknown->QueryInterface +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject ) +{ + OSL_ASSERT( NULL != ppvObject ); + + if ( NULL == ppvObject ) + return E_INVALIDARG; + + HRESULT hr = E_NOINTERFACE; + + *ppvObject = NULL; + + if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) ) + { + *ppvObject = static_cast< IUnknown* >( this ); + ( (LPUNKNOWN)*ppvObject )->AddRef( ); + hr = S_OK; + } + + return hr; +} + +//------------------------------------------------------------------------ +// IUnknown->AddRef +//------------------------------------------------------------------------ + +STDMETHODIMP_(ULONG) CXTDataObject::AddRef( ) +{ + return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) ); +} + +//------------------------------------------------------------------------ +// IUnknown->Release +//------------------------------------------------------------------------ + +STDMETHODIMP_(ULONG) CXTDataObject::Release( ) +{ + // we need a helper variable because it's + // not allowed to access a member variable + // after an object is destroyed + ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) ); + + if ( 0 == nRefCnt ) + { + delete this; + } + + return nRefCnt; +} + +/*------------------------------------------------------------------------ + + IDataObject->GetData + we deliver data only into global memory + + algo: + 1. convert the given formatect struct into a valid dataflavor + 2. if the transferable directly supports the requested format + 2.1. if text data requested add a trailing '\0' in order to prevent + problems (windows needs '\0' terminated strings + 2.2. we expect unicode data as Sequence< sal_Unicode > and all other + text and raw data as Sequence< sal_Int8 > + +------------------------------------------------------------------------*/ + +STDMETHODIMP CXTDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ) +{ + if ( ( NULL == pFormatetc ) || ( NULL == pmedium ) ) + return E_INVALIDARG; + + HRESULT hr = E_FAIL; + char pBuff[] = "Test OleClipboard"; + + if ( CF_TEXT == pFormatetc->cfFormat ) + { + CHGlobalHelper hGlobHlp( TRUE ); + + hGlobHlp.Write( pBuff, sizeof( pBuff ), NULL ); + + pmedium->tymed = TYMED_HGLOBAL; + pmedium->hGlobal = hGlobHlp.GetHGlobal( ); + pmedium->pUnkForRelease = NULL; + + hr = S_OK; + } + + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->EnumFormatEtc +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ) +{ + if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) ) + return E_INVALIDARG; + + *ppenumFormatetc = NULL; + + HRESULT hr = E_FAIL; + + if ( DATADIR_GET == dwDirection ) + { + *ppenumFormatetc = new CEnumFormatEtc( this ); + static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( ); + hr = S_OK; + } + + return hr; +} + +//------------------------------------------------------------------------ +// IDataObject->QueryGetData +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->GetDataHere +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->GetCanonicalFormatEtc +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->SetData +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->DAdvise +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->DUnadvise +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::DUnadvise( DWORD ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// IDataObject->EnumDAdvise +//------------------------------------------------------------------------ + +STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * ) +{ + return E_NOTIMPL; +} + +//------------------------------------------------------------------------ +// for our convenience +//------------------------------------------------------------------------ + +CXTDataObject::operator IDataObject*( ) +{ + return static_cast< IDataObject* >( this ); +} + + +//============================================================================ +// CEnumFormatEtc +//============================================================================ + +//---------------------------------------------------------------------------- +// ctor +//---------------------------------------------------------------------------- + +CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) : + m_nRefCnt( 0 ), + m_pUnkDataObj( pUnkDataObj ), + m_nCurrPos( 0 ) +{ +} + +//---------------------------------------------------------------------------- +// IUnknown->QueryInterface +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject ) +{ + if ( NULL == ppvObject ) + return E_INVALIDARG; + + HRESULT hr = E_NOINTERFACE; + + *ppvObject = NULL; + + if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) ) + { + *ppvObject = static_cast< IUnknown* >( this ); + static_cast< LPUNKNOWN >( *ppvObject )->AddRef( ); + hr = S_OK; + } + + return hr; +} + +//---------------------------------------------------------------------------- +// IUnknown->AddRef +//---------------------------------------------------------------------------- + +STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( ) +{ + // keep the dataobject alive + m_pUnkDataObj->AddRef( ); + return InterlockedIncrement( &m_nRefCnt ); +} + +//---------------------------------------------------------------------------- +// IUnknown->Release +//---------------------------------------------------------------------------- + +STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( ) +{ + // release the outer dataobject + m_pUnkDataObj->Release( ); + + // we need a helper variable because it's + // not allowed to access a member variable + // after an object is destroyed + ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt ); + if ( 0 == nRefCnt ) + delete this; + + return nRefCnt; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Next +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched ) +{ + if ( ( 0 != celt ) && ( NULL == rgelt ) ) + return E_INVALIDARG; + + ULONG ulFetched = 0; + ULONG ulToFetch = celt; + HRESULT hr = S_FALSE; + + while( m_nCurrPos < 1 ) + { + rgelt->cfFormat = CF_TEXT; + rgelt->ptd = NULL; + rgelt->dwAspect = DVASPECT_CONTENT; + rgelt->lindex = -1; + rgelt->tymed = TYMED_HGLOBAL; + + ++m_nCurrPos; + ++rgelt; + --ulToFetch; + ++ulFetched; + } + + if ( ulFetched == celt ) + hr = S_OK; + + if ( NULL != pceltFetched ) + { + *pceltFetched = ulFetched; + } + + return hr; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Skip +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt ) +{ + HRESULT hr = S_FALSE; + + /* + if ( ( m_nCurrPos + celt ) < m_nClipFormats ) + { + m_nCurrPos += celt; + hr = S_OK; + } + */ + + return hr; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Reset +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Reset( ) +{ + m_nCurrPos = 0; + return S_OK; +} + +//---------------------------------------------------------------------------- +// IEnumFORMATETC->Clone +//---------------------------------------------------------------------------- + +STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum ) +{ + OSL_ASSERT( NULL != ppenum ); + + if ( NULL == ppenum ) + return E_INVALIDARG; + + HRESULT hr = E_FAIL; + + *ppenum = NULL; + + CEnumFormatEtc* pCEnumFEtc = new CEnumFormatEtc( m_pUnkDataObj ); + if ( NULL != pCEnumFEtc ) + { + pCEnumFEtc->m_nCurrPos = m_nCurrPos; + *ppenum = static_cast< IEnumFORMATETC* >( pCEnumFEtc ); + static_cast< LPUNKNOWN >( *ppenum )->AddRef( ); + hr = NOERROR; + } + + return hr; +} diff --git a/dtrans/source/win32/workbench/XTDo.hxx b/dtrans/source/win32/workbench/XTDo.hxx new file mode 100644 index 000000000000..e34a931380f8 --- /dev/null +++ b/dtrans/source/win32/workbench/XTDo.hxx @@ -0,0 +1,134 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _XTDATAOBJECT_HXX_ +#define _XTDATAOBJECT_HXX_ + + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <ole2.h> +#include <objidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <vector> + +// forward declaration +//class CWinClipbImpl; +class EnumFormatEtc; + +/*-------------------------------------------------------------------------- + - the function principle of the windows clipboard: + a data provider offers all formats he can deliver on the clipboard + a clipboard client ask for the available formats on the clipboard + and decides if there is a format he can use + if there is one, he requests the data in this format + + - This class inherits from IDataObject an so can be placed on the + OleClipboard. The class wrapps a transferable object which is the + original DataSource + - DataFlavors offerd by this transferable will be translated into + appropriate clipboard formats + - if the transferable contains text data always text and unicodetext + will be offered or vice versa + - text data will be automaticaly converted between text und unicode text + - although the transferable may support text in different charsets + (codepages) only text in one codepage can be offered by the clipboard + +----------------------------------------------------------------------------*/ + +class CXTDataObject : public IDataObject +{ +public: + CXTDataObject( ); + + //----------------------------------------------------------------- + // ole interface implementation + //----------------------------------------------------------------- + + //IUnknown interface methods + STDMETHODIMP QueryInterface(REFIID iid, LPVOID* ppvObject); + STDMETHODIMP_( ULONG ) AddRef( ); + STDMETHODIMP_( ULONG ) Release( ); + + // IDataObject interface methods + STDMETHODIMP GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium ); + STDMETHODIMP QueryGetData( LPFORMATETC pFormatetc ); + STDMETHODIMP GetCanonicalFormatEtc( LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut ); + STDMETHODIMP SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease ); + STDMETHODIMP EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc ); + STDMETHODIMP DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD* pdwConnection ); + STDMETHODIMP DUnadvise( DWORD dwConnection ); + STDMETHODIMP EnumDAdvise( LPENUMSTATDATA* ppenumAdvise ); + + operator IDataObject*( ); + +private: + +private: + LONG m_nRefCnt; +}; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +class CEnumFormatEtc : public IEnumFORMATETC +{ +public: + CEnumFormatEtc( LPUNKNOWN pUnkDataObj ); + + // IUnknown + STDMETHODIMP QueryInterface( REFIID iid, LPVOID* ppvObject ); + STDMETHODIMP_( ULONG ) AddRef( ); + STDMETHODIMP_( ULONG ) Release( ); + + //IEnumFORMATETC + STDMETHODIMP Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched ); + STDMETHODIMP Skip( ULONG celt ); + STDMETHODIMP Reset( ); + STDMETHODIMP Clone( IEnumFORMATETC** ppenum ); + +private: + LONG m_nRefCnt; + LPUNKNOWN m_pUnkDataObj; + ULONG m_nCurrPos; +}; + +typedef CEnumFormatEtc *PCEnumFormatEtc; + +#endif diff --git a/dtrans/source/win32/workbench/makefile.mk b/dtrans/source/win32/workbench/makefile.mk new file mode 100644 index 000000000000..be85525016c9 --- /dev/null +++ b/dtrans/source/win32/workbench/makefile.mk @@ -0,0 +1,96 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME= dtrans +TARGET= testwincb +TARGET1= testmshl +LIBTARGET= NO +TARGETTYPE= CUI +USE_BOUNDCHK= +TESTCB=TRUE + +.IF "$(USE_BOUNDCHK)"=="TR" +bndchk=tr +stoponerror=tr +.ENDIF + +# --- Settings ----------------------------------------------------- +#.INCLUDE : $(PRJ)$/util$/makefile.pmk + +.INCLUDE : settings.mk + +.IF "$(TESTCB)"=="TRUE" + +CFLAGS+=-D_WIN32_DCOM -EHsc -Ob0 + +# --- Files -------------------------------------------------------- + +OBJFILES= $(OBJ)$/test_wincb.obj +APP1TARGET= $(TARGET) +APP1OBJS= $(OBJ)$/test_wincb.obj + + +APP1STDLIBS= $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SOLARLIBDIR)$/uwinapi.lib\ + $(USER32LIB) \ + $(OLE32LIB)\ + $(COMDLG32LIB) + +APP1LIBS= $(SLB)$/dtutils.lib + + +APP1NOSAL= TRUE + +.ENDIF + +.IF "$(TESTCB)"=="" + +CFLAGS+=/D_WIN32_DCOM /EHsc /Ob0 + +OBJFILES= $(OBJ)$/testmarshal.obj +APP1TARGET= $(TARGET1) +APP1OBJS= $(OBJ)$/testmarshal.obj + +APP1STDLIBS= $(SALLIB)\ + $(USER32LIB)\ + $(OLE32LIB)\ + comsupp.lib\ + $(OLEAUT32LIB) + +APP1LIBS= + +APP1NOSAL= TRUE + +.ENDIF + +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk +#.INCLUDE : $(PRJ)$/util$/target.pmk diff --git a/dtrans/source/win32/workbench/test_wincb.cxx b/dtrans/source/win32/workbench/test_wincb.cxx new file mode 100644 index 000000000000..b3f1a2ef95ee --- /dev/null +++ b/dtrans/source/win32/workbench/test_wincb.cxx @@ -0,0 +1,348 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +//_________________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________________ + + +#include "..\misc\ImplHelper.hxx" + +//_________________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________________ +#include <cppuhelper/servicefactory.hxx> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase2.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <osl/diagnose.h> + +#include <stdio.h> +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <objbase.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <memory> + +#include <process.h> + +//------------------------------------------------------------- +// my defines +//------------------------------------------------------------- + +#define TEST_CLIPBOARD +#define RDB_SYSPATH "d:\\projects\\src623\\dtrans\\wntmsci7\\bin\\applicat.rdb" +#define WINCLIPBOARD_SERVICE_NAME L"com.sun.star.datatransfer.clipboard.SystemClipboard" +#define WRITE_CB +#define EVT_MANUAL_RESET TRUE +#define EVT_INIT_NONSIGNALED FALSE +#define EVT_NONAME "" + +//------------------------------------------------------------ +// namesapces +//------------------------------------------------------------ + +using namespace ::rtl; +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::clipboard; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; + +//------------------------------------------------------------ +// globales +//------------------------------------------------------------ + +Reference< XTransferable > rXTransfRead; +HANDLE g_hEvtThreadWakeup; + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +class CClipboardListener : public WeakImplHelper1 < XClipboardListener > +{ +public: + ~CClipboardListener( ); + + //------------------------------------------------- + // XClipboardListener + //------------------------------------------------- + + virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); + virtual void SAL_CALL changedContents( const ClipboardEvent& event ) throw( RuntimeException ); +}; + +CClipboardListener::~CClipboardListener( ) +{ +} + +void SAL_CALL CClipboardListener::disposing( const EventObject& Source ) throw(RuntimeException) +{ + +} + +void SAL_CALL CClipboardListener::changedContents( const ClipboardEvent& event ) throw( RuntimeException ) +{ + //MessageBox( NULL, TEXT("Clipboard content changed"), TEXT("Info"), MB_OK | MB_ICONINFORMATION ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +class CTransferable : public WeakImplHelper2< XClipboardOwner, XTransferable > +{ +public: + CTransferable( ); + + //------------------------------------------------- + // XTransferable + //------------------------------------------------- + + virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor ) + throw(UnsupportedFlavorException, IOException, RuntimeException); + + virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(RuntimeException); + + virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor ) throw(RuntimeException); + + //------------------------------------------------- + // XClipboardOwner + //------------------------------------------------- + + virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) + throw(RuntimeException); + +private: + Sequence< DataFlavor > m_FlavorList; + OUString m_Data; +}; + +//---------------------------------------------------------------- +// ctor +//---------------------------------------------------------------- + +CTransferable::CTransferable( ) : + m_FlavorList( 1 ), + m_Data( OUString::createFromAscii( "Ich habe mir ein neues Fahrrad gekauft!" ) ) +{ + DataFlavor df; + + //df.MimeType = L"text/plain;charset=utf-16"; + //df.DataType = getCppuType( ( OUString* )0 ); + + df.MimeType = L"text/plain;charset=Windows1252"; + df.DataType = getCppuType( (Sequence< sal_Int8 >*)0 ); + + m_FlavorList[0] = df; +} + +//---------------------------------------------------------------- +// getTransferData +//---------------------------------------------------------------- + +Any SAL_CALL CTransferable::getTransferData( const DataFlavor& aFlavor ) + throw(UnsupportedFlavorException, IOException, RuntimeException) +{ + Any anyData; + + /* + if ( aFlavor.MimeType == m_FlavorList[0].MimeType ) + anyData = makeAny( m_Data ); + */ + if ( aFlavor.MimeType.equalsIgnoreCase( m_FlavorList[0].MimeType ) ) + { + OString text( + m_Data.getStr( ), + m_Data.getLength( ), + RTL_TEXTENCODING_ASCII_US ); + + Sequence< sal_Int8 > textStream( text.getLength( ) + 1 ); + + rtl_copyMemory( textStream.getArray( ), text.getStr( ), textStream.getLength( ) ); + + anyData = makeAny( textStream ); + } + else + throw UnsupportedFlavorException( ); + + return anyData; +} + +//---------------------------------------------------------------- +// getTransferDataFlavors +//---------------------------------------------------------------- + +Sequence< DataFlavor > SAL_CALL CTransferable::getTransferDataFlavors( ) + throw(RuntimeException) +{ + return m_FlavorList; +} + +//---------------------------------------------------------------- +// isDataFlavorSupported +//---------------------------------------------------------------- + +sal_Bool SAL_CALL CTransferable::isDataFlavorSupported( const DataFlavor& aFlavor ) + throw(RuntimeException) +{ + sal_Int32 nLength = m_FlavorList.getLength( ); + + for ( sal_Int32 i = 0; i < nLength; ++i ) + if ( m_FlavorList[i].MimeType == aFlavor.MimeType ) + return sal_True; + + return sal_False; +} + +//---------------------------------------------------------------- +// lostOwnership +//---------------------------------------------------------------- + +void SAL_CALL CTransferable::lostOwnership( + const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) + throw(RuntimeException) +{ + //MessageBox( NULL, TEXT("No longer clipboard owner"), TEXT("Info"), MB_OK | MB_ICONINFORMATION ); +} + +//---------------------------------------------------------------- +// main +//---------------------------------------------------------------- + +int SAL_CALL main( int nArgc, char* Argv[] ) +{ + // create a multi-threaded apartment; we can test only + // with a multithreaded apartment because for a single + // threaded apartment we need a message loop to deliver + // messages to our XTDataObject + //HRESULT hr = CoInitializeEx( NULL, COINIT_MULTITHREADED ); + HRESULT hr = CoInitialize( NULL ); + + char buff[6]; + + LCID lcid = MAKELCID( MAKELANGID( LANG_GERMAN, SUBLANG_GERMAN ), SORT_DEFAULT ); + + BOOL bValid = IsValidLocale( lcid, LCID_SUPPORTED ); + GetLocaleInfoA( lcid, LOCALE_IDEFAULTANSICODEPAGE, buff, sizeof( buff ) ); + + //------------------------------------------------- + // get the global service-manager + //------------------------------------------------- + + OUString rdbName = OUString( RTL_CONSTASCII_USTRINGPARAM( RDB_SYSPATH ) ); + Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( rdbName ) ); + + // Print a message if an error occured. + if ( !g_xFactory.is( ) ) + { + OSL_ENSURE(sal_False, "Can't create RegistryServiceFactory"); + return(-1); + } + + //------------------------------------------------- + // try to get an Interface to a XFilePicker Service + //------------------------------------------------- + + Reference< XTransferable > rXTransf( static_cast< XTransferable* >( new CTransferable ) ); + + Reference< XClipboard > + xClipboard( g_xFactory->createInstance( OUString( WINCLIPBOARD_SERVICE_NAME ) ), UNO_QUERY ); + if ( !xClipboard.is( ) ) + { + OSL_ENSURE( sal_False, "Error creating Clipboard Service" ); + return(-1); + } + + Reference< XClipboardNotifier > xClipNotifier( xClipboard, UNO_QUERY ); + Reference< XClipboardListener > rXClipListener( static_cast< XClipboardListener* >( new CClipboardListener() ) ); + xClipNotifier->addClipboardListener( rXClipListener ); + + MessageBox( NULL, TEXT("Go"), TEXT("INFO"), MB_OK|MB_ICONINFORMATION); + + // set new clipboard content + xClipboard->setContents( rXTransf, Reference< XClipboardOwner >( rXTransf, UNO_QUERY ) ); + + /* + MessageBox( NULL, TEXT("Clear content"), TEXT("INFO"), MB_OK|MB_ICONINFORMATION); + + Reference< XClipboardOwner > rXClipOwner; + Reference< XTransferable > rXEmptyTransf; + xClipboard->setContents( rXEmptyTransf, rXClipOwner ); + */ + + MessageBox( NULL, TEXT("Stop"), TEXT("INFO"), MB_OK|MB_ICONINFORMATION); + + // flush the clipboard content + Reference< XFlushableClipboard > rXFlushableClip( xClipboard, UNO_QUERY ); + rXFlushableClip->flushClipboard( ); + rXFlushableClip = Reference< XFlushableClipboard >( ); + + xClipNotifier->removeClipboardListener( rXClipListener ); + rXClipListener = Reference< XClipboardListener >( ); + xClipNotifier = Reference< XClipboardNotifier >( ); + + //-------------------------------------------------- + // shutdown the service manager + //-------------------------------------------------- + + // Cast factory to XComponent + Reference< XComponent > xComponent( g_xFactory, UNO_QUERY ); + + if ( !xComponent.is() ) + OSL_ENSURE(sal_False, "Error shuting down"); + + // Dispose and clear factory + xComponent->dispose(); + xComponent = Reference< XComponent >( ); + + g_xFactory.clear(); + g_xFactory = Reference< XMultiServiceFactory >(); + + CoUninitialize( ); + + return 0; +} diff --git a/dtrans/source/win32/workbench/testmarshal.cxx b/dtrans/source/win32/workbench/testmarshal.cxx new file mode 100644 index 000000000000..3927a1dcf449 --- /dev/null +++ b/dtrans/source/win32/workbench/testmarshal.cxx @@ -0,0 +1,243 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +//_________________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________________ +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <osl/diagnose.h> + +#include <stdio.h> +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <objbase.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <memory> + +#include <process.h> +#include "XTDo.hxx" + +//------------------------------------------------------------- +// my defines +//------------------------------------------------------------- + +#define WRITE_CB +#define EVT_MANUAL_RESET TRUE +#define EVT_INIT_NONSIGNALED FALSE +#define EVT_NONAME "" +#define WAIT_MSGLOOP +#define RAW_MARSHALING + +//------------------------------------------------------------ +// namesapces +//------------------------------------------------------------ + +using namespace ::rtl; +using namespace ::std; + +//------------------------------------------------------------ +// globales +//------------------------------------------------------------ + +HANDLE g_hEvtThreadWakeup; + +#ifdef RAW_MARSHALING + HGLOBAL g_hGlob; +#else + IStream* g_pStm; +#endif + +//################################################################ +// a thread in another apartment to test apartment transparency + +unsigned int _stdcall ThreadProc(LPVOID pParam) +{ + // setup another apartment + HRESULT hr = OleInitialize( NULL ); + + WaitForSingleObject( g_hEvtThreadWakeup, INFINITE ); + + IDataObject* pIDo; + +#ifdef RAW_MARSHALING + + IStream* pStm = NULL; + hr = CreateStreamOnHGlobal( g_hGlob, FALSE, &pStm ); + if ( SUCCEEDED( hr ) ) + { + hr = CoUnmarshalInterface( + pStm, + __uuidof( IDataObject ), + (void**)&pIDo ); + + hr = pStm->Release( ); + } + +#else + + hr = CoGetInterfaceAndReleaseStream( + g_pStm, + __uuidof( IDataObject ), + (void**)&pIDo + ); + +#endif + + IEnumFORMATETC* pIEEtc; + hr = pIDo->EnumFormatEtc( DATADIR_GET, &pIEEtc ); + + hr = OleIsCurrentClipboard( pIDo ); + + hr = OleFlushClipboard( ); + + OleUninitialize( ); + + return 0; +} + +//################################################################ + +//---------------------------------------------------------------- +// main +//---------------------------------------------------------------- + +int SAL_CALL main( int nArgc, char* Argv[] ) +{ + HRESULT hr = OleInitialize( NULL ); + + g_hEvtThreadWakeup = CreateEvent( 0, + EVT_MANUAL_RESET, + EVT_INIT_NONSIGNALED, + EVT_NONAME ); + + unsigned uThreadId; + HANDLE hThread; + + // create a thread in another apartment + hThread = (void*)_beginthreadex( NULL, 0, ThreadProc, NULL, 0, &uThreadId ); + + IDataObject* pIDo = new CXTDataObject( ); + + hr = OleSetClipboard( pIDo ); + hr = E_FAIL; + + hr = OleIsCurrentClipboard( pIDo ); + + //hr = OleGetClipboard( &pIDo ); + if ( SUCCEEDED( hr ) ) + { +#ifdef RAW_MARSHALING + + IStream* pStm = NULL; + + hr = CreateStreamOnHGlobal( 0, FALSE, &pStm ); + if ( SUCCEEDED( hr ) ) + { + hr = CoMarshalInterface( + pStm, + __uuidof( IDataObject ), + pIDo, + MSHCTX_INPROC, + 0, + MSHLFLAGS_NORMAL ); + if ( SUCCEEDED( hr ) ) + hr = GetHGlobalFromStream( pStm, &g_hGlob ); + + hr = pStm->Release( ); + } + +#else + + hr = CoMarshalInterThreadInterfaceInStream( + __uuidof( IDataObject ), + pIDo, + &g_pStm ); + +#endif + + if ( SUCCEEDED( hr ) ) + { + // wakeup the thread and waiting util it ends + SetEvent( g_hEvtThreadWakeup ); + +#ifdef WAIT_MSGLOOP + + BOOL bContinue = TRUE; + + while( bContinue ) + { + DWORD dwResult = WaitForMultipleObjects( + 1, + &hThread, + TRUE, + 0 ); + + if ( WAIT_OBJECT_0 == dwResult ) + { + bContinue = FALSE; + } + else + { + MSG msg; + while( PeekMessage( + &msg, + NULL, + 0, + 0, + PM_REMOVE ) ) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } // while + +#endif + + } // if + } // if + + OleFlushClipboard( ); + + OleUninitialize( ); + + return 0; +} diff --git a/dtrans/test/win32/dnd/atlwindow.cxx b/dtrans/test/win32/dnd/atlwindow.cxx new file mode 100644 index 000000000000..2ed1b1b956bb --- /dev/null +++ b/dtrans/test/win32/dnd/atlwindow.cxx @@ -0,0 +1,262 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> + +#include <cppuhelper/servicefactory.hxx> +#include <rtl/string.h> + +#include "atlwindow.hxx" +#include "targetlistener.hxx" +#include "sourcelistener.hxx" +//#include "transferable.hxx" +#include <map> + +#include <winbase.h> +using namespace com::sun::star::lang; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +using namespace cppu; +using namespace rtl; +using namespace std; + +LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam) ; + + +extern Reference< XMultiServiceFactory > MultiServiceFactory; +DWORD WINAPI MTAFunc(LPVOID pParams); + +char* szSTAWin= "XDragSource::executeDrag is called from the same " + "OLE STA thread that created the window."; +char* szMTAWin= "XDragSource::executeDrag is called from a MTA thread " + "that did not create the window."; + +WNDPROC wpOrigEditProc; + +map<HWND, HWND> mapEditToMainWnd; + +LRESULT AWindow::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + Reference<XComponent> xcompSource( m_xDragSource, UNO_QUERY); + + PostQuitMessage(0); + + + m_xDropTarget=0; + m_xDragSource=0; + + + // Remove the subclass from the edit control. + ::SetWindowLong(m_hwndEdit, GWL_WNDPROC, + (LONG) wpOrigEditProc); + + return 0; +} + + +LRESULT AWindow::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + // Prepare the EDIT control + m_hwndEdit = CreateWindowA( + "EDIT", // predefined class + NULL, // no window title + WS_CHILD | WS_VISIBLE | WS_VSCROLL | + ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, + 0, 0, 0, 0, // set size in WM_SIZE message + m_hWnd, // parent window + (HMENU) NULL, // edit control ID + (HINSTANCE) GetWindowLong( GWL_HINSTANCE), + NULL); + + // the map is used in the window procedure for the edit window to associate the + // it to the right main window ( AWindow) + mapEditToMainWnd[m_hwndEdit]= m_hWnd; + // Superclass the edit window, because we want to process mouse messages + wpOrigEditProc = (WNDPROC) ::SetWindowLongA(m_hwndEdit, + GWL_WNDPROC, (LONG) EditSubclassProc); + + + // Add text to the window. + if( m_isMTA) + ::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szMTAWin); + else + ::SendMessageA(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) szSTAWin); + + + // create the DragSource + Reference< XInterface> xint= MultiServiceFactory->createInstance(OUString(L"com.sun.star.datatransfer.dnd.OleDragSource")); + m_xDragSource= Reference<XDragSource>( xint, UNO_QUERY); + Reference<XInitialization> xInit( xint, UNO_QUERY); + + Any ar[2]; + ar[1]<<= (sal_uInt32)m_hWnd; + xInit->initialize( Sequence<Any>( ar, 2) ); + + //create the DropTarget + Reference< XInterface> xintTarget= MultiServiceFactory->createInstance(OUString(L"com.sun.star.datatransfer.dnd.OleDropTarget")); + m_xDropTarget= Reference<XDropTarget>( xintTarget, UNO_QUERY); + Reference<XInitialization> xInitTarget( xintTarget, UNO_QUERY); + + Any any; + any <<= (sal_uInt32)m_hWnd; + xInitTarget->initialize( Sequence<Any>( &any, 1) ); + + + m_xDropTarget->addDropTargetListener( static_cast<XDropTargetListener*> + ( new DropTargetListener( m_hwndEdit)) ); +// // make this window tho a drop target + m_xDropTarget->setActive(sal_True); + + return 0; +} + +// When the mouse is dragged for a second than a drag is initiated +LRESULT AWindow::OnMouseAction(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + if( uMsg== WM_LBUTTONDOWN) + { + SetTimer( 1, 1000); + } + + else if( uMsg == WM_LBUTTONUP) + { + KillTimer( 1); + } + + return 0; +} + +LRESULT AWindow::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + HRESULT hr; + USES_CONVERSION; + KillTimer( 1); + if(m_xDragSource.is()) + { + + //Get the Text out of the Edit window + int length= (int)::SendMessageA( m_hwndEdit, WM_GETTEXTLENGTH, 0, 0); + char * pBuffer= new char[length + 1]; + ZeroMemory( pBuffer, length + 1); + ::SendMessageA( m_hwndEdit, WM_GETTEXT, length, (LPARAM) pBuffer); + + IDataObject* pData= NULL; + HRESULT hr= CreateDataCache( NULL, CLSID_NULL, __uuidof(IDataObject),(void**) &pData); + if( pData) + { + FORMATETC format={ CF_TEXT, NULL, DVASPECT_CONTENT, -1, }; + + HGLOBAL mem= GlobalAlloc(GHND, length + 1 ); + void* pMem= GlobalLock( mem); + memcpy( pMem, pBuffer, length+1); + GlobalUnlock( mem); + + STGMEDIUM medium; + medium.tymed= TYMED_HGLOBAL; + medium.hGlobal= mem; + medium.pUnkForRelease= NULL; + + pData->SetData( &format, &medium, TRUE); // releases HGLOBAL eventually + + Reference<XTransferable> xTrans= m_aDataConverter.createTransferableFromDataObj( + MultiServiceFactory, pData); + + // call XDragSource::executeDrag from an MTA + if( m_isMTA ) + { + DWORD mtaThreadId; + ThreadData data; + data.source= m_xDragSource; + data.transferable= xTrans; + + data.evtThreadReady= CreateEvent( NULL, FALSE, FALSE, NULL); + + HANDLE hThread= CreateThread( NULL, 0, MTAFunc, &data, 0, &mtaThreadId); + // We must wait until the thread copied the ThreadData structure + WaitForSingleObject( data.evtThreadReady, INFINITE); + CloseHandle( data.evtThreadReady); + + + } + else + { + m_xDragSource->startDrag( DragGestureEvent(), + ACTION_LINK|ACTION_MOVE|ACTION_COPY, + 0, + 0, + xTrans, + Reference<XDragSourceListener>( static_cast<XDragSourceListener*>(new DragSourceListener() ) ) ); + } + } + + delete[] pBuffer; + } + + return 0; +} + +LRESULT AWindow::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + // Make the edit control the size of the window's + // client area. + ::MoveWindow(m_hwndEdit, + 0, 0, // starting x- and y-coordinates + LOWORD(lParam), // width of client area + HIWORD(lParam), // height of client area + TRUE); // repaint window + + return 0; +} +LRESULT AWindow::OnFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + ::SetFocus(m_hwndEdit); + return 0; +} + + + +// Subclass procedure for EDIT window +LRESULT APIENTRY EditSubclassProc( HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam) +{ + + if( uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST) + { + HWND hAWindow= mapEditToMainWnd[hwnd]; + ::SendMessage( hAWindow, uMsg, wParam, lParam); + + } + return CallWindowProc( wpOrigEditProc, hwnd, uMsg, + wParam, lParam); +} + diff --git a/dtrans/test/win32/dnd/atlwindow.hxx b/dtrans/test/win32/dnd/atlwindow.hxx new file mode 100644 index 000000000000..7befe05bbb4e --- /dev/null +++ b/dtrans/test/win32/dnd/atlwindow.hxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _WINDOW_HXX_ +#define _WINDOW_HXX_ +#include <atlbase.h> +extern CComModule _Module; +#include<atlcom.h> +#include<atlctl.h> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#include <com/sun/star/datatransfer/dnd/XDragSource.hpp> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/uno/Reference.h> +#include "../../source/inc/DtObjFactory.hxx" + + +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer; + +struct ThreadData +{ + Reference<XDragSource> source; + Reference<XTransferable> transferable; + HANDLE evtThreadReady; +}; + +class AWindow: public CWindowImpl<AWindow, CWindow, + CWinTraits<WS_CAPTION |WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0> > +{ + TCHAR m_strName[80]; + Reference<XDropTarget> m_xDropTarget; + Reference<XDragSource> m_xDragSource; + BOOL m_isMTA; + + HWND m_hwndEdit; + + CDTransObjFactory m_aDataConverter; + +public: + AWindow(LPCTSTR strName) + { + RECT rcPos= {0,0,200,200}; + Create(0, rcPos, strName); + } + AWindow(LPCTSTR strName, RECT pos, BOOL mta=FALSE): m_isMTA( mta) + { + Create(0, pos, strName); + } + + ~AWindow() + { + if(m_hWnd) + DestroyWindow(); + } + + + BEGIN_MSG_MAP(AWindow) + MESSAGE_HANDLER( WM_CLOSE, OnClose) + MESSAGE_HANDLER( WM_CREATE, OnCreate) + MESSAGE_RANGE_HANDLER( WM_MOUSEFIRST, WM_MOUSELAST, OnMouseAction) + MESSAGE_HANDLER( WM_TIMER, OnTimer) + MESSAGE_HANDLER( WM_SIZE, OnSize) + MESSAGE_HANDLER( WM_SETFOCUS, OnFocus) + + END_MSG_MAP() + + LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnMouseAction(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + +}; + +#endif diff --git a/dtrans/test/win32/dnd/dndTest.cxx b/dtrans/test/win32/dnd/dndTest.cxx new file mode 100644 index 000000000000..e1a96598da62 --- /dev/null +++ b/dtrans/test/win32/dnd/dndTest.cxx @@ -0,0 +1,210 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <comdef.h> +#include <tchar.h> +#include <atlbase.h> +CComModule _Module; +#include<atlcom.h> +#include<atlimpl.cpp> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <com/sun/star/uno/Reference.h> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp> +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> + +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <rtl/process.h> +#include <cppuhelper/servicefactory.hxx> +//#include "transferable.hxx" +#include "sourcelistener.hxx" + + +#include "atlwindow.hxx" +BEGIN_OBJECT_MAP(ObjectMap) +END_OBJECT_MAP() + +using namespace com::sun::star::lang; +using namespace com::sun::star::datatransfer; +using namespace com::sun::star::uno; +using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +using namespace rtl; + +// defined in atlwindow.hxx +// #define WM_SOURCE_INIT WM_APP+100 +// #define WM_SOURCE_STARTDRAG WM_APP+101 +#define WM_CREATE_MTA_WND + +HRESULT doTest(); +DWORD WINAPI MTAFunc( void* threadData); + +Reference< XMultiServiceFactory > MultiServiceFactory; +//int APIENTRY WinMain(HINSTANCE hInstance, +// HINSTANCE hPrevInstance, +// LPSTR lpCmdLine, +// int nCmdShow) +//int _tmain( int argc, TCHAR *argv[ ], TCHAR *envp[ ] ) +int main( int argc, char *argv[ ], char *envp[ ] ) +{ + HRESULT hr; + if( FAILED( hr=CoInitialize(NULL ))) + { + _tprintf(_T("CoInitialize failed \n")); + return -1; + } + + + _Module.Init( ObjectMap, GetModuleHandle( NULL)); + + if( FAILED(hr=doTest())) + { + _com_error err( hr); + const TCHAR * errMsg= err.ErrorMessage(); +// MessageBox( NULL, errMsg, "Test failed", MB_ICONERROR); + } + + + _Module.Term(); + CoUninitialize(); + return 0; +} + +HRESULT doTest() +{ + + MultiServiceFactory= createRegistryServiceFactory( OUString(L"types.rdb"), OUString( L"services.rdb") , sal_True); + + // create the MTA thread that is used to realize MTA calls to the services + // We create the thread and wait until the thread has created its message queue + HANDLE evt= CreateEvent(NULL, FALSE, FALSE, NULL); + DWORD threadIdMTA=0; + HANDLE hMTAThread= CreateThread( NULL, 0, MTAFunc, &evt, 0, &threadIdMTA); + WaitForSingleObject( evt, INFINITE); + CloseHandle(evt); + + + HRESULT hr= S_OK; + RECT pos1={0,0,300,200}; + AWindow win(_T("DnD starting in Ole STA"), threadIdMTA, pos1); + + RECT pos2={ 0, 205, 300, 405}; + AWindow win2( _T("DnD starting in MTA"), threadIdMTA, pos2, true); + + // win3 and win4 call initialize from an MTA but they are created in an STA + RECT pos3={300,0,600,200}; + AWindow win3(_T("DnD starting in OLE STA"), threadIdMTA, pos3, false, true); + + RECT pos4={ 300, 205, 600, 405}; + AWindow win24( _T("DnD starting in Ole MTA"), threadIdMTA, pos4, true, true); + + + MSG msg; + while( GetMessage(&msg, (HWND)NULL, 0, 0) ) + { + TranslateMessage( &msg); + DispatchMessage( &msg); + } + + // Shut down the MTA thread + PostThreadMessage( threadIdMTA, WM_QUIT, 0, 0); + WaitForSingleObject(hMTAThread, INFINITE); + CloseHandle(hMTAThread); + + return S_OK; +} + +extern Reference<XMultiServiceFactory> MultiServiceFactory; +DWORD WINAPI MTAFunc( void* threadData) +{ + HRESULT hr= S_OK; + hr= CoInitializeEx( NULL, COINIT_MULTITHREADED); + ATLASSERT( FAILED(hr) ); + MSG msg; + // force the creation of a message queue + PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); + SetEvent( *(HANDLE*)threadData ); + + RECT pos={0, 406, 300, 605}; + AWindow win(_T("DnD, full MTA"), GetCurrentThreadId(), pos, false, true); +// ThreadData data= *( ThreadData*)pParams; +// SetEvent(data.evtThreadReady); + while( GetMessage(&msg, (HWND)NULL, 0, 0) ) + { + switch( msg.message) + { + case WM_SOURCE_INIT: + { + InitializationData* pData= (InitializationData*)msg.wParam; + Any any; + any <<= (sal_uInt32) pData->hWnd; + pData->xInit->initialize( Sequence<Any>( &any, 1)); + + CoTaskMemFree( pData); + break; + } + case WM_SOURCE_STARTDRAG: + { + // wParam contains necessary data + StartDragData* pData= (StartDragData*)msg.wParam; + Sequence<DataFlavor> seq= pData->transferable->getTransferDataFlavors(); + // have a look what flavours are supported + for( int i=0; i<seq.getLength(); i++) + { + DataFlavor d= seq[i]; + } + pData->source->startDrag( DragGestureEvent(), + ACTION_LINK|ACTION_MOVE|ACTION_COPY, + 0, + 0, + pData->transferable, + Reference<XDragSourceListener>( static_cast<XDragSourceListener*> + ( new DragSourceListener()))); + CoTaskMemFree( pData); + break; + } + + } // end switch + + TranslateMessage( &msg); + DispatchMessage( &msg); + } + + + CoUninitialize(); + return 0; +} diff --git a/dtrans/test/win32/dnd/makefile.mk b/dtrans/test/win32/dnd/makefile.mk new file mode 100644 index 000000000000..3744e6135806 --- /dev/null +++ b/dtrans/test/win32/dnd/makefile.mk @@ -0,0 +1,83 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/ + +PRJNAME=dtrans +TARGET=dndTest +TARGETTYPE=CUI +LIBTARGET=NO + +#USE_DEFFILE= TRUE +ENABLE_EXCEPTIONS=TRUE + +# --- Settings --- + +.INCLUDE : settings.mk + +# --- Files --- + +# CFLAGS+=-GR -DUNICODE -D_UNICODE +CFLAGS+= -D_WIN32_DCOM + +INCPRE+= -I$(ATL_INCLUDE) + +OBJFILES= $(OBJ)$/dndTest.obj \ + $(OBJ)$/atlwindow.obj \ + $(OBJ)$/targetlistener.obj \ + $(OBJ)$/sourcelistener.obj \ + $(OBJ)$/dataobject.obj + +APP1NOSAL=TRUE + +APP1TARGET= $(TARGET) +APP1OBJS=$(OBJFILES) + +APP1STDLIBS= \ + $(SALLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(UWINAPILIB) \ + $(USER32LIB) \ + $(OLE32LIB) \ + comsupp.lib \ + $(OLEAUT32LIB) \ + $(GDI32LIB) \ + $(UUIDLIB) + +APP1LIBS= \ + $(SLB)$/dtobjfact.lib \ + $(SLB)$/dtutils.lib + +# $(SOLARLIBDIR)$/imtaolecb.lib\ + +APP1DEF= $(MISC)\$(APP1TARGET).def + +# --- Targets --- + +.INCLUDE : target.mk + diff --git a/dtrans/test/win32/dnd/sourcelistener.cxx b/dtrans/test/win32/dnd/sourcelistener.cxx new file mode 100644 index 000000000000..377157b5512e --- /dev/null +++ b/dtrans/test/win32/dnd/sourcelistener.cxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + + +#include "sourcelistener.hxx" + + + +DragSourceListener::DragSourceListener() +{ +} +DragSourceListener::~DragSourceListener() +{ +} + +void SAL_CALL DragSourceListener::disposing( const EventObject& Source ) + throw(RuntimeException) +{ +} + +void SAL_CALL DragSourceListener::dragDropEnd( const DragSourceDropEvent& dsde ) + throw(RuntimeException) +{ +} + +void SAL_CALL DragSourceListener::dragEnter( const DragSourceDragEvent& dsde ) + throw(RuntimeException) +{ +} + +void SAL_CALL DragSourceListener::dragExit( const DragSourceEvent& dse ) + throw(RuntimeException) +{ +} + +void SAL_CALL DragSourceListener::dragOver( const DragSourceDragEvent& dsde ) + throw(RuntimeException) +{ +} + +void SAL_CALL DragSourceListener::dropActionChanged( const DragSourceDragEvent& dsde ) + throw(RuntimeException) +{ +} + diff --git a/dtrans/test/win32/dnd/sourcelistener.hxx b/dtrans/test/win32/dnd/sourcelistener.hxx new file mode 100644 index 000000000000..0480102d7e00 --- /dev/null +++ b/dtrans/test/win32/dnd/sourcelistener.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SOURCELISTENER_HXX_ +#define _SOURCELISTENER_HXX_ + +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDragSourceListener.hpp> +#include <com/sun/star/datatransfer/dnd/DragSourceDropEvent.hpp> +#include <com/sun/star/datatransfer/dnd/DragSourceDragEvent.hpp> + +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +class DragSourceListener: public WeakImplHelper1<XDragSourceListener> +{ + // this is a window where droped data are shown as text (only text) +public: + DragSourceListener( ); + ~DragSourceListener(); + + virtual void SAL_CALL disposing( const EventObject& Source ) + throw(RuntimeException); + + virtual void SAL_CALL dragDropEnd( const DragSourceDropEvent& dsde ) + throw(RuntimeException); + virtual void SAL_CALL dragEnter( const DragSourceDragEvent& dsde ) + throw(RuntimeException); + virtual void SAL_CALL dragExit( const DragSourceEvent& dse ) + throw(RuntimeException); + virtual void SAL_CALL dragOver( const DragSourceDragEvent& dsde ) + throw(RuntimeException); + virtual void SAL_CALL dropActionChanged( const DragSourceDragEvent& dsde ) + throw(RuntimeException); + +}; + +#endif diff --git a/dtrans/test/win32/dnd/targetlistener.cxx b/dtrans/test/win32/dnd/targetlistener.cxx new file mode 100644 index 000000000000..cb4a5ac72664 --- /dev/null +++ b/dtrans/test/win32/dnd/targetlistener.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" + + +#include "targetlistener.hxx" +#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp> +#include <com/sun/star/datatransfer/DataFlavor.hpp> + +//using namespace com::sun::star::datatransfer::dnd; +using namespace com::sun::star::datatransfer::dnd::DNDConstants; +using namespace com::sun::star::datatransfer; +using namespace rtl; + +DropTargetListener::DropTargetListener(HWND hEdit):m_hEdit( hEdit) +{ +} +DropTargetListener::~DropTargetListener() +{ +} + +void SAL_CALL DropTargetListener::disposing( const EventObject& Source ) + throw(RuntimeException) +{ + +} + + + +void SAL_CALL DropTargetListener::drop( const DropTargetDropEvent& e ) + throw(RuntimeException) +{ +// e.Context->dropComplete( sal_True); +// e.Context->acceptDrop( ACTION_COPY); + e.Context->rejectDrop(); + + // if the Transferable contains text, then we send it to the edit window +// Sequence<DataFlavor> flavors= e.Transferable->getTransferDataFlavors(); +// DataFlavor aFlavor; +// for( int i=0; i < flavors.getLength(); i++) +// aFlavor= flavors[4]; + + DataFlavor flavor( OUString(OUString::createFromAscii("text/plain;charset=windows-1252")), + OUString(L"Text plain"), getCppuType( ( Sequence<sal_Int8>*)0 ) ); + + Any anyData= e.Transferable->getTransferData( flavor); + Sequence<sal_Int8> seq= *( Sequence<sal_Int8>*)anyData.getValue(); + SendMessage( m_hEdit, WM_SETTEXT, 0, (LPARAM) seq.getConstArray() ); +} + +void SAL_CALL DropTargetListener::dragEnter( const DropTargetDragEnterEvent& dtde ) + throw(RuntimeException) +{ + //If one drags something that is not moveable + if( !(dtde.SourceActions & dtde.DropAction) ) + dtde.Context->acceptDrag( ACTION_COPY); + +// dtde.Context->rejectDrag( ); + +} + +void SAL_CALL DropTargetListener::dragExit( const DropTargetEvent& dte ) + throw(RuntimeException) +{ +} + +void SAL_CALL DropTargetListener::dragOver( const DropTargetDragEvent& dtde ) + throw(RuntimeException) +{ + if( !(dtde.SourceActions & dtde.DropAction) ) + dtde.Context->acceptDrag( ACTION_COPY); +} + +void SAL_CALL DropTargetListener::dropActionChanged( const DropTargetDragEvent& dtde ) + throw(RuntimeException) +{ +} diff --git a/dtrans/test/win32/dnd/targetlistener.hxx b/dtrans/test/win32/dnd/targetlistener.hxx new file mode 100644 index 000000000000..9c3402e961da --- /dev/null +++ b/dtrans/test/win32/dnd/targetlistener.hxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TARGETLISTENER_HXX_ +#define _TARGETLISTENER_HXX_ + +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDropEvent.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDragEvent.hpp> +#include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp> + +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::dnd; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +class DropTargetListener: public WeakImplHelper1<XDropTargetListener> +{ + // this is a window where droped data are shown as text (only text) + HWND m_hEdit; +public: + DropTargetListener( HWND hEdit); + ~DropTargetListener(); + + virtual void SAL_CALL disposing( const EventObject& Source ) + throw(RuntimeException); + + + virtual void SAL_CALL drop( const DropTargetDropEvent& dtde ) + throw(RuntimeException); + virtual void SAL_CALL dragEnter( const DropTargetDragEnterEvent& dtde ) + throw(RuntimeException); + virtual void SAL_CALL dragExit( const DropTargetEvent& dte ) + throw(RuntimeException); + virtual void SAL_CALL dragOver( const DropTargetDragEvent& dtde ) + throw(RuntimeException); + virtual void SAL_CALL dropActionChanged( const DropTargetDragEvent& dtde ) + throw(RuntimeException); +}; + +#endif diff --git a/dtrans/test/win32/dnd/transferable.cxx b/dtrans/test/win32/dnd/transferable.cxx new file mode 100644 index 000000000000..4c76ec2fee73 --- /dev/null +++ b/dtrans/test/win32/dnd/transferable.cxx @@ -0,0 +1,126 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dtrans.hxx" +#include "transferable.hxx" + +//---------------------------------------------------------------- +// ctor +//---------------------------------------------------------------- + + + +CTransferable::CTransferable( wchar_t* dataString ) : + m_seqDFlv( 1 ), + m_Data( dataString ) +{ + DataFlavor df; + + /* + df.MimeType = L"text/plain; charset=unicode"; + df.DataType = getCppuType( ( OUString* )0 ); + + m_seqDFlv[0] = df; + */ + + //df.MimeType = L"text/plain; charset=windows1252"; + df.MimeType = L"text/plain"; + df.DataType = getCppuType( ( Sequence< sal_Int8 >* )0 ); + + + m_seqDFlv[0] = df; +} + +//---------------------------------------------------------------- +// getTransferData +//---------------------------------------------------------------- + +Any SAL_CALL CTransferable::getTransferData( const DataFlavor& aFlavor ) + throw(UnsupportedFlavorException, IOException, RuntimeException) +{ + Any anyData; + + /*if ( aFlavor == m_seqDFlv[0] ) + { + anyData = makeAny( m_Data ); + } + else*/ if ( aFlavor == m_seqDFlv[0] ) + { + OString aStr( m_Data.getStr( ), m_Data.getLength( ), 1252 ); + Sequence< sal_Int8 > sOfChars( aStr.getLength( ) ); + sal_Int32 lenStr = aStr.getLength( ); + + for ( sal_Int32 i = 0; i < lenStr; ++i ) + sOfChars[i] = aStr[i]; + + anyData = makeAny( sOfChars ); + } + + return anyData; +} + +//---------------------------------------------------------------- +// getTransferDataFlavors +//---------------------------------------------------------------- + +Sequence< DataFlavor > SAL_CALL CTransferable::getTransferDataFlavors( ) + throw(RuntimeException) +{ + return m_seqDFlv; +} + +//---------------------------------------------------------------- +// isDataFlavorSupported +//---------------------------------------------------------------- + +sal_Bool SAL_CALL CTransferable::isDataFlavorSupported( const DataFlavor& aFlavor ) + throw(RuntimeException) +{ + sal_Int32 nLength = m_seqDFlv.getLength( ); + sal_Bool bRet = sal_False; + + for ( sal_Int32 i = 0; i < nLength; ++i ) + { + if ( m_seqDFlv[i] == aFlavor ) + { + bRet = sal_True; + break; + } + } + + return bRet; +} + +//---------------------------------------------------------------- +// lostOwnership +//---------------------------------------------------------------- + +void SAL_CALL CTransferable::lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) + throw(RuntimeException) +{ +} diff --git a/dtrans/test/win32/dnd/transferable.hxx b/dtrans/test/win32/dnd/transferable.hxx new file mode 100644 index 000000000000..a9509f497ab1 --- /dev/null +++ b/dtrans/test/win32/dnd/transferable.hxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _TRANSFERABLE_HXX_ +#define _TRANSFERABLE_HXX_ + +//_________________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________________ + + +//#include "..\ImplHelper.hxx" + +//_________________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________________ + +#include <cppuhelper/servicefactory.hxx> +#include <com/sun/star/datatransfer/XTransferable.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardOwner.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp> +#include <com/sun/star/datatransfer/clipboard/XClipboardEx.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <cppuhelper/implbase2.hxx> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <osl/diagnose.h> + +#include <stdio.h> +#if defined _MSC_VER +#pragma warning(push,1) +#endif +#include <windows.h> +#include <objbase.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <memory> + +#include <process.h> + +#include "..\..\source\win32\ImplHelper.hxx" + + +//------------------------------------------------------------- +// my defines +//------------------------------------------------------------- + +#define TEST_CLIPBOARD +#define RDB_SYSPATH "d:\\projects\\src616\\dtrans\\wntmsci7\\bin\\applicat.rdb" +#define WINCLIPBOARD_SERVICE_NAME L"com.sun.star.datatransfer.clipboard.SystemClipboard" +#define WRITE_CB +#define EVT_MANUAL_RESET TRUE +#define EVT_INIT_NONSIGNALED FALSE +#define EVT_NONAME "" + +//------------------------------------------------------------ +// namesapces +//------------------------------------------------------------ + +using namespace ::rtl; +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::datatransfer::clipboard; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +class CTransferable : public WeakImplHelper2< XClipboardOwner, XTransferable > +{ +public: + CTransferable( ){}; + CTransferable( wchar_t* dataString); + + //------------------------------------------------- + // XTransferable + //------------------------------------------------- + + virtual Any SAL_CALL getTransferData( const DataFlavor& aFlavor ) throw(UnsupportedFlavorException, IOException, RuntimeException); + virtual Sequence< DataFlavor > SAL_CALL getTransferDataFlavors( ) throw(RuntimeException); + virtual sal_Bool SAL_CALL isDataFlavorSupported( const DataFlavor& aFlavor ) throw(RuntimeException); + + //------------------------------------------------- + // XClipboardOwner + //------------------------------------------------- + + virtual void SAL_CALL lostOwnership( const Reference< XClipboard >& xClipboard, const Reference< XTransferable >& xTrans ) throw(RuntimeException); + +private: + Sequence< DataFlavor > m_seqDFlv; + OUString m_Data; +}; + + +#endif diff --git a/dtrans/util/dnd.component b/dtrans/util/dnd.component new file mode 100644 index 000000000000..b56fe326f04f --- /dev/null +++ b/dtrans/util/dnd.component @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.datatransfer.dnd.OleDragSource_V1"> + <service name="com.sun.star.datatransfer.dnd.OleDragSource"/> + </implementation> + <implementation name="com.sun.star.comp.datatransfer.dnd.OleDropTarget_V1"> + <service name="com.sun.star.datatransfer.dnd.OleDropTarget"/> + </implementation> +</component> diff --git a/dtrans/util/exports.dxp b/dtrans/util/exports.dxp new file mode 100644 index 000000000000..f0e1c69934bc --- /dev/null +++ b/dtrans/util/exports.dxp @@ -0,0 +1,2 @@ +component_getImplementationEnvironment +component_getFactory diff --git a/dtrans/util/ftransl.component b/dtrans/util/ftransl.component new file mode 100644 index 000000000000..dad7d341cce7 --- /dev/null +++ b/dtrans/util/ftransl.component @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.datatransfer.DataFormatTranslator"> + <service name="com.sun.star.datatransfer.DataFormatTranslator"/> + </implementation> +</component> diff --git a/dtrans/util/makefile.mk b/dtrans/util/makefile.mk new file mode 100644 index 000000000000..8df69bbf1d36 --- /dev/null +++ b/dtrans/util/makefile.mk @@ -0,0 +1,211 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=.. + +PRJNAME=dtrans +TARGET=dtrans +TARGET1=mcnttype +TARGET2=ftransl +TARGET3=sysdtrans +TARGET4=dnd + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.IF "$(L10N_framework)"=="" + +# --- mcnttype dynlib ---------------------------------------------- + +SHL1TARGET=$(TARGET1) + +SHL1LIBS=$(SLB)$/mcnttype.lib + +SHL1STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) + +.IF "$(GUI)"=="WNT" +SHL1STDLIBS+= \ + $(UWINAPILIB) +.ENDIF + + + +SHL1IMPLIB=i$(SHL1TARGET) + +#--- comment ----------------- + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp +SHL1VERSIONMAP=$(SOLARENV)/src/component.map + + +.IF "$(GUI)"=="WNT" + +# --- ftransl dll --- + +SHL2TARGET=$(TARGET2) + +SHL2LIBS=$(SLB)$/ftransl.lib\ + $(SLB)$/dtutils.lib + +SHL2STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB)\ + $(UWINAPILIB)\ + $(ADVAPI32LIB)\ + $(OLE32LIB)\ + $(GDI32LIB) + +SHL2IMPLIB=i$(SHL2TARGET) + +SHL2DEF= $(MISC)$/$(SHL2TARGET).def +DEF2NAME= $(SHL2TARGET) +DEF2EXPORTFILE= exports.dxp + + +# --- sysdtrans dll --- + +SHL3TARGET=$(TARGET3) + +SHL3LIBS=$(SLB)$/sysdtrans.lib\ + $(SLB)$/dtutils.lib\ + $(SLB)$/dtobjfact.lib\ + $(SLB)$/mtaolecb.lib + +.IF "$(COM)" == "GCC" +SHL3OBJS=$(SLO)$/XNotifyingDataObject.obj +.ENDIF + +SHL3STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB)\ + $(UWINAPILIB)\ + $(ADVAPI32LIB)\ + $(OLE32LIB)\ + $(OLEAUT32LIB)\ + $(GDI32LIB)\ + $(SHELL32LIB)\ + $(UUIDLIB) + +SHL3IMPLIB=i$(SHL3TARGET) + +SHL3DEF= $(MISC)$/$(SHL3TARGET).def +DEF3NAME= $(SHL3TARGET) +DEF3EXPORTFILE= exports.dxp + + +# --- dnd dll --- + +SHL4TARGET=$(TARGET4) + +SHL4LIBS= \ + $(SLB)$/dnd.lib\ + $(SLB)$/dtobjfact.lib\ + $(SLB)$/dtutils.lib + +SHL4STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(UWINAPILIB)\ + $(ADVAPI32LIB)\ + $(OLE32LIB)\ + $(OLEAUT32LIB)\ + $(GDI32LIB)\ + $(SHELL32LIB)\ + $(UUIDLIB) + +SHL4DEPN= +SHL4IMPLIB=i$(SHL4TARGET) + +SHL4DEF= $(MISC)$/$(SHL4TARGET).def + +DEF4NAME= $(SHL4TARGET) +DEF4EXPORTFILE= exports.dxp + +.ENDIF # "$(GUI)"=="WNT" + +.IF "$(GUI)"=="OS2" + +# --- sysdtrans dll --- + +SHL3TARGET=$(TARGET3) + +SHL3LIBS=$(SLB)$/sysdtrans.lib + +SHL3STDLIBS= \ + $(SALLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + UClip.lib + +SHL3IMPLIB=i$(SHL3TARGET) + +SHL3DEF= $(MISC)$/$(SHL3TARGET).def +DEF3NAME= $(SHL3TARGET) +DEF3EXPORTFILE= exports.dxp + +.ENDIF # "$(GUI)"=="OS2" +.ENDIF # L10N_framework + +.INCLUDE : target.mk + +ALLTAR : \ + $(MISC)/dnd.component \ + $(MISC)/ftransl.component \ + $(MISC)/mcnttype.component \ + $(MISC)/sysdtrans.component + +$(MISC)/dnd.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + dnd.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL4TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt dnd.component + +$(MISC)/ftransl.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + ftransl.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL2TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt ftransl.component + +$(MISC)/mcnttype.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + mcnttype.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt mcnttype.component + +$(MISC)/sysdtrans.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + sysdtrans.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL3TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt sysdtrans.component diff --git a/dtrans/util/mcnttype.component b/dtrans/util/mcnttype.component new file mode 100644 index 000000000000..f5a937a7a77a --- /dev/null +++ b/dtrans/util/mcnttype.component @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.datatransfer.MimeCntTypeFactory"> + <service name="com.sun.star.datatransfer.MimeContentTypeFactory"/> + </implementation> +</component> diff --git a/dtrans/util/sysdtrans.component b/dtrans/util/sysdtrans.component new file mode 100644 index 000000000000..ec1807000b3f --- /dev/null +++ b/dtrans/util/sysdtrans.component @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.datatransfer.clipboard.ClipboardW32"> + <service name="com.sun.star.datatransfer.clipboard.SystemClipboard"/> + </implementation> +</component> |