summaryrefslogtreecommitdiff
path: root/dtrans
diff options
context:
space:
mode:
authorPhilipp Lohmann <pl@openoffice.org>2001-12-12 18:05:41 +0000
committerPhilipp Lohmann <pl@openoffice.org>2001-12-12 18:05:41 +0000
commit7e3ddd934d378364629ae68ba2591ecaa118eee4 (patch)
tree657538b682c95cac9308722c5638a7e4fa793828 /dtrans
parent33994b0c80c8efcdc9df614459d97b023add9f26 (diff)
#95912# #i2345# support more type conversions
Diffstat (limited to 'dtrans')
-rw-r--r--dtrans/source/X11/X11_selection.cxx172
-rw-r--r--dtrans/source/X11/X11_selection.hxx11
2 files changed, 118 insertions, 65 deletions
diff --git a/dtrans/source/X11/X11_selection.cxx b/dtrans/source/X11/X11_selection.cxx
index dd671aa952c1..2b5b0d7ad39f 100644
--- a/dtrans/source/X11/X11_selection.cxx
+++ b/dtrans/source/X11/X11_selection.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: X11_selection.cxx,v $
*
- * $Revision: 1.43 $
+ * $Revision: 1.44 $
*
- * last change: $Author: pl $ $Date: 2001-12-11 20:19:13 $
+ * last change: $Author: pl $ $Date: 2001-12-12 19:05:41 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -134,7 +134,6 @@ static const int nXdndProtocolRevision = 4;
// and X convention types
// for clipboard and primary selections there is only a convention for text
// that the encoding name of the text is taken as type in all capitalized letters
-// TODO: implement Compound Text conversion
// the convention for Xdnd is mime types as specified by the corresponding
// RFC's with the addition that text/plain without charset tag contains iso8859-1
struct NativeTypeEntry
@@ -155,6 +154,7 @@ static NativeTypeEntry aNativeConversionTab[] =
{ 0, "text/plain;charset=utf-16", "ISO10646-1", 16 },
{ 0, "text/plain;charset=utf-8", "UTF8_STRING", 8 },
{ 0, "text/plain;charset=utf-8", "UTF-8", 8 },
+ { 0, "text/plain;charset=utf-8", "text/plain;charset=UTF-8", 8 },
// ISO encodings
{ 0, "text/plain;charset=iso8859-2", "ISO8859-2", 8 },
{ 0, "text/plain;charset=iso8859-3", "ISO8859-3", 8 },
@@ -202,9 +202,9 @@ rtl_TextEncoding x11::getTextPlainEncoding( const OUString& rMimeType )
{
OString aEncToken = OUStringToOString( aToken.getToken( 0, '=', nPos ), RTL_TEXTENCODING_ISO_8859_1 );
aEncoding = rtl_getTextEncodingFromUnixCharset( aEncToken.getStr() );
- if( aEncToken == RTL_TEXTENCODING_DONTKNOW )
+ if( aEncoding == RTL_TEXTENCODING_DONTKNOW )
{
- if( aEncToken.equals( "utf-8" ) )
+ if( aEncToken.equalsIgnoreAsciiCase( "utf-8" ) )
aEncoding = RTL_TEXTENCODING_UTF8;
}
if( aEncoding != RTL_TEXTENCODING_DONTKNOW )
@@ -213,6 +213,10 @@ rtl_TextEncoding x11::getTextPlainEncoding( const OUString& rMimeType )
}
}
}
+#ifdef DEBUG
+ if( aEncoding == RTL_TEXTENCODING_DONTKNOW )
+ fprintf( stderr, "getTextPlainEncoding( %s ) failed\n", OUStringToOString( rMimeType, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
+#endif
return aEncoding;
}
@@ -379,7 +383,7 @@ void SelectionManager::initialize( const Sequence< Any >& arguments ) throw (::c
m_nINCRAtom = getAtom( OUString::createFromAscii( "INCR" ) );
m_nCOMPOUNDAtom = getAtom( OUString::createFromAscii( "COMPOUND_TEXT" ) );
m_nUTF16Atom = getAtom( OUString::createFromAscii( "ISO10646-1" ) );
- m_nUTF8Atom = getAtom( OUString::createFromAscii( "UTF8_STRING" ) );
+// m_nUTF16Atom = getAtom( OUString::createFromAscii( "text/plain;charset=ISO-10646-UCS-2" ) );
// Atoms for Xdnd protocol
m_nXdndAware = getAtom( OUString::createFromAscii( "XdndAware" ) );
@@ -746,7 +750,7 @@ bool SelectionManager::requestOwnership( Atom selection )
// ------------------------------------------------------------------------
-Atom SelectionManager::convertTypeToNative( const OUString& rType, Atom selection, int& rFormat )
+void SelectionManager::convertTypeToNative( const OUString& rType, Atom selection, int& rFormat, ::std::list< Atom >& rConversions )
{
NativeTypeEntry* pTab = selection == m_nXdndSelection ? aXdndConversionTab : aNativeConversionTab;
int nTabEntries = selection == m_nXdndSelection
@@ -754,6 +758,7 @@ Atom SelectionManager::convertTypeToNative( const OUString& rType, Atom selectio
sizeof(aNativeConversionTab)/sizeof(aNativeConversionTab[0]);
OString aType( OUStringToOString( rType, RTL_TEXTENCODING_ISO_8859_1 ) );
+ rFormat = 0;
for( int i = 0; i < nTabEntries; i++ )
{
if( aType.equalsIgnoreAsciiCase( pTab[i].pType ) )
@@ -761,11 +766,12 @@ Atom SelectionManager::convertTypeToNative( const OUString& rType, Atom selectio
if( ! pTab[i].nAtom )
pTab[i].nAtom = getAtom( OStringToOUString( pTab[i].pNativeType, RTL_TEXTENCODING_ISO_8859_1 ) );
rFormat = pTab[i].nFormat;
- return pTab[i].nAtom;
+ rConversions.push_back( pTab[i].nAtom );
}
}
- rFormat = 8; // byte buffer
- return getAtom( rType );
+ if( ! rFormat )
+ rFormat = 8; // byte buffer
+ rConversions.push_back( getAtom( rType ) );
};
// ------------------------------------------------------------------------
@@ -851,20 +857,22 @@ bool SelectionManager::getPasteData( Atom selection, const ::rtl::OUString& rTyp
int nFormat;
bool bSuccess = false;
+ ::std::hash_map< Atom, Selection* >::iterator it;
+ {
+ MutexGuard aGuard(m_aMutex);
+
+ it = m_aSelections.find( selection );
+ if( it == m_aSelections.end() )
+ return false;
+ }
+ const Sequence< DataFlavor >& rTypes( it->second->m_aTypes );
+ const Sequence< Atom >& rNativeTypes( it->second->m_aNativeTypes );
+
if( rType.equalsAsciiL( "text/plain;charset=utf-16", 25 ) )
{
// lets see if we have UTF16 else try to find something convertible
- ::std::hash_map< Atom, Selection* >::iterator it;
- {
- MutexGuard aGuard(m_aMutex);
-
- it = m_aSelections.find( selection );
- if( it == m_aSelections.end() )
- return false;
- }
if( it->second->m_aTypes.getLength() && ! it->second->m_bHaveUTF16 )
{
- const Sequence< DataFlavor >& rTypes( it->second->m_aTypes );
Sequence< sal_Int8 > aData;
if( it->second->m_bHaveCompound &&
getPasteData( selection,
@@ -883,12 +891,9 @@ bool SelectionManager::getPasteData( Atom selection, const ::rtl::OUString& rTyp
rtl_TextEncoding aEncoding = getTextPlainEncoding( rTypes.getConstArray()[i].MimeType );
if( aEncoding != RTL_TEXTENCODING_DONTKNOW &&
aEncoding != RTL_TEXTENCODING_UNICODE &&
- getPasteData(
- selection,
- convertTypeToNative(
- rTypes.getConstArray()[i].MimeType,
- selection, nFormat ),
- aData )
+ getPasteData( selection,
+ rNativeTypes.getConstArray()[i],
+ aData )
)
{
#ifdef DEBUG
@@ -908,7 +913,21 @@ bool SelectionManager::getPasteData( Atom selection, const ::rtl::OUString& rTyp
}
}
if( ! bSuccess )
- bSuccess = getPasteData( selection, convertTypeToNative( rType, selection, nFormat ), rData );
+ {
+ ::std::list< Atom > aTypes;
+ convertTypeToNative( rType, selection, nFormat, aTypes );
+ ::std::list< Atom >::const_iterator type_it;
+ Atom nSelectedType = None;
+ const Atom* pNativeTypes = rNativeTypes.getConstArray();
+ for( type_it = aTypes.begin(); type_it != aTypes.end() && nSelectedType == None; ++type_it )
+ {
+ for( int i = 0; i < rNativeTypes.getLength() && nSelectedType == None; i++ )
+ if( pNativeTypes[i] == *type_it )
+ nSelectedType = *type_it;
+ }
+ if( nSelectedType != None )
+ bSuccess = getPasteData( selection, nSelectedType, rData );
+ }
#ifdef DEBUG
fprintf( stderr, "getPasteData for selection %s and data type %s returns %s, returned sequence has length %d\n",
OUStringToOString( getString( selection ), RTL_TEXTENCODING_ISO_8859_1 ).getStr(),
@@ -1014,12 +1033,15 @@ bool SelectionManager::getPasteDataTypes( Atom selection, Sequence< DataFlavor >
else if( ! getPasteData( selection, m_nTARGETSAtom, aAtoms ) )
aAtoms = Sequence< sal_Int8 >();
+ Sequence< Atom > aNativeTypes;
if( aAtoms.getLength() )
{
int nAtoms = aAtoms.getLength() / 4;
Atom* pAtoms = (Atom*)aAtoms.getArray();
rTypes.realloc( nAtoms );
+ aNativeTypes.realloc( nAtoms );
DataFlavor* pFlavors = rTypes.getArray();
+ Atom* pNativeTypes = aNativeTypes.getArray();
while( nAtoms-- )
{
if( *pAtoms == m_nCOMPOUNDAtom )
@@ -1040,6 +1062,7 @@ bool SelectionManager::getPasteDataTypes( Atom selection, Sequence< DataFlavor >
}
}
pFlavors++;
+ *pNativeTypes++ = *pAtoms;
}
pAtoms++;
}
@@ -1053,6 +1076,11 @@ bool SelectionManager::getPasteDataTypes( Atom selection, Sequence< DataFlavor >
aTemp.getArray()[0].MimeType = OUString::createFromAscii( "text/plain;charset=utf-16" );
aTemp.getArray()[0].DataType = getCppuType( (OUString*)0 );
rTypes = aTemp;
+
+ Sequence< Atom > aNativeTemp( nNewFlavors );
+ memcpy( aNativeTemp.getArray()+1, aNativeTypes.getConstArray(), sizeof(Atom)*(nNewFlavors-1) );
+ aNativeTemp.getArray()[0] = None;
+ aNativeTypes = aNativeTemp;
}
}
@@ -1065,6 +1093,7 @@ bool SelectionManager::getPasteDataTypes( Atom selection, Sequence< DataFlavor >
if( bSuccess )
{
it->second->m_aTypes = rTypes;
+ it->second->m_aNativeTypes = aNativeTypes;
it->second->m_nLastTimestamp = time( NULL );
it->second->m_bHaveUTF16 = bHaveUTF16;
it->second->m_bHaveCompound = bHaveCompound;
@@ -1072,6 +1101,7 @@ bool SelectionManager::getPasteDataTypes( Atom selection, Sequence< DataFlavor >
else
{
it->second->m_aTypes = Sequence< DataFlavor >();
+ it->second->m_aNativeTypes = Sequence< Atom >();
it->second->m_nLastTimestamp = 0;
it->second->m_bHaveUTF16 = false;
it->second->m_bHaveCompound = false;
@@ -1128,24 +1158,35 @@ void SelectionManager::handleSelectionRequest( XSelectionRequestEvent& rRequest
aGuard.clear();
Sequence< DataFlavor > aFlavors = xTrans->getTransferDataFlavors();
aGuard.reset();
- Atom* pTypes = (Atom*)alloca( aFlavors.getLength()+2 * sizeof( Atom ) );
- int nFormat;
+
+ ::std::list< Atom > aConversions;
+ int i, nFormat;
+ int nFlavors = aFlavors.getLength();
+ for( i = 0; i < nFlavors; i++ )
+ convertTypeToNative( aFlavors.getConstArray()[i].MimeType, rRequest.selection, nFormat, aConversions );
bool bHaveUTF16 = false;
- int nTypes = aFlavors.getLength();
- for( int i = 0; i < nTypes; i++ )
- {
- pTypes[i] = convertTypeToNative( aFlavors.getConstArray()[i].MimeType, rRequest.selection, nFormat );
- if( pTypes[i] == m_nUTF16Atom )
+ ::std::list< Atom >::const_iterator it;
+ for( it = aConversions.begin(); it != aConversions.end() && ! bHaveUTF16; ++it )
+ if( *it == m_nUTF16Atom )
bHaveUTF16 = true;
- }
if( bHaveUTF16 )
{
- pTypes[ nTypes++ ] = m_nUTF8Atom;
- pTypes[ nTypes++ ] = m_nCOMPOUNDAtom;
+ convertTypeToNative( OUString::createFromAscii( "text/plain;charset=utf-8" ), rRequest.selection, nFormat, aConversions );
+ aConversions.push_back( m_nCOMPOUNDAtom );
}
+
+ int nTypes = aConversions.size();
+ Atom* pTypes = (Atom*)alloca( nTypes * sizeof( Atom ) );
+ for( i = 0, it = aConversions.begin(); i < nTypes; i++, ++it )
+ pTypes[i] = *it;
XChangeProperty( m_pDisplay, rRequest.requestor, rRequest.property,
XA_ATOM, 32, PropModeReplace, (const unsigned char*)pTypes, nTypes );
aNotify.xselection.property = rRequest.property;
+#ifdef DEBUG
+ fprintf( stderr, "sending type list:\n" );
+ for( int k = 0; k < nTypes; k++ )
+ fprintf( stderr, " %s\n", pTypes[k] ? XGetAtomName( m_pDisplay, pTypes[k] ) : "<None>" );
+#endif
}
}
else
@@ -2347,13 +2388,15 @@ void SelectionManager::updateDragWindow( int nX, int nY, Window aRoot )
aEvent.xclient.data.l[1] = m_nCurrentProtocolVersion << 24;
memset( aEvent.xclient.data.l + 2, 0, sizeof( long )*3 );
// fill in data types
- if( m_aDragFlavors.getLength() > 3 )
- aEvent.xclient.data.l[1] |= 1;
int format;
- for( int i = 0; i < m_aDragFlavors.getLength() && i < 3; i++ )
- {
- aEvent.xclient.data.l[i+2] = convertTypeToNative( m_aDragFlavors.getConstArray()[i].MimeType, m_nXdndSelection, format );
- }
+ ::std::list< Atom > aConversions;
+ for( int nFlavor = 0; nFlavor < m_aDragFlavors.getLength(); nFlavor++ )
+ convertTypeToNative( m_aDragFlavors.getConstArray()[nFlavor].MimeType, m_nXdndSelection, format, aConversions );
+ if( aConversions.size() > 3 )
+ aEvent.xclient.data.l[1] |= 1;
+ ::std::list< Atom >::const_iterator type_it = aConversions.begin();
+ for( int i = 0; type_it != aConversions.end() && i < 3; i++, ++type_it )
+ aEvent.xclient.data.l[i+2] = *type_it;
XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
}
}
@@ -2480,14 +2523,19 @@ void SelectionManager::startDrag(
requestOwnership( m_nXdndSelection );
- Atom* pTypes = new Atom[m_aDragFlavors.getLength()];
+ ::std::list< Atom > aConversions;
+ ::std::list< Atom >::const_iterator type_it;
int format;
for( int i = 0; i < m_aDragFlavors.getLength(); i++ )
- {
- pTypes[i] = convertTypeToNative( m_aDragFlavors.getConstArray()[i].MimeType, m_nXdndSelection, format );
- }
- XChangeProperty( m_pDisplay, m_aWindow, m_nXdndTypeList, XA_ATOM, 32, PropModeReplace, (unsigned char*)pTypes, m_aDragFlavors.getLength() );
- delete pTypes;
+ convertTypeToNative( m_aDragFlavors.getConstArray()[i].MimeType, m_nXdndSelection, format, aConversions );
+
+ int nTypes = aConversions.size();
+ Atom* pTypes = (Atom*)alloca( sizeof(Atom)*nTypes );
+ type_it = aConversions.begin();
+ for( int n = 0; n < nTypes; n++, ++type_it )
+ pTypes[n] = *type_it;
+
+ XChangeProperty( m_pDisplay, m_aWindow, m_nXdndTypeList, XA_ATOM, 32, PropModeReplace, (unsigned char*)pTypes, nTypes );
m_nSourceActions = sourceActions | DNDConstants::ACTION_DEFAULT;
m_nUserDragAction = DNDConstants::ACTION_MOVE & m_nSourceActions;
@@ -2668,15 +2716,18 @@ void SelectionManager::transferablesFlavorsChanged()
MutexGuard aGuard(m_aMutex);
m_aDragFlavors = m_xDragSourceTransferable->getTransferDataFlavors();
+ int format, i;
- Atom* pTypes = new Atom[m_aDragFlavors.getLength()];
- int format;
- for( int i = 0; i < m_aDragFlavors.getLength(); i++ )
- {
- pTypes[i] = convertTypeToNative( m_aDragFlavors.getConstArray()[i].MimeType, m_nXdndSelection, format );
- }
- XChangeProperty( m_pDisplay, m_aWindow, m_nXdndTypeList, XA_ATOM, 32, PropModeReplace, (unsigned char*)pTypes, m_aDragFlavors.getLength() );
- delete pTypes;
+ ::std::list< Atom > aConversions;
+ ::std::list< Atom >::const_iterator type_it;
+ for( i = 0; i < m_aDragFlavors.getLength(); i++ )
+ convertTypeToNative( m_aDragFlavors.getConstArray()[i].MimeType, m_nXdndSelection, format, aConversions );
+
+ int nTypes = aConversions.size();
+ Atom* pTypes = (Atom*)alloca( sizeof(Atom)*aConversions.size() );
+ for( i = 0, type_it = aConversions.begin(); type_it != aConversions.end(); ++type_it, i++ )
+ pTypes[i] = *type_it;
+ XChangeProperty( m_pDisplay, m_aWindow, m_nXdndTypeList, XA_ATOM, 32, PropModeReplace, (unsigned char*)pTypes, nTypes );
if( m_aCurrentDropWindow != None && m_nCurrentProtocolVersion >= 0 )
{
@@ -2698,12 +2749,11 @@ void SelectionManager::transferablesFlavorsChanged()
aEvent.xclient.data.l[1] = m_nCurrentProtocolVersion << 24;
memset( aEvent.xclient.data.l + 2, 0, sizeof( long )*3 );
// fill in data types
- if( m_aDragFlavors.getLength() > 3 )
+ if( nTypes > 3 )
aEvent.xclient.data.l[1] |= 1;
- for( int i = 0; i < m_aDragFlavors.getLength() && i < 3; i++ )
- {
- aEvent.xclient.data.l[i+2] = convertTypeToNative( m_aDragFlavors.getConstArray()[i].MimeType, m_nXdndSelection, format );
- }
+ for( int i = 0; i < nTypes && i < 3; i++ )
+ aEvent.xclient.data.l[i+2] = pTypes[i];
+
XSendEvent( m_pDisplay, m_aDropProxy, False, NoEventMask, &aEvent );
}
}
diff --git a/dtrans/source/X11/X11_selection.hxx b/dtrans/source/X11/X11_selection.hxx
index 9f41ef910fb0..b26588eb10da 100644
--- a/dtrans/source/X11/X11_selection.hxx
+++ b/dtrans/source/X11/X11_selection.hxx
@@ -2,9 +2,9 @@
*
* $RCSfile: X11_selection.hxx,v $
*
- * $Revision: 1.15 $
+ * $Revision: 1.16 $
*
- * last change: $Author: pl $ $Date: 2001-11-26 14:14:30 $
+ * last change: $Author: pl $ $Date: 2001-12-12 19:05:41 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -255,8 +255,10 @@ namespace x11 {
m_aData;
Sequence< ::com::sun::star::datatransfer::DataFlavor >
m_aTypes;
+ Sequence< Atom > m_aNativeTypes;
// this is used for caching
// m_aTypes is invalid after 2 seconds
+ // m_aNativeTypes contains the corresponding original atom
int m_nLastTimestamp;
bool m_bHaveUTF16;
bool m_bHaveCompound;
@@ -376,7 +378,6 @@ namespace x11 {
Atom m_nINCRAtom;
Atom m_nCOMPOUNDAtom;
Atom m_nUTF16Atom;
- Atom m_nUTF8Atom;
Atom m_nXdndAware;
Atom m_nXdndEnter;
Atom m_nXdndLeave;
@@ -468,7 +469,9 @@ namespace x11 {
const ::rtl::OUString& getString( Atom nAtom );
// type conversion
- Atom convertTypeToNative( const ::rtl::OUString& rType, Atom selection, int& rFormat );
+ // note: convertTypeToNative does NOT clear the list, so you can append
+ // multiple types to the same list
+ void convertTypeToNative( const ::rtl::OUString& rType, Atom selection, int& rFormat, ::std::list< Atom >& rConversions );
::rtl::OUString convertTypeFromNative( Atom nType, Atom selection, int& rFormat );
// methods for transferable