xref: /aoo41x/main/svx/source/fmcomp/dbaexchange.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <svx/dbaexchange.hxx>
31 #include <osl/diagnose.h>
32 #include <com/sun/star/sdb/CommandType.hpp>
33 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
34 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
35 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
36 #ifndef _SVX_FMPROP_HRC
37 #include "fmprop.hrc"
38 #endif
39 #include <comphelper/extract.hxx>
40 #include <sot/formats.hxx>
41 #include <sot/exchange.hxx>
42 #include <comphelper/propertysetinfo.hxx>
43 #ifndef _SVX_FMPROP_HRC
44 #include "fmprop.hrc"
45 #endif
46 #include <tools/urlobj.hxx>
47 
48 //........................................................................
49 namespace svx
50 {
51 //........................................................................
52 
53 	using namespace ::com::sun::star::uno;
54 	using namespace ::com::sun::star::beans;
55 	using namespace ::com::sun::star::sdb;
56 	using namespace ::com::sun::star::sdbc;
57 	using namespace ::com::sun::star::lang;
58 	using namespace ::com::sun::star::sdbcx;
59 	using namespace ::com::sun::star::container;
60 	using namespace ::com::sun::star::datatransfer;
61 	using namespace ::comphelper;
62 
63 	//====================================================================
64 	//= OColumnTransferable
65 	//====================================================================
66 	//--------------------------------------------------------------------
67 	OColumnTransferable::OColumnTransferable(const ::rtl::OUString&	_rDatasource
68 											,const ::rtl::OUString& _rConnectionResource
69 											,const sal_Int32		_nCommandType
70 											,const ::rtl::OUString&	_rCommand
71 											,const ::rtl::OUString&	_rFieldName
72 											,sal_Int32	_nFormats)
73 		:m_nFormatFlags(_nFormats)
74 	{
75 		implConstruct(_rDatasource,_rConnectionResource,_nCommandType, _rCommand, _rFieldName);
76 	}
77 
78 	//--------------------------------------------------------------------
79 	OColumnTransferable::OColumnTransferable(const ODataAccessDescriptor& _rDescriptor, sal_Int32 _nFormats )
80 		:m_nFormatFlags(_nFormats)
81 	{
82         ::rtl::OUString sDataSource, sDatabaseLocation, sConnectionResource, sCommand, sFieldName;
83         if ( _rDescriptor.has( daDataSource ) )         _rDescriptor[ daDataSource ] >>= sDataSource;
84         if ( _rDescriptor.has( daDatabaseLocation ) )   _rDescriptor[ daDatabaseLocation ] >>= sDatabaseLocation;
85         if ( _rDescriptor.has( daConnectionResource ) ) _rDescriptor[ daConnectionResource ] >>= sConnectionResource;
86         if ( _rDescriptor.has( daCommand ) )            _rDescriptor[ daCommand ] >>= sCommand;
87         if ( _rDescriptor.has( daColumnName ) )         _rDescriptor[ daColumnName ] >>= sFieldName;
88 
89         sal_Int32 nCommandType = CommandType::TABLE;
90         OSL_VERIFY( _rDescriptor[ daCommandType ] >>= nCommandType );
91 
92 
93         implConstruct(
94             sDataSource.getLength() ? sDataSource : sDatabaseLocation,
95             sConnectionResource, nCommandType, sCommand, sFieldName );
96 
97         if ( m_nFormatFlags & CTF_COLUMN_DESCRIPTOR )
98         {
99             if ( _rDescriptor.has( daConnection ) )
100                 m_aDescriptor[ daConnection ] = _rDescriptor[ daConnection ];
101             if ( _rDescriptor.has( daColumnObject ) )
102                 m_aDescriptor[ daColumnObject ] = _rDescriptor[ daColumnObject ];
103         }
104 	}
105 
106 	//--------------------------------------------------------------------
107 	OColumnTransferable::OColumnTransferable(const Reference< XPropertySet >& _rxForm,
108 			const ::rtl::OUString& _rFieldName, const Reference< XPropertySet >& _rxColumn,
109 			const Reference< XConnection >& _rxConnection, sal_Int32 _nFormats)
110 		:m_nFormatFlags(_nFormats)
111 	{
112 		OSL_ENSURE(_rxForm.is(), "OColumnTransferable::OColumnTransferable: invalid form!");
113 		// collect the necessary information from the form
114 		::rtl::OUString sCommand;
115 		sal_Int32		nCommandType = CommandType::TABLE;
116 		::rtl::OUString sDatasource,sURL;
117 
118 		sal_Bool		bTryToParse = sal_True;
119 		try
120 		{
121 			_rxForm->getPropertyValue(FM_PROP_COMMANDTYPE)	>>= nCommandType;
122 			_rxForm->getPropertyValue(FM_PROP_COMMAND)		>>= sCommand;
123 			_rxForm->getPropertyValue(FM_PROP_DATASOURCE)	>>= sDatasource;
124 			_rxForm->getPropertyValue(FM_PROP_URL)			>>= sURL;
125 			bTryToParse = ::cppu::any2bool(_rxForm->getPropertyValue(FM_PROP_ESCAPE_PROCESSING));
126 		}
127 		catch(Exception&)
128 		{
129 			OSL_ENSURE(sal_False, "OColumnTransferable::OColumnTransferable: could not collect essential data source attributes !");
130 		}
131 
132 		// If the data source is an SQL-statement and simple enough (means "select <field list> from <table> where ....")
133 		// we are able to fake the drag information we are about to create.
134 		if (bTryToParse && (CommandType::COMMAND == nCommandType))
135 		{
136 			try
137 			{
138                 Reference< XTablesSupplier > xSupTab;
139                 _rxForm->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSupTab;
140 
141 				if(xSupTab.is())
142 				{
143 					Reference< XNameAccess > xNames = xSupTab->getTables();
144 					if (xNames.is())
145 					{
146 						Sequence< ::rtl::OUString > aTables = xNames->getElementNames();
147 						if (1 == aTables.getLength())
148 						{
149 							sCommand		= aTables[0];
150 							nCommandType	= CommandType::TABLE;
151 						}
152 					}
153 				}
154 			}
155 			catch(Exception&)
156 			{
157 				OSL_ENSURE(sal_False, "OColumnTransferable::OColumnTransferable: could not collect essential data source attributes (part two) !");
158 			}
159 		}
160 
161 		implConstruct(sDatasource, sURL,nCommandType, sCommand, _rFieldName);
162 
163 		if ((m_nFormatFlags & CTF_COLUMN_DESCRIPTOR) == CTF_COLUMN_DESCRIPTOR)
164 		{
165 			if (_rxColumn.is())
166 				m_aDescriptor[daColumnObject] <<= _rxColumn;
167 			if (_rxConnection.is())
168 				m_aDescriptor[daConnection] <<= _rxConnection;
169 		}
170 	}
171 
172 	//--------------------------------------------------------------------
173 	sal_uInt32 OColumnTransferable::getDescriptorFormatId()
174 	{
175 		static sal_uInt32 s_nFormat = (sal_uInt32)-1;
176 		if ((sal_uInt32)-1 == s_nFormat)
177 		{
178 			s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"dbaccess.ColumnDescriptorTransfer\""));
179 			OSL_ENSURE((sal_uInt32)-1 != s_nFormat, "OColumnTransferable::getDescriptorFormatId: bad exchange id!");
180 		}
181 		return s_nFormat;
182 	}
183 
184 	//--------------------------------------------------------------------
185 	void OColumnTransferable::implConstruct( const ::rtl::OUString& _rDatasource
186 											,const ::rtl::OUString& _rConnectionResource
187 											,const sal_Int32 _nCommandType
188 											,const ::rtl::OUString& _rCommand
189 											, const ::rtl::OUString& _rFieldName)
190 	{
191 		const sal_Unicode		cSeparator = sal_Unicode(11);
192 		const ::rtl::OUString	sSeparator(&cSeparator, 1);
193 
194 		m_sCompatibleFormat = ::rtl::OUString();
195 		m_sCompatibleFormat += _rDatasource;
196 		m_sCompatibleFormat += sSeparator;
197 		m_sCompatibleFormat += _rCommand;
198 		m_sCompatibleFormat += sSeparator;
199 
200 		sal_Unicode cCommandType;
201 		switch (_nCommandType)
202 		{
203 			case CommandType::TABLE:
204 				cCommandType = '0';
205 				break;
206 			case CommandType::QUERY:
207 				cCommandType = '1';
208 				break;
209 			default:
210 				cCommandType = '2';
211 				break;
212 		}
213 		m_sCompatibleFormat += ::rtl::OUString(&cCommandType, 1);
214 		m_sCompatibleFormat += sSeparator;
215 		m_sCompatibleFormat += _rFieldName;
216 
217 		m_aDescriptor.clear();
218 		if ((m_nFormatFlags & CTF_COLUMN_DESCRIPTOR) == CTF_COLUMN_DESCRIPTOR)
219 		{
220 			m_aDescriptor.setDataSource(_rDatasource);
221 			if ( _rConnectionResource.getLength() )
222 				m_aDescriptor[daConnectionResource]	<<= _rConnectionResource;
223 
224 			m_aDescriptor[daCommand]		<<= _rCommand;
225 			m_aDescriptor[daCommandType]	<<= _nCommandType;
226 			m_aDescriptor[daColumnName]		<<= _rFieldName;
227 		}
228 	}
229 
230 	//--------------------------------------------------------------------
231 	void OColumnTransferable::AddSupportedFormats()
232 	{
233 		if (CTF_CONTROL_EXCHANGE & m_nFormatFlags)
234 			AddFormat(SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE);
235 
236 		if (CTF_FIELD_DESCRIPTOR & m_nFormatFlags)
237 			AddFormat(SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE);
238 
239 		if (CTF_COLUMN_DESCRIPTOR & m_nFormatFlags)
240 			AddFormat(getDescriptorFormatId());
241 	}
242 
243 	//--------------------------------------------------------------------
244 	sal_Bool OColumnTransferable::GetData( const DataFlavor& _rFlavor )
245 	{
246 		const sal_uInt32 nFormatId = SotExchange::GetFormat(_rFlavor);
247 		switch (nFormatId)
248 		{
249 			case SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE:
250 			case SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE:
251 				return SetString(m_sCompatibleFormat, _rFlavor);
252 		}
253 		if (nFormatId == getDescriptorFormatId())
254 			return SetAny( makeAny( m_aDescriptor.createPropertyValueSequence() ), _rFlavor );
255 
256 		return sal_False;
257 	}
258 
259 	//--------------------------------------------------------------------
260 	sal_Bool OColumnTransferable::canExtractColumnDescriptor(const DataFlavorExVector& _rFlavors, sal_Int32 _nFormats)
261 	{
262 		sal_Bool bFieldFormat		= 0 != (_nFormats & CTF_FIELD_DESCRIPTOR);
263 		sal_Bool bControlFormat		= 0 != (_nFormats & CTF_CONTROL_EXCHANGE);
264 		sal_Bool bDescriptorFormat	= 0 != (_nFormats & CTF_COLUMN_DESCRIPTOR);
265 		for (	DataFlavorExVector::const_iterator aCheck = _rFlavors.begin();
266 				aCheck != _rFlavors.end();
267 				++aCheck
268 			)
269 		{
270 			if (bFieldFormat && (SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE == aCheck->mnSotId))
271 				return sal_True;
272 			if (bControlFormat && (SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE == aCheck->mnSotId))
273 				return sal_True;
274 			if (bDescriptorFormat && (getDescriptorFormatId() == aCheck->mnSotId))
275 				return sal_True;
276 		}
277 
278 		return sal_False;
279 	}
280 
281 	//--------------------------------------------------------------------
282 	ODataAccessDescriptor OColumnTransferable::extractColumnDescriptor(const TransferableDataHelper& _rData)
283 	{
284 		if (_rData.HasFormat(getDescriptorFormatId()))
285 		{
286 			// the object has a real descriptor object (not just the old compatible format)
287 
288 			// extract the any from the transferable
289 			DataFlavor aFlavor;
290 #if OSL_DEBUG_LEVEL > 0
291 			sal_Bool bSuccess =
292 #endif
293 			SotExchange::GetFormatDataFlavor(getDescriptorFormatId(), aFlavor);
294 			OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid data format (no flavor)!");
295 
296 			Any aDescriptor = _rData.GetAny(aFlavor);
297 
298 			// extract the property value sequence
299 			Sequence< PropertyValue > aDescriptorProps;
300 #if OSL_DEBUG_LEVEL > 0
301 			bSuccess =
302 #endif
303 			aDescriptor >>= aDescriptorProps;
304 			OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid clipboard format!");
305 
306 			// build the real descriptor
307 			return ODataAccessDescriptor(aDescriptorProps);
308 		}
309 
310 		// only the old (compatible) format exists -> use the other extract method ...
311 		::rtl::OUString sDatasource, sCommand, sFieldName,sDatabaseLocation,sConnectionResource;
312 		sal_Int32 nCommandType = CommandType::COMMAND;
313 
314 		ODataAccessDescriptor aDescriptor;
315 		if (extractColumnDescriptor(_rData, sDatasource, sDatabaseLocation,sConnectionResource,nCommandType, sCommand, sFieldName))
316 		{
317 			// and build an own descriptor
318 			if ( sDatasource.getLength() )
319 				aDescriptor[daDataSource]	<<= sDatasource;
320 			if ( sDatabaseLocation.getLength() )
321 				aDescriptor[daDatabaseLocation] <<= sDatabaseLocation;
322 			if ( sConnectionResource.getLength() )
323 				aDescriptor[daConnectionResource]	<<= sConnectionResource;
324 
325 			aDescriptor[daCommand]		<<= sCommand;
326 			aDescriptor[daCommandType]	<<= nCommandType;
327 			aDescriptor[daColumnName]	<<= sFieldName;
328 		}
329 		return aDescriptor;
330 	}
331 
332 	//--------------------------------------------------------------------
333 	sal_Bool OColumnTransferable::extractColumnDescriptor(const TransferableDataHelper& _rData
334 											,::rtl::OUString& _rDatasource
335 											,::rtl::OUString& _rDatabaseLocation
336 											,::rtl::OUString& _rConnectionResource
337 											,sal_Int32& _nCommandType
338 											,::rtl::OUString& _rCommand
339 											,::rtl::OUString& _rFieldName)
340 	{
341 		if ( _rData.HasFormat(getDescriptorFormatId()) )
342 		{
343 			ODataAccessDescriptor aDescriptor = extractColumnDescriptor(_rData);
344 			if ( aDescriptor.has(daDataSource) )
345 				aDescriptor[daDataSource]			>>= _rDatasource;
346 			if ( aDescriptor.has(daDatabaseLocation) )
347 				aDescriptor[daDatabaseLocation]		>>= _rDatabaseLocation;
348 			if ( aDescriptor.has(daConnectionResource) )
349 				aDescriptor[daConnectionResource]	>>= _rConnectionResource;
350 
351 			aDescriptor[daCommand]				>>= _rCommand;
352 			aDescriptor[daCommandType]			>>= _nCommandType;
353 			aDescriptor[daColumnName]			>>= _rFieldName;
354 			return sal_True;
355 		}
356 
357 		// check if we have a (string) format we can use ....
358 		SotFormatStringId	nRecognizedFormat = 0;
359 		if (_rData.HasFormat(SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE))
360 			nRecognizedFormat = SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE;
361 		if (_rData.HasFormat(SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE))
362 			nRecognizedFormat = SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE;
363 		if (!nRecognizedFormat)
364 			return sal_False;
365 
366 		String sFieldDescription;
367 		const_cast<TransferableDataHelper&>(_rData).GetString(nRecognizedFormat, sFieldDescription);
368 
369 		const sal_Unicode cSeparator = sal_Unicode(11);
370 		_rDatasource	= sFieldDescription.GetToken(0, cSeparator);
371 		_rCommand		= sFieldDescription.GetToken(1, cSeparator);
372 		_nCommandType	= sFieldDescription.GetToken(2, cSeparator).ToInt32();
373 		_rFieldName		= sFieldDescription.GetToken(3, cSeparator);
374 
375 		return sal_True;
376 	}
377 
378 	//--------------------------------------------------------------------
379 	void OColumnTransferable::addDataToContainer( TransferDataContainer* _pContainer )
380 	{
381 		OSL_ENSURE( _pContainer, "OColumnTransferable::addDataToContainer: invalid container!" );
382 		if ( _pContainer )
383 		{
384 			if ( m_nFormatFlags & CTF_FIELD_DESCRIPTOR )
385 				_pContainer->CopyAny( SOT_FORMATSTR_ID_SBA_FIELDDATAEXCHANGE, makeAny( m_sCompatibleFormat ) );
386 
387 			if ( m_nFormatFlags & CTF_CONTROL_EXCHANGE )
388 				_pContainer->CopyAny( SOT_FORMATSTR_ID_SBA_CTRLDATAEXCHANGE, makeAny( m_sCompatibleFormat ) );
389 
390 			if ( m_nFormatFlags & CTF_COLUMN_DESCRIPTOR )
391 			{
392 				Any aContent = makeAny( m_aDescriptor.createPropertyValueSequence() );
393 				_pContainer->CopyAny(
394                     sal::static_int_cast< sal_uInt16 >( getDescriptorFormatId() ),
395                     aContent );
396 			}
397 		}
398 	}
399 
400 	//====================================================================
401 	//= ODataAccessObjectTransferable
402 	//====================================================================
403 	ODataAccessObjectTransferable::ODataAccessObjectTransferable(
404 			const ::rtl::OUString&	_rDatasource
405 			,const ::rtl::OUString& _rConnectionResource
406 			,const sal_Int32		_nCommandType
407 			,const ::rtl::OUString&	_rCommand
408 		)
409 	{
410 		construct(_rDatasource,_rConnectionResource,_nCommandType,_rCommand,NULL,(CommandType::COMMAND == _nCommandType),_rCommand);
411 	}
412 	//--------------------------------------------------------------------
413 	ODataAccessObjectTransferable::ODataAccessObjectTransferable(
414 					const ::rtl::OUString&	_rDatasource
415 					,const ::rtl::OUString& _rConnectionResource
416 					,const sal_Int32		_nCommandType
417 					,const ::rtl::OUString&	_rCommand
418 					,const Reference< XConnection >& _rxConnection)
419 	{
420 		OSL_ENSURE(_rxConnection.is(),"Wrong ctor used.!");
421 		construct(_rDatasource,_rConnectionResource,_nCommandType,_rCommand,_rxConnection,(CommandType::COMMAND == _nCommandType),_rCommand);
422 	}
423 
424 	// -----------------------------------------------------------------------------
425 	ODataAccessObjectTransferable::ODataAccessObjectTransferable(const Reference< XPropertySet >& _rxLivingForm)
426 	{
427 		// collect some properties of the form
428 		::rtl::OUString sDatasourceName,sConnectionResource;
429 		sal_Int32		nObjectType = CommandType::COMMAND;
430 		::rtl::OUString sObjectName;
431 		Reference< XConnection > xConnection;
432 		try
433 		{
434 			_rxLivingForm->getPropertyValue(FM_PROP_COMMANDTYPE) >>= nObjectType;
435 			_rxLivingForm->getPropertyValue(FM_PROP_COMMAND) >>= sObjectName;
436 			_rxLivingForm->getPropertyValue(FM_PROP_DATASOURCE) >>= sDatasourceName;
437 			_rxLivingForm->getPropertyValue(FM_PROP_URL) >>= sConnectionResource;
438 			_rxLivingForm->getPropertyValue(FM_PROP_ACTIVE_CONNECTION) >>= xConnection;
439 		}
440 		catch(Exception&)
441 		{
442 			OSL_ENSURE(sal_False, "ODataAccessObjectTransferable::ODataAccessObjectTransferable: could not collect essential form attributes !");
443 			return;
444 		}
445 
446 		String sObjectKind = (CommandType::TABLE == nObjectType) ? String('1') : String('0');
447 
448 		// check if the SQL-statement is modified
449 		::rtl::OUString sCompleteStatement;
450 		try
451 		{
452 			_rxLivingForm->getPropertyValue(FM_PROP_ACTIVECOMMAND) >>= sCompleteStatement;
453 		}
454 		catch(Exception&)
455 		{
456 			OSL_ENSURE(sal_False, "ODataAccessObjectTransferable::ODataAccessObjectTransferable: could not collect essential form attributes (part two) !");
457 			return;
458 		}
459 
460 		construct(	sDatasourceName
461 					,sConnectionResource
462 					,nObjectType
463 					,sObjectName,xConnection
464 					,!((CommandType::QUERY == nObjectType))
465 					,sCompleteStatement);
466 	}
467 
468 	// -----------------------------------------------------------------------------
469 	void ODataAccessObjectTransferable::AddSupportedFormats()
470 	{
471 		sal_Int32 nObjectType = CommandType::COMMAND;
472 		m_aDescriptor[daCommandType] >>= nObjectType;
473 		switch (nObjectType)
474 		{
475 			case CommandType::TABLE:
476 				AddFormat(SOT_FORMATSTR_ID_DBACCESS_TABLE);
477 				break;
478 			case CommandType::QUERY:
479 				AddFormat(SOT_FORMATSTR_ID_DBACCESS_QUERY);
480 				break;
481 			case CommandType::COMMAND:
482 				AddFormat(SOT_FORMATSTR_ID_DBACCESS_COMMAND);
483 				break;
484 		}
485 
486 		sal_Int32 nDescriptorLen = m_sCompatibleObjectDescription.getLength();
487 		if (nDescriptorLen)
488 		{
489 			if (m_sCompatibleObjectDescription.getStr()[nDescriptorLen] == 11)
490 				m_sCompatibleObjectDescription = m_sCompatibleObjectDescription.copy(0, nDescriptorLen - 1);
491 
492 			if (nDescriptorLen)
493 				AddFormat(SOT_FORMATSTR_ID_SBA_DATAEXCHANGE);
494 		}
495 	}
496 
497 	// -----------------------------------------------------------------------------
498 	sal_Bool ODataAccessObjectTransferable::GetData( const DataFlavor& rFlavor )
499 	{
500 		sal_uIntPtr nFormat = SotExchange::GetFormat(rFlavor);
501 		switch (nFormat)
502 		{
503 			case SOT_FORMATSTR_ID_DBACCESS_TABLE:
504 			case SOT_FORMATSTR_ID_DBACCESS_QUERY:
505 			case SOT_FORMATSTR_ID_DBACCESS_COMMAND:
506 				return SetAny( makeAny(m_aDescriptor.createPropertyValueSequence()), rFlavor );
507 
508 			case SOT_FORMATSTR_ID_SBA_DATAEXCHANGE:
509 				return SetString(m_sCompatibleObjectDescription, rFlavor);
510 		}
511 		return sal_False;
512 	}
513 
514 	// -----------------------------------------------------------------------------
515 	sal_Bool ODataAccessObjectTransferable::canExtractObjectDescriptor(const DataFlavorExVector& _rFlavors)
516 	{
517 		for (	DataFlavorExVector::const_iterator aCheck = _rFlavors.begin();
518 				aCheck != _rFlavors.end();
519 				++aCheck
520 			)
521 		{
522 			if (SOT_FORMATSTR_ID_DBACCESS_TABLE == aCheck->mnSotId)
523 				return sal_True;
524 			if (SOT_FORMATSTR_ID_DBACCESS_QUERY == aCheck->mnSotId)
525 				return sal_True;
526 			if (SOT_FORMATSTR_ID_DBACCESS_COMMAND == aCheck->mnSotId)
527 				return sal_True;
528 		}
529 		return sal_False;
530 	}
531 
532 	// -----------------------------------------------------------------------------
533 	ODataAccessDescriptor ODataAccessObjectTransferable::extractObjectDescriptor(const TransferableDataHelper& _rData)
534 	{
535 		sal_Int32 nKnownFormatId = 0;
536 		if ( _rData.HasFormat( SOT_FORMATSTR_ID_DBACCESS_TABLE ) )
537 			nKnownFormatId = SOT_FORMATSTR_ID_DBACCESS_TABLE;
538 		if ( _rData.HasFormat( SOT_FORMATSTR_ID_DBACCESS_QUERY ) )
539 			nKnownFormatId = SOT_FORMATSTR_ID_DBACCESS_QUERY;
540 		if ( _rData.HasFormat( SOT_FORMATSTR_ID_DBACCESS_COMMAND ) )
541 			nKnownFormatId = SOT_FORMATSTR_ID_DBACCESS_COMMAND;
542 
543 		if (0 != nKnownFormatId)
544 		{
545 			// extract the any from the transferable
546 			DataFlavor aFlavor;
547 #if OSL_DEBUG_LEVEL > 0
548 			sal_Bool bSuccess =
549 #endif
550 			SotExchange::GetFormatDataFlavor(nKnownFormatId, aFlavor);
551 			OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid data format (no flavor)!");
552 
553 			Any aDescriptor = _rData.GetAny(aFlavor);
554 
555 			// extract the property value sequence
556 			Sequence< PropertyValue > aDescriptorProps;
557 #if OSL_DEBUG_LEVEL > 0
558 			bSuccess =
559 #endif
560 			aDescriptor >>= aDescriptorProps;
561 			OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid clipboard format!");
562 
563 			// build the real descriptor
564 			return ODataAccessDescriptor(aDescriptorProps);
565 		}
566 
567 		OSL_ENSURE( sal_False, "OColumnTransferable::extractColumnDescriptor: unsupported formats only!" );
568 		return ODataAccessDescriptor();
569 	}
570 
571 	// -----------------------------------------------------------------------------
572 	void ODataAccessObjectTransferable::addCompatibleSelectionDescription( const Sequence< Any >& _rSelRows )
573 	{
574 		const sal_Unicode		cSeparator(11);
575 		const ::rtl::OUString	sSeparator(&cSeparator, 1);
576 
577 		const Any* pSelRows = _rSelRows.getConstArray();
578 		const Any* pSelRowsEnd = pSelRows + _rSelRows.getLength();
579 		for ( ; pSelRows < pSelRowsEnd; ++pSelRows )
580 		{
581 			sal_Int32 nSelectedRow( 0 );
582 			OSL_VERIFY( *pSelRows >>= nSelectedRow );
583 
584 			m_sCompatibleObjectDescription += ::rtl::OUString::valueOf((sal_Int32)nSelectedRow);
585 			m_sCompatibleObjectDescription += sSeparator;
586 		}
587 	}
588 
589 	// -----------------------------------------------------------------------------
590 	void ODataAccessObjectTransferable::ObjectReleased()
591 	{
592 		m_aDescriptor.clear();
593 	}
594 	// -----------------------------------------------------------------------------
595 	void ODataAccessObjectTransferable::construct(	const ::rtl::OUString&	_rDatasource
596 													,const ::rtl::OUString& _rConnectionResource
597 													,const sal_Int32		_nCommandType
598 													,const ::rtl::OUString&	_rCommand
599 													,const Reference< XConnection >& _rxConnection
600 													,sal_Bool _bAddCommand
601 													,const ::rtl::OUString& _sActiveCommand)
602 	{
603 		m_aDescriptor.setDataSource(_rDatasource);
604 		// build the descriptor (the property sequence)
605 		if ( _rConnectionResource.getLength() )
606 			m_aDescriptor[daConnectionResource]	<<= _rConnectionResource;
607 		if ( _rxConnection.is() )
608 			m_aDescriptor[daConnection]		<<= _rxConnection;
609 		m_aDescriptor[daCommand]		<<= _rCommand;
610 		m_aDescriptor[daCommandType]	<<= _nCommandType;
611 
612 		// extract the single values from the sequence
613 
614 		::rtl::OUString sObjectName;
615 		::rtl::OUString sDatasourceName = _rDatasource;
616 		sObjectName = _rCommand;
617 
618 		// for compatibility: create a string which can be used for the SOT_FORMATSTR_ID_SBA_DATAEXCHANGE format
619 
620 		sal_Bool bTreatAsStatement = (CommandType::COMMAND == _nCommandType);
621 			// statements are - in this old and ugly format - described as queries
622 
623 		const sal_Unicode		cSeparator = sal_Unicode(11);
624 		const ::rtl::OUString	sSeparator(&cSeparator, 1);
625 
626 		const sal_Unicode		cTableMark = '1';
627 		const sal_Unicode		cQueryMark = '0';
628 
629 		// build the descriptor string
630 		m_sCompatibleObjectDescription += sDatasourceName;
631 		m_sCompatibleObjectDescription += sSeparator;
632 		m_sCompatibleObjectDescription += bTreatAsStatement ? ::rtl::OUString() : sObjectName;
633 		m_sCompatibleObjectDescription += sSeparator;
634 		switch (_nCommandType)
635 		{
636 			case CommandType::TABLE:
637 				m_sCompatibleObjectDescription += ::rtl::OUString(&cTableMark, 1);
638 				break;
639 			case CommandType::QUERY:
640 				m_sCompatibleObjectDescription += ::rtl::OUString(&cQueryMark, 1);
641 				break;
642 			case CommandType::COMMAND:
643 				m_sCompatibleObjectDescription += ::rtl::OUString(&cQueryMark, 1);
644 				// think of it as a query
645 				break;
646 		}
647 		m_sCompatibleObjectDescription += sSeparator;
648 		m_sCompatibleObjectDescription += _bAddCommand ? _sActiveCommand : ::rtl::OUString();
649 		m_sCompatibleObjectDescription += sSeparator;
650 	}
651 
652     //--------------------------------------------------------------------
653     OMultiColumnTransferable::OMultiColumnTransferable(const Sequence< PropertyValue >& _aDescriptors) : m_aDescriptors(_aDescriptors)
654     {
655     }
656     //--------------------------------------------------------------------
657     sal_uInt32 OMultiColumnTransferable::getDescriptorFormatId()
658 	{
659 		static sal_uInt32 s_nFormat = (sal_uInt32)-1;
660 		if ((sal_uInt32)-1 == s_nFormat)
661 		{
662 			s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"dbaccess.MultipleColumnDescriptorTransfer\""));
663 			OSL_ENSURE((sal_uInt32)-1 != s_nFormat, "OColumnTransferable::getDescriptorFormatId: bad exchange id!");
664 		}
665 		return s_nFormat;
666 	}
667     //--------------------------------------------------------------------
668 	void OMultiColumnTransferable::AddSupportedFormats()
669 	{
670 		AddFormat(getDescriptorFormatId());
671 	}
672     //--------------------------------------------------------------------
673 	void OMultiColumnTransferable::push_back(ODataAccessDescriptor& _aDescriptor)
674     {
675         const sal_Int32 nCount = m_aDescriptors.getLength();
676         m_aDescriptors.realloc(nCount+1);
677         m_aDescriptors[nCount].Value <<= _aDescriptor.createPropertyValueSequence();
678     }
679 	//--------------------------------------------------------------------
680 	sal_Bool OMultiColumnTransferable::GetData( const DataFlavor& _rFlavor )
681 	{
682 		const sal_uInt32 nFormatId = SotExchange::GetFormat(_rFlavor);
683 		if (nFormatId == getDescriptorFormatId())
684         {
685 			return SetAny( makeAny( m_aDescriptors ), _rFlavor );
686         }
687 
688 		return sal_False;
689 	}
690 
691 	//--------------------------------------------------------------------
692 	sal_Bool OMultiColumnTransferable::canExtractDescriptor(const DataFlavorExVector& _rFlavors)
693 	{
694         DataFlavorExVector::const_iterator aCheck = _rFlavors.begin();
695 		for (	;
696 				aCheck != _rFlavors.end() && getDescriptorFormatId() == aCheck->mnSotId;
697 				++aCheck
698 			)
699             ;
700 
701 		return aCheck == _rFlavors.end();
702 	}
703 
704 	//--------------------------------------------------------------------
705 	Sequence< PropertyValue > OMultiColumnTransferable::extractDescriptor(const TransferableDataHelper& _rData)
706 	{
707         Sequence< PropertyValue > aList;
708 		if (_rData.HasFormat(getDescriptorFormatId()))
709 		{
710 			// extract the any from the transferable
711 			DataFlavor aFlavor;
712 #if OSL_DEBUG_LEVEL > 0
713 			sal_Bool bSuccess =
714 #endif
715 			SotExchange::GetFormatDataFlavor(getDescriptorFormatId(), aFlavor);
716 			OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid data format (no flavor)!");
717 
718 			_rData.GetAny(aFlavor) >>= aList;
719 		} // if (_rData.HasFormat(getDescriptorFormatId()))
720         return aList;
721 	}
722     // -----------------------------------------------------------------------------
723 	void OMultiColumnTransferable::ObjectReleased()
724 	{
725         m_aDescriptors.realloc(0);
726 	}
727 
728 //........................................................................
729 }	// namespace svx
730 //........................................................................
731 
732 
733