Coverage Report

Created: 2026-05-16 09:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/fmcomp/dbaexchange.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <svx/dbaexchange.hxx>
21
#include <osl/diagnose.h>
22
#include <com/sun/star/beans/XPropertySet.hpp>
23
#include <com/sun/star/sdb/CommandType.hpp>
24
#include <com/sun/star/sdbc/XConnection.hpp>
25
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
26
#include <fmprop.hxx>
27
#include <comphelper/extract.hxx>
28
#include <sot/formats.hxx>
29
#include <sot/exchange.hxx>
30
#include <o3tl/string_view.hxx>
31
32
33
namespace svx
34
{
35
36
37
    using namespace ::com::sun::star::uno;
38
    using namespace ::com::sun::star::beans;
39
    using namespace ::com::sun::star::sdb;
40
    using namespace ::com::sun::star::sdbc;
41
    using namespace ::com::sun::star::sdbcx;
42
    using namespace ::com::sun::star::container;
43
    using namespace ::com::sun::star::datatransfer;
44
45
    OColumnTransferable::OColumnTransferable(ColumnTransferFormatFlags nFormats)
46
0
        : m_nFormatFlags(nFormats)
47
0
    {
48
0
    }
49
50
    void OColumnTransferable::setDescriptor(const ODataAccessDescriptor& rDescriptor)
51
0
    {
52
0
        ClearFormats();
53
54
0
        OUString sDataSource, sDatabaseLocation, sConnectionResource, sCommand, sFieldName;
55
0
        if ( rDescriptor.has( DataAccessDescriptorProperty::DataSource ) )         rDescriptor[ DataAccessDescriptorProperty::DataSource ] >>= sDataSource;
56
0
        if ( rDescriptor.has( DataAccessDescriptorProperty::DatabaseLocation ) )   rDescriptor[ DataAccessDescriptorProperty::DatabaseLocation ] >>= sDatabaseLocation;
57
0
        if ( rDescriptor.has( DataAccessDescriptorProperty::ConnectionResource ) ) rDescriptor[ DataAccessDescriptorProperty::ConnectionResource ] >>= sConnectionResource;
58
0
        if ( rDescriptor.has( DataAccessDescriptorProperty::Command ) )            rDescriptor[ DataAccessDescriptorProperty::Command ] >>= sCommand;
59
0
        if ( rDescriptor.has( DataAccessDescriptorProperty::ColumnName ) )         rDescriptor[ DataAccessDescriptorProperty::ColumnName ] >>= sFieldName;
60
61
0
        sal_Int32 nCommandType = CommandType::TABLE;
62
0
        OSL_VERIFY( rDescriptor[ DataAccessDescriptorProperty::CommandType ] >>= nCommandType );
63
64
0
        implConstruct(
65
0
            sDataSource.isEmpty() ? sDatabaseLocation : sDataSource,
66
0
            sConnectionResource, nCommandType, sCommand, sFieldName );
67
68
0
        if ( m_nFormatFlags & ColumnTransferFormatFlags::COLUMN_DESCRIPTOR )
69
0
        {
70
0
            if ( rDescriptor.has( DataAccessDescriptorProperty::Connection ) )
71
0
                m_aDescriptor[ DataAccessDescriptorProperty::Connection ] = rDescriptor[ DataAccessDescriptorProperty::Connection ];
72
0
            if ( rDescriptor.has( DataAccessDescriptorProperty::ColumnObject ) )
73
0
                m_aDescriptor[ DataAccessDescriptorProperty::ColumnObject ] = rDescriptor[ DataAccessDescriptorProperty::ColumnObject ];
74
0
        }
75
0
    }
76
77
    OColumnTransferable::OColumnTransferable(const Reference< XPropertySet >& _rxForm,
78
            const OUString& _rFieldName, const Reference< XPropertySet >& _rxColumn,
79
            const Reference< XConnection >& _rxConnection, ColumnTransferFormatFlags _nFormats)
80
0
        :m_nFormatFlags(_nFormats)
81
0
    {
82
0
        OSL_ENSURE(_rxForm.is(), "OColumnTransferable::OColumnTransferable: invalid form!");
83
        // collect the necessary information from the form
84
0
        OUString sCommand;
85
0
        sal_Int32       nCommandType = CommandType::TABLE;
86
0
        OUString sDatasource,sURL;
87
88
0
        bool        bTryToParse = true;
89
0
        try
90
0
        {
91
0
            _rxForm->getPropertyValue(FM_PROP_COMMANDTYPE)  >>= nCommandType;
92
0
            _rxForm->getPropertyValue(FM_PROP_COMMAND)      >>= sCommand;
93
0
            _rxForm->getPropertyValue(FM_PROP_DATASOURCE)   >>= sDatasource;
94
0
            _rxForm->getPropertyValue(FM_PROP_URL)          >>= sURL;
95
0
            bTryToParse = ::cppu::any2bool(_rxForm->getPropertyValue(FM_PROP_ESCAPE_PROCESSING));
96
0
        }
97
0
        catch(Exception&)
98
0
        {
99
0
            OSL_FAIL("OColumnTransferable::OColumnTransferable: could not collect essential data source attributes !");
100
0
        }
101
102
        // If the data source is an SQL-statement and simple enough (means "select <field list> from <table> where...")
103
        // we are able to fake the drag information we are about to create.
104
0
        if (bTryToParse && (CommandType::COMMAND == nCommandType))
105
0
        {
106
0
            try
107
0
            {
108
0
                Reference< XTablesSupplier > xSupTab;
109
0
                _rxForm->getPropertyValue(u"SingleSelectQueryComposer"_ustr) >>= xSupTab;
110
111
0
                if(xSupTab.is())
112
0
                {
113
0
                    Reference< XNameAccess > xNames = xSupTab->getTables();
114
0
                    if (xNames.is())
115
0
                    {
116
0
                        Sequence< OUString > aTables = xNames->getElementNames();
117
0
                        if (1 == aTables.getLength())
118
0
                        {
119
0
                            sCommand        = aTables[0];
120
0
                            nCommandType    = CommandType::TABLE;
121
0
                        }
122
0
                    }
123
0
                }
124
0
            }
125
0
            catch(Exception&)
126
0
            {
127
0
                OSL_FAIL("OColumnTransferable::OColumnTransferable: could not collect essential data source attributes (part two) !");
128
0
            }
129
0
        }
130
131
0
        implConstruct(sDatasource, sURL,nCommandType, sCommand, _rFieldName);
132
133
0
        if ((m_nFormatFlags & ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) == ColumnTransferFormatFlags::COLUMN_DESCRIPTOR)
134
0
        {
135
0
            if (_rxColumn.is())
136
0
                m_aDescriptor[DataAccessDescriptorProperty::ColumnObject] <<= _rxColumn;
137
0
            if (_rxConnection.is())
138
0
                m_aDescriptor[DataAccessDescriptorProperty::Connection] <<= _rxConnection;
139
0
        }
140
0
    }
141
142
143
    SotClipboardFormatId OColumnTransferable::getDescriptorFormatId()
144
0
    {
145
0
        static SotClipboardFormatId s_nFormat = static_cast<SotClipboardFormatId>(-1);
146
0
        if (static_cast<SotClipboardFormatId>(-1) == s_nFormat)
147
0
        {
148
0
            s_nFormat = SotExchange::RegisterFormatName(u"application/x-openoffice;windows_formatname=\"dbaccess.ColumnDescriptorTransfer\""_ustr);
149
0
            OSL_ENSURE(static_cast<SotClipboardFormatId>(-1) != s_nFormat, "OColumnTransferable::getDescriptorFormatId: bad exchange id!");
150
0
        }
151
0
        return s_nFormat;
152
0
    }
153
154
155
    void OColumnTransferable::implConstruct( const OUString& _rDatasource
156
                                            ,const OUString& _rConnectionResource
157
                                            ,const sal_Int32 _nCommandType
158
                                            ,const OUString& _rCommand
159
                                            , const OUString& _rFieldName)
160
0
    {
161
0
        const sal_Unicode       cSeparator = u'\x000B';
162
0
        const OUString   sSeparator(&cSeparator, 1);
163
164
0
        m_sCompatibleFormat.clear();
165
0
        m_sCompatibleFormat += _rDatasource;
166
0
        m_sCompatibleFormat += sSeparator;
167
0
        m_sCompatibleFormat += _rCommand;
168
0
        m_sCompatibleFormat += sSeparator;
169
170
0
        sal_Unicode cCommandType;
171
0
        switch (_nCommandType)
172
0
        {
173
0
            case CommandType::TABLE:
174
0
                cCommandType = '0';
175
0
                break;
176
0
            case CommandType::QUERY:
177
0
                cCommandType = '1';
178
0
                break;
179
0
            default:
180
0
                cCommandType = '2';
181
0
                break;
182
0
        }
183
0
        m_sCompatibleFormat += OUStringChar(cCommandType);
184
0
        m_sCompatibleFormat += sSeparator;
185
0
        m_sCompatibleFormat += _rFieldName;
186
187
0
        m_aDescriptor.clear();
188
0
        if ((m_nFormatFlags & ColumnTransferFormatFlags::COLUMN_DESCRIPTOR) == ColumnTransferFormatFlags::COLUMN_DESCRIPTOR)
189
0
        {
190
0
            m_aDescriptor.setDataSource(_rDatasource);
191
0
            if ( !_rConnectionResource.isEmpty() )
192
0
                m_aDescriptor[DataAccessDescriptorProperty::ConnectionResource] <<= _rConnectionResource;
193
194
0
            m_aDescriptor[DataAccessDescriptorProperty::Command]        <<= _rCommand;
195
0
            m_aDescriptor[DataAccessDescriptorProperty::CommandType]    <<= _nCommandType;
196
0
            m_aDescriptor[DataAccessDescriptorProperty::ColumnName]     <<= _rFieldName;
197
0
        }
198
0
    }
199
200
201
    void OColumnTransferable::AddSupportedFormats()
202
0
    {
203
0
        if (ColumnTransferFormatFlags::CONTROL_EXCHANGE & m_nFormatFlags)
204
0
            AddFormat(SotClipboardFormatId::SBA_CTRLDATAEXCHANGE);
205
206
0
        if (ColumnTransferFormatFlags::FIELD_DESCRIPTOR & m_nFormatFlags)
207
0
            AddFormat(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE);
208
209
0
        if (ColumnTransferFormatFlags::COLUMN_DESCRIPTOR & m_nFormatFlags)
210
0
            AddFormat(getDescriptorFormatId());
211
0
    }
212
213
214
    bool OColumnTransferable::GetData( const DataFlavor& _rFlavor, const OUString& /*rDestDoc*/ )
215
0
    {
216
0
        const SotClipboardFormatId nFormatId = SotExchange::GetFormat(_rFlavor);
217
0
        switch (nFormatId)
218
0
        {
219
0
            case SotClipboardFormatId::SBA_FIELDDATAEXCHANGE:
220
0
            case SotClipboardFormatId::SBA_CTRLDATAEXCHANGE:
221
0
                return SetString(m_sCompatibleFormat);
222
0
            default: break;
223
0
        }
224
0
        if (nFormatId == getDescriptorFormatId())
225
0
            return SetAny( Any( m_aDescriptor.createPropertyValueSequence() ) );
226
227
0
        return false;
228
0
    }
229
230
231
    bool OColumnTransferable::canExtractColumnDescriptor(const DataFlavorExVector& _rFlavors, ColumnTransferFormatFlags _nFormats)
232
0
    {
233
0
        bool bFieldFormat       = bool(_nFormats & ColumnTransferFormatFlags::FIELD_DESCRIPTOR);
234
0
        bool bControlFormat     = bool(_nFormats & ColumnTransferFormatFlags::CONTROL_EXCHANGE);
235
0
        bool bDescriptorFormat  = bool(_nFormats & ColumnTransferFormatFlags::COLUMN_DESCRIPTOR);
236
0
        SotClipboardFormatId nFormatId = getDescriptorFormatId();
237
0
        return std::any_of(_rFlavors.begin(), _rFlavors.end(),
238
0
            [&](const DataFlavorEx& rCheck) {
239
0
                return (bFieldFormat && (SotClipboardFormatId::SBA_FIELDDATAEXCHANGE == rCheck.mnSotId))
240
0
                    || (bControlFormat && (SotClipboardFormatId::SBA_CTRLDATAEXCHANGE == rCheck.mnSotId))
241
0
                    || (bDescriptorFormat && (nFormatId == rCheck.mnSotId));
242
0
            });
243
0
    }
244
245
246
    ODataAccessDescriptor OColumnTransferable::extractColumnDescriptor(const TransferableDataHelper& _rData)
247
0
    {
248
0
        if (_rData.HasFormat(getDescriptorFormatId()))
249
0
        {
250
            // the object has a real descriptor object (not just the old compatible format)
251
252
            // extract the any from the transferable
253
0
            DataFlavor aFlavor;
254
0
            bool bSuccess =
255
0
                SotExchange::GetFormatDataFlavor(getDescriptorFormatId(), aFlavor);
256
0
            OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid data format (no flavor)!");
257
258
0
            Any aDescriptor = _rData.GetAny(aFlavor, OUString());
259
260
            // extract the property value sequence
261
0
            Sequence< PropertyValue > aDescriptorProps;
262
0
            bSuccess = aDescriptor >>= aDescriptorProps;
263
0
            OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid clipboard format!");
264
265
            // build the real descriptor
266
0
            return ODataAccessDescriptor(aDescriptorProps);
267
0
        }
268
269
        // only the old (compatible) format exists -> use the other extract method ...
270
0
        OUString sDatasource, sCommand, sFieldName,sDatabaseLocation,sConnectionResource;
271
0
        sal_Int32 nCommandType = CommandType::COMMAND;
272
273
0
        ODataAccessDescriptor aDescriptor;
274
0
        if (extractColumnDescriptor(_rData, sDatasource, sDatabaseLocation,sConnectionResource,nCommandType, sCommand, sFieldName))
275
0
        {
276
            // and build an own descriptor
277
0
            if ( !sDatasource.isEmpty() )
278
0
                aDescriptor[DataAccessDescriptorProperty::DataSource]   <<= sDatasource;
279
0
            if ( !sDatabaseLocation.isEmpty() )
280
0
                aDescriptor[DataAccessDescriptorProperty::DatabaseLocation] <<= sDatabaseLocation;
281
0
            if ( !sConnectionResource.isEmpty() )
282
0
                aDescriptor[DataAccessDescriptorProperty::ConnectionResource]   <<= sConnectionResource;
283
284
0
            aDescriptor[DataAccessDescriptorProperty::Command]      <<= sCommand;
285
0
            aDescriptor[DataAccessDescriptorProperty::CommandType]  <<= nCommandType;
286
0
            aDescriptor[DataAccessDescriptorProperty::ColumnName]   <<= sFieldName;
287
0
        }
288
0
        return aDescriptor;
289
0
    }
290
291
292
    bool OColumnTransferable::extractColumnDescriptor(const TransferableDataHelper& _rData
293
                                            ,OUString& _rDatasource
294
                                            ,OUString& _rDatabaseLocation
295
                                            ,OUString& _rConnectionResource
296
                                            ,sal_Int32& _nCommandType
297
                                            ,OUString& _rCommand
298
                                            ,OUString& _rFieldName)
299
0
    {
300
0
        if ( _rData.HasFormat(getDescriptorFormatId()) )
301
0
        {
302
0
            ODataAccessDescriptor aDescriptor = extractColumnDescriptor(_rData);
303
0
            if ( aDescriptor.has(DataAccessDescriptorProperty::DataSource) )
304
0
                aDescriptor[DataAccessDescriptorProperty::DataSource]           >>= _rDatasource;
305
0
            if ( aDescriptor.has(DataAccessDescriptorProperty::DatabaseLocation) )
306
0
                aDescriptor[DataAccessDescriptorProperty::DatabaseLocation]     >>= _rDatabaseLocation;
307
0
            if ( aDescriptor.has(DataAccessDescriptorProperty::ConnectionResource) )
308
0
                aDescriptor[DataAccessDescriptorProperty::ConnectionResource]   >>= _rConnectionResource;
309
310
0
            aDescriptor[DataAccessDescriptorProperty::Command]              >>= _rCommand;
311
0
            aDescriptor[DataAccessDescriptorProperty::CommandType]          >>= _nCommandType;
312
0
            aDescriptor[DataAccessDescriptorProperty::ColumnName]           >>= _rFieldName;
313
0
            return true;
314
0
        }
315
316
        // check if we have a (string) format we can use...
317
0
        SotClipboardFormatId   nRecognizedFormat = SotClipboardFormatId::NONE;
318
0
        if (_rData.HasFormat(SotClipboardFormatId::SBA_FIELDDATAEXCHANGE))
319
0
            nRecognizedFormat = SotClipboardFormatId::SBA_FIELDDATAEXCHANGE;
320
0
        if (_rData.HasFormat(SotClipboardFormatId::SBA_CTRLDATAEXCHANGE))
321
0
            nRecognizedFormat = SotClipboardFormatId::SBA_CTRLDATAEXCHANGE;
322
0
        if (nRecognizedFormat == SotClipboardFormatId::NONE)
323
0
            return false;
324
325
0
        OUString sFieldDescription;
326
0
        (void)_rData.GetString(nRecognizedFormat, sFieldDescription);
327
328
0
        const sal_Unicode cSeparator = u'\x000B';
329
0
        sal_Int32 nIdx{ 0 };
330
0
        _rDatasource    = sFieldDescription.getToken(0, cSeparator, nIdx);
331
0
        _rCommand       = sFieldDescription.getToken(0, cSeparator, nIdx);
332
0
        _nCommandType   = o3tl::toInt32(o3tl::getToken(sFieldDescription, 0, cSeparator, nIdx));
333
0
        _rFieldName     = sFieldDescription.getToken(0, cSeparator, nIdx);
334
335
0
        return true;
336
0
    }
337
338
    ODataAccessObjectTransferable::ODataAccessObjectTransferable()
339
0
    {
340
0
    }
341
342
    void ODataAccessObjectTransferable::Update(
343
            const OUString&  _rDatasource,
344
            const sal_Int32  _nCommandType,
345
            const OUString& _rCommand)
346
0
    {
347
0
        construct(_rDatasource,OUString(),_nCommandType,_rCommand,nullptr,(CommandType::COMMAND == _nCommandType),_rCommand);
348
0
    }
349
350
    void ODataAccessObjectTransferable::Update(
351
                    const OUString&  _rDatasource,
352
                    const sal_Int32 _nCommandType,
353
                    const OUString& _rCommand,
354
                    const Reference< XConnection >& _rxConnection)
355
0
    {
356
0
        OSL_ENSURE(_rxConnection.is(), "Wrong Update used.!");
357
0
        construct(_rDatasource,OUString(),_nCommandType,_rCommand,_rxConnection,(CommandType::COMMAND == _nCommandType),_rCommand);
358
0
    }
359
360
    ODataAccessObjectTransferable::ODataAccessObjectTransferable(const Reference< XPropertySet >& _rxLivingForm)
361
0
    {
362
        // collect some properties of the form
363
0
        OUString sDatasourceName,sConnectionResource;
364
0
        sal_Int32       nObjectType = CommandType::COMMAND;
365
0
        OUString sObjectName;
366
0
        Reference< XConnection > xConnection;
367
0
        try
368
0
        {
369
0
            _rxLivingForm->getPropertyValue(FM_PROP_COMMANDTYPE) >>= nObjectType;
370
0
            _rxLivingForm->getPropertyValue(FM_PROP_COMMAND) >>= sObjectName;
371
0
            _rxLivingForm->getPropertyValue(FM_PROP_DATASOURCE) >>= sDatasourceName;
372
0
            _rxLivingForm->getPropertyValue(FM_PROP_URL) >>= sConnectionResource;
373
0
            _rxLivingForm->getPropertyValue(FM_PROP_ACTIVE_CONNECTION) >>= xConnection;
374
0
        }
375
0
        catch(Exception&)
376
0
        {
377
0
            OSL_FAIL("ODataAccessObjectTransferable::ODataAccessObjectTransferable: could not collect essential form attributes !");
378
0
            return;
379
0
        }
380
381
        // check if the SQL-statement is modified
382
0
        OUString sCompleteStatement;
383
0
        try
384
0
        {
385
0
            _rxLivingForm->getPropertyValue(FM_PROP_ACTIVECOMMAND) >>= sCompleteStatement;
386
0
        }
387
0
        catch (const Exception&)
388
0
        {
389
0
            OSL_FAIL("ODataAccessObjectTransferable::ODataAccessObjectTransferable: could not collect essential form attributes (part two) !");
390
0
            return;
391
0
        }
392
393
0
        construct(  sDatasourceName
394
0
                    ,sConnectionResource
395
0
                    ,nObjectType
396
0
                    ,sObjectName,xConnection
397
0
                    ,CommandType::QUERY != nObjectType
398
0
                    ,sCompleteStatement);
399
0
    }
400
401
402
    void ODataAccessObjectTransferable::AddSupportedFormats()
403
0
    {
404
0
        sal_Int32 nObjectType = CommandType::COMMAND;
405
0
        m_aDescriptor[DataAccessDescriptorProperty::CommandType] >>= nObjectType;
406
0
        switch (nObjectType)
407
0
        {
408
0
            case CommandType::TABLE:
409
0
                AddFormat(SotClipboardFormatId::DBACCESS_TABLE);
410
0
                break;
411
0
            case CommandType::QUERY:
412
0
                AddFormat(SotClipboardFormatId::DBACCESS_QUERY);
413
0
                break;
414
0
            case CommandType::COMMAND:
415
0
                AddFormat(SotClipboardFormatId::DBACCESS_COMMAND);
416
0
                break;
417
0
        }
418
419
0
        if (!m_sCompatibleObjectDescription.isEmpty())
420
0
            AddFormat(SotClipboardFormatId::SBA_DATAEXCHANGE);
421
0
    }
422
423
424
    bool ODataAccessObjectTransferable::GetData( const DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
425
0
    {
426
0
        SotClipboardFormatId nFormat = SotExchange::GetFormat(rFlavor);
427
0
        switch (nFormat)
428
0
        {
429
0
            case SotClipboardFormatId::DBACCESS_TABLE:
430
0
            case SotClipboardFormatId::DBACCESS_QUERY:
431
0
            case SotClipboardFormatId::DBACCESS_COMMAND:
432
0
                return SetAny( Any(m_aDescriptor.createPropertyValueSequence()) );
433
434
0
            case SotClipboardFormatId::SBA_DATAEXCHANGE:
435
0
                return SetString(m_sCompatibleObjectDescription);
436
0
            default: break;
437
0
        }
438
0
        return false;
439
0
    }
440
441
442
    bool ODataAccessObjectTransferable::canExtractObjectDescriptor(const DataFlavorExVector& _rFlavors)
443
0
    {
444
0
        return std::any_of(_rFlavors.begin(), _rFlavors.end(),
445
0
            [](const DataFlavorEx& rCheck) {
446
0
                return SotClipboardFormatId::DBACCESS_TABLE == rCheck.mnSotId
447
0
                    || SotClipboardFormatId::DBACCESS_QUERY == rCheck.mnSotId
448
0
                    || SotClipboardFormatId::DBACCESS_COMMAND == rCheck.mnSotId;
449
0
            });
450
0
    }
451
452
453
    ODataAccessDescriptor ODataAccessObjectTransferable::extractObjectDescriptor(const TransferableDataHelper& _rData)
454
0
    {
455
0
        SotClipboardFormatId nKnownFormatId = SotClipboardFormatId::NONE;
456
0
        if ( _rData.HasFormat( SotClipboardFormatId::DBACCESS_TABLE ) )
457
0
            nKnownFormatId = SotClipboardFormatId::DBACCESS_TABLE;
458
0
        if ( _rData.HasFormat( SotClipboardFormatId::DBACCESS_QUERY ) )
459
0
            nKnownFormatId = SotClipboardFormatId::DBACCESS_QUERY;
460
0
        if ( _rData.HasFormat( SotClipboardFormatId::DBACCESS_COMMAND ) )
461
0
            nKnownFormatId = SotClipboardFormatId::DBACCESS_COMMAND;
462
463
0
        if (SotClipboardFormatId::NONE != nKnownFormatId)
464
0
        {
465
            // extract the any from the transferable
466
0
            DataFlavor aFlavor;
467
0
            bool bSuccess =
468
0
                SotExchange::GetFormatDataFlavor(nKnownFormatId, aFlavor);
469
0
            OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid data format (no flavor)!");
470
471
0
            Any aDescriptor = _rData.GetAny(aFlavor, OUString());
472
473
            // extract the property value sequence
474
0
            Sequence< PropertyValue > aDescriptorProps;
475
0
            bSuccess = aDescriptor >>= aDescriptorProps;
476
0
            OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid clipboard format!");
477
478
            // build the real descriptor
479
0
            return ODataAccessDescriptor(aDescriptorProps);
480
0
        }
481
482
0
        OSL_FAIL( "OColumnTransferable::extractColumnDescriptor: unsupported formats only!" );
483
0
        return ODataAccessDescriptor();
484
0
    }
485
486
487
    void ODataAccessObjectTransferable::addCompatibleSelectionDescription( const Sequence< Any >& _rSelRows )
488
0
    {
489
0
        const sal_Unicode       cSeparator(11);
490
0
        const OUString   sSeparator(&cSeparator, 1);
491
492
0
        for ( const Any& rSelRow : _rSelRows )
493
0
        {
494
0
            sal_Int32 nSelectedRow( 0 );
495
0
            OSL_VERIFY( rSelRow >>= nSelectedRow );
496
497
0
            m_sCompatibleObjectDescription += OUString::number(nSelectedRow);
498
0
            m_sCompatibleObjectDescription += sSeparator;
499
0
        }
500
0
    }
501
502
503
    void ODataAccessObjectTransferable::ObjectReleased()
504
0
    {
505
0
        m_aDescriptor.clear();
506
0
    }
507
508
    void ODataAccessObjectTransferable::construct(  const OUString&  _rDatasource
509
                                                    ,const OUString& _rConnectionResource
510
                                                    ,const sal_Int32        _nCommandType
511
                                                    ,const OUString& _rCommand
512
                                                    ,const Reference< XConnection >& _rxConnection
513
                                                    ,bool _bAddCommand
514
                                                    ,const OUString& _sActiveCommand)
515
0
    {
516
0
        m_aDescriptor.setDataSource(_rDatasource);
517
        // build the descriptor (the property sequence)
518
0
        if ( !_rConnectionResource.isEmpty() )
519
0
            m_aDescriptor[DataAccessDescriptorProperty::ConnectionResource] <<= _rConnectionResource;
520
0
        if ( _rxConnection.is() )
521
0
            m_aDescriptor[DataAccessDescriptorProperty::Connection]     <<= _rxConnection;
522
0
        m_aDescriptor[DataAccessDescriptorProperty::Command]        <<= _rCommand;
523
0
        m_aDescriptor[DataAccessDescriptorProperty::CommandType]    <<= _nCommandType;
524
525
        // extract the single values from the sequence
526
527
0
        OUString sObjectName = _rCommand;
528
529
        // for compatibility: create a string which can be used for the SotClipboardFormatId::SBA_DATAEXCHANGE format
530
531
0
        bool bTreatAsStatement = (CommandType::COMMAND == _nCommandType);
532
            // statements are - in this old and ugly format - described as queries
533
534
0
        const sal_Unicode       cSeparator = u'\x000B';
535
0
        const OUString   sSeparator(&cSeparator, 1);
536
537
0
        const sal_Unicode       cTableMark = '1';
538
0
        const sal_Unicode       cQueryMark = '0';
539
540
        // build the descriptor string
541
0
        m_sCompatibleObjectDescription += _rDatasource;
542
0
        m_sCompatibleObjectDescription += sSeparator;
543
0
        m_sCompatibleObjectDescription += bTreatAsStatement ? OUString() : sObjectName;
544
0
        m_sCompatibleObjectDescription += sSeparator;
545
0
        switch (_nCommandType)
546
0
        {
547
0
            case CommandType::TABLE:
548
0
                m_sCompatibleObjectDescription += OUStringChar(cTableMark);
549
0
                break;
550
0
            case CommandType::QUERY:
551
0
                m_sCompatibleObjectDescription += OUStringChar(cQueryMark);
552
0
                break;
553
0
            case CommandType::COMMAND:
554
0
                m_sCompatibleObjectDescription += OUStringChar(cQueryMark);
555
                // think of it as a query
556
0
                break;
557
0
        }
558
0
        m_sCompatibleObjectDescription += sSeparator;
559
0
        m_sCompatibleObjectDescription += _bAddCommand ? _sActiveCommand : OUString();
560
0
        m_sCompatibleObjectDescription += sSeparator;
561
0
    }
562
563
    OMultiColumnTransferable::OMultiColumnTransferable()
564
0
    {
565
0
    }
566
567
    void OMultiColumnTransferable::setDescriptors(const Sequence< PropertyValue >& rDescriptors)
568
0
    {
569
0
        ClearFormats();
570
0
        m_aDescriptors = rDescriptors;
571
0
    }
572
573
    SotClipboardFormatId OMultiColumnTransferable::getDescriptorFormatId()
574
0
    {
575
0
        static SotClipboardFormatId s_nFormat = static_cast<SotClipboardFormatId>(-1);
576
0
        if (static_cast<SotClipboardFormatId>(-1) == s_nFormat)
577
0
        {
578
0
            s_nFormat = SotExchange::RegisterFormatName(u"application/x-openoffice;windows_formatname=\"dbaccess.MultipleColumnDescriptorTransfer\""_ustr);
579
0
            OSL_ENSURE(static_cast<SotClipboardFormatId>(-1) != s_nFormat, "OColumnTransferable::getDescriptorFormatId: bad exchange id!");
580
0
        }
581
0
        return s_nFormat;
582
0
    }
583
584
    void OMultiColumnTransferable::AddSupportedFormats()
585
0
    {
586
0
        AddFormat(getDescriptorFormatId());
587
0
    }
588
589
    bool OMultiColumnTransferable::GetData( const DataFlavor& _rFlavor, const OUString& /*rDestDoc*/ )
590
0
    {
591
0
        const SotClipboardFormatId nFormatId = SotExchange::GetFormat(_rFlavor);
592
0
        if (nFormatId == getDescriptorFormatId())
593
0
        {
594
0
            return SetAny( Any( m_aDescriptors ) );
595
0
        }
596
597
0
        return false;
598
0
    }
599
600
    bool OMultiColumnTransferable::canExtractDescriptor(const DataFlavorExVector& _rFlavors)
601
0
    {
602
0
        const SotClipboardFormatId nFormatId = getDescriptorFormatId();
603
0
        return std::all_of(_rFlavors.begin(), _rFlavors.end(),
604
0
            [&nFormatId](const DataFlavorEx& rCheck) { return nFormatId == rCheck.mnSotId; });
605
0
    }
606
607
    Sequence< PropertyValue > OMultiColumnTransferable::extractDescriptor(const TransferableDataHelper& _rData)
608
0
    {
609
0
        Sequence< PropertyValue > aList;
610
0
        if (_rData.HasFormat(getDescriptorFormatId()))
611
0
        {
612
            // extract the any from the transferable
613
0
            DataFlavor aFlavor;
614
0
            bool bSuccess =
615
0
                SotExchange::GetFormatDataFlavor(getDescriptorFormatId(), aFlavor);
616
0
            OSL_ENSURE(bSuccess, "OColumnTransferable::extractColumnDescriptor: invalid data format (no flavor)!");
617
618
0
            _rData.GetAny(aFlavor, OUString()) >>= aList;
619
0
        } // if (_rData.HasFormat(getDescriptorFormatId()))
620
0
        return aList;
621
0
    }
622
623
    void OMultiColumnTransferable::ObjectReleased()
624
0
    {
625
0
        m_aDescriptors.realloc(0);
626
0
    }
627
}
628
629
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */