1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <dbexchange.hxx>
21 #include <sot/formats.hxx>
22 #include <sot/storage.hxx>
23 #include <osl/diagnose.h>
24 #include <com/sun/star/sdb/CommandType.hpp>
25 #include <com/sun/star/sdb/XResultSetAccess.hpp>
26 #include <com/sun/star/lang/XComponent.hpp>
27 #include <TokenWriter.hxx>
28 #include <svx/dataaccessdescriptor.hxx>
29 #include <UITools.hxx>
33 constexpr sal_uInt32 FORMAT_OBJECT_ID_RTF
= 1;
34 constexpr sal_uInt32 FORMAT_OBJECT_ID_HTML
= 2;
36 using namespace ::com::sun::star::uno
;
37 using namespace ::com::sun::star::beans
;
38 using namespace ::com::sun::star::sdb
;
39 using namespace ::com::sun::star::lang
;
40 using namespace ::com::sun::star::util
;
41 using namespace ::com::sun::star::sdbc
;
42 using namespace ::com::sun::star::datatransfer
;
43 using namespace ::svx
;
47 template<class T
> void lcl_setListener(const Reference
<T
>& _xComponent
, const Reference
< XEventListener
>& i_rListener
, const bool i_bAdd
)
49 if ( !_xComponent
.is() )
52 Reference
< XComponent
> xCom( _xComponent
, UNO_QUERY
);
53 OSL_ENSURE( xCom
.is(), "lcl_setListener: no component!" );
57 i_bAdd
? xCom
->addEventListener( i_rListener
) : xCom
->removeEventListener( i_rListener
);
61 ODataClipboard::ODataClipboard()
65 void ODataClipboard::Update(
66 const OUString
& rDatasource
,
67 const sal_Int32 nCommandType
,
68 const OUString
& rCommand
,
69 const Reference
< XConnection
>& rxConnection
,
70 const Reference
< XNumberFormatter
>& rxFormatter
,
71 const Reference
< XComponentContext
>& rxORB
)
75 ODataAccessObjectTransferable::Update(rDatasource
, nCommandType
, rCommand
, rxConnection
);
77 lcl_setListener(rxConnection
, this, true);
79 m_pHtml
.set(new OHTMLImportExport(getDescriptor(), rxORB
, rxFormatter
));
80 m_pRtf
.set(new ORTFImportExport(getDescriptor(), rxORB
, rxFormatter
));
82 AddSupportedFormats();
85 void ODataClipboard::Update(
86 const OUString
& rDatasource
,
87 const sal_Int32 nCommandType
,
88 const OUString
& rCommand
,
89 const Reference
< XNumberFormatter
>& rxFormatter
,
90 const Reference
< XComponentContext
>& rxORB
)
94 ODataAccessObjectTransferable::Update(rDatasource
, nCommandType
, rCommand
);
96 m_pHtml
.set(new OHTMLImportExport(getDescriptor(), rxORB
, rxFormatter
));
97 m_pRtf
.set(new ORTFImportExport(getDescriptor(), rxORB
, rxFormatter
));
99 AddSupportedFormats();
102 ODataClipboard::ODataClipboard( const Reference
< XPropertySet
>& i_rAliveForm
,
103 const Sequence
< Any
>& i_rSelectedRows
,
104 const bool i_bBookmarkSelection
,
105 const Reference
< XComponentContext
>& i_rORB
)
106 :ODataAccessObjectTransferable( i_rAliveForm
)
108 OSL_PRECOND( i_rORB
.is(), "ODataClipboard::ODataClipboard: having no factory is not good ..." );
110 osl_atomic_increment( &m_refCount
);
112 Reference
<XConnection
> xConnection
;
113 getDescriptor()[ DataAccessDescriptorProperty::Connection
] >>= xConnection
;
114 lcl_setListener( xConnection
, this, true );
116 // do not pass the form itself as source result set, since the client might operate on the form, which
117 // might lead to undesired effects. Instead, use a clone.
118 Reference
< XResultSet
> xResultSetClone
;
119 Reference
< XResultSetAccess
> xResultSetAccess( i_rAliveForm
, UNO_QUERY
);
120 if ( xResultSetAccess
.is() )
121 xResultSetClone
= xResultSetAccess
->createResultSet();
122 OSL_ENSURE( xResultSetClone
.is(), "ODataClipboard::ODataClipboard: could not clone the form's result set" );
123 lcl_setListener( xResultSetClone
, this, true );
125 getDescriptor()[DataAccessDescriptorProperty::Cursor
] <<= xResultSetClone
;
126 getDescriptor()[DataAccessDescriptorProperty::Selection
] <<= i_rSelectedRows
;
127 getDescriptor()[DataAccessDescriptorProperty::BookmarkSelection
]<<= i_bBookmarkSelection
;
128 addCompatibleSelectionDescription( i_rSelectedRows
);
130 if ( xConnection
.is() && i_rORB
.is() )
132 Reference
< XNumberFormatter
> xFormatter( getNumberFormatter( xConnection
, i_rORB
) );
133 if ( xFormatter
.is() )
135 m_pHtml
.set( new OHTMLImportExport( getDescriptor(), i_rORB
, xFormatter
) );
136 m_pRtf
.set( new ORTFImportExport( getDescriptor(), i_rORB
, xFormatter
) );
140 osl_atomic_decrement( &m_refCount
);
143 bool ODataClipboard::WriteObject( SvStream
& rOStm
, void* pUserObject
, sal_uInt32 nUserObjectId
, const css::datatransfer::DataFlavor
& /*rFlavor*/ )
145 if (nUserObjectId
== FORMAT_OBJECT_ID_RTF
|| nUserObjectId
== FORMAT_OBJECT_ID_HTML
)
147 ODatabaseImportExport
* pExport
= static_cast<ODatabaseImportExport
*>(pUserObject
);
150 pExport
->setStream(&rOStm
);
151 return pExport
->Write();
157 void ODataClipboard::AddSupportedFormats()
160 AddFormat( SotClipboardFormatId::RTF
);
163 AddFormat( SotClipboardFormatId::HTML
);
165 ODataAccessObjectTransferable::AddSupportedFormats();
168 bool ODataClipboard::GetData( const DataFlavor
& rFlavor
, const OUString
& rDestDoc
)
170 const SotClipboardFormatId nFormat
= SotExchange::GetFormat(rFlavor
);
173 case SotClipboardFormatId::RTF
:
175 m_pRtf
->initialize(getDescriptor());
176 return m_pRtf
.is() && SetObject( m_pRtf
.get(), FORMAT_OBJECT_ID_RTF
, rFlavor
);
178 case SotClipboardFormatId::HTML
:
180 m_pHtml
->initialize(getDescriptor());
181 return m_pHtml
.is() && SetObject( m_pHtml
.get(), FORMAT_OBJECT_ID_HTML
, rFlavor
);
186 return ODataAccessObjectTransferable::GetData(rFlavor
, rDestDoc
);
189 void ODataClipboard::ObjectReleased()
203 if ( getDescriptor().has( DataAccessDescriptorProperty::Connection
) )
205 Reference
<XConnection
> xConnection( getDescriptor()[DataAccessDescriptorProperty::Connection
], UNO_QUERY
);
206 lcl_setListener( xConnection
, this, false );
209 if ( getDescriptor().has( DataAccessDescriptorProperty::Cursor
) )
211 Reference
< XResultSet
> xResultSet( getDescriptor()[ DataAccessDescriptorProperty::Cursor
], UNO_QUERY
);
212 lcl_setListener( xResultSet
, this, false );
215 ODataAccessObjectTransferable::ObjectReleased( );
218 void SAL_CALL
ODataClipboard::disposing( const css::lang::EventObject
& i_rSource
)
220 ODataAccessDescriptor
& rDescriptor( getDescriptor() );
222 if ( rDescriptor
.has( DataAccessDescriptorProperty::Connection
) )
224 Reference
< XConnection
> xConnection( rDescriptor
[DataAccessDescriptorProperty::Connection
], UNO_QUERY
);
225 if ( xConnection
== i_rSource
.Source
)
227 rDescriptor
.erase( DataAccessDescriptorProperty::Connection
);
231 if ( rDescriptor
.has( DataAccessDescriptorProperty::Cursor
) )
233 Reference
< XResultSet
> xResultSet( rDescriptor
[ DataAccessDescriptorProperty::Cursor
], UNO_QUERY
);
234 if ( xResultSet
== i_rSource
.Source
)
236 rDescriptor
.erase( DataAccessDescriptorProperty::Cursor
);
237 // Selection and BookmarkSelection are meaningless without a result set
238 if ( rDescriptor
.has( DataAccessDescriptorProperty::Selection
) )
239 rDescriptor
.erase( DataAccessDescriptorProperty::Selection
);
240 if ( rDescriptor
.has( DataAccessDescriptorProperty::BookmarkSelection
) )
241 rDescriptor
.erase( DataAccessDescriptorProperty::BookmarkSelection
);
245 // no matter whether it was the source connection or the source result set which died,
246 // we cannot provide the data anymore.
251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */