LibreOffice Module dbaccess (master) 1
AppControllerDnD.cxx
Go to the documentation of this file.
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#include <memory>
21#include "AppController.hxx"
23#include <core_resource.hxx>
24#include <strings.hxx>
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/container/XNameContainer.hpp>
29#include <com/sun/star/frame/XStorable.hpp>
30#include <com/sun/star/container/XHierarchicalNameContainer.hpp>
31#include <com/sun/star/lang/XSingleServiceFactory.hpp>
32#include <com/sun/star/sdb/CommandType.hpp>
33#include <com/sun/star/sdb/SQLContext.hpp>
34#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
35#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
36#include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
37#include <com/sun/star/sdbcx/XDrop.hpp>
38#include <dlgsave.hxx>
39#include <vcl/weld.hxx>
42#include <sal/log.hxx>
43#include "AppView.hxx"
45#include <svx/dbaobjectex.hxx>
46#include <strings.hrc>
47#include <vcl/svapp.hxx>
48#include <linkeddocuments.hxx>
50#include <dbexchange.hxx>
51#include <UITools.hxx>
52#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
53#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
56#include <osl/diagnose.h>
58#include <osl/mutex.hxx>
60#include <set>
61
62namespace dbaui
63{
64using namespace ::dbtools;
65using namespace ::svx;
66using namespace ::svtools;
67using namespace ::com::sun::star::uno;
68using namespace ::com::sun::star::task;
69using namespace ::com::sun::star::beans;
70using namespace ::com::sun::star::lang;
71using namespace ::com::sun::star::container;
72using namespace ::com::sun::star::sdb;
73using namespace ::com::sun::star::sdbc;
74using namespace ::com::sun::star::sdbcx;
75using namespace ::com::sun::star::frame;
76using namespace ::com::sun::star::ucb;
77using namespace ::com::sun::star::util;
78
79void OApplicationController::deleteTables(const std::vector< OUString>& _rList)
80{
81 SharedConnection xConnection( ensureConnection() );
82
83 Reference<XTablesSupplier> xSup(xConnection,UNO_QUERY);
84 OSL_ENSURE(xSup.is(),"OApplicationController::deleteTable: no XTablesSupplier!");
85 if ( !xSup.is() )
86 return;
87
88 Reference<XNameAccess> xTables = xSup->getTables();
89 Reference<XDrop> xDrop(xTables,UNO_QUERY);
90 if ( xDrop.is() )
91 {
92 bool bConfirm = true;
93 std::vector< OUString>::const_iterator aEnd = _rList.end();
94 for (std::vector< OUString>::const_iterator aIter = _rList.begin(); aIter != aEnd; ++aIter)
95 {
96 OUString sTableName = *aIter;
97
98 sal_Int32 nResult = RET_YES;
99 if ( bConfirm )
100 nResult = ::dbaui::askForUserAction(getFrameWeld(), STR_TITLE_CONFIRM_DELETION, STR_QUERY_DELETE_TABLE, _rList.size() > 1 && (aIter+1) != _rList.end(), sTableName);
101
102 bool bUserConfirmedDelete =
103 ( RET_YES == nResult )
104 || ( RET_ALL == nResult );
105 if ( bUserConfirmedDelete && m_pSubComponentManager->closeSubFrames( sTableName, E_TABLE ) )
106 {
107 SQLExceptionInfo aErrorInfo;
108 try
109 {
110 if ( xTables->hasByName(sTableName) )
111 xDrop->dropByName(sTableName);
112 else
113 {// could be a view
114 Reference<XViewsSupplier> xViewsSup(xConnection,UNO_QUERY);
115
117 if ( xViewsSup.is() )
118 {
119 xViews = xViewsSup->getViews();
120 if ( xViews.is() && xViews->hasByName(sTableName) )
121 {
122 xDrop.set(xViews,UNO_QUERY);
123 if ( xDrop.is() )
124 xDrop->dropByName(sTableName);
125 }
126 }
127 }
128 }
129 catch(SQLContext& e) { aErrorInfo = e; }
130 catch(SQLWarning& e) { aErrorInfo = e; }
131 catch(SQLException& e) { aErrorInfo = e; }
132 catch(WrappedTargetException& e)
133 {
134 SQLException aSql;
135 if(e.TargetException >>= aSql)
136 aErrorInfo = aSql;
137 else
138 OSL_FAIL("OApplicationController::implDropTable: something strange happened!");
139 }
140 catch( const Exception& )
141 {
142 DBG_UNHANDLED_EXCEPTION("dbaccess");
143 }
144
145 if ( aErrorInfo.isValid() )
146 showError(aErrorInfo);
147
148 if ( RET_ALL == nResult )
149 bConfirm = false;
150 }
151 else
152 break;
153 }
154 }
155 else
156 {
157 OUString sMessage(DBA_RES(STR_MISSING_TABLES_XDROP));
158 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(getFrameWeld(),
159 VclMessageType::Warning, VclButtonsType::Ok,
160 sMessage));
161 xError->run();
162 }
163}
164
165void OApplicationController::deleteObjects( ElementType _eType, const std::vector< OUString>& _rList, bool _bConfirm )
166{
167 Reference< XNameContainer > xNames( getElements( _eType ), UNO_QUERY );
168 Reference< XHierarchicalNameContainer > xHierarchyName( xNames, UNO_QUERY );
169 if ( !xNames.is() )
170 return;
171
172 short eResult = _bConfirm ? svtools::QUERYDELETE_YES : svtools::QUERYDELETE_ALL;
173
174 // The list of elements to delete is allowed to contain related elements: A given element may
175 // be the ancestor or child of another element from the list.
176 // We want to ensure that ancestors get deleted first, so we normalize the list in this respect.
177 // #i33353#
178 // Note that this implicitly uses std::less< OUString > a comparison operation, which
179 // results in lexicographical order, which is exactly what we need, because "foo" is *before*
180 // any "foo/bar" in this order.
181 std::set< OUString > aDeleteNames(_rList.begin(), _rList.end());
182
183 std::set< OUString >::size_type nCount = aDeleteNames.size();
184 for ( std::set< OUString >::size_type nObjectsLeft = nCount; !aDeleteNames.empty(); )
185 {
186 std::set< OUString >::const_iterator aThisRound = aDeleteNames.begin();
187
188 if ( eResult != svtools::QUERYDELETE_ALL )
189 {
190 svtools::QueryDeleteDlg_Impl aDlg(getFrameWeld(), *aThisRound);
191
192 if ( nObjectsLeft > 1 )
193 aDlg.EnableAllButton();
194
195 eResult = aDlg.run();
196 }
197
198 bool bSuccess = false;
199
200 bool bUserConfirmedDelete =
201 ( eResult == svtools::QUERYDELETE_ALL )
202 || ( eResult == svtools::QUERYDELETE_YES );
203
204 if ( bUserConfirmedDelete
205 && ( _eType != E_QUERY || m_pSubComponentManager->closeSubFrames( *aThisRound, _eType ) )
206 )
207 {
208 try
209 {
210 if ( xHierarchyName.is() )
211 xHierarchyName->removeByHierarchicalName( *aThisRound );
212 else
213 xNames->removeByName( *aThisRound );
214
215 bSuccess = true;
216
217 // now that we removed the element, care for all its child elements
218 // which may also be a part of the list
219 // #i33353#
220 OSL_ENSURE( aThisRound->getLength() - 1 >= 0, "OApplicationController::deleteObjects: empty name?" );
221 OUString sSmallestSiblingName = *aThisRound + OUStringChar( sal_Unicode( '/' + 1) );
222
223 std::set< OUString >::const_iterator aUpperChildrenBound = aDeleteNames.lower_bound( sSmallestSiblingName );
224 for ( std::set< OUString >::const_iterator aObsolete = aThisRound;
225 aObsolete != aUpperChildrenBound;
226 )
227 {
228 std::set< OUString >::const_iterator aNextObsolete = aObsolete; ++aNextObsolete;
229 aDeleteNames.erase( aObsolete );
230 --nObjectsLeft;
231 aObsolete = aNextObsolete;
232 }
233 }
234 catch(const SQLException&)
235 {
236 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
237 }
238 catch(const WrappedTargetException& e)
239 {
240 SQLException aSql;
241 if ( e.TargetException >>= aSql )
242 showError( SQLExceptionInfo( e.TargetException ) );
243 else
244 OSL_FAIL( "OApplicationController::deleteObjects: something strange happened!" );
245 }
246 catch( const Exception& )
247 {
248 DBG_UNHANDLED_EXCEPTION("dbaccess");
249 }
250 }
251
252 if ( !bSuccess )
253 {
254 // okay, this object could not be deleted (or the user did not want to delete it),
255 // but continue with the rest
256 aDeleteNames.erase( aThisRound );
257 --nObjectsLeft;
258 }
259 }
260}
261
263{
264 SolarMutexGuard aSolarGuard;
265 ::osl::MutexGuard aGuard( getMutex() );
266
267 if ( !getContainer() )
268 return;
269
270 std::vector< OUString> aList;
273 switch(eType)
274 {
275 case E_TABLE:
276 deleteTables(aList);
277 break;
278 case E_QUERY:
279 deleteObjects( E_QUERY, aList, true );
280 break;
281 case E_FORM:
282 deleteObjects( E_FORM, aList, true );
283 break;
284 case E_REPORT:
285 deleteObjects( E_REPORT, aList, true );
286 break;
287 case E_NONE:
288 break;
289 }
290}
291
292// DO NOT CALL with getMutex() held!!
294{
295
296 // This looks like double checked locking, but it is not,
297 // because every access (read *or* write) to m_xDataSourceConnection
298 // is mutexed.
299 // See http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
300 // for what I'm referring to.
301 // We cannot use the TLS (thread-local storage) solution
302 // since support for TLS is not up to the snuff on Windows :-(
303
304 {
305 ::osl::MutexGuard aGuard( getMutex() );
306
309 }
310
313 {
314 SolarMutexGuard aSolarGuard;
315
316 OUString sConnectingContext(DBA_RES(STR_COULDNOTCONNECT_DATASOURCE));
317 sConnectingContext = sConnectingContext.replaceFirst("$name$", getStrippedDatabaseName());
318
319 // do the connection *without* holding getMutex() to avoid deadlock
320 // when we are not in the main thread and we need username/password
321 // (and thus to display a dialog, which will be done by the main thread)
322 // and there is an event that needs getMutex() *before* us in the main thread's queue
323 // See fdo#63391
324 conn.set( connect( getDatabaseName(), sConnectingContext, _pErrorInfo ) );
325 }
326
327 if (conn.is())
328 {
329 ::osl::MutexGuard aGuard( getMutex() );
331 {
332 Reference< XComponent > comp (conn, UNO_QUERY);
333 if(comp.is())
334 {
335 try
336 {
337 comp->dispose();
338 }
339 catch( const Exception& )
340 {
341 OSL_FAIL( "dbaui::OApplicationController::ensureConnection could not dispose of temporary unused connection" );
342 }
343 }
344 conn.clear();
345 }
346 else
347 {
349 SQLExceptionInfo aError;
350 try
351 {
352 m_xMetaData = m_xDataSourceConnection->getMetaData();
353 }
354 catch( const SQLException& )
355 {
356 aError = ::cppu::getCaughtException();
357 }
358 catch( const Exception& )
359 {
360 DBG_UNHANDLED_EXCEPTION("dbaccess");
361 }
362 if ( aError.isValid() )
363 {
364 if ( _pErrorInfo )
365 {
366 *_pErrorInfo = aError;
367 }
368 else
369 {
370 SolarMutexGuard aSolarGuard;
371 showError( aError );
372 }
373 }
374 }
375 }
376
378}
379
381{
382 Reference<XStorable> xStore(m_xModel,UNO_QUERY);
383 return !xStore.is() || xStore->isReadonly();
384}
385
387{
388 bool bIsConnectionReadOnly = true;
389 if ( m_xMetaData.is() )
390 {
391 try
392 {
393 bIsConnectionReadOnly = m_xMetaData->isReadOnly();
394 }
395 catch(const SQLException&)
396 {
397 DBG_UNHANDLED_EXCEPTION("dbaccess");
398 }
399 }
400 // TODO check configuration
401 return bIsConnectionReadOnly;
402}
403
405{
406 Reference< XNameAccess > xElements;
407 try
408 {
409 switch ( _eType )
410 {
411 case E_REPORT:
412 {
413 Reference< XReportDocumentsSupplier > xSupp( m_xModel, UNO_QUERY_THROW );
414 xElements.set( xSupp->getReportDocuments(), UNO_SET_THROW );
415 }
416 break;
417
418 case E_FORM:
419 {
420 Reference< XFormDocumentsSupplier > xSupp( m_xModel, UNO_QUERY_THROW );
421 xElements.set( xSupp->getFormDocuments(), UNO_SET_THROW );
422 }
423 break;
424
425 case E_QUERY:
426 {
427 xElements.set( getQueryDefinitions(), UNO_QUERY_THROW );
428 }
429 break;
430
431 case E_TABLE:
432 {
434 {
435 Reference< XTablesSupplier > xSup( getConnection(), UNO_QUERY_THROW );
436 xElements.set( xSup->getTables(), UNO_SET_THROW );
437 }
438 }
439 break;
440
441 default:
442 break;
443 }
444 }
445 catch(const Exception&)
446 {
447 DBG_UNHANDLED_EXCEPTION("dbaccess");
448 }
449
450 return xElements;
451}
452
453void OApplicationController::getSelectionElementNames(std::vector< OUString>& _rNames) const
454{
455 SolarMutexGuard aSolarGuard;
456 ::osl::MutexGuard aGuard( getMutex() );
457
458 OSL_ENSURE(getContainer(),"View isn't valid! -> GPF");
459
461}
462
463std::unique_ptr< OLinkedDocumentsAccess > OApplicationController::getDocumentsAccess( ElementType _eType )
464{
465 OSL_ENSURE( ( _eType == E_TABLE ) || ( _eType == E_QUERY ) || ( _eType == E_FORM ) || ( _eType == E_REPORT ),
466 "OApplicationController::getDocumentsAccess: only forms and reports are supported here!" );
467
468 SharedConnection xConnection( ensureConnection() );
469 Reference< XNameAccess > xDocContainer;
470
471 if ( ( _eType == E_FORM ) || ( _eType == E_REPORT ) )
472 {
473 xDocContainer.set( getElements( _eType ) );
474 OSL_ENSURE( xDocContainer.is(), "OApplicationController::getDocumentsAccess: invalid container!" );
475 }
476
477 std::unique_ptr< OLinkedDocumentsAccess > pDocuments( new OLinkedDocumentsAccess(
478 getFrameWeld(), this, getORB(), xDocContainer, xConnection, getDatabaseName()
479 ) );
480 return pDocuments;
481}
482
484{
485 bool bSuccess = false;
486 try
487 {
488 SolarMutexGuard aSolarGuard;
489 ::osl::MutexGuard aGuard( getMutex() );
490
492 switch( eType )
493 {
494 case E_TABLE:
495 case E_QUERY:
496 {
497 SharedConnection xConnection( ensureConnection() );
499 if ( xConnection.is() )
500 xMetaData = xConnection->getMetaData();
501
502 OUString sName = getContainer()->getQualifiedName( nullptr );
503 if ( !sName.isEmpty() )
504 {
505 OUString sDataSource = getDatabaseName();
506
507 if ( eType == E_TABLE )
508 {
509 rExchange.Update(sDataSource, CommandType::TABLE, sName, xConnection, getNumberFormatter(xConnection, getORB()), getORB());
510 }
511 else
512 {
513 rExchange.Update(sDataSource, CommandType::QUERY, sName, getNumberFormatter(xConnection, getORB()), getORB());
514 }
515 bSuccess = true;
516 }
517 break;
518 }
519 default:
520 break;
521 }
522 }
523 catch(const SQLException&)
524 {
525 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
526 }
527 catch( const Exception& )
528 {
529 DBG_UNHANDLED_EXCEPTION("dbaccess");
530 }
531 return bSuccess;
532}
533
535{
536 bool bSuccess = false;
537 try
538 {
539 SolarMutexGuard aSolarGuard;
540 ::osl::MutexGuard aGuard( getMutex() );
541
543 switch( eType )
544 {
545 case E_FORM:
546 case E_REPORT:
547 {
548 std::vector< OUString> aList;
551 if ( xElements.is() && !aList.empty() )
552 {
553 Reference< XContent> xContent(xElements->getByHierarchicalName(*aList.begin()),UNO_QUERY);
554 rExchange.Update(getDatabaseName(), xContent);
555 bSuccess = true;
556 }
557 break;
558 }
559 default:
560 break;
561 }
562 }
563 catch(const SQLException&)
564 {
565 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
566 }
567 catch( const Exception& )
568 {
569 DBG_UNHANDLED_EXCEPTION("dbaccess");
570 }
571 return bSuccess;
572}
573
575{
576 try
577 {
578 SolarMutexGuard aSolarGuard;
579 ::osl::MutexGuard aGuard( getMutex() );
580
582 switch( eType )
583 {
584 case E_TABLE:
585 case E_QUERY:
586 {
588 if (copySQLObject(*xExchange))
589 return xExchange;
590 break;
591 }
592 case E_FORM:
593 case E_REPORT:
594 {
596 if (copyDocObject(*xExchange))
597 return xExchange;
598 break;
599 }
600 break;
601 default:
602 break;
603 }
604 }
605 catch(const SQLException&)
606 {
607 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
608 }
609 catch( const Exception& )
610 {
611 DBG_UNHANDLED_EXCEPTION("dbaccess");
612 }
613 return nullptr;
614}
615
616bool OApplicationController::paste( ElementType _eType, const svx::ODataAccessDescriptor& _rPasteData, const OUString& _sParentFolder, bool _bMove)
617{
618 try
619 {
620 if ( _eType == E_QUERY )
621 {
622 sal_Int32 nCommandType = CommandType::TABLE;
623 if ( _rPasteData.has(DataAccessDescriptorProperty::CommandType) )
624 _rPasteData[DataAccessDescriptorProperty::CommandType] >>= nCommandType;
625
626 if ( CommandType::QUERY == nCommandType || CommandType::COMMAND == nCommandType )
627 {
628 // read all necessary data
629
630 OUString sCommand;
631 bool bEscapeProcessing = true;
632
633 _rPasteData[DataAccessDescriptorProperty::Command] >>= sCommand;
634 if ( _rPasteData.has(DataAccessDescriptorProperty::EscapeProcessing) )
635 _rPasteData[DataAccessDescriptorProperty::EscapeProcessing] >>= bEscapeProcessing;
636
637 // plausibility check
638 bool bValidDescriptor = false;
639 OUString sDataSourceName = _rPasteData.getDataSource();
640 if (CommandType::QUERY == nCommandType)
641 bValidDescriptor = sDataSourceName.getLength() && sCommand.getLength();
642 else if (CommandType::COMMAND == nCommandType)
643 bValidDescriptor = !sCommand.isEmpty();
644 if (!bValidDescriptor)
645 {
646 OSL_FAIL("OApplicationController::paste: invalid descriptor!");
647 return false;
648 }
649
650 // the target object name (as we'll suggest it to the user)
651 OUString sTargetName;
652 try
653 {
654 if ( CommandType::QUERY == nCommandType )
655 sTargetName = sCommand;
656
657 if ( sTargetName.isEmpty() )
658 {
659 OUString sDefaultName = DBA_RES(STR_QRY_TITLE);
660 sDefaultName = sDefaultName.getToken( 0, ' ' );
661
662 Reference< XNameAccess > xQueries( getQueryDefinitions(), UNO_QUERY_THROW );
663 sTargetName = ::dbtools::createUniqueName( xQueries, sDefaultName, false );
664 }
665 }
666 catch(const Exception&)
667 {
668 DBG_UNHANDLED_EXCEPTION("dbaccess");
669 }
670
672 if (CommandType::QUERY == nCommandType)
673 {
674 // need to extract the statement and the escape processing flag from the query object
675 bool bSuccess = false;
676 try
677 {
678 // the concrete query
680 getDataSourceByName( sDataSourceName, getFrameWeld(), getORB(), nullptr ),
681 UNO_QUERY_THROW );
682 Reference< XNameAccess > xQueries( xSourceQuerySup->getQueryDefinitions(), UNO_SET_THROW );
683 if ( xQueries->hasByName( sCommand ) )
684 {
685 xQuery.set( xQueries->getByName(sCommand), UNO_QUERY_THROW );
686 bSuccess = true;
687 }
688 }
689 catch(SQLException&) { throw; } // caught and handled by the outer catch
690 catch( const Exception& )
691 {
692 DBG_UNHANDLED_EXCEPTION("dbaccess");
693 }
694
695 if (!bSuccess)
696 {
697 OSL_FAIL("OApplicationController::paste: could not extract the source query object!");
698 // TODO: maybe this is worth an error message to be displayed to the user...
699 return false;
700 }
701 }
702
704 Reference< XSingleServiceFactory > xQueryFactory(xDestQueries, UNO_QUERY);
705 if (!xQueryFactory.is())
706 {
707 OSL_FAIL("OApplicationController::paste: invalid destination query container!");
708 return false;
709 }
710
711 // here we have everything needed to create a new query object...
712 // ... ehm, except a new name
714
717 bool bNeedAskForName = ( sCommand.isEmpty() )
718 /* we did not have a source name, so the target name was auto-generated */
719 || ( !aNameChecker.isNameValid( sTargetName, aDummy ) );
720 /* name is invalid in the target DB (e.g. because it already
721 has a /table/ with that name) */
722 if ( bNeedAskForName )
723 {
724 OSaveAsDlg aAskForName(getFrameWeld(),
726 getORB(),
728 sTargetName,
729 aNameChecker,
731 if ( RET_OK != aAskForName.run() )
732 // cancelled by the user
733 return false;
734 sTargetName = aAskForName.getName();
735 }
736
737 // create a new object
738 Reference< XPropertySet > xNewQuery(xQueryFactory->createInstance(), UNO_QUERY);
739 OSL_ENSURE(xNewQuery.is(), "OApplicationController::paste: invalid object created by factory!");
740 if (xNewQuery.is())
741 {
742 // initialize
743 if ( xQuery.is() )
744 ::comphelper::copyProperties(xQuery,xNewQuery);
745 else
746 {
747 xNewQuery->setPropertyValue(PROPERTY_COMMAND,Any(sCommand));
748 xNewQuery->setPropertyValue(PROPERTY_ESCAPE_PROCESSING,Any(bEscapeProcessing));
749 }
750 // insert
751 xDestQueries->insertByName( sTargetName, Any(xNewQuery) );
752 xNewQuery.set(xDestQueries->getByName( sTargetName),UNO_QUERY);
753 if ( xQuery.is() && xNewQuery.is() )
754 {
755 Reference<XColumnsSupplier> xSrcColSup(xQuery,UNO_QUERY);
756 Reference<XColumnsSupplier> xDstColSup(xNewQuery,UNO_QUERY);
757 if ( xSrcColSup.is() && xDstColSup.is() )
758 {
759 Reference<XNameAccess> xSrcNameAccess = xSrcColSup->getColumns();
760 Reference<XNameAccess> xDstNameAccess = xDstColSup->getColumns();
761 Reference<XDataDescriptorFactory> xFac(xDstNameAccess,UNO_QUERY);
762 Reference<XAppend> xAppend(xFac,UNO_QUERY);
763 if ( xSrcNameAccess.is() && xDstNameAccess.is() && xSrcNameAccess->hasElements() && xAppend.is() )
764 {
765 Reference<XPropertySet> xDstProp(xFac->createDataDescriptor());
766
767 Sequence< OUString> aSeq = xSrcNameAccess->getElementNames();
768 const OUString* pIter = aSeq.getConstArray();
769 const OUString* pEnd = pIter + aSeq.getLength();
770 for( ; pIter != pEnd ; ++pIter)
771 {
772 Reference<XPropertySet> xSrcProp(xSrcNameAccess->getByName(*pIter),UNO_QUERY);
773 ::comphelper::copyProperties(xSrcProp,xDstProp);
774 xAppend->appendByDescriptor(xDstProp);
775 }
776 }
777 }
778 }
779 }
780 }
781 else
782 SAL_WARN("dbaccess", "There should be a sequence in it!");
783 return true;
784 }
785 else if ( _rPasteData.has(DataAccessDescriptorProperty::Component) ) // forms or reports
786 {
787 Reference<XContent> xContent;
788 _rPasteData[DataAccessDescriptorProperty::Component] >>= xContent;
789 return insertHierarchyElement(_eType,_sParentFolder,Reference<XNameAccess>(xContent,UNO_QUERY).is(),xContent,_bMove);
790 }
791 }
792 catch(const SQLException&) { showError( SQLExceptionInfo( ::cppu::getCaughtException() ) ); }
793 catch(const Exception& )
794 {
795 DBG_UNHANDLED_EXCEPTION("dbaccess");
796 }
797 return false;
798}
799
801{
804 if ( xSet.is() )
805 {
806 xNames.set(xSet->getQueryDefinitions(),UNO_QUERY);
807 }
808 return xNames;
809}
810
811void OApplicationController::getSupportedFormats(ElementType _eType,std::vector<SotClipboardFormatId>& _rFormatIds)
812{
813 switch( _eType )
814 {
815 case E_TABLE:
816 _rFormatIds.push_back(SotClipboardFormatId::DBACCESS_TABLE);
817 _rFormatIds.push_back(SotClipboardFormatId::RTF);
818 _rFormatIds.push_back(SotClipboardFormatId::HTML);
819 [[fallthrough]];
820 case E_QUERY:
821 _rFormatIds.push_back(SotClipboardFormatId::DBACCESS_QUERY);
822 break;
823 default:
824 break;
825 }
826}
827
829{
831}
832
833IMPL_LINK_NOARG( OApplicationController, OnAsyncDrop, void*, void )
834{
835 m_nAsyncDrop = nullptr;
836 SolarMutexGuard aSolarGuard;
837 ::osl::MutexGuard aGuard( getMutex() );
838
839 if ( m_aAsyncDrop.nType == E_TABLE )
840 {
841 SharedConnection xConnection( ensureConnection() );
842 if ( xConnection.is() )
843 m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDatabaseName(), xConnection );
844 }
845 else
846 {
847 if ( paste(m_aAsyncDrop.nType,m_aAsyncDrop.aDroppedData,m_aAsyncDrop.aUrl,m_aAsyncDrop.nAction == DND_ACTION_MOVE)
848 && m_aAsyncDrop.nAction == DND_ACTION_MOVE )
849 {
850 Reference<XContent> xContent;
851 m_aAsyncDrop.aDroppedData[DataAccessDescriptorProperty::Component] >>= xContent;
852 std::vector< OUString> aList;
853 sal_Int32 nIndex = 0;
854 OUString sName = xContent->getIdentifier()->getContentIdentifier();
855 std::u16string_view sErase = o3tl::getToken(sName,0,'/',nIndex); // we don't want to have the "private:forms" part
856 if ( nIndex != -1 )
857 {
858 aList.push_back(sName.copy(sErase.size() + 1));
859 deleteObjects( m_aAsyncDrop.nType, aList, false );
860 }
861 }
862 }
863
864 m_aAsyncDrop.aDroppedData.clear();
865}
866
867} // namespace dbaui
868
869/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sName
#define RET_ALL
Definition: UITools.hxx:32
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
class implementing the IObjectNameCheck interface, and checking a given name for being valid as eithe...
virtual bool isNameValid(const OUString &_rObjectName, ::dbtools::SQLExceptionInfo &_out_rErrorToDisplay) const override
determines whether a given object name is valid
css::uno::Reference< css::container::XNameContainer > getQueryDefinitions() const
returns the query definitions of the active data source.
void deleteTables(const std::vector< OUString > &_rList)
deletes tables.
const TransferableDataHelper & getViewClipboard() const
returns the system clipboard.
bool insertHierarchyElement(ElementType _eType, const OUString &_sParentFolder, bool _bCollection=true, const css::uno::Reference< css::ucb::XContent > &_xContent=css::uno::Reference< css::ucb::XContent >(), bool _bMove=false)
Inserts a new object into the hierarchy given be the type.
static void getSupportedFormats(ElementType _eType, std::vector< SotClipboardFormatId > &_rFormatIds)
fills the vector with all supported formats
void deleteObjects(ElementType _eType, const std::vector< OUString > &_rList, bool _bConfirm)
deletes queries, forms, or reports
bool isConnectionReadOnly() const
checks if the connection for the selected data source is read only.
css::uno::Reference< css::sdbc::XDatabaseMetaData > m_xMetaData
virtual bool isDataSourceReadOnly() const override
checks if the selected data source is read only
bool copySQLObject(ODataClipboard &rExchange)
fills rExchange with current object if it's a Table or Query
const SharedConnection & ensureConnection(::dbtools::SQLExceptionInfo *_pErrorInfo=nullptr)
retrieves the current connection, creates it if necessary
bool paste(ElementType _eType, const svx::ODataAccessDescriptor &_rPasteData, const OUString &_sParentFolder=OUString(), bool _bMove=false)
pastes a query, form or report into the data source
rtl::Reference< TransferableHelper > copyObject()
copies the current object into clipboard
void deleteEntries()
deletes the entries selected.
const SharedConnection & getConnection() const
retrieves the current connection
css::uno::Reference< css::beans::XPropertySet > m_xDataSource
void getSelectionElementNames(std::vector< OUString > &_rNames) const
fills the list with the selected entries.
std::unique_ptr< OLinkedDocumentsAccess > getDocumentsAccess(ElementType _eType)
returns the document access for the specific type
virtual void SAL_CALL connect() override
css::uno::Reference< css::frame::XModel > m_xModel
bool copyDocObject(svx::OComponentTransferable &rExchange)
fills rExchange with current object if it's a Form or Report
OUString getStrippedDatabaseName() const
returns the stripped database name.
OUString getDatabaseName() const
returns the database name
css::uno::Reference< css::container::XNameAccess > getElements(ElementType _eType)
returns the nameaccess
::rtl::Reference< SubComponentManager > m_pSubComponentManager
bool isTableFormat() const
returns <TRUE> if the clipboard supports a table format, otherwise <FALSE>.
OApplicationView * getContainer() const
SharedConnection m_xDataSourceConnection
OUString getQualifiedName(const weld::TreeIter *_pEntry) const
return the qualified name.
Definition: AppView.cxx:240
void getSelectionElementNames(std::vector< OUString > &_rNames) const
returns the element names which are selected
Definition: AppView.cxx:306
ElementType getElementType() const
return the element of currently select entry
Definition: AppView.cxx:288
void Update(const OUString &_rDatasource, const sal_Int32 _nCommandType, const OUString &_rCommand, const css::uno::Reference< css::sdbc::XConnection > &_rxConnection, const css::uno::Reference< css::util::XNumberFormatter > &_rxFormatter, const css::uno::Reference< css::uno::XComponentContext > &_rxORB)
weld::Window * getFrameWeld() const
void showError(const ::dbtools::SQLExceptionInfo &_rInfo)
::osl::Mutex & getMutex() const
const css::uno::Reference< css::uno::XComponentContext > & getORB() const
const OUString & getName() const
Definition: dlgsave.cxx:276
static bool isTableFormat(const TransferableDataHelper &_rClipboard)
returns <TRUE> if the clipboard supports a table format, otherwise <FALSE>.
void Update(const OUString &rDatasourceOrLocation, const css::uno::Reference< css::ucb::XContent > &xContent)
bool has(DataAccessDescriptorProperty _eWhich) const
OUString getDataSource() const
void reset(const css::uno::Reference< INTERFACE > &_rxComponent, AssignmentMode _eMode=TakeOwnership)
virtual short run()
#define DBA_RES(id)
int nCount
#define DBG_UNHANDLED_EXCEPTION(...)
@ AdditionalDescription
OUString eType
Definition: generalpage.cxx:78
sal_Int32 nIndex
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
@ Exception
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper *, void)
css::uno::Reference< css::sdbc::XDataSource > getDataSourceByName(const OUString &_rDataSourceName, weld::Window *_pErrorMessageParent, const css::uno::Reference< css::uno::XComponentContext > &_rxContext, ::dbtools::SQLExceptionInfo *_pErrorInfo)
retrieves a data source given by name or URL, and displays an error if this fails
css::uno::Reference< css::util::XNumberFormatter > getNumberFormatter(const css::uno::Reference< css::sdbc::XConnection > &_rxConnection, const css::uno::Reference< css::uno::XComponentContext > &_rxContext)
creates a number formatter
sal_Int32 askForUserAction(weld::Window *pParent, TranslateId pTitle, TranslateId pText, bool bAll, std::u16string_view rName)
returns the configuration node name of user defined drivers.
Definition: UITools.cxx:1149
::osl::Mutex & getMutex()
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
comp
OUString sMessage
Definition: sqlmessage.cxx:159
constexpr OUStringLiteral PROPERTY_COMMAND(u"Command")
constexpr OUStringLiteral PROPERTY_ESCAPE_PROCESSING(u"EscapeProcessing")
#define DND_ACTION_MOVE
sal_uInt16 sal_Unicode
RET_OK
RET_YES