1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "dbexchange.hxx"
21 #include "dbtreelistbox.hxx"
22 #include "dbtreemodel.hxx"
23 #include "dbtreeview.hxx"
24 #include "dbu_brw.hrc"
25 #include "dbustrings.hrc"
26 #include "QEnumTypes.hxx"
27 #include "UITools.hxx"
28 #include "unodatbr.hxx"
30 #include <com/sun/star/frame/XStorable.hpp>
31 #include <com/sun/star/sdb/CommandType.hpp>
32 #include <com/sun/star/sdbc/XConnection.hpp>
34 #include <connectivity/dbexception.hxx>
35 #include <connectivity/dbtools.hxx>
36 #include <cppuhelper/exc_hlp.hxx>
37 #include <svx/dataaccessdescriptor.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <osl/diagnose.h>
40 #include "svtools/treelistentry.hxx"
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::sdb
;
49 using namespace ::com::sun::star::sdbc
;
50 using namespace ::com::sun::star::sdbcx
;
51 using namespace ::com::sun::star::beans
;
52 using namespace ::com::sun::star::util
;
53 using namespace ::com::sun::star::frame
;
54 using namespace ::com::sun::star::container
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star::form
;
57 using namespace ::com::sun::star::io
;
58 using namespace ::com::sun::star::i18n
;
59 using namespace ::com::sun::star::task
;
60 using namespace ::com::sun::star::datatransfer
;
61 using namespace ::dbtools
;
62 using namespace ::svx
;
64 TransferableHelper
* SbaTableQueryBrowser::implCopyObject( SvTreeListEntry
* _pApplyTo
, sal_Int32 _nCommandType
, bool _bAllowConnection
)
68 OUString aName
= GetEntryText( _pApplyTo
);
69 OUString aDSName
= getDataSourceAcessor( m_pTreeView
->getListBox().GetRootLevelParent( _pApplyTo
) );
71 ODataClipboard
* pData
= NULL
;
72 SharedConnection xConnection
;
73 if ( CommandType::QUERY
!= _nCommandType
)
75 if ( _bAllowConnection
&& !ensureConnection( _pApplyTo
, xConnection
) )
77 pData
= new ODataClipboard(aDSName
, _nCommandType
, aName
, xConnection
, getNumberFormatter(), getORB());
80 pData
= new ODataClipboard(aDSName
, _nCommandType
, aName
, getNumberFormatter(), getORB());
82 // the ownership goes to ODataClipboards
85 catch(const SQLException
& )
87 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
89 catch( const Exception
& )
91 DBG_UNHANDLED_EXCEPTION();
95 sal_Int8
SbaTableQueryBrowser::queryDrop( const AcceptDropEvent
& _rEvt
, const DataFlavorExVector
& _rFlavors
)
97 // check if we're a table or query container
98 SvTreeListEntry
* pHitEntry
= m_pTreeView
->getListBox().GetEntry( _rEvt
.maPosPixel
);
100 if ( pHitEntry
) // no drop if no entry was hit ....
102 // it must be a container
103 EntryType eEntryType
= getEntryType( pHitEntry
);
104 SharedConnection xConnection
;
105 if ( eEntryType
== etTableContainer
&& ensureConnection( pHitEntry
, xConnection
) && xConnection
.is() )
107 Reference
<XChild
> xChild(xConnection
,UNO_QUERY
);
108 Reference
<XStorable
> xStore
;
109 xStore
= Reference
<XStorable
>( xChild
.is() ? getDataSourceOrModel(xChild
->getParent()) : Reference
<XInterface
>(),UNO_QUERY
);
110 // check for the concrete type
111 if ( xStore
.is() && !xStore
->isReadonly() && ::std::any_of(_rFlavors
.begin(),_rFlavors
.end(),TAppSupportedSotFunctor(E_TABLE
,true)) )
112 return DND_ACTION_COPY
;
116 return DND_ACTION_NONE
;
118 sal_Int8
SbaTableQueryBrowser::executeDrop( const ExecuteDropEvent
& _rEvt
)
120 SvTreeListEntry
* pHitEntry
= m_pTreeView
->getListBox().GetEntry( _rEvt
.maPosPixel
);
121 EntryType eEntryType
= getEntryType( pHitEntry
);
122 if (!isContainer(eEntryType
))
124 OSL_FAIL("SbaTableQueryBrowser::executeDrop: what the hell did queryDrop do?");
125 // queryDrop should not have allowed us to reach this situation ....
126 return DND_ACTION_NONE
;
128 // a TransferableDataHelper for accessing the dropped data
129 TransferableDataHelper
aDroppedData(_rEvt
.maDropEvent
.Transferable
);
131 // reset the data of the previous async drop (if any)
133 Application::RemoveUserEvent(m_nAsyncDrop
);
136 m_aAsyncDrop
.aDroppedData
.clear();
137 m_aAsyncDrop
.nType
= E_TABLE
;
138 m_aAsyncDrop
.nAction
= _rEvt
.mnAction
;
139 m_aAsyncDrop
.bError
= false;
140 m_aAsyncDrop
.bHtml
= false;
141 m_aAsyncDrop
.pDroppedAt
= NULL
;
142 m_aAsyncDrop
.aUrl
.clear();
144 // loop through the available formats and see what we can do ...
145 // first we have to check if it is our own format, if not we have to copy the stream :-(
146 if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData
.GetDataFlavorExVector()) )
148 m_aAsyncDrop
.aDroppedData
= ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData
);
149 m_aAsyncDrop
.pDroppedAt
= pHitEntry
;
151 // asynchron because we some dialogs and we aren't allowed to show them while in D&D
152 m_nAsyncDrop
= Application::PostUserEvent(LINK(this, SbaTableQueryBrowser
, OnAsyncDrop
));
153 return DND_ACTION_COPY
;
157 SharedConnection xDestConnection
;
158 if ( ensureConnection( pHitEntry
, xDestConnection
)
159 && xDestConnection
.is()
160 && m_aTableCopyHelper
.copyTagTable( aDroppedData
, m_aAsyncDrop
, xDestConnection
)
163 m_aAsyncDrop
.pDroppedAt
= pHitEntry
;
165 // asynchron because we some dialogs and we aren't allowed to show them while in D&D
166 m_nAsyncDrop
= Application::PostUserEvent(LINK(this, SbaTableQueryBrowser
, OnAsyncDrop
));
167 return DND_ACTION_COPY
;
171 return DND_ACTION_NONE
;
174 bool SbaTableQueryBrowser::requestDrag( sal_Int8
/*_nAction*/, const Point
& _rPosPixel
)
176 // get the affected list entry
177 // ensure that the entry which the user clicked at is selected
178 SvTreeListEntry
* pHitEntry
= m_pTreeView
->getListBox().GetEntry( _rPosPixel
);
180 // no drag of no entry was hit ....
183 // it must be a query/table
184 EntryType eEntryType
= getEntryType( pHitEntry
);
185 if (!isObject(eEntryType
))
188 TransferableHelper
* pTransfer
= implCopyObject( pHitEntry
, ( etTableOrView
== eEntryType
) ? CommandType::TABLE
: CommandType::QUERY
);
189 Reference
< XTransferable
> xEnsureDelete
= pTransfer
;
192 pTransfer
->StartDrag( &m_pTreeView
->getListBox(), DND_ACTION_COPY
);
194 return NULL
!= pTransfer
;
196 IMPL_LINK_NOARG(SbaTableQueryBrowser
, OnCopyEntry
)
198 SvTreeListEntry
* pSelected
= m_pTreeView
->getListBox().FirstSelected();
199 if( isEntryCopyAllowed( pSelected
) )
200 copyEntry( pSelected
);
203 bool SbaTableQueryBrowser::isEntryCopyAllowed(SvTreeListEntry
* _pEntry
) const
205 EntryType eType
= getEntryType(_pEntry
);
206 return ( eType
== etTableOrView
|| eType
== etQuery
);
208 void SbaTableQueryBrowser::copyEntry(SvTreeListEntry
* _pEntry
)
210 TransferableHelper
* pTransfer
= NULL
;
211 Reference
< XTransferable
> aEnsureDelete
;
212 EntryType eType
= getEntryType(_pEntry
);
213 pTransfer
= implCopyObject( _pEntry
, eType
== etQuery
? CommandType::QUERY
: CommandType::TABLE
);
214 aEnsureDelete
= pTransfer
;
216 pTransfer
->CopyToClipboard(getView());
218 IMPL_LINK_NOARG( SbaTableQueryBrowser
, OnAsyncDrop
)
221 SolarMutexGuard aSolarGuard
;
222 ::osl::MutexGuard
aGuard( getMutex() );
224 if ( m_aAsyncDrop
.nType
== E_TABLE
)
226 SharedConnection xDestConnection
;
227 if ( ensureConnection( m_aAsyncDrop
.pDroppedAt
, xDestConnection
) && xDestConnection
.is() )
229 SvTreeListEntry
* pDataSourceEntry
= m_pTreeView
->getListBox().GetRootLevelParent(m_aAsyncDrop
.pDroppedAt
);
230 m_aTableCopyHelper
.asyncCopyTagTable( m_aAsyncDrop
, getDataSourceAcessor( pDataSourceEntry
), xDestConnection
);
234 m_aAsyncDrop
.aDroppedData
.clear();
238 void SbaTableQueryBrowser::clearTreeModel()
242 // clear the user data of the tree model
243 SvTreeListEntry
* pEntryLoop
= m_pTreeModel
->First();
246 DBTreeListUserData
* pData
= static_cast<DBTreeListUserData
*>(pEntryLoop
->GetUserData());
249 pEntryLoop
->SetUserData(NULL
);
250 Reference
< XContainer
> xContainer(pData
->xContainer
, UNO_QUERY
);
252 xContainer
->removeContainerListener(this);
254 if ( pData
->xConnection
.is() )
256 OSL_ENSURE( impl_isDataSourceEntry( pEntryLoop
), "SbaTableQueryBrowser::clearTreeModel: no data source entry, but a connection?" );
257 // connections are to be stored *only* at the data source entries
258 impl_releaseConnection( pData
->xConnection
);
263 pEntryLoop
= m_pTreeModel
->Next(pEntryLoop
);
266 m_pCurrentlyDisplayed
= NULL
;
270 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */