196de5490SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 396de5490SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 496de5490SAndrew Rist * or more contributor license agreements. See the NOTICE file 596de5490SAndrew Rist * distributed with this work for additional information 696de5490SAndrew Rist * regarding copyright ownership. The ASF licenses this file 796de5490SAndrew Rist * to you under the Apache License, Version 2.0 (the 896de5490SAndrew Rist * "License"); you may not use this file except in compliance 996de5490SAndrew Rist * with the License. You may obtain a copy of the License at 1096de5490SAndrew Rist * 1196de5490SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 1296de5490SAndrew Rist * 1396de5490SAndrew Rist * Unless required by applicable law or agreed to in writing, 1496de5490SAndrew Rist * software distributed under the License is distributed on an 1596de5490SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1696de5490SAndrew Rist * KIND, either express or implied. See the License for the 1796de5490SAndrew Rist * specific language governing permissions and limitations 1896de5490SAndrew Rist * under the License. 1996de5490SAndrew Rist * 2096de5490SAndrew Rist *************************************************************/ 2196de5490SAndrew Rist 2296de5490SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25*b63233d8Sdamjan #include "precompiled_dbui.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "dbexchange.hxx" 28cdf0e10cSrcweir #include "dbtreelistbox.hxx" 29cdf0e10cSrcweir #include "dbtreemodel.hxx" 30cdf0e10cSrcweir #include "dbtreeview.hxx" 31cdf0e10cSrcweir #include "dbu_brw.hrc" 32cdf0e10cSrcweir #include "dbustrings.hrc" 33cdf0e10cSrcweir #include "QEnumTypes.hxx" 34cdf0e10cSrcweir #include "UITools.hxx" 35cdf0e10cSrcweir #include "unodatbr.hxx" 36cdf0e10cSrcweir 37cdf0e10cSrcweir /** === begin UNO includes === **/ 38cdf0e10cSrcweir #include <com/sun/star/frame/XStorable.hpp> 39cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp> 40cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp> 41cdf0e10cSrcweir /** === end UNO includes === **/ 42cdf0e10cSrcweir 43cdf0e10cSrcweir #include <connectivity/dbexception.hxx> 44cdf0e10cSrcweir #include <connectivity/dbtools.hxx> 45cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx> 46cdf0e10cSrcweir #include <svtools/treelist.hxx> 47cdf0e10cSrcweir #include <svx/dataaccessdescriptor.hxx> 48cdf0e10cSrcweir #include <tools/diagnose_ex.h> 49cdf0e10cSrcweir 50cdf0e10cSrcweir #include <functional> 51cdf0e10cSrcweir // ......................................................................... 52cdf0e10cSrcweir namespace dbaui 53cdf0e10cSrcweir { 54cdf0e10cSrcweir // ......................................................................... 55cdf0e10cSrcweir 56cdf0e10cSrcweir using namespace ::com::sun::star::uno; 57cdf0e10cSrcweir using namespace ::com::sun::star::sdb; 58cdf0e10cSrcweir using namespace ::com::sun::star::sdbc; 59cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx; 60cdf0e10cSrcweir using namespace ::com::sun::star::beans; 61cdf0e10cSrcweir using namespace ::com::sun::star::util; 62cdf0e10cSrcweir using namespace ::com::sun::star::frame; 63cdf0e10cSrcweir using namespace ::com::sun::star::container; 64cdf0e10cSrcweir using namespace ::com::sun::star::lang; 65cdf0e10cSrcweir using namespace ::com::sun::star::form; 66cdf0e10cSrcweir using namespace ::com::sun::star::io; 67cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 68cdf0e10cSrcweir using namespace ::com::sun::star::task; 69cdf0e10cSrcweir using namespace ::com::sun::star::datatransfer; 70cdf0e10cSrcweir using namespace ::dbtools; 71cdf0e10cSrcweir using namespace ::svx; 72cdf0e10cSrcweir 73cdf0e10cSrcweir // ----------------------------------------------------------------------------- implCopyObject(SvLBoxEntry * _pApplyTo,sal_Int32 _nCommandType,sal_Bool _bAllowConnection)74cdf0e10cSrcweir TransferableHelper* SbaTableQueryBrowser::implCopyObject( SvLBoxEntry* _pApplyTo, sal_Int32 _nCommandType, sal_Bool _bAllowConnection ) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir try 77cdf0e10cSrcweir { 78cdf0e10cSrcweir ::rtl::OUString aName = GetEntryText( _pApplyTo ); 79cdf0e10cSrcweir ::rtl::OUString aDSName = getDataSourceAcessor( m_pTreeView->getListBox().GetRootLevelParent( _pApplyTo ) ); 80cdf0e10cSrcweir 81cdf0e10cSrcweir ODataClipboard* pData = NULL; 82cdf0e10cSrcweir SharedConnection xConnection; 83cdf0e10cSrcweir if ( CommandType::QUERY != _nCommandType ) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir if ( _bAllowConnection && !ensureConnection( _pApplyTo, xConnection) ) 86cdf0e10cSrcweir return NULL; 87cdf0e10cSrcweir pData = new ODataClipboard(aDSName, _nCommandType, aName, xConnection, getNumberFormatter(), getORB()); 88cdf0e10cSrcweir } 89cdf0e10cSrcweir else 90cdf0e10cSrcweir pData = new ODataClipboard(aDSName, _nCommandType, aName, getNumberFormatter(), getORB()); 91cdf0e10cSrcweir 92cdf0e10cSrcweir // the owner ship goes to ODataClipboards 93cdf0e10cSrcweir return pData; 94cdf0e10cSrcweir } 95cdf0e10cSrcweir catch(const SQLException& ) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir showError( SQLExceptionInfo( ::cppu::getCaughtException() ) ); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir catch( const Exception& ) 100cdf0e10cSrcweir { 101cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 102cdf0e10cSrcweir } 103cdf0e10cSrcweir return NULL; 104cdf0e10cSrcweir } 105cdf0e10cSrcweir // ----------------------------------------------------------------------------- queryDrop(const AcceptDropEvent & _rEvt,const DataFlavorExVector & _rFlavors)106cdf0e10cSrcweir sal_Int8 SbaTableQueryBrowser::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors ) 107cdf0e10cSrcweir { 108cdf0e10cSrcweir // check if we're a table or query container 109cdf0e10cSrcweir SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel ); 110cdf0e10cSrcweir 111cdf0e10cSrcweir if ( pHitEntry ) // no drop if no entry was hit .... 112cdf0e10cSrcweir { 113cdf0e10cSrcweir // it must be a container 114cdf0e10cSrcweir EntryType eEntryType = getEntryType( pHitEntry ); 115cdf0e10cSrcweir SharedConnection xConnection; 116cdf0e10cSrcweir if ( eEntryType == etTableContainer && ensureConnection( pHitEntry, xConnection ) && xConnection.is() ) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir Reference<XChild> xChild(xConnection,UNO_QUERY); 119cdf0e10cSrcweir Reference<XStorable> xStore(xChild.is() ? getDataSourceOrModel(xChild->getParent()) : Reference<XInterface>(),UNO_QUERY); 120cdf0e10cSrcweir // check for the concrete type 121cdf0e10cSrcweir if ( xStore.is() && !xStore->isReadonly() && ::std::find_if(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(E_TABLE,sal_True)) != _rFlavors.end()) 122cdf0e10cSrcweir return DND_ACTION_COPY; 123cdf0e10cSrcweir } 124cdf0e10cSrcweir } 125cdf0e10cSrcweir 126cdf0e10cSrcweir return DND_ACTION_NONE; 127cdf0e10cSrcweir } 128cdf0e10cSrcweir // ----------------------------------------------------------------------------- executeDrop(const ExecuteDropEvent & _rEvt)129cdf0e10cSrcweir sal_Int8 SbaTableQueryBrowser::executeDrop( const ExecuteDropEvent& _rEvt ) 130cdf0e10cSrcweir { 131cdf0e10cSrcweir SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel ); 132cdf0e10cSrcweir EntryType eEntryType = getEntryType( pHitEntry ); 133cdf0e10cSrcweir if (!isContainer(eEntryType)) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir DBG_ERROR("SbaTableQueryBrowser::executeDrop: what the hell did queryDrop do?"); 136cdf0e10cSrcweir // queryDrop shoud not have allowed us to reach this situation .... 137cdf0e10cSrcweir return DND_ACTION_NONE; 138cdf0e10cSrcweir } 139cdf0e10cSrcweir // a TransferableDataHelper for accessing the dropped data 140cdf0e10cSrcweir TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable); 141cdf0e10cSrcweir 142cdf0e10cSrcweir 143cdf0e10cSrcweir // reset the data of the previous async drop (if any) 144cdf0e10cSrcweir if ( m_nAsyncDrop ) 145cdf0e10cSrcweir Application::RemoveUserEvent(m_nAsyncDrop); 146cdf0e10cSrcweir 147cdf0e10cSrcweir 148cdf0e10cSrcweir m_nAsyncDrop = 0; 149cdf0e10cSrcweir m_aAsyncDrop.aDroppedData.clear(); 150cdf0e10cSrcweir m_aAsyncDrop.nType = E_TABLE; 151cdf0e10cSrcweir m_aAsyncDrop.nAction = _rEvt.mnAction; 152cdf0e10cSrcweir m_aAsyncDrop.bError = sal_False; 153cdf0e10cSrcweir m_aAsyncDrop.bHtml = sal_False; 154cdf0e10cSrcweir m_aAsyncDrop.pDroppedAt = NULL; 155cdf0e10cSrcweir m_aAsyncDrop.aUrl = ::rtl::OUString(); 156cdf0e10cSrcweir 157cdf0e10cSrcweir 158cdf0e10cSrcweir // loop through the available formats and see what we can do ... 159cdf0e10cSrcweir // first we have to check if it is our own format, if not we have to copy the stream :-( 160cdf0e10cSrcweir if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) ) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir m_aAsyncDrop.aDroppedData = ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData); 163cdf0e10cSrcweir m_aAsyncDrop.pDroppedAt = pHitEntry; 164cdf0e10cSrcweir 165cdf0e10cSrcweir // asyncron because we some dialogs and we aren't allowed to show them while in D&D 166cdf0e10cSrcweir m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop)); 167cdf0e10cSrcweir return DND_ACTION_COPY; 168cdf0e10cSrcweir } 169cdf0e10cSrcweir else 170cdf0e10cSrcweir { 171cdf0e10cSrcweir SharedConnection xDestConnection; 172cdf0e10cSrcweir if ( ensureConnection( pHitEntry, xDestConnection ) 173cdf0e10cSrcweir && xDestConnection.is() 174cdf0e10cSrcweir && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xDestConnection ) 175cdf0e10cSrcweir ) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir m_aAsyncDrop.pDroppedAt = pHitEntry; 178cdf0e10cSrcweir 179cdf0e10cSrcweir // asyncron because we some dialogs and we aren't allowed to show them while in D&D 180cdf0e10cSrcweir m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop)); 181cdf0e10cSrcweir return DND_ACTION_COPY; 182cdf0e10cSrcweir } 183cdf0e10cSrcweir } 184cdf0e10cSrcweir 185cdf0e10cSrcweir return DND_ACTION_NONE; 186cdf0e10cSrcweir } 187cdf0e10cSrcweir 188cdf0e10cSrcweir // ----------------------------------------------------------------------------- requestDrag(sal_Int8,const Point & _rPosPixel)189cdf0e10cSrcweir sal_Bool SbaTableQueryBrowser::requestDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir // get the affected list entry 192cdf0e10cSrcweir // ensure that the entry which the user clicked at is selected 193cdf0e10cSrcweir SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rPosPixel ); 194cdf0e10cSrcweir if (!pHitEntry) 195cdf0e10cSrcweir // no drag of no entry was hit .... 196cdf0e10cSrcweir return sal_False; 197cdf0e10cSrcweir 198cdf0e10cSrcweir // it must be a query/table 199cdf0e10cSrcweir EntryType eEntryType = getEntryType( pHitEntry ); 200cdf0e10cSrcweir if (!isObject(eEntryType)) 201cdf0e10cSrcweir return DND_ACTION_NONE; 202cdf0e10cSrcweir 203cdf0e10cSrcweir TransferableHelper* pTransfer = implCopyObject( pHitEntry, ( etTableOrView == eEntryType ) ? CommandType::TABLE : CommandType::QUERY); 204cdf0e10cSrcweir Reference< XTransferable> xEnsureDelete = pTransfer; 205cdf0e10cSrcweir 206cdf0e10cSrcweir if (pTransfer) 207cdf0e10cSrcweir pTransfer->StartDrag( &m_pTreeView->getListBox(), DND_ACTION_COPY ); 208cdf0e10cSrcweir 209cdf0e10cSrcweir return NULL != pTransfer; 210cdf0e10cSrcweir } 211cdf0e10cSrcweir // ----------------------------------------------------------------------------- 212cdf0e10cSrcweir IMPL_LINK(SbaTableQueryBrowser, OnCopyEntry, void*, /*NOTINTERESIN*/) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected(); 215cdf0e10cSrcweir if( isEntryCopyAllowed( pSelected ) ) 216cdf0e10cSrcweir copyEntry( pSelected ); 217cdf0e10cSrcweir return 0; 218cdf0e10cSrcweir } 219cdf0e10cSrcweir // ----------------------------------------------------------------------------- isEntryCopyAllowed(SvLBoxEntry * _pEntry) const220cdf0e10cSrcweir sal_Bool SbaTableQueryBrowser::isEntryCopyAllowed(SvLBoxEntry* _pEntry) const 221cdf0e10cSrcweir { 222cdf0e10cSrcweir EntryType eType = getEntryType(_pEntry); 223cdf0e10cSrcweir return ( eType == etTableOrView || eType == etQuery ); 224cdf0e10cSrcweir } 225cdf0e10cSrcweir // ----------------------------------------------------------------------------- copyEntry(SvLBoxEntry * _pEntry)226cdf0e10cSrcweir void SbaTableQueryBrowser::copyEntry(SvLBoxEntry* _pEntry) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir TransferableHelper* pTransfer = NULL; 229cdf0e10cSrcweir Reference< XTransferable> aEnsureDelete; 230cdf0e10cSrcweir EntryType eType = getEntryType(_pEntry); 231cdf0e10cSrcweir pTransfer = implCopyObject( _pEntry, eType == etQuery ? CommandType::QUERY : CommandType::TABLE); 232cdf0e10cSrcweir aEnsureDelete = pTransfer; 233cdf0e10cSrcweir if (pTransfer) 234cdf0e10cSrcweir pTransfer->CopyToClipboard(getView()); 235cdf0e10cSrcweir } 236cdf0e10cSrcweir // ----------------------------------------------------------------------------- 237cdf0e10cSrcweir IMPL_LINK( SbaTableQueryBrowser, OnAsyncDrop, void*, /*NOTINTERESTEDIN*/ ) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir m_nAsyncDrop = 0; 240cdf0e10cSrcweir ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 241cdf0e10cSrcweir ::osl::MutexGuard aGuard( getMutex() ); 242cdf0e10cSrcweir 243cdf0e10cSrcweir if ( m_aAsyncDrop.nType == E_TABLE ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir SharedConnection xDestConnection; 246cdf0e10cSrcweir if ( ensureConnection( m_aAsyncDrop.pDroppedAt, xDestConnection ) && xDestConnection.is() ) 247cdf0e10cSrcweir { 248cdf0e10cSrcweir SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(m_aAsyncDrop.pDroppedAt); 249cdf0e10cSrcweir m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDataSourceAcessor( pDataSourceEntry ), xDestConnection ); 250cdf0e10cSrcweir } 251cdf0e10cSrcweir } 252cdf0e10cSrcweir 253cdf0e10cSrcweir m_aAsyncDrop.aDroppedData.clear(); 254cdf0e10cSrcweir 255cdf0e10cSrcweir return 0L; 256cdf0e10cSrcweir } 257cdf0e10cSrcweir // ----------------------------------------------------------------------------- clearTreeModel()258cdf0e10cSrcweir void SbaTableQueryBrowser::clearTreeModel() 259cdf0e10cSrcweir { 260cdf0e10cSrcweir if (m_pTreeModel) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir // clear the user data of the tree model 263cdf0e10cSrcweir SvLBoxEntry* pEntryLoop = m_pTreeModel->First(); 264cdf0e10cSrcweir while (pEntryLoop) 265cdf0e10cSrcweir { 266cdf0e10cSrcweir DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pEntryLoop->GetUserData()); 267cdf0e10cSrcweir if(pData) 268cdf0e10cSrcweir { 269cdf0e10cSrcweir pEntryLoop->SetUserData(NULL); 270cdf0e10cSrcweir Reference< XContainer > xContainer(pData->xContainer, UNO_QUERY); 271cdf0e10cSrcweir if (xContainer.is()) 272cdf0e10cSrcweir xContainer->removeContainerListener(this); 273cdf0e10cSrcweir 274cdf0e10cSrcweir if ( pData->xConnection.is() ) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir DBG_ASSERT( impl_isDataSourceEntry( pEntryLoop ), "SbaTableQueryBrowser::clearTreeModel: no data source entry, but a connection?" ); 277cdf0e10cSrcweir // connections are to be stored *only* at the data source entries 278cdf0e10cSrcweir impl_releaseConnection( pData->xConnection ); 279cdf0e10cSrcweir } 280cdf0e10cSrcweir 281cdf0e10cSrcweir delete pData; 282cdf0e10cSrcweir } 283cdf0e10cSrcweir pEntryLoop = m_pTreeModel->Next(pEntryLoop); 284cdf0e10cSrcweir } 285cdf0e10cSrcweir } 286cdf0e10cSrcweir m_pCurrentlyDisplayed = NULL; 287cdf0e10cSrcweir } 288cdf0e10cSrcweir // ......................................................................... 289cdf0e10cSrcweir } // namespace dbaui 290cdf0e10cSrcweir // ......................................................................... 291cdf0e10cSrcweir 292