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