1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_dbaccess.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "dbexchange.hxx"
32*cdf0e10cSrcweir #include "dbtreelistbox.hxx"
33*cdf0e10cSrcweir #include "dbtreemodel.hxx"
34*cdf0e10cSrcweir #include "dbtreeview.hxx"
35*cdf0e10cSrcweir #include "dbu_brw.hrc"
36*cdf0e10cSrcweir #include "dbustrings.hrc"
37*cdf0e10cSrcweir #include "QEnumTypes.hxx"
38*cdf0e10cSrcweir #include "UITools.hxx"
39*cdf0e10cSrcweir #include "unodatbr.hxx"
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir /** === begin UNO includes === **/
42*cdf0e10cSrcweir #include <com/sun/star/frame/XStorable.hpp>
43*cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp>
44*cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp>
45*cdf0e10cSrcweir /** === end UNO includes === **/
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir #include <connectivity/dbexception.hxx>
48*cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
49*cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
50*cdf0e10cSrcweir #include <svtools/treelist.hxx>
51*cdf0e10cSrcweir #include <svx/dataaccessdescriptor.hxx>
52*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir #include <functional>
55*cdf0e10cSrcweir // .........................................................................
56*cdf0e10cSrcweir namespace dbaui
57*cdf0e10cSrcweir {
58*cdf0e10cSrcweir // .........................................................................
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir 	using namespace ::com::sun::star::uno;
61*cdf0e10cSrcweir 	using namespace ::com::sun::star::sdb;
62*cdf0e10cSrcweir 	using namespace ::com::sun::star::sdbc;
63*cdf0e10cSrcweir 	using namespace ::com::sun::star::sdbcx;
64*cdf0e10cSrcweir 	using namespace ::com::sun::star::beans;
65*cdf0e10cSrcweir 	using namespace ::com::sun::star::util;
66*cdf0e10cSrcweir 	using namespace ::com::sun::star::frame;
67*cdf0e10cSrcweir 	using namespace ::com::sun::star::container;
68*cdf0e10cSrcweir 	using namespace ::com::sun::star::lang;
69*cdf0e10cSrcweir 	using namespace ::com::sun::star::form;
70*cdf0e10cSrcweir 	using namespace ::com::sun::star::io;
71*cdf0e10cSrcweir 	using namespace ::com::sun::star::i18n;
72*cdf0e10cSrcweir 	using namespace ::com::sun::star::task;
73*cdf0e10cSrcweir 	using namespace ::com::sun::star::datatransfer;
74*cdf0e10cSrcweir 	using namespace ::dbtools;
75*cdf0e10cSrcweir 	using namespace ::svx;
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
78*cdf0e10cSrcweir 	TransferableHelper* SbaTableQueryBrowser::implCopyObject( SvLBoxEntry* _pApplyTo, sal_Int32 _nCommandType, sal_Bool _bAllowConnection )
79*cdf0e10cSrcweir 	{
80*cdf0e10cSrcweir 		try
81*cdf0e10cSrcweir 		{
82*cdf0e10cSrcweir 			::rtl::OUString aName = GetEntryText( _pApplyTo );
83*cdf0e10cSrcweir 			::rtl::OUString aDSName = getDataSourceAcessor( m_pTreeView->getListBox().GetRootLevelParent( _pApplyTo ) );
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir 			ODataClipboard* pData = NULL;
86*cdf0e10cSrcweir 			SharedConnection xConnection;
87*cdf0e10cSrcweir 			if ( CommandType::QUERY != _nCommandType )
88*cdf0e10cSrcweir 			{
89*cdf0e10cSrcweir 				if ( _bAllowConnection && !ensureConnection( _pApplyTo, xConnection) )
90*cdf0e10cSrcweir 					return NULL;
91*cdf0e10cSrcweir 				pData = new ODataClipboard(aDSName, _nCommandType, aName, xConnection, getNumberFormatter(), getORB());
92*cdf0e10cSrcweir 			}
93*cdf0e10cSrcweir 			else
94*cdf0e10cSrcweir 				pData = new ODataClipboard(aDSName, _nCommandType, aName, getNumberFormatter(), getORB());
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir 			// the owner ship goes to ODataClipboards
97*cdf0e10cSrcweir 			return pData;
98*cdf0e10cSrcweir 		}
99*cdf0e10cSrcweir 		catch(const SQLException& )
100*cdf0e10cSrcweir 		{
101*cdf0e10cSrcweir             showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
102*cdf0e10cSrcweir 		}
103*cdf0e10cSrcweir         catch( const Exception& )
104*cdf0e10cSrcweir         {
105*cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
106*cdf0e10cSrcweir         }
107*cdf0e10cSrcweir 		return NULL;
108*cdf0e10cSrcweir 	}
109*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
110*cdf0e10cSrcweir 	sal_Int8 SbaTableQueryBrowser::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors )
111*cdf0e10cSrcweir 	{
112*cdf0e10cSrcweir         // check if we're a table or query container
113*cdf0e10cSrcweir 		SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel );
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir 		if ( pHitEntry ) // no drop if no entry was hit ....
116*cdf0e10cSrcweir 		{
117*cdf0e10cSrcweir 			// it must be a container
118*cdf0e10cSrcweir 			EntryType eEntryType = getEntryType( pHitEntry );
119*cdf0e10cSrcweir             SharedConnection xConnection;
120*cdf0e10cSrcweir 			if ( eEntryType == etTableContainer && ensureConnection( pHitEntry, xConnection ) && xConnection.is() )
121*cdf0e10cSrcweir 			{
122*cdf0e10cSrcweir                 Reference<XChild> xChild(xConnection,UNO_QUERY);
123*cdf0e10cSrcweir                 Reference<XStorable> xStore(xChild.is() ? getDataSourceOrModel(xChild->getParent()) : Reference<XInterface>(),UNO_QUERY);
124*cdf0e10cSrcweir 				// check for the concrete type
125*cdf0e10cSrcweir 				if ( xStore.is() && !xStore->isReadonly() && ::std::find_if(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(E_TABLE,sal_True)) != _rFlavors.end())
126*cdf0e10cSrcweir 					return DND_ACTION_COPY;
127*cdf0e10cSrcweir 			}
128*cdf0e10cSrcweir 		}
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 		return DND_ACTION_NONE;
131*cdf0e10cSrcweir 	}
132*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
133*cdf0e10cSrcweir 	sal_Int8 SbaTableQueryBrowser::executeDrop( const ExecuteDropEvent& _rEvt )
134*cdf0e10cSrcweir 	{
135*cdf0e10cSrcweir         SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel );
136*cdf0e10cSrcweir 		EntryType eEntryType = getEntryType( pHitEntry );
137*cdf0e10cSrcweir 		if (!isContainer(eEntryType))
138*cdf0e10cSrcweir 		{
139*cdf0e10cSrcweir 			DBG_ERROR("SbaTableQueryBrowser::executeDrop: what the hell did queryDrop do?");
140*cdf0e10cSrcweir 				// queryDrop shoud not have allowed us to reach this situation ....
141*cdf0e10cSrcweir 			return DND_ACTION_NONE;
142*cdf0e10cSrcweir 		}
143*cdf0e10cSrcweir 		// a TransferableDataHelper for accessing the dropped data
144*cdf0e10cSrcweir 	    TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable);
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir 	    // reset the data of the previous async drop (if any)
148*cdf0e10cSrcweir 	    if ( m_nAsyncDrop )
149*cdf0e10cSrcweir 		    Application::RemoveUserEvent(m_nAsyncDrop);
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 	    m_nAsyncDrop = 0;
153*cdf0e10cSrcweir 	    m_aAsyncDrop.aDroppedData.clear();
154*cdf0e10cSrcweir         m_aAsyncDrop.nType			= E_TABLE;
155*cdf0e10cSrcweir 	    m_aAsyncDrop.nAction		= _rEvt.mnAction;
156*cdf0e10cSrcweir 	    m_aAsyncDrop.bError			= sal_False;
157*cdf0e10cSrcweir 	    m_aAsyncDrop.bHtml			= sal_False;
158*cdf0e10cSrcweir         m_aAsyncDrop.pDroppedAt		= NULL;
159*cdf0e10cSrcweir 	    m_aAsyncDrop.aUrl			= ::rtl::OUString();
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 	    // loop through the available formats and see what we can do ...
163*cdf0e10cSrcweir 	    // first we have to check if it is our own format, if not we have to copy the stream :-(
164*cdf0e10cSrcweir 	    if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) )
165*cdf0e10cSrcweir 	    {
166*cdf0e10cSrcweir             m_aAsyncDrop.aDroppedData	= ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData);
167*cdf0e10cSrcweir 			m_aAsyncDrop.pDroppedAt		= pHitEntry;
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir 		    // asyncron because we some dialogs and we aren't allowed to show them while in D&D
170*cdf0e10cSrcweir 		    m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop));
171*cdf0e10cSrcweir 		    return DND_ACTION_COPY;
172*cdf0e10cSrcweir 	    }
173*cdf0e10cSrcweir 	    else
174*cdf0e10cSrcweir 	    {
175*cdf0e10cSrcweir             SharedConnection xDestConnection;
176*cdf0e10cSrcweir 		    if (  ensureConnection( pHitEntry, xDestConnection )
177*cdf0e10cSrcweir                && xDestConnection.is()
178*cdf0e10cSrcweir                && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xDestConnection )
179*cdf0e10cSrcweir                )
180*cdf0e10cSrcweir             {
181*cdf0e10cSrcweir                 m_aAsyncDrop.pDroppedAt	= pHitEntry;
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir 			    // asyncron because we some dialogs and we aren't allowed to show them while in D&D
184*cdf0e10cSrcweir 			    m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop));
185*cdf0e10cSrcweir 			    return DND_ACTION_COPY;
186*cdf0e10cSrcweir 		    }
187*cdf0e10cSrcweir 	    }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 	    return DND_ACTION_NONE;
190*cdf0e10cSrcweir 	}
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
193*cdf0e10cSrcweir 	sal_Bool SbaTableQueryBrowser::requestDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel )
194*cdf0e10cSrcweir 	{
195*cdf0e10cSrcweir 		// get the affected list entry
196*cdf0e10cSrcweir 		// ensure that the entry which the user clicked at is selected
197*cdf0e10cSrcweir 		SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rPosPixel );
198*cdf0e10cSrcweir 		if (!pHitEntry)
199*cdf0e10cSrcweir 			// no drag of no entry was hit ....
200*cdf0e10cSrcweir 			return sal_False;
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 		// it must be a query/table
203*cdf0e10cSrcweir 		EntryType eEntryType = getEntryType( pHitEntry );
204*cdf0e10cSrcweir 		if (!isObject(eEntryType))
205*cdf0e10cSrcweir 			return DND_ACTION_NONE;
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 		TransferableHelper* pTransfer = implCopyObject( pHitEntry, ( etTableOrView == eEntryType ) ? CommandType::TABLE : CommandType::QUERY);
208*cdf0e10cSrcweir 		Reference< XTransferable> xEnsureDelete = pTransfer;
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir 		if (pTransfer)
211*cdf0e10cSrcweir 			pTransfer->StartDrag( &m_pTreeView->getListBox(), DND_ACTION_COPY );
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir 		return NULL != pTransfer;
214*cdf0e10cSrcweir 	}
215*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
216*cdf0e10cSrcweir 	IMPL_LINK(SbaTableQueryBrowser, OnCopyEntry, void*, /*NOTINTERESIN*/)
217*cdf0e10cSrcweir 	{
218*cdf0e10cSrcweir         SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
219*cdf0e10cSrcweir 		if( isEntryCopyAllowed( pSelected ) )
220*cdf0e10cSrcweir 			copyEntry( pSelected );
221*cdf0e10cSrcweir 		return 0;
222*cdf0e10cSrcweir 	}
223*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
224*cdf0e10cSrcweir 	sal_Bool SbaTableQueryBrowser::isEntryCopyAllowed(SvLBoxEntry* _pEntry) const
225*cdf0e10cSrcweir 	{
226*cdf0e10cSrcweir 		EntryType eType = getEntryType(_pEntry);
227*cdf0e10cSrcweir 		return  ( eType == etTableOrView || eType == etQuery );
228*cdf0e10cSrcweir 	}
229*cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
230*cdf0e10cSrcweir 	void SbaTableQueryBrowser::copyEntry(SvLBoxEntry* _pEntry)
231*cdf0e10cSrcweir 	{
232*cdf0e10cSrcweir 		TransferableHelper* pTransfer = NULL;
233*cdf0e10cSrcweir 		Reference< XTransferable> aEnsureDelete;
234*cdf0e10cSrcweir 		EntryType eType = getEntryType(_pEntry);
235*cdf0e10cSrcweir 		pTransfer		= implCopyObject( _pEntry, eType == etQuery ? CommandType::QUERY : CommandType::TABLE);
236*cdf0e10cSrcweir 		aEnsureDelete	= pTransfer;
237*cdf0e10cSrcweir 		if (pTransfer)
238*cdf0e10cSrcweir 			pTransfer->CopyToClipboard(getView());
239*cdf0e10cSrcweir 	}
240*cdf0e10cSrcweir     // -----------------------------------------------------------------------------
241*cdf0e10cSrcweir     IMPL_LINK( SbaTableQueryBrowser, OnAsyncDrop, void*, /*NOTINTERESTEDIN*/ )
242*cdf0e10cSrcweir     {
243*cdf0e10cSrcweir 	    m_nAsyncDrop = 0;
244*cdf0e10cSrcweir 	    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
245*cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( getMutex() );
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir 	    if ( m_aAsyncDrop.nType == E_TABLE )
248*cdf0e10cSrcweir 	    {
249*cdf0e10cSrcweir             SharedConnection xDestConnection;
250*cdf0e10cSrcweir 		    if ( ensureConnection( m_aAsyncDrop.pDroppedAt, xDestConnection ) && xDestConnection.is() )
251*cdf0e10cSrcweir             {
252*cdf0e10cSrcweir                 SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(m_aAsyncDrop.pDroppedAt);
253*cdf0e10cSrcweir 		        m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDataSourceAcessor( pDataSourceEntry ), xDestConnection );
254*cdf0e10cSrcweir             }
255*cdf0e10cSrcweir 	    }
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir 	    m_aAsyncDrop.aDroppedData.clear();
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir 	    return 0L;
260*cdf0e10cSrcweir     }
261*cdf0e10cSrcweir     // -----------------------------------------------------------------------------
262*cdf0e10cSrcweir 	void SbaTableQueryBrowser::clearTreeModel()
263*cdf0e10cSrcweir 	{
264*cdf0e10cSrcweir 		if (m_pTreeModel)
265*cdf0e10cSrcweir 		{
266*cdf0e10cSrcweir 			// clear the user data of the tree model
267*cdf0e10cSrcweir 			SvLBoxEntry* pEntryLoop = m_pTreeModel->First();
268*cdf0e10cSrcweir 			while (pEntryLoop)
269*cdf0e10cSrcweir 			{
270*cdf0e10cSrcweir 				DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pEntryLoop->GetUserData());
271*cdf0e10cSrcweir 				if(pData)
272*cdf0e10cSrcweir 				{
273*cdf0e10cSrcweir 					pEntryLoop->SetUserData(NULL);
274*cdf0e10cSrcweir 					Reference< XContainer > xContainer(pData->xContainer, UNO_QUERY);
275*cdf0e10cSrcweir 					if (xContainer.is())
276*cdf0e10cSrcweir 						xContainer->removeContainerListener(this);
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 					if ( pData->xConnection.is() )
279*cdf0e10cSrcweir 					{
280*cdf0e10cSrcweir                         DBG_ASSERT( impl_isDataSourceEntry( pEntryLoop ), "SbaTableQueryBrowser::clearTreeModel: no data source entry, but a connection?" );
281*cdf0e10cSrcweir                         // connections are to be stored *only* at the data source entries
282*cdf0e10cSrcweir                         impl_releaseConnection( pData->xConnection );
283*cdf0e10cSrcweir 					}
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 					delete pData;
286*cdf0e10cSrcweir 				}
287*cdf0e10cSrcweir 				pEntryLoop = m_pTreeModel->Next(pEntryLoop);
288*cdf0e10cSrcweir 			}
289*cdf0e10cSrcweir 		}
290*cdf0e10cSrcweir 		m_pCurrentlyDisplayed = NULL;
291*cdf0e10cSrcweir 	}
292*cdf0e10cSrcweir // .........................................................................
293*cdf0e10cSrcweir }	// namespace dbaui
294*cdf0e10cSrcweir // .........................................................................
295*cdf0e10cSrcweir 
296