1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dbaccess.hxx" 30 31 #include "dbexchange.hxx" 32 #include <sot/formats.hxx> 33 #include <sot/storage.hxx> 34 #include <osl/diagnose.h> 35 #include <com/sun/star/sdb/CommandType.hpp> 36 #include <com/sun/star/sdb/XResultSetAccess.hpp> 37 #include "TokenWriter.hxx" 38 #include "dbustrings.hrc" 39 #include <comphelper/uno3.hxx> 40 #include <svx/dataaccessdescriptor.hxx> 41 #include "UITools.hxx" 42 43 44 namespace dbaui 45 { 46 using namespace ::com::sun::star::uno; 47 using namespace ::com::sun::star::beans; 48 using namespace ::com::sun::star::sdb; 49 using namespace ::com::sun::star::beans; 50 using namespace ::com::sun::star::lang; 51 using namespace ::com::sun::star::util; 52 using namespace ::com::sun::star::sdbc; 53 using namespace ::com::sun::star::datatransfer; 54 using namespace ::svx; 55 56 namespace 57 { 58 template<class T > void lcl_setListener(const Reference<T>& _xComponent, const Reference< XEventListener >& i_rListener, const bool i_bAdd ) 59 { 60 if ( !_xComponent.is() ) 61 return; 62 63 Reference< XComponent> xCom( _xComponent, UNO_QUERY ); 64 OSL_ENSURE( xCom.is(), "lcl_setListener: no component!" ); 65 if ( !xCom.is() ) 66 return; 67 68 i_bAdd ? xCom->addEventListener( i_rListener ) : xCom->removeEventListener( i_rListener ); 69 } 70 } 71 72 // ----------------------------------------------------------------------------- 73 ODataClipboard::ODataClipboard( 74 const ::rtl::OUString& _rDatasource, 75 const sal_Int32 _nCommandType, 76 const ::rtl::OUString& _rCommand, 77 const Reference< XConnection >& _rxConnection, 78 const Reference< XNumberFormatter >& _rxFormatter, 79 const Reference< XMultiServiceFactory >& _rxORB) 80 :ODataAccessObjectTransferable( _rDatasource,::rtl::OUString(), _nCommandType, _rCommand, _rxConnection ) 81 ,m_pHtml(NULL) 82 ,m_pRtf(NULL) 83 { 84 osl_incrementInterlockedCount( &m_refCount ); 85 lcl_setListener( _rxConnection, this, true ); 86 87 m_pHtml.set( new OHTMLImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); 88 m_pRtf.set( new ORTFImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); 89 90 osl_decrementInterlockedCount( &m_refCount ); 91 } 92 93 // ----------------------------------------------------------------------------- 94 ODataClipboard::ODataClipboard( 95 const ::rtl::OUString& _rDatasource, 96 const sal_Int32 _nCommandType, 97 const ::rtl::OUString& _rCommand, 98 const Reference< XNumberFormatter >& _rxFormatter, 99 const Reference< XMultiServiceFactory >& _rxORB) 100 :ODataAccessObjectTransferable( _rDatasource, ::rtl::OUString(),_nCommandType, _rCommand) 101 ,m_pHtml(NULL) 102 ,m_pRtf(NULL) 103 { 104 m_pHtml.set( new OHTMLImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); 105 m_pRtf.set( new ORTFImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); 106 } 107 108 // ----------------------------------------------------------------------------- 109 ODataClipboard::ODataClipboard( const Reference< XPropertySet >& i_rAliveForm, 110 const Sequence< Any >& i_rSelectedRows, 111 const sal_Bool i_bBookmarkSelection, 112 const Reference< XMultiServiceFactory >& i_rORB ) 113 :ODataAccessObjectTransferable( i_rAliveForm ) 114 ,m_pHtml(NULL) 115 ,m_pRtf(NULL) 116 { 117 OSL_PRECOND( i_rORB.is(), "ODataClipboard::ODataClipboard: having no factory is not good ..." ); 118 119 osl_incrementInterlockedCount( &m_refCount ); 120 121 Reference<XConnection> xConnection; 122 getDescriptor()[ daConnection ] >>= xConnection; 123 lcl_setListener( xConnection, this, true ); 124 125 // do not pass the form itself as source result set, since the client might operate on the form, which 126 // might lead to undesired effects. Instead, use a clone. 127 Reference< XResultSet > xResultSetClone; 128 Reference< XResultSetAccess > xResultSetAccess( i_rAliveForm, UNO_QUERY ); 129 if ( xResultSetAccess.is() ) 130 xResultSetClone = xResultSetAccess->createResultSet(); 131 OSL_ENSURE( xResultSetClone.is(), "ODataClipboard::ODataClipboard: could not clone the form's result set" ); 132 lcl_setListener( xResultSetClone, this, true ); 133 134 getDescriptor()[daCursor] <<= xResultSetClone; 135 getDescriptor()[daSelection] <<= i_rSelectedRows; 136 getDescriptor()[daBookmarkSelection]<<= i_bBookmarkSelection; 137 addCompatibleSelectionDescription( i_rSelectedRows ); 138 139 if ( xConnection.is() && i_rORB.is() ) 140 { 141 Reference< XNumberFormatter > xFormatter( getNumberFormatter( xConnection, i_rORB ) ); 142 if ( xFormatter.is() ) 143 { 144 m_pHtml.set( new OHTMLImportExport( getDescriptor(), i_rORB, xFormatter ) ); 145 m_pRtf.set( new ORTFImportExport( getDescriptor(), i_rORB, xFormatter ) ); 146 } 147 } 148 149 osl_decrementInterlockedCount( &m_refCount ); 150 } 151 152 // ----------------------------------------------------------------------------- 153 sal_Bool ODataClipboard::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, const ::com::sun::star::datatransfer::DataFlavor& /*rFlavor*/ ) 154 { 155 if (nUserObjectId == SOT_FORMAT_RTF || nUserObjectId == SOT_FORMATSTR_ID_HTML ) 156 { 157 ODatabaseImportExport* pExport = reinterpret_cast<ODatabaseImportExport*>(pUserObject); 158 if ( pExport && rxOStm.Is() ) 159 { 160 pExport->setStream(&rxOStm); 161 return pExport->Write(); 162 } 163 } 164 return sal_False; 165 } 166 167 // ----------------------------------------------------------------------------- 168 void ODataClipboard::AddSupportedFormats() 169 { 170 if ( m_pRtf.is() ) 171 AddFormat( SOT_FORMAT_RTF ); 172 173 if ( m_pHtml.is() ) 174 AddFormat( SOT_FORMATSTR_ID_HTML ); 175 176 ODataAccessObjectTransferable::AddSupportedFormats(); 177 } 178 179 // ----------------------------------------------------------------------------- 180 sal_Bool ODataClipboard::GetData( const DataFlavor& rFlavor ) 181 { 182 const sal_uLong nFormat = SotExchange::GetFormat(rFlavor); 183 switch (nFormat) 184 { 185 case SOT_FORMAT_RTF: 186 if ( m_pRtf.is() ) 187 m_pRtf->initialize(getDescriptor()); 188 return m_pRtf.is() && SetObject( m_pRtf.get(), SOT_FORMAT_RTF, rFlavor ); 189 190 case SOT_FORMATSTR_ID_HTML: 191 if ( m_pHtml.is() ) 192 m_pHtml->initialize(getDescriptor()); 193 return m_pHtml.is() && SetObject( m_pHtml.get(), SOT_FORMATSTR_ID_HTML, rFlavor ); 194 } 195 196 return ODataAccessObjectTransferable::GetData( rFlavor ); 197 } 198 199 // ----------------------------------------------------------------------------- 200 void ODataClipboard::ObjectReleased() 201 { 202 if ( m_pHtml.is() ) 203 { 204 m_pHtml->dispose(); 205 m_pHtml.clear(); 206 } 207 208 if ( m_pRtf.is() ) 209 { 210 m_pRtf->dispose(); 211 m_pRtf.clear(); 212 } 213 214 if ( getDescriptor().has( daConnection ) ) 215 { 216 Reference<XConnection> xConnection( getDescriptor()[daConnection], UNO_QUERY ); 217 lcl_setListener( xConnection, this, false ); 218 } 219 220 if ( getDescriptor().has( daCursor ) ) 221 { 222 Reference< XResultSet > xResultSet( getDescriptor()[ daCursor ], UNO_QUERY ); 223 lcl_setListener( xResultSet, this, false ); 224 } 225 226 ODataAccessObjectTransferable::ObjectReleased( ); 227 } 228 229 // ----------------------------------------------------------------------------- 230 void SAL_CALL ODataClipboard::disposing( const ::com::sun::star::lang::EventObject& i_rSource ) throw (::com::sun::star::uno::RuntimeException) 231 { 232 ODataAccessDescriptor& rDescriptor( getDescriptor() ); 233 234 if ( rDescriptor.has( daConnection ) ) 235 { 236 Reference< XConnection > xConnection( rDescriptor[daConnection], UNO_QUERY ); 237 if ( xConnection == i_rSource.Source ) 238 { 239 rDescriptor.erase( daConnection ); 240 } 241 } 242 243 if ( rDescriptor.has( daCursor ) ) 244 { 245 Reference< XResultSet > xResultSet( rDescriptor[ daCursor ], UNO_QUERY ); 246 if ( xResultSet == i_rSource.Source ) 247 { 248 rDescriptor.erase( daCursor ); 249 // Selection and BookmarkSelection are meaningless without a result set 250 if ( rDescriptor.has( daSelection ) ) 251 rDescriptor.erase( daSelection ); 252 if ( rDescriptor.has( daBookmarkSelection ) ) 253 rDescriptor.erase( daBookmarkSelection ); 254 } 255 } 256 257 // no matter whether it was the source connection or the source result set which died, 258 // we cannot provide the data anymore. 259 ClearFormats(); 260 } 261 } 262 263 264