Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / app / AppControllerDnD.cxx
blobf2943256c0a165d5ed6d20b5472ff3b4f1926737
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "AppController.hxx"
21 #include <comphelper/sequence.hxx>
22 #include <comphelper/property.hxx>
23 #include <comphelper/processfactory.hxx>
24 #include "dbustrings.hrc"
25 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
26 #include <com/sun/star/sdbcx/XAppend.hpp>
27 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
28 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
29 #include <com/sun/star/container/XNameContainer.hpp>
30 #include <com/sun/star/uno/XNamingService.hpp>
31 #include <com/sun/star/sdbc/XDataSource.hpp>
32 #include <com/sun/star/frame/XStorable.hpp>
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
35 #include <com/sun/star/sdbc/DataType.hpp>
36 #include <com/sun/star/sdb/CommandType.hpp>
37 #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
38 #include <com/sun/star/sdb/SQLContext.hpp>
39 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
40 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
41 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
42 #include <com/sun/star/sdbcx/XDrop.hpp>
43 #include <unotools/ucbhelper.hxx>
44 #include "dlgsave.hxx"
45 #include <comphelper/types.hxx>
46 #include <vcl/layout.hxx>
47 #include <cppuhelper/typeprovider.hxx>
48 #include <cppuhelper/exc_hlp.hxx>
49 #include <connectivity/dbexception.hxx>
50 #include <vcl/waitobj.hxx>
51 #include <rtl/ustrbuf.hxx>
52 #include "AppView.hxx"
53 #include <svx/dataaccessdescriptor.hxx>
54 #include <svx/dbaobjectex.hxx>
55 #include "browserids.hxx"
56 #include "dbu_reghelper.hxx"
57 #include "dbu_app.hrc"
58 #include <vcl/menu.hxx>
59 #include <comphelper/uno3.hxx>
60 #include <vcl/svapp.hxx>
61 #include <svtools/svlbitm.hxx>
62 #include "listviewitems.hxx"
63 #include "AppDetailView.hxx"
64 #include "linkeddocuments.hxx"
65 #include <vcl/lstbox.hxx>
66 #include <connectivity/dbtools.hxx>
67 #include "sqlmessage.hxx"
68 #include "dbexchange.hxx"
69 #include "UITools.hxx"
70 #include <algorithm>
71 #include <svtools/treelistbox.hxx>
72 #include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
73 #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
74 #include <unotools/pathoptions.hxx>
75 #include <sfx2/docfilt.hxx>
76 #include <svtools/fileview.hxx>
77 #include <tools/diagnose_ex.h>
78 #include <osl/diagnose.h>
79 #include "defaultobjectnamecheck.hxx"
80 #include <osl/mutex.hxx>
81 #include "subcomponentmanager.hxx"
83 namespace dbaui
85 using namespace ::dbtools;
86 using namespace ::svx;
87 using namespace ::svtools;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::task;
90 using namespace ::com::sun::star::beans;
91 using namespace ::com::sun::star::lang;
92 using namespace ::com::sun::star::container;
93 using namespace ::com::sun::star::sdb;
94 using namespace ::com::sun::star::sdbc;
95 using namespace ::com::sun::star::sdbcx;
96 using namespace ::com::sun::star::frame;
97 using namespace ::com::sun::star::ucb;
98 using namespace ::com::sun::star::util;
100 void OApplicationController::deleteTables(const ::std::vector< OUString>& _rList)
102 SharedConnection xConnection( ensureConnection() );
104 Reference<XTablesSupplier> xSup(xConnection,UNO_QUERY);
105 OSL_ENSURE(xSup.is(),"OApplicationController::deleteTable: no XTablesSuppier!");
106 if ( xSup.is() )
108 Reference<XNameAccess> xTables = xSup->getTables();
109 Reference<XDrop> xDrop(xTables,UNO_QUERY);
110 if ( xDrop.is() )
112 bool bConfirm = true;
113 ::std::vector< OUString>::const_iterator aEnd = _rList.end();
114 for (::std::vector< OUString>::const_iterator aIter = _rList.begin(); aIter != aEnd; ++aIter)
116 OUString sTableName = *aIter;
118 sal_Int32 nResult = RET_YES;
119 if ( bConfirm )
120 nResult = ::dbaui::askForUserAction(getView(),STR_TITLE_CONFIRM_DELETION ,STR_QUERY_DELETE_TABLE,_rList.size() > 1 && (aIter+1) != _rList.end(),sTableName);
122 bool bUserConfirmedDelete =
123 ( RET_YES == nResult )
124 || ( RET_ALL == nResult );
125 if ( bUserConfirmedDelete && m_pSubComponentManager->closeSubFrames( sTableName, E_TABLE ) )
127 SQLExceptionInfo aErrorInfo;
130 if ( xTables->hasByName(sTableName) )
131 xDrop->dropByName(sTableName);
132 else
133 {// could be a view
134 Reference<XViewsSupplier> xViewsSup(xConnection,UNO_QUERY);
136 Reference<XNameAccess> xViews;
137 if ( xViewsSup.is() )
139 xViews = xViewsSup->getViews();
140 if ( xViews.is() && xViews->hasByName(sTableName) )
142 xDrop.set(xViews,UNO_QUERY);
143 if ( xDrop.is() )
144 xDrop->dropByName(sTableName);
149 catch(SQLContext& e) { aErrorInfo = e; }
150 catch(SQLWarning& e) { aErrorInfo = e; }
151 catch(SQLException& e) { aErrorInfo = e; }
152 catch(WrappedTargetException& e)
154 SQLException aSql;
155 if(e.TargetException >>= aSql)
156 aErrorInfo = aSql;
157 else
158 OSL_FAIL("OApplicationController::implDropTable: something strange happened!");
160 catch( const Exception& )
162 DBG_UNHANDLED_EXCEPTION();
165 if ( aErrorInfo.isValid() )
166 showError(aErrorInfo);
168 if ( RET_ALL == nResult )
169 bConfirm = false;
171 else
172 break;
175 else
177 OUString sMessage(ModuleRes(STR_MISSING_TABLES_XDROP));
178 ScopedVclPtrInstance< MessageDialog > aError(getView(), sMessage);
179 aError->Execute();
184 void OApplicationController::deleteObjects( ElementType _eType, const ::std::vector< OUString>& _rList, bool _bConfirm )
186 Reference< XNameContainer > xNames( getElements( _eType ), UNO_QUERY );
187 Reference< XHierarchicalNameContainer > xHierarchyName( xNames, UNO_QUERY );
188 if ( xNames.is() )
190 OString sDialogPosition;
191 short eResult = _bConfirm ? svtools::QUERYDELETE_YES : svtools::QUERYDELETE_ALL;
193 // The list of elements to delete is allowed to contain related elements: A given element may
194 // be the ancestor or child of another element from the list.
195 // We want to ensure that ancestors get deleted first, so we normalize the list in this respect.
196 // #i33353#
197 ::std::set< OUString > aDeleteNames;
198 // Note that this implicitly uses ::std::less< OUString > a comparison operation, which
199 // results in lexicographical order, which is exactly what we need, because "foo" is *before*
200 // any "foo/bar" in this order.
201 ::std::copy(
202 _rList.begin(), _rList.end(),
203 ::std::insert_iterator< ::std::set< OUString > >( aDeleteNames, aDeleteNames.begin() )
206 ::std::set< OUString >::size_type nCount = aDeleteNames.size();
207 for ( ::std::set< OUString >::size_type nObjectsLeft = nCount; !aDeleteNames.empty(); )
209 ::std::set< OUString >::iterator aThisRound = aDeleteNames.begin();
211 if ( eResult != svtools::QUERYDELETE_ALL )
213 ScopedVclPtrInstance< svtools::QueryDeleteDlg_Impl > aDlg(getView(), *aThisRound);
215 if ( !sDialogPosition.isEmpty() )
216 aDlg->SetWindowState( sDialogPosition );
218 if ( nObjectsLeft > 1 )
219 aDlg->EnableAllButton();
221 eResult = aDlg->Execute();
222 if (eResult == svtools::QUERYDELETE_CANCEL)
223 return;
225 sDialogPosition = aDlg->GetWindowState( );
228 bool bSuccess = false;
230 bool bUserConfirmedDelete =
231 ( eResult == svtools::QUERYDELETE_ALL )
232 || ( eResult == svtools::QUERYDELETE_YES );
234 if ( bUserConfirmedDelete
235 && ( _eType != E_QUERY || m_pSubComponentManager->closeSubFrames( *aThisRound, _eType ) )
240 if ( xHierarchyName.is() )
241 xHierarchyName->removeByHierarchicalName( *aThisRound );
242 else
243 xNames->removeByName( *aThisRound );
245 bSuccess = true;
247 // now that we removed the element, care for all its child elements
248 // which may also be a part of the list
249 // #i33353#
250 OSL_ENSURE( aThisRound->getLength() - 1 >= 0, "OApplicationController::deleteObjects: empty name?" );
251 OUStringBuffer sSmallestSiblingName( *aThisRound );
252 sSmallestSiblingName.append( (sal_Unicode)( '/' + 1) );
254 ::std::set< OUString >::iterator aUpperChildrenBound = aDeleteNames.lower_bound( sSmallestSiblingName.makeStringAndClear() );
255 for ( ::std::set< OUString >::iterator aObsolete = aThisRound;
256 aObsolete != aUpperChildrenBound;
259 ::std::set< OUString >::iterator aNextObsolete = aObsolete; ++aNextObsolete;
260 aDeleteNames.erase( aObsolete );
261 --nObjectsLeft;
262 aObsolete = aNextObsolete;
265 catch(const SQLException&)
267 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
269 catch(const WrappedTargetException& e)
271 SQLException aSql;
272 if ( e.TargetException >>= aSql )
273 showError( SQLExceptionInfo( e.TargetException ) );
274 else
275 OSL_FAIL( "OApplicationController::deleteObjects: something strange happened!" );
277 catch( const Exception& )
279 DBG_UNHANDLED_EXCEPTION();
283 if ( !bSuccess )
285 // okay, this object could not be deleted (or the user did not want to delete it),
286 // but continue with the rest
287 aDeleteNames.erase( aThisRound );
288 --nObjectsLeft;
294 void OApplicationController::deleteEntries()
296 SolarMutexGuard aSolarGuard;
297 ::osl::MutexGuard aGuard( getMutex() );
299 if ( getContainer() )
301 ::std::vector< OUString> aList;
302 getSelectionElementNames(aList);
303 ElementType eType = getContainer()->getElementType();
304 switch(eType)
306 case E_TABLE:
307 deleteTables(aList);
308 break;
309 case E_QUERY:
310 deleteObjects( E_QUERY, aList, true );
311 break;
312 case E_FORM:
313 deleteObjects( E_FORM, aList, true );
314 break;
315 case E_REPORT:
316 deleteObjects( E_REPORT, aList, true );
317 break;
318 case E_NONE:
319 break;
324 // DO NOT CALL with getMutex() held!!
325 const SharedConnection& OApplicationController::ensureConnection( ::dbtools::SQLExceptionInfo* _pErrorInfo )
328 // This looks like double checked locking, but it is not,
329 // because every access (read *or* write) to m_xDataSourceConnection
330 // is mutexed.
331 // See http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
332 // for what I'm referring to.
333 // We cannot use the TLS (thread-local storage) solution
334 // since support for TLS is not up to the snuff on Windows :-(
337 ::osl::MutexGuard aGuard( getMutex() );
339 if ( m_xDataSourceConnection.is() )
340 return m_xDataSourceConnection;
343 WaitObject aWO(getView());
344 Reference<XConnection> conn;
346 SolarMutexGuard aSolarGuard;
348 OUString sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) );
349 sConnectingContext = sConnectingContext.replaceFirst("$name$", getStrippedDatabaseName());
351 // do the connection *without* holding getMutex() to avoid deadlock
352 // when we are not in the main thread and we need username/password
353 // (and thus to display a dialog, which will be done by the main thread)
354 // and there is an event that needs getMutex() *before* us in the main thread's queue
355 // See fdo#63391
356 conn.set( connect( getDatabaseName(), sConnectingContext, _pErrorInfo ) );
359 if (conn.is())
361 ::osl::MutexGuard aGuard( getMutex() );
362 if ( m_xDataSourceConnection.is() )
364 Reference< XComponent > comp (conn, UNO_QUERY);
365 if(comp.is())
369 comp->dispose();
371 catch( const Exception& )
373 OSL_FAIL( "dbaui::OApplicationController::ensureConnection could not dispose of temporary unused connection" );
376 conn.clear();
378 else
380 m_xDataSourceConnection.reset(conn);
381 SQLExceptionInfo aError;
384 m_xMetaData = m_xDataSourceConnection->getMetaData();
386 catch( const SQLException& )
388 aError = ::cppu::getCaughtException();
390 catch( const Exception& )
392 DBG_UNHANDLED_EXCEPTION();
394 if ( aError.isValid() )
396 if ( _pErrorInfo )
398 *_pErrorInfo = aError;
400 else
402 SolarMutexGuard aSolarGuard;
403 showError( aError );
409 return m_xDataSourceConnection;
412 bool OApplicationController::isDataSourceReadOnly() const
414 Reference<XStorable> xStore(m_xModel,UNO_QUERY);
415 return !xStore.is() || xStore->isReadonly();
418 bool OApplicationController::isConnectionReadOnly() const
420 bool bIsConnectionReadOnly = true;
421 if ( m_xMetaData.is() )
425 bIsConnectionReadOnly = m_xMetaData->isReadOnly();
427 catch(const SQLException&)
429 DBG_UNHANDLED_EXCEPTION();
432 // TODO check configuration
433 return bIsConnectionReadOnly;
436 Reference< XNameAccess > OApplicationController::getElements( ElementType _eType )
438 Reference< XNameAccess > xElements;
441 switch ( _eType )
443 case E_REPORT:
445 Reference< XReportDocumentsSupplier > xSupp( m_xModel, UNO_QUERY_THROW );
446 xElements.set( xSupp->getReportDocuments(), UNO_SET_THROW );
448 break;
450 case E_FORM:
452 Reference< XFormDocumentsSupplier > xSupp( m_xModel, UNO_QUERY_THROW );
453 xElements.set( xSupp->getFormDocuments(), UNO_SET_THROW );
455 break;
457 case E_QUERY:
459 xElements.set( getQueryDefinitions(), UNO_QUERY_THROW );
461 break;
463 case E_TABLE:
465 if ( m_xDataSourceConnection.is() )
467 Reference< XTablesSupplier > xSup( getConnection(), UNO_QUERY_THROW );
468 xElements.set( xSup->getTables(), UNO_SET_THROW );
471 break;
473 default:
474 break;
477 catch(const Exception&)
479 DBG_UNHANDLED_EXCEPTION();
482 return xElements;
485 void OApplicationController::getSelectionElementNames(::std::vector< OUString>& _rNames) const
487 SolarMutexGuard aSolarGuard;
488 ::osl::MutexGuard aGuard( getMutex() );
490 OSL_ENSURE(getContainer(),"View isn't valid! -> GPF");
492 getContainer()->getSelectionElementNames( _rNames );
495 ::std::unique_ptr< OLinkedDocumentsAccess > OApplicationController::getDocumentsAccess( ElementType _eType )
497 OSL_ENSURE( ( _eType == E_TABLE ) || ( _eType == E_QUERY ) || ( _eType == E_FORM ) || ( _eType == E_REPORT ),
498 "OApplicationController::getDocumentsAccess: only forms and reports are supported here!" );
500 SharedConnection xConnection( ensureConnection() );
501 Reference< XNameAccess > xDocContainer;
503 if ( ( _eType == E_FORM ) || ( _eType == E_REPORT ) )
505 xDocContainer.set( getElements( _eType ) );
506 OSL_ENSURE( xDocContainer.is(), "OApplicationController::getDocumentsAccess: invalid container!" );
509 ::std::unique_ptr< OLinkedDocumentsAccess > pDocuments( new OLinkedDocumentsAccess(
510 getView(), this, getORB(), xDocContainer, xConnection, getDatabaseName()
511 ) );
512 return pDocuments;
515 TransferableHelper* OApplicationController::copyObject()
519 SolarMutexGuard aSolarGuard;
520 ::osl::MutexGuard aGuard( getMutex() );
522 ElementType eType = getContainer()->getElementType();
523 TransferableHelper* pData = NULL;
524 switch( eType )
526 case E_TABLE:
527 case E_QUERY:
529 SharedConnection xConnection( ensureConnection() );
530 Reference< XDatabaseMetaData> xMetaData;
531 if ( xConnection.is() )
532 xMetaData = xConnection->getMetaData();
534 OUString sName = getContainer()->getQualifiedName( NULL );
535 if ( !sName.isEmpty() )
537 OUString sDataSource = getDatabaseName();
539 if ( eType == E_TABLE )
541 pData = new ODataClipboard(sDataSource, CommandType::TABLE, sName, xConnection, getNumberFormatter(xConnection, getORB()), getORB());
543 else
545 pData = new ODataClipboard(sDataSource, CommandType::QUERY, sName, getNumberFormatter(xConnection, getORB()), getORB());
549 break;
550 case E_FORM:
551 case E_REPORT:
553 ::std::vector< OUString> aList;
554 getSelectionElementNames(aList);
555 Reference< XHierarchicalNameAccess > xElements(getElements(eType),UNO_QUERY);
556 if ( xElements.is() && !aList.empty() )
558 Reference< XContent> xContent(xElements->getByHierarchicalName(*aList.begin()),UNO_QUERY);
559 pData = new OComponentTransferable( getDatabaseName(), xContent );
562 break;
563 default:
564 break;
567 // the ownership goes to ODataClipboards
568 return pData;
570 catch(const SQLException&)
572 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
574 catch( const Exception& )
576 DBG_UNHANDLED_EXCEPTION();
578 return NULL;
581 bool OApplicationController::paste( ElementType _eType, const svx::ODataAccessDescriptor& _rPasteData, const OUString& _sParentFolder, bool _bMove)
585 if ( _eType == E_QUERY )
587 sal_Int32 nCommandType = CommandType::TABLE;
588 if ( _rPasteData.has(daCommandType) )
589 _rPasteData[daCommandType] >>= nCommandType;
591 if ( CommandType::QUERY == nCommandType || CommandType::COMMAND == nCommandType )
593 // read all necessary data
595 OUString sCommand;
596 bool bEscapeProcessing = true;
598 _rPasteData[daCommand] >>= sCommand;
599 if ( _rPasteData.has(daEscapeProcessing) )
600 _rPasteData[daEscapeProcessing] >>= bEscapeProcessing;
602 // plausibility check
603 bool bValidDescriptor = false;
604 OUString sDataSourceName = _rPasteData.getDataSource();
605 if (CommandType::QUERY == nCommandType)
606 bValidDescriptor = sDataSourceName.getLength() && sCommand.getLength();
607 else if (CommandType::COMMAND == nCommandType)
608 bValidDescriptor = !sCommand.isEmpty();
609 if (!bValidDescriptor)
611 OSL_FAIL("OApplicationController::paste: invalid descriptor!");
612 return false;
615 // the target object name (as we'll suggest it to the user)
616 OUString sTargetName;
619 if ( CommandType::QUERY == nCommandType )
620 sTargetName = sCommand;
622 if ( sTargetName.isEmpty() )
624 OUString sDefaultName = OUString( ModuleRes( STR_QRY_TITLE ) );
625 sDefaultName = sDefaultName.getToken( 0, ' ' );
627 Reference< XNameAccess > xQueries( getQueryDefinitions(), UNO_QUERY_THROW );
628 sTargetName = ::dbtools::createUniqueName( xQueries, sDefaultName, false );
631 catch(const Exception&)
633 DBG_UNHANDLED_EXCEPTION();
636 Reference< XPropertySet > xQuery;
637 if (CommandType::QUERY == nCommandType)
639 // need to extract the statement and the escape processing flag from the query object
640 bool bSuccess = false;
643 // the concrete query
644 Reference< XQueryDefinitionsSupplier > xSourceQuerySup(
645 getDataSourceByName( sDataSourceName, getView(), getORB(), NULL ),
646 UNO_QUERY_THROW );
647 Reference< XNameAccess > xQueries( xSourceQuerySup->getQueryDefinitions(), UNO_SET_THROW );
648 if ( xQueries->hasByName( sCommand ) )
650 xQuery.set( xQueries->getByName(sCommand), UNO_QUERY_THROW );
651 bSuccess = true;
654 catch(SQLException&) { throw; } // caught and handled by the outer catch
655 catch( const Exception& )
657 DBG_UNHANDLED_EXCEPTION();
660 if (!bSuccess)
662 OSL_FAIL("OApplicationController::paste: could not extract the source query object!");
663 // TODO: maybe this is worth an error message to be displayed to the user ....
664 return false;
668 Reference< XNameContainer > xDestQueries(getQueryDefinitions(), UNO_QUERY);
669 Reference< XSingleServiceFactory > xQueryFactory(xDestQueries, UNO_QUERY);
670 if (!xQueryFactory.is())
672 OSL_FAIL("OApplicationController::paste: invalid destination query container!");
673 return false;
676 // here we have everything needed to create a new query object ...
677 // ... ehm, except a new name
678 ensureConnection();
680 DynamicTableOrQueryNameCheck aNameChecker( getConnection(), CommandType::QUERY );
681 ::dbtools::SQLExceptionInfo aDummy;
682 bool bNeedAskForName = ( sCommand.isEmpty() )
683 /* we did not have a source name, so the target name was auto-generated */
684 || ( !aNameChecker.isNameValid( sTargetName, aDummy ) );
685 /* name is invalid in the target DB (e.g. because it already
686 has a /table/ with that name) */
687 if ( bNeedAskForName )
689 ScopedVclPtrInstance<OSaveAsDlg> aAskForName(
690 getView(),
691 CommandType::QUERY,
692 getORB(),
693 getConnection(),
694 sTargetName,
695 aNameChecker,
696 SAD_ADDITIONAL_DESCRIPTION | SAD_TITLE_PASTE_AS );
697 if ( RET_OK != aAskForName->Execute() )
698 // cancelled by the user
699 return false;
700 sTargetName = aAskForName->getName();
703 // create a new object
704 Reference< XPropertySet > xNewQuery(xQueryFactory->createInstance(), UNO_QUERY);
705 OSL_ENSURE(xNewQuery.is(), "OApplicationController::paste: invalid object created by factory!");
706 if (xNewQuery.is())
708 // initialize
709 if ( xQuery.is() )
710 ::comphelper::copyProperties(xQuery,xNewQuery);
711 else
713 xNewQuery->setPropertyValue(PROPERTY_COMMAND,makeAny(sCommand));
714 xNewQuery->setPropertyValue(PROPERTY_ESCAPE_PROCESSING,makeAny(bEscapeProcessing));
716 // insert
717 xDestQueries->insertByName( sTargetName, makeAny(xNewQuery) );
718 xNewQuery.set(xDestQueries->getByName( sTargetName),UNO_QUERY);
719 if ( xQuery.is() && xNewQuery.is() )
721 Reference<XColumnsSupplier> xSrcColSup(xQuery,UNO_QUERY);
722 Reference<XColumnsSupplier> xDstColSup(xNewQuery,UNO_QUERY);
723 if ( xSrcColSup.is() && xDstColSup.is() )
725 Reference<XNameAccess> xSrcNameAccess = xSrcColSup->getColumns();
726 Reference<XNameAccess> xDstNameAccess = xDstColSup->getColumns();
727 Reference<XDataDescriptorFactory> xFac(xDstNameAccess,UNO_QUERY);
728 Reference<XAppend> xAppend(xFac,UNO_QUERY);
729 if ( xSrcNameAccess.is() && xDstNameAccess.is() && xSrcNameAccess->hasElements() && xAppend.is() )
731 Reference<XPropertySet> xDstProp(xFac->createDataDescriptor());
733 Sequence< OUString> aSeq = xSrcNameAccess->getElementNames();
734 const OUString* pIter = aSeq.getConstArray();
735 const OUString* pEnd = pIter + aSeq.getLength();
736 for( ; pIter != pEnd ; ++pIter)
738 Reference<XPropertySet> xSrcProp(xSrcNameAccess->getByName(*pIter),UNO_QUERY);
739 ::comphelper::copyProperties(xSrcProp,xDstProp);
740 xAppend->appendByDescriptor(xDstProp);
747 else
748 OSL_TRACE("There should be a sequence in it!");
749 return true;
751 else if ( _rPasteData.has(daComponent) ) // forms or reports
753 Reference<XContent> xContent;
754 _rPasteData[daComponent] >>= xContent;
755 return insertHierachyElement(_eType,_sParentFolder,Reference<XNameAccess>(xContent,UNO_QUERY).is(),xContent,_bMove);
758 catch(const SQLException&) { showError( SQLExceptionInfo( ::cppu::getCaughtException() ) ); }
759 catch(const Exception& )
761 DBG_UNHANDLED_EXCEPTION();
763 return false;
766 Reference<XNameContainer> OApplicationController::getQueryDefinitions() const
768 Reference<XQueryDefinitionsSupplier> xSet(m_xDataSource,UNO_QUERY);
769 Reference<XNameContainer> xNames;
770 if ( xSet.is() )
772 xNames.set(xSet->getQueryDefinitions(),UNO_QUERY);
774 return xNames;
777 void OApplicationController::getSupportedFormats(ElementType _eType,::std::vector<SotClipboardFormatId>& _rFormatIds)
779 switch( _eType )
781 case E_TABLE:
782 _rFormatIds.push_back(SotClipboardFormatId::DBACCESS_TABLE);
783 _rFormatIds.push_back(SotClipboardFormatId::RTF);
784 _rFormatIds.push_back(SotClipboardFormatId::HTML);
785 // run through
786 case E_QUERY:
787 _rFormatIds.push_back(SotClipboardFormatId::DBACCESS_QUERY);
788 break;
789 default:
790 break;
794 bool OApplicationController::isTableFormat() const
796 return OTableCopyHelper::isTableFormat(getViewClipboard());
799 IMPL_LINK_NOARG( OApplicationController, OnAsyncDrop )
801 m_nAsyncDrop = 0;
802 SolarMutexGuard aSolarGuard;
803 ::osl::MutexGuard aGuard( getMutex() );
805 if ( m_aAsyncDrop.nType == E_TABLE )
807 SharedConnection xConnection( ensureConnection() );
808 if ( xConnection.is() )
809 m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDatabaseName(), xConnection );
811 else
813 if ( paste(m_aAsyncDrop.nType,m_aAsyncDrop.aDroppedData,m_aAsyncDrop.aUrl,m_aAsyncDrop.nAction == DND_ACTION_MOVE)
814 && m_aAsyncDrop.nAction == DND_ACTION_MOVE )
816 Reference<XContent> xContent;
817 m_aAsyncDrop.aDroppedData[daComponent] >>= xContent;
818 ::std::vector< OUString> aList;
819 sal_Int32 nIndex = 0;
820 OUString sName = xContent->getIdentifier()->getContentIdentifier();
821 OUString sErase = sName.getToken(0,'/',nIndex); // we don't want to have the "private:forms" part
822 if ( nIndex != -1 )
824 aList.push_back(sName.copy(sErase.getLength() + 1));
825 deleteObjects( m_aAsyncDrop.nType, aList, false );
830 m_aAsyncDrop.aDroppedData.clear();
832 return 0L;
835 } // namespace dbaui
837 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */