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