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_dbui.hxx" 26 27 #include "dbexchange.hxx" 28 #include <sot/formats.hxx> 29 #include <sot/storage.hxx> 30 #include <osl/diagnose.h> 31 #include <com/sun/star/sdb/CommandType.hpp> 32 #include <com/sun/star/sdb/XResultSetAccess.hpp> 33 #include "TokenWriter.hxx" 34 #include "dbustrings.hrc" 35 #include <comphelper/uno3.hxx> 36 #include <svx/dataaccessdescriptor.hxx> 37 #include "UITools.hxx" 38 39 40 namespace dbaui 41 { 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star::beans; 44 using namespace ::com::sun::star::sdb; 45 using namespace ::com::sun::star::beans; 46 using namespace ::com::sun::star::lang; 47 using namespace ::com::sun::star::util; 48 using namespace ::com::sun::star::sdbc; 49 using namespace ::com::sun::star::datatransfer; 50 using namespace ::svx; 51 52 namespace 53 { lcl_setListener(const Reference<T> & _xComponent,const Reference<XEventListener> & i_rListener,const bool i_bAdd)54 template<class T > void lcl_setListener(const Reference<T>& _xComponent, const Reference< XEventListener >& i_rListener, const bool i_bAdd ) 55 { 56 if ( !_xComponent.is() ) 57 return; 58 59 Reference< XComponent> xCom( _xComponent, UNO_QUERY ); 60 OSL_ENSURE( xCom.is(), "lcl_setListener: no component!" ); 61 if ( !xCom.is() ) 62 return; 63 64 i_bAdd ? xCom->addEventListener( i_rListener ) : xCom->removeEventListener( i_rListener ); 65 } 66 } 67 68 // ----------------------------------------------------------------------------- ODataClipboard(const::rtl::OUString & _rDatasource,const sal_Int32 _nCommandType,const::rtl::OUString & _rCommand,const Reference<XConnection> & _rxConnection,const Reference<XNumberFormatter> & _rxFormatter,const Reference<XMultiServiceFactory> & _rxORB)69 ODataClipboard::ODataClipboard( 70 const ::rtl::OUString& _rDatasource, 71 const sal_Int32 _nCommandType, 72 const ::rtl::OUString& _rCommand, 73 const Reference< XConnection >& _rxConnection, 74 const Reference< XNumberFormatter >& _rxFormatter, 75 const Reference< XMultiServiceFactory >& _rxORB) 76 :ODataAccessObjectTransferable( _rDatasource,::rtl::OUString(), _nCommandType, _rCommand, _rxConnection ) 77 ,m_pHtml(NULL) 78 ,m_pRtf(NULL) 79 { 80 osl_incrementInterlockedCount( &m_refCount ); 81 lcl_setListener( _rxConnection, this, true ); 82 83 m_pHtml.set( new OHTMLImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); 84 m_pRtf.set( new ORTFImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); 85 86 osl_decrementInterlockedCount( &m_refCount ); 87 } 88 89 // ----------------------------------------------------------------------------- ODataClipboard(const::rtl::OUString & _rDatasource,const sal_Int32 _nCommandType,const::rtl::OUString & _rCommand,const Reference<XNumberFormatter> & _rxFormatter,const Reference<XMultiServiceFactory> & _rxORB)90 ODataClipboard::ODataClipboard( 91 const ::rtl::OUString& _rDatasource, 92 const sal_Int32 _nCommandType, 93 const ::rtl::OUString& _rCommand, 94 const Reference< XNumberFormatter >& _rxFormatter, 95 const Reference< XMultiServiceFactory >& _rxORB) 96 :ODataAccessObjectTransferable( _rDatasource, ::rtl::OUString(),_nCommandType, _rCommand) 97 ,m_pHtml(NULL) 98 ,m_pRtf(NULL) 99 { 100 m_pHtml.set( new OHTMLImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); 101 m_pRtf.set( new ORTFImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); 102 } 103 104 // ----------------------------------------------------------------------------- ODataClipboard(const Reference<XPropertySet> & i_rAliveForm,const Sequence<Any> & i_rSelectedRows,const sal_Bool i_bBookmarkSelection,const Reference<XMultiServiceFactory> & i_rORB)105 ODataClipboard::ODataClipboard( const Reference< XPropertySet >& i_rAliveForm, 106 const Sequence< Any >& i_rSelectedRows, 107 const sal_Bool i_bBookmarkSelection, 108 const Reference< XMultiServiceFactory >& i_rORB ) 109 :ODataAccessObjectTransferable( i_rAliveForm ) 110 ,m_pHtml(NULL) 111 ,m_pRtf(NULL) 112 { 113 OSL_PRECOND( i_rORB.is(), "ODataClipboard::ODataClipboard: having no factory is not good ..." ); 114 115 osl_incrementInterlockedCount( &m_refCount ); 116 117 Reference<XConnection> xConnection; 118 getDescriptor()[ daConnection ] >>= xConnection; 119 lcl_setListener( xConnection, this, true ); 120 121 // do not pass the form itself as source result set, since the client might operate on the form, which 122 // might lead to undesired effects. Instead, use a clone. 123 Reference< XResultSet > xResultSetClone; 124 Reference< XResultSetAccess > xResultSetAccess( i_rAliveForm, UNO_QUERY ); 125 if ( xResultSetAccess.is() ) 126 xResultSetClone = xResultSetAccess->createResultSet(); 127 OSL_ENSURE( xResultSetClone.is(), "ODataClipboard::ODataClipboard: could not clone the form's result set" ); 128 lcl_setListener( xResultSetClone, this, true ); 129 130 getDescriptor()[daCursor] <<= xResultSetClone; 131 getDescriptor()[daSelection] <<= i_rSelectedRows; 132 getDescriptor()[daBookmarkSelection]<<= i_bBookmarkSelection; 133 addCompatibleSelectionDescription( i_rSelectedRows ); 134 135 if ( xConnection.is() && i_rORB.is() ) 136 { 137 Reference< XNumberFormatter > xFormatter( getNumberFormatter( xConnection, i_rORB ) ); 138 if ( xFormatter.is() ) 139 { 140 m_pHtml.set( new OHTMLImportExport( getDescriptor(), i_rORB, xFormatter ) ); 141 m_pRtf.set( new ORTFImportExport( getDescriptor(), i_rORB, xFormatter ) ); 142 } 143 } 144 145 osl_decrementInterlockedCount( &m_refCount ); 146 } 147 148 // ----------------------------------------------------------------------------- WriteObject(SotStorageStreamRef & rxOStm,void * pUserObject,sal_uInt32 nUserObjectId,const::com::sun::star::datatransfer::DataFlavor &)149 sal_Bool ODataClipboard::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, const ::com::sun::star::datatransfer::DataFlavor& /*rFlavor*/ ) 150 { 151 if (nUserObjectId == SOT_FORMAT_RTF || nUserObjectId == SOT_FORMATSTR_ID_HTML ) 152 { 153 ODatabaseImportExport* pExport = reinterpret_cast<ODatabaseImportExport*>(pUserObject); 154 if ( pExport && rxOStm.Is() ) 155 { 156 pExport->setStream(&rxOStm); 157 return pExport->Write(); 158 } 159 } 160 return sal_False; 161 } 162 163 // ----------------------------------------------------------------------------- AddSupportedFormats()164 void ODataClipboard::AddSupportedFormats() 165 { 166 if ( m_pRtf.is() ) 167 AddFormat( SOT_FORMAT_RTF ); 168 169 if ( m_pHtml.is() ) 170 AddFormat( SOT_FORMATSTR_ID_HTML ); 171 172 ODataAccessObjectTransferable::AddSupportedFormats(); 173 } 174 175 // ----------------------------------------------------------------------------- GetData(const DataFlavor & rFlavor)176 sal_Bool ODataClipboard::GetData( const DataFlavor& rFlavor ) 177 { 178 const sal_uLong nFormat = SotExchange::GetFormat(rFlavor); 179 switch (nFormat) 180 { 181 case SOT_FORMAT_RTF: 182 if ( m_pRtf.is() ) 183 m_pRtf->initialize(getDescriptor()); 184 return m_pRtf.is() && SetObject( m_pRtf.get(), SOT_FORMAT_RTF, rFlavor ); 185 186 case SOT_FORMATSTR_ID_HTML: 187 if ( m_pHtml.is() ) 188 m_pHtml->initialize(getDescriptor()); 189 return m_pHtml.is() && SetObject( m_pHtml.get(), SOT_FORMATSTR_ID_HTML, rFlavor ); 190 } 191 192 return ODataAccessObjectTransferable::GetData( rFlavor ); 193 } 194 195 // ----------------------------------------------------------------------------- ObjectReleased()196 void ODataClipboard::ObjectReleased() 197 { 198 if ( m_pHtml.is() ) 199 { 200 m_pHtml->dispose(); 201 m_pHtml.clear(); 202 } 203 204 if ( m_pRtf.is() ) 205 { 206 m_pRtf->dispose(); 207 m_pRtf.clear(); 208 } 209 210 if ( getDescriptor().has( daConnection ) ) 211 { 212 Reference<XConnection> xConnection( getDescriptor()[daConnection], UNO_QUERY ); 213 lcl_setListener( xConnection, this, false ); 214 } 215 216 if ( getDescriptor().has( daCursor ) ) 217 { 218 Reference< XResultSet > xResultSet( getDescriptor()[ daCursor ], UNO_QUERY ); 219 lcl_setListener( xResultSet, this, false ); 220 } 221 222 ODataAccessObjectTransferable::ObjectReleased( ); 223 } 224 225 // ----------------------------------------------------------------------------- disposing(const::com::sun::star::lang::EventObject & i_rSource)226 void SAL_CALL ODataClipboard::disposing( const ::com::sun::star::lang::EventObject& i_rSource ) throw (::com::sun::star::uno::RuntimeException) 227 { 228 ODataAccessDescriptor& rDescriptor( getDescriptor() ); 229 230 if ( rDescriptor.has( daConnection ) ) 231 { 232 Reference< XConnection > xConnection( rDescriptor[daConnection], UNO_QUERY ); 233 if ( xConnection == i_rSource.Source ) 234 { 235 rDescriptor.erase( daConnection ); 236 } 237 } 238 239 if ( rDescriptor.has( daCursor ) ) 240 { 241 Reference< XResultSet > xResultSet( rDescriptor[ daCursor ], UNO_QUERY ); 242 if ( xResultSet == i_rSource.Source ) 243 { 244 rDescriptor.erase( daCursor ); 245 // Selection and BookmarkSelection are meaningless without a result set 246 if ( rDescriptor.has( daSelection ) ) 247 rDescriptor.erase( daSelection ); 248 if ( rDescriptor.has( daBookmarkSelection ) ) 249 rDescriptor.erase( daBookmarkSelection ); 250 } 251 } 252 253 // no matter whether it was the source connection or the source result set which died, 254 // we cannot provide the data anymore. 255 ClearFormats(); 256 } 257 } 258 259 260