xref: /AOO41X/main/svx/source/fmcomp/dbaexchange.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
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