Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : :
21 : : #include "dbexchange.hxx"
22 : : #include "dbtreelistbox.hxx"
23 : : #include "dbtreemodel.hxx"
24 : : #include "dbtreeview.hxx"
25 : : #include "dbu_brw.hrc"
26 : : #include "dbustrings.hrc"
27 : : #include "QEnumTypes.hxx"
28 : : #include "UITools.hxx"
29 : : #include "unodatbr.hxx"
30 : :
31 : : #include <com/sun/star/frame/XStorable.hpp>
32 : : #include <com/sun/star/sdb/CommandType.hpp>
33 : : #include <com/sun/star/sdbc/XConnection.hpp>
34 : :
35 : : #include <connectivity/dbexception.hxx>
36 : : #include <connectivity/dbtools.hxx>
37 : : #include <cppuhelper/exc_hlp.hxx>
38 : : #include <svx/dataaccessdescriptor.hxx>
39 : : #include <tools/diagnose_ex.h>
40 : : #include <osl/diagnose.h>
41 : :
42 : : #include <functional>
43 : : // .........................................................................
44 : : namespace dbaui
45 : : {
46 : : // .........................................................................
47 : :
48 : : using namespace ::com::sun::star::uno;
49 : : using namespace ::com::sun::star::sdb;
50 : : using namespace ::com::sun::star::sdbc;
51 : : using namespace ::com::sun::star::sdbcx;
52 : : using namespace ::com::sun::star::beans;
53 : : using namespace ::com::sun::star::util;
54 : : using namespace ::com::sun::star::frame;
55 : : using namespace ::com::sun::star::container;
56 : : using namespace ::com::sun::star::lang;
57 : : using namespace ::com::sun::star::form;
58 : : using namespace ::com::sun::star::io;
59 : : using namespace ::com::sun::star::i18n;
60 : : using namespace ::com::sun::star::task;
61 : : using namespace ::com::sun::star::datatransfer;
62 : : using namespace ::dbtools;
63 : : using namespace ::svx;
64 : :
65 : : // -----------------------------------------------------------------------------
66 : 0 : TransferableHelper* SbaTableQueryBrowser::implCopyObject( SvLBoxEntry* _pApplyTo, sal_Int32 _nCommandType, sal_Bool _bAllowConnection )
67 : : {
68 : : try
69 : : {
70 [ # # ][ # # ]: 0 : ::rtl::OUString aName = GetEntryText( _pApplyTo );
[ # # ]
71 [ # # ][ # # ]: 0 : ::rtl::OUString aDSName = getDataSourceAcessor( m_pTreeView->getListBox().GetRootLevelParent( _pApplyTo ) );
[ # # ][ # # ]
72 : :
73 : 0 : ODataClipboard* pData = NULL;
74 [ # # ]: 0 : SharedConnection xConnection;
75 [ # # ]: 0 : if ( CommandType::QUERY != _nCommandType )
76 : : {
77 [ # # ][ # # ]: 0 : if ( _bAllowConnection && !ensureConnection( _pApplyTo, xConnection) )
[ # # ][ # # ]
78 : 0 : return NULL;
79 [ # # ][ # # ]: 0 : pData = new ODataClipboard(aDSName, _nCommandType, aName, xConnection, getNumberFormatter(), getORB());
[ # # ]
80 : : }
81 : : else
82 [ # # ][ # # ]: 0 : pData = new ODataClipboard(aDSName, _nCommandType, aName, getNumberFormatter(), getORB());
[ # # ]
83 : :
84 : : // the owner ship goes to ODataClipboards
85 [ # # ]: 0 : return pData;
86 : : }
87 [ # # # ]: 0 : catch(const SQLException& )
88 : : {
89 [ # # # # : 0 : showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
# # # # ]
90 : : }
91 : 0 : catch( const Exception& )
92 : : {
93 : : DBG_UNHANDLED_EXCEPTION();
94 : : }
95 : 0 : return NULL;
96 : : }
97 : : // -----------------------------------------------------------------------------
98 : 0 : sal_Int8 SbaTableQueryBrowser::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors )
99 : : {
100 : : // check if we're a table or query container
101 : 0 : SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel );
102 : :
103 [ # # ]: 0 : if ( pHitEntry ) // no drop if no entry was hit ....
104 : : {
105 : : // it must be a container
106 [ # # ]: 0 : EntryType eEntryType = getEntryType( pHitEntry );
107 [ # # ]: 0 : SharedConnection xConnection;
108 [ # # ][ # # ]: 0 : if ( eEntryType == etTableContainer && ensureConnection( pHitEntry, xConnection ) && xConnection.is() )
[ # # ][ # # ]
[ # # ]
109 : : {
110 [ # # ]: 0 : Reference<XChild> xChild(xConnection,UNO_QUERY);
111 [ # # ][ # # ]: 0 : Reference<XStorable> xStore(xChild.is() ? getDataSourceOrModel(xChild->getParent()) : Reference<XInterface>(),UNO_QUERY);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
112 : : // check for the concrete type
113 [ # # ][ # # ]: 0 : if ( xStore.is() && !xStore->isReadonly() && ::std::find_if(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(E_TABLE,sal_True)) != _rFlavors.end())
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # #
# # # ]
114 [ # # ][ # # ]: 0 : return DND_ACTION_COPY;
115 [ # # ][ # # ]: 0 : }
116 : : }
117 : :
118 : 0 : return DND_ACTION_NONE;
119 : : }
120 : : // -----------------------------------------------------------------------------
121 : 0 : sal_Int8 SbaTableQueryBrowser::executeDrop( const ExecuteDropEvent& _rEvt )
122 : : {
123 [ # # ]: 0 : SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel );
124 [ # # ]: 0 : EntryType eEntryType = getEntryType( pHitEntry );
125 [ # # ]: 0 : if (!isContainer(eEntryType))
126 : : {
127 : : OSL_FAIL("SbaTableQueryBrowser::executeDrop: what the hell did queryDrop do?");
128 : : // queryDrop shoud not have allowed us to reach this situation ....
129 : 0 : return DND_ACTION_NONE;
130 : : }
131 : : // a TransferableDataHelper for accessing the dropped data
132 [ # # ]: 0 : TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable);
133 : :
134 : :
135 : : // reset the data of the previous async drop (if any)
136 [ # # ]: 0 : if ( m_nAsyncDrop )
137 [ # # ]: 0 : Application::RemoveUserEvent(m_nAsyncDrop);
138 : :
139 : :
140 : 0 : m_nAsyncDrop = 0;
141 [ # # ]: 0 : m_aAsyncDrop.aDroppedData.clear();
142 : 0 : m_aAsyncDrop.nType = E_TABLE;
143 : 0 : m_aAsyncDrop.nAction = _rEvt.mnAction;
144 : 0 : m_aAsyncDrop.bError = sal_False;
145 : 0 : m_aAsyncDrop.bHtml = sal_False;
146 : 0 : m_aAsyncDrop.pDroppedAt = NULL;
147 [ # # ]: 0 : m_aAsyncDrop.aUrl = ::rtl::OUString();
148 : :
149 : :
150 : : // loop through the available formats and see what we can do ...
151 : : // first we have to check if it is our own format, if not we have to copy the stream :-(
152 [ # # ][ # # ]: 0 : if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) )
153 : : {
154 [ # # ][ # # ]: 0 : m_aAsyncDrop.aDroppedData = ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData);
[ # # ]
155 : 0 : m_aAsyncDrop.pDroppedAt = pHitEntry;
156 : :
157 : : // asyncron because we some dialogs and we aren't allowed to show them while in D&D
158 [ # # ][ # # ]: 0 : m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop));
159 : 0 : return DND_ACTION_COPY;
160 : : }
161 : : else
162 : : {
163 [ # # ]: 0 : SharedConnection xDestConnection;
164 [ # # ]: 0 : if ( ensureConnection( pHitEntry, xDestConnection )
[ # # # # ]
[ # # ][ # # ]
165 : 0 : && xDestConnection.is()
166 [ # # ]: 0 : && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xDestConnection )
167 : : )
168 : : {
169 : 0 : m_aAsyncDrop.pDroppedAt = pHitEntry;
170 : :
171 : : // asyncron because we some dialogs and we aren't allowed to show them while in D&D
172 [ # # ][ # # ]: 0 : m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop));
173 : 0 : return DND_ACTION_COPY;
174 [ # # ][ # # ]: 0 : }
175 : : }
176 : :
177 [ # # ]: 0 : return DND_ACTION_NONE;
178 : : }
179 : :
180 : : // -----------------------------------------------------------------------------
181 : 0 : sal_Bool SbaTableQueryBrowser::requestDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel )
182 : : {
183 : : // get the affected list entry
184 : : // ensure that the entry which the user clicked at is selected
185 [ # # ]: 0 : SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rPosPixel );
186 [ # # ]: 0 : if (!pHitEntry)
187 : : // no drag of no entry was hit ....
188 : 0 : return sal_False;
189 : :
190 : : // it must be a query/table
191 [ # # ]: 0 : EntryType eEntryType = getEntryType( pHitEntry );
192 [ # # ]: 0 : if (!isObject(eEntryType))
193 : 0 : return DND_ACTION_NONE;
194 : :
195 [ # # ][ # # ]: 0 : TransferableHelper* pTransfer = implCopyObject( pHitEntry, ( etTableOrView == eEntryType ) ? CommandType::TABLE : CommandType::QUERY);
196 [ # # ][ # # ]: 0 : Reference< XTransferable> xEnsureDelete = pTransfer;
197 : :
198 [ # # ]: 0 : if (pTransfer)
199 [ # # ]: 0 : pTransfer->StartDrag( &m_pTreeView->getListBox(), DND_ACTION_COPY );
200 : :
201 : 0 : return NULL != pTransfer;
202 : : }
203 : : // -----------------------------------------------------------------------------
204 : 0 : IMPL_LINK(SbaTableQueryBrowser, OnCopyEntry, void*, /*NOTINTERESIN*/)
205 : : {
206 : 0 : SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected();
207 [ # # ]: 0 : if( isEntryCopyAllowed( pSelected ) )
208 : 0 : copyEntry( pSelected );
209 : 0 : return 0;
210 : : }
211 : : // -----------------------------------------------------------------------------
212 : 0 : sal_Bool SbaTableQueryBrowser::isEntryCopyAllowed(SvLBoxEntry* _pEntry) const
213 : : {
214 : 0 : EntryType eType = getEntryType(_pEntry);
215 [ # # ][ # # ]: 0 : return ( eType == etTableOrView || eType == etQuery );
216 : : }
217 : : // -----------------------------------------------------------------------------
218 : 0 : void SbaTableQueryBrowser::copyEntry(SvLBoxEntry* _pEntry)
219 : : {
220 : 0 : TransferableHelper* pTransfer = NULL;
221 : 0 : Reference< XTransferable> aEnsureDelete;
222 [ # # ]: 0 : EntryType eType = getEntryType(_pEntry);
223 [ # # ][ # # ]: 0 : pTransfer = implCopyObject( _pEntry, eType == etQuery ? CommandType::QUERY : CommandType::TABLE);
224 [ # # ][ # # ]: 0 : aEnsureDelete = pTransfer;
225 [ # # ]: 0 : if (pTransfer)
226 [ # # ]: 0 : pTransfer->CopyToClipboard(getView());
227 : 0 : }
228 : : // -----------------------------------------------------------------------------
229 : 0 : IMPL_LINK( SbaTableQueryBrowser, OnAsyncDrop, void*, /*NOTINTERESTEDIN*/ )
230 : : {
231 : 0 : m_nAsyncDrop = 0;
232 [ # # ]: 0 : SolarMutexGuard aSolarGuard;
233 [ # # ][ # # ]: 0 : ::osl::MutexGuard aGuard( getMutex() );
234 : :
235 [ # # ]: 0 : if ( m_aAsyncDrop.nType == E_TABLE )
236 : : {
237 [ # # ]: 0 : SharedConnection xDestConnection;
238 [ # # ][ # # ]: 0 : if ( ensureConnection( m_aAsyncDrop.pDroppedAt, xDestConnection ) && xDestConnection.is() )
[ # # ][ # # ]
239 : : {
240 [ # # ]: 0 : SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(m_aAsyncDrop.pDroppedAt);
241 [ # # ][ # # ]: 0 : m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDataSourceAcessor( pDataSourceEntry ), xDestConnection );
[ # # ][ # # ]
242 [ # # ]: 0 : }
243 : : }
244 : :
245 [ # # ]: 0 : m_aAsyncDrop.aDroppedData.clear();
246 : :
247 [ # # ][ # # ]: 0 : return 0L;
248 : : }
249 : : // -----------------------------------------------------------------------------
250 : 2 : void SbaTableQueryBrowser::clearTreeModel()
251 : : {
252 [ + - ]: 2 : if (m_pTreeModel)
253 : : {
254 : : // clear the user data of the tree model
255 : 2 : SvLBoxEntry* pEntryLoop = m_pTreeModel->First();
256 [ + + ]: 10 : while (pEntryLoop)
257 : : {
258 : 8 : DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pEntryLoop->GetUserData());
259 [ + - ]: 8 : if(pData)
260 : : {
261 : 8 : pEntryLoop->SetUserData(NULL);
262 [ + - ]: 8 : Reference< XContainer > xContainer(pData->xContainer, UNO_QUERY);
263 [ + + ]: 8 : if (xContainer.is())
264 [ + - ][ + - ]: 2 : xContainer->removeContainerListener(this);
[ + - ]
265 : :
266 [ + + ]: 8 : if ( pData->xConnection.is() )
267 : : {
268 : : OSL_ENSURE( impl_isDataSourceEntry( pEntryLoop ), "SbaTableQueryBrowser::clearTreeModel: no data source entry, but a connection?" );
269 : : // connections are to be stored *only* at the data source entries
270 [ + - ]: 2 : impl_releaseConnection( pData->xConnection );
271 : : }
272 : :
273 [ + - ][ + - ]: 8 : delete pData;
274 : : }
275 : 8 : pEntryLoop = m_pTreeModel->Next(pEntryLoop);
276 : : }
277 : : }
278 : 2 : m_pCurrentlyDisplayed = NULL;
279 : 2 : }
280 : : // .........................................................................
281 : : } // namespace dbaui
282 : : // .........................................................................
283 : :
284 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|