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 "AppController.hxx"
22 : #include <comphelper/sequence.hxx>
23 : #include <comphelper/property.hxx>
24 : #include <comphelper/processfactory.hxx>
25 : #include "dbustrings.hrc"
26 : #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
27 : #include <com/sun/star/sdbcx/XAppend.hpp>
28 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
29 : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
30 : #include <com/sun/star/container/XNameContainer.hpp>
31 : #include <com/sun/star/uno/XNamingService.hpp>
32 : #include <com/sun/star/sdbc/XDataSource.hpp>
33 : #include <com/sun/star/frame/XStorable.hpp>
34 : #include <com/sun/star/container/XChild.hpp>
35 : #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
36 : #include <com/sun/star/sdbc/DataType.hpp>
37 : #include <com/sun/star/sdb/CommandType.hpp>
38 : #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
39 : #include <com/sun/star/sdb/SQLContext.hpp>
40 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
41 : #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
42 : #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
43 : #include <com/sun/star/sdbcx/XDrop.hpp>
44 : #include <unotools/ucbhelper.hxx>
45 : #include "dlgsave.hxx"
46 : #include <comphelper/types.hxx>
47 : #include <vcl/msgbox.hxx>
48 : #include <cppuhelper/typeprovider.hxx>
49 : #include <cppuhelper/exc_hlp.hxx>
50 : #include <connectivity/dbexception.hxx>
51 : #include <vcl/waitobj.hxx>
52 : #include <rtl/ustrbuf.hxx>
53 : #include "AppView.hxx"
54 : #include <svx/dataaccessdescriptor.hxx>
55 : #include <svx/dbaobjectex.hxx>
56 : #include "browserids.hxx"
57 : #include "dbu_reghelper.hxx"
58 : #include "dbu_app.hrc"
59 : #include <vcl/menu.hxx>
60 : #include <comphelper/uno3.hxx>
61 : #include <vcl/svapp.hxx>
62 : #include <svtools/svlbitm.hxx>
63 : #include "listviewitems.hxx"
64 : #include "AppDetailView.hxx"
65 : #include "linkeddocuments.hxx"
66 : #include <vcl/lstbox.hxx>
67 : #include <connectivity/dbtools.hxx>
68 : #include "sqlmessage.hxx"
69 : #include <tools/string.hxx>
70 : #include "dbexchange.hxx"
71 : #include "UITools.hxx"
72 : #include <algorithm>
73 : #include <svtools/treelistbox.hxx>
74 : #include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
75 : #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
76 : #include <unotools/pathoptions.hxx>
77 : #include <sfx2/docfilt.hxx>
78 : #include <svtools/fileview.hxx>
79 : #include <tools/diagnose_ex.h>
80 : #include <osl/diagnose.h>
81 : #include "defaultobjectnamecheck.hxx"
82 : #include <osl/mutex.hxx>
83 : #include "subcomponentmanager.hxx"
84 :
85 : //........................................................................
86 : namespace dbaui
87 : {
88 : //........................................................................
89 : using namespace ::dbtools;
90 : using namespace ::svx;
91 : using namespace ::svtools;
92 : using namespace ::com::sun::star::uno;
93 : using namespace ::com::sun::star::task;
94 : using namespace ::com::sun::star::beans;
95 : using namespace ::com::sun::star::lang;
96 : using namespace ::com::sun::star::container;
97 : using namespace ::com::sun::star::sdb;
98 : using namespace ::com::sun::star::sdbc;
99 : using namespace ::com::sun::star::sdbcx;
100 : using namespace ::com::sun::star::frame;
101 : using namespace ::com::sun::star::ucb;
102 : using namespace ::com::sun::star::util;
103 :
104 : // -----------------------------------------------------------------------------
105 0 : void OApplicationController::deleteTables(const ::std::vector< ::rtl::OUString>& _rList)
106 : {
107 0 : SharedConnection xConnection( ensureConnection() );
108 :
109 0 : Reference<XTablesSupplier> xSup(xConnection,UNO_QUERY);
110 : OSL_ENSURE(xSup.is(),"OApplicationController::deleteTable: no XTablesSuppier!");
111 0 : if ( xSup.is() )
112 : {
113 0 : Reference<XNameAccess> xTables = xSup->getTables();
114 0 : Reference<XDrop> xDrop(xTables,UNO_QUERY);
115 0 : if ( xDrop.is() )
116 : {
117 0 : bool bConfirm = true;
118 0 : ::std::vector< ::rtl::OUString>::const_iterator aEnd = _rList.end();
119 0 : for (::std::vector< ::rtl::OUString>::const_iterator aIter = _rList.begin(); aIter != aEnd; ++aIter)
120 : {
121 0 : ::rtl::OUString sTableName = *aIter;
122 :
123 0 : sal_Int32 nResult = RET_YES;
124 0 : if ( bConfirm )
125 0 : nResult = ::dbaui::askForUserAction(getView(),STR_TITLE_CONFIRM_DELETION ,STR_QUERY_DELETE_TABLE,_rList.size() > 1 && (aIter+1) != _rList.end(),sTableName);
126 :
127 : bool bUserConfirmedDelete =
128 : ( RET_YES == nResult )
129 0 : || ( RET_ALL == nResult );
130 0 : if ( bUserConfirmedDelete && m_pSubComponentManager->closeSubFrames( sTableName, E_TABLE ) )
131 : {
132 0 : SQLExceptionInfo aErrorInfo;
133 : try
134 : {
135 0 : if ( xTables->hasByName(sTableName) )
136 0 : xDrop->dropByName(sTableName);
137 : else
138 : {// could be a view
139 0 : Reference<XViewsSupplier> xViewsSup(xConnection,UNO_QUERY);
140 :
141 0 : Reference<XNameAccess> xViews;
142 0 : if ( xViewsSup.is() )
143 : {
144 0 : xViews = xViewsSup->getViews();
145 0 : if ( xViews.is() && xViews->hasByName(sTableName) )
146 : {
147 0 : xDrop.set(xViews,UNO_QUERY);
148 0 : if ( xDrop.is() )
149 0 : xDrop->dropByName(sTableName);
150 : }
151 0 : }
152 : }
153 : }
154 0 : catch(SQLContext& e) { aErrorInfo = e; }
155 0 : catch(SQLWarning& e) { aErrorInfo = e; }
156 0 : catch(SQLException& e) { aErrorInfo = e; }
157 0 : catch(WrappedTargetException& e)
158 : {
159 0 : SQLException aSql;
160 0 : if(e.TargetException >>= aSql)
161 0 : aErrorInfo = aSql;
162 : else
163 0 : OSL_FAIL("OApplicationController::implDropTable: something strange happended!");
164 : }
165 0 : catch( const Exception& )
166 : {
167 : DBG_UNHANDLED_EXCEPTION();
168 : }
169 :
170 0 : if ( aErrorInfo.isValid() )
171 0 : showError(aErrorInfo);
172 :
173 0 : if ( RET_ALL == nResult )
174 0 : bConfirm = false;
175 : }
176 : else
177 : break;
178 0 : }
179 : }
180 : else
181 : {
182 0 : String sMessage(ModuleRes(STR_MISSING_TABLES_XDROP));
183 0 : ErrorBox aError(getView(), WB_OK, sMessage);
184 0 : aError.Execute();
185 0 : }
186 0 : }
187 0 : }
188 : // -----------------------------------------------------------------------------
189 0 : void OApplicationController::deleteObjects( ElementType _eType, const ::std::vector< ::rtl::OUString>& _rList, bool _bConfirm )
190 : {
191 0 : Reference< XNameContainer > xNames( getElements( _eType ), UNO_QUERY );
192 0 : Reference< XHierarchicalNameContainer > xHierarchyName( xNames, UNO_QUERY );
193 0 : if ( xNames.is() )
194 : {
195 0 : rtl::OString sDialogPosition;
196 0 : svtools::QueryDeleteResult_Impl eResult = _bConfirm ? svtools::QUERYDELETE_YES : svtools::QUERYDELETE_ALL;
197 :
198 : // The list of elements to delete is allowed to contain related elements: A given element may
199 : // be the ancestor or child of another element from the list.
200 : // We want to ensure that ancestors get deleted first, so we normalize the list in this respect.
201 : // #i33353#
202 0 : ::std::set< ::rtl::OUString > aDeleteNames;
203 : // Note that this implicitly uses ::std::less< ::rtl::OUString > a comparison operation, which
204 : // results in lexicographical order, which is exactly what we need, because "foo" is *before*
205 : // any "foo/bar" in this order.
206 : ::std::copy(
207 : _rList.begin(), _rList.end(),
208 : ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aDeleteNames, aDeleteNames.begin() )
209 0 : );
210 :
211 0 : ::std::set< ::rtl::OUString >::size_type nCount = aDeleteNames.size();
212 0 : for ( ::std::set< ::rtl::OUString >::size_type nObjectsLeft = nCount; !aDeleteNames.empty(); )
213 : {
214 0 : ::std::set< ::rtl::OUString >::iterator aThisRound = aDeleteNames.begin();
215 :
216 0 : if ( eResult != svtools::QUERYDELETE_ALL )
217 : {
218 0 : svtools::QueryDeleteDlg_Impl aDlg( getView(), *aThisRound );
219 :
220 0 : if ( !sDialogPosition.isEmpty() )
221 0 : aDlg.SetWindowState( sDialogPosition );
222 :
223 0 : if ( nObjectsLeft > 1 )
224 0 : aDlg.EnableAllButton();
225 :
226 0 : if ( aDlg.Execute() == RET_OK )
227 0 : eResult = aDlg.GetResult();
228 : else
229 0 : return;
230 :
231 0 : sDialogPosition = aDlg.GetWindowState( );
232 : }
233 :
234 0 : bool bSuccess = false;
235 :
236 : bool bUserConfirmedDelete =
237 : ( eResult == svtools::QUERYDELETE_ALL )
238 0 : || ( eResult == svtools::QUERYDELETE_YES );
239 :
240 0 : if ( bUserConfirmedDelete
241 0 : && ( ( _eType == E_QUERY ) ? m_pSubComponentManager->closeSubFrames( *aThisRound, _eType ) : true )
242 : )
243 : {
244 : try
245 : {
246 0 : if ( xHierarchyName.is() )
247 0 : xHierarchyName->removeByHierarchicalName( *aThisRound );
248 : else
249 0 : xNames->removeByName( *aThisRound );
250 :
251 0 : bSuccess = true;
252 :
253 : // now that we removed the element, care for all it's child elements
254 : // which may also be a part of the list
255 : // #i33353#
256 : OSL_ENSURE( aThisRound->getLength() - 1 >= 0, "OApplicationController::deleteObjects: empty name?" );
257 0 : ::rtl::OUStringBuffer sSmallestSiblingName( *aThisRound );
258 0 : sSmallestSiblingName.append( (sal_Unicode)( '/' + 1) );
259 :
260 0 : ::std::set< ::rtl::OUString >::iterator aUpperChildrenBound = aDeleteNames.lower_bound( sSmallestSiblingName.makeStringAndClear() );
261 0 : for ( ::std::set< ::rtl::OUString >::iterator aObsolete = aThisRound;
262 : aObsolete != aUpperChildrenBound;
263 : )
264 : {
265 : #if OSL_DEBUG_LEVEL > 0
266 : ::rtl::OUString sObsoleteName = *aObsolete;
267 : #endif
268 0 : ::std::set< ::rtl::OUString >::iterator aNextObsolete = aObsolete; ++aNextObsolete;
269 0 : aDeleteNames.erase( aObsolete );
270 0 : --nObjectsLeft;
271 0 : aObsolete = aNextObsolete;
272 0 : }
273 : }
274 0 : catch(const SQLException&)
275 : {
276 0 : showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
277 : }
278 0 : catch(const WrappedTargetException& e)
279 : {
280 0 : SQLException aSql;
281 0 : if ( e.TargetException >>= aSql )
282 0 : showError( SQLExceptionInfo( e.TargetException ) );
283 : else
284 0 : OSL_FAIL( "OApplicationController::deleteObjects: something strange happended!" );
285 : }
286 0 : catch( const Exception& )
287 : {
288 : DBG_UNHANDLED_EXCEPTION();
289 : }
290 : }
291 :
292 0 : if ( !bSuccess )
293 : {
294 : // okay, this object could not be deleted (or the user did not want to delete it),
295 : // but continue with the rest
296 0 : aDeleteNames.erase( aThisRound );
297 0 : --nObjectsLeft;
298 : }
299 0 : }
300 0 : }
301 : }
302 : // -----------------------------------------------------------------------------
303 0 : void OApplicationController::deleteEntries()
304 : {
305 0 : SolarMutexGuard aSolarGuard;
306 0 : ::osl::MutexGuard aGuard( getMutex() );
307 :
308 0 : if ( getContainer() )
309 : {
310 0 : ::std::vector< ::rtl::OUString> aList;
311 0 : getSelectionElementNames(aList);
312 0 : ElementType eType = getContainer()->getElementType();
313 0 : switch(eType)
314 : {
315 : case E_TABLE:
316 0 : deleteTables(aList);
317 0 : break;
318 : case E_QUERY:
319 0 : deleteObjects( E_QUERY, aList, true );
320 0 : break;
321 : case E_FORM:
322 0 : deleteObjects( E_FORM, aList, true );
323 0 : break;
324 : case E_REPORT:
325 0 : deleteObjects( E_REPORT, aList, true );
326 0 : break;
327 : case E_NONE:
328 0 : break;
329 0 : }
330 0 : }
331 0 : }
332 : // -----------------------------------------------------------------------------
333 0 : const SharedConnection& OApplicationController::ensureConnection( ::dbtools::SQLExceptionInfo* _pErrorInfo )
334 : {
335 0 : SolarMutexGuard aSolarGuard;
336 0 : ::osl::MutexGuard aGuard( getMutex() );
337 :
338 0 : if ( !m_xDataSourceConnection.is() )
339 : {
340 0 : WaitObject aWO(getView());
341 0 : String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) );
342 0 : sConnectingContext.SearchAndReplaceAscii("$name$", getStrippedDatabaseName());
343 :
344 0 : m_xDataSourceConnection.reset( connect( getDatabaseName(), sConnectingContext, _pErrorInfo ) );
345 0 : if ( m_xDataSourceConnection.is() )
346 : {
347 0 : SQLExceptionInfo aError;
348 : try
349 : {
350 0 : m_xMetaData = m_xDataSourceConnection->getMetaData();
351 : }
352 0 : catch( const SQLException& )
353 : {
354 0 : aError = ::cppu::getCaughtException();
355 : }
356 0 : catch( const Exception& )
357 : {
358 : DBG_UNHANDLED_EXCEPTION();
359 : }
360 0 : if ( aError.isValid() )
361 : {
362 0 : if ( _pErrorInfo )
363 : {
364 0 : *_pErrorInfo = aError;
365 : }
366 : else
367 : {
368 0 : showError( aError );
369 : }
370 0 : }
371 0 : }
372 : }
373 0 : return m_xDataSourceConnection;
374 : }
375 : // -----------------------------------------------------------------------------
376 0 : sal_Bool OApplicationController::isDataSourceReadOnly() const
377 : {
378 0 : Reference<XStorable> xStore(m_xModel,UNO_QUERY);
379 0 : return !xStore.is() || xStore->isReadonly();
380 : }
381 : // -----------------------------------------------------------------------------
382 0 : sal_Bool OApplicationController::isConnectionReadOnly() const
383 : {
384 0 : sal_Bool bIsConnectionReadOnly = sal_True;
385 0 : if ( m_xMetaData.is() )
386 : {
387 : try
388 : {
389 0 : bIsConnectionReadOnly = m_xMetaData->isReadOnly();
390 : }
391 0 : catch(const SQLException&)
392 : {
393 : DBG_UNHANDLED_EXCEPTION();
394 : }
395 : }
396 : // TODO check configuration
397 0 : return bIsConnectionReadOnly;
398 : }
399 : // -----------------------------------------------------------------------------
400 0 : Reference< XNameAccess > OApplicationController::getElements( ElementType _eType )
401 : {
402 0 : Reference< XNameAccess > xElements;
403 : try
404 : {
405 0 : switch ( _eType )
406 : {
407 : case E_REPORT:
408 : {
409 0 : Reference< XReportDocumentsSupplier > xSupp( m_xModel, UNO_QUERY_THROW );
410 0 : xElements.set( xSupp->getReportDocuments(), UNO_SET_THROW );
411 : }
412 0 : break;
413 :
414 : case E_FORM:
415 : {
416 0 : Reference< XFormDocumentsSupplier > xSupp( m_xModel, UNO_QUERY_THROW );
417 0 : xElements.set( xSupp->getFormDocuments(), UNO_SET_THROW );
418 : }
419 0 : break;
420 :
421 : case E_QUERY:
422 : {
423 0 : xElements.set( getQueryDefintions(), UNO_QUERY_THROW );
424 : }
425 0 : break;
426 :
427 : case E_TABLE:
428 : {
429 0 : if ( m_xDataSourceConnection.is() )
430 : {
431 0 : Reference< XTablesSupplier > xSup( getConnection(), UNO_QUERY_THROW );
432 0 : xElements.set( xSup->getTables(), UNO_SET_THROW );
433 : }
434 : }
435 0 : break;
436 :
437 : default:
438 0 : break;
439 : }
440 : }
441 0 : catch(const Exception&)
442 : {
443 : DBG_UNHANDLED_EXCEPTION();
444 : }
445 :
446 0 : return xElements;
447 : }
448 : // -----------------------------------------------------------------------------
449 0 : void OApplicationController::getSelectionElementNames(::std::vector< ::rtl::OUString>& _rNames) const
450 : {
451 0 : SolarMutexGuard aSolarGuard;
452 0 : ::osl::MutexGuard aGuard( getMutex() );
453 :
454 : OSL_ENSURE(getContainer(),"View isn't valid! -> GPF");
455 :
456 0 : getContainer()->getSelectionElementNames( _rNames );
457 0 : }
458 :
459 : // -----------------------------------------------------------------------------
460 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
461 0 : ::std::auto_ptr< OLinkedDocumentsAccess > OApplicationController::getDocumentsAccess( ElementType _eType )
462 : {
463 : OSL_ENSURE( ( _eType == E_TABLE ) || ( _eType == E_QUERY ) || ( _eType == E_FORM ) || ( _eType == E_REPORT ),
464 : "OApplicationController::getDocumentsAccess: only forms and reports are supported here!" );
465 :
466 0 : SharedConnection xConnection( ensureConnection() );
467 0 : Reference< XNameAccess > xDocContainer;
468 :
469 0 : if ( ( _eType == E_FORM ) | ( _eType == E_REPORT ) )
470 : {
471 0 : xDocContainer.set( getElements( _eType ) );
472 : OSL_ENSURE( xDocContainer.is(), "OApplicationController::getDocumentsAccess: invalid container!" );
473 : }
474 :
475 : ::std::auto_ptr< OLinkedDocumentsAccess > pDocuments( new OLinkedDocumentsAccess(
476 0 : getView(), this, comphelper::getComponentContext(getORB()), xDocContainer, xConnection, getDatabaseName()
477 0 : ) );
478 0 : return pDocuments;
479 : }
480 : SAL_WNODEPRECATED_DECLARATIONS_POP
481 :
482 : // -----------------------------------------------------------------------------
483 0 : TransferableHelper* OApplicationController::copyObject()
484 : {
485 : try
486 : {
487 0 : SolarMutexGuard aSolarGuard;
488 0 : ::osl::MutexGuard aGuard( getMutex() );
489 :
490 0 : ElementType eType = getContainer()->getElementType();
491 0 : TransferableHelper* pData = NULL;
492 0 : switch( eType )
493 : {
494 : case E_TABLE:
495 : case E_QUERY:
496 : {
497 0 : SharedConnection xConnection( ensureConnection() );
498 0 : Reference< XDatabaseMetaData> xMetaData;
499 0 : if ( xConnection.is() )
500 0 : xMetaData = xConnection->getMetaData();
501 :
502 0 : ::rtl::OUString sName = getContainer()->getQualifiedName( NULL );
503 0 : if ( !sName.isEmpty() )
504 : {
505 0 : ::rtl::OUString sDataSource = getDatabaseName();
506 :
507 0 : if ( eType == E_TABLE )
508 : {
509 0 : pData = new ODataClipboard(sDataSource, CommandType::TABLE, sName, xConnection, getNumberFormatter(xConnection, comphelper::getComponentContext(getORB())), getORB());
510 : }
511 : else
512 : {
513 0 : pData = new ODataClipboard(sDataSource, CommandType::QUERY, sName, getNumberFormatter(xConnection, comphelper::getComponentContext(getORB())), getORB());
514 0 : }
515 0 : }
516 : }
517 0 : break;
518 : case E_FORM:
519 : case E_REPORT:
520 : {
521 0 : ::std::vector< ::rtl::OUString> aList;
522 0 : getSelectionElementNames(aList);
523 0 : Reference< XHierarchicalNameAccess > xElements(getElements(eType),UNO_QUERY);
524 0 : if ( xElements.is() && !aList.empty() )
525 : {
526 0 : Reference< XContent> xContent(xElements->getByHierarchicalName(*aList.begin()),UNO_QUERY);
527 0 : pData = new OComponentTransferable( getDatabaseName(), xContent );
528 0 : }
529 : }
530 0 : break;
531 : default:
532 0 : break;
533 : }
534 :
535 : // the owner ship goes to ODataClipboards
536 0 : return pData;
537 : }
538 0 : catch(const SQLException&)
539 : {
540 0 : showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
541 : }
542 0 : catch( const Exception& )
543 : {
544 : DBG_UNHANDLED_EXCEPTION();
545 : }
546 0 : return NULL;
547 : }
548 : // -----------------------------------------------------------------------------
549 0 : sal_Bool OApplicationController::paste( ElementType _eType,const ::svx::ODataAccessDescriptor& _rPasteData,const String& _sParentFolder ,sal_Bool _bMove)
550 : {
551 : try
552 : {
553 0 : if ( _eType == E_QUERY )
554 : {
555 0 : sal_Int32 nCommandType = CommandType::TABLE;
556 0 : if ( _rPasteData.has(daCommandType) )
557 0 : _rPasteData[daCommandType] >>= nCommandType;
558 :
559 0 : if ( CommandType::QUERY == nCommandType || CommandType::COMMAND == nCommandType )
560 : {
561 : // read all necessary data
562 :
563 0 : ::rtl::OUString sCommand;
564 0 : sal_Bool bEscapeProcessing = sal_True;
565 :
566 0 : _rPasteData[daCommand] >>= sCommand;
567 0 : if ( _rPasteData.has(daEscapeProcessing) )
568 0 : _rPasteData[daEscapeProcessing] >>= bEscapeProcessing;
569 :
570 : // plausibility check
571 0 : sal_Bool bValidDescriptor = sal_False;
572 0 : ::rtl::OUString sDataSourceName = _rPasteData.getDataSource();
573 0 : if (CommandType::QUERY == nCommandType)
574 0 : bValidDescriptor = sDataSourceName.getLength() && sCommand.getLength();
575 0 : else if (CommandType::COMMAND == nCommandType)
576 0 : bValidDescriptor = !sCommand.isEmpty();
577 0 : if (!bValidDescriptor)
578 : {
579 : OSL_FAIL("OApplicationController::paste: invalid descriptor!");
580 0 : return sal_False;
581 : }
582 :
583 : // the target object name (as we'll suggest it to the user)
584 0 : ::rtl::OUString sTargetName;
585 : try
586 : {
587 0 : if ( CommandType::QUERY == nCommandType )
588 0 : sTargetName = sCommand;
589 :
590 0 : if ( sTargetName.isEmpty() )
591 : {
592 0 : String sDefaultName = String( ModuleRes( STR_QRY_TITLE ) );
593 0 : sDefaultName = sDefaultName.GetToken( 0, ' ' );
594 :
595 0 : Reference< XNameAccess > xQueries( getQueryDefintions(), UNO_QUERY_THROW );
596 0 : sTargetName = ::dbtools::createUniqueName( xQueries, sDefaultName, sal_False );
597 : }
598 : }
599 0 : catch(const Exception&)
600 : {
601 : DBG_UNHANDLED_EXCEPTION();
602 : }
603 :
604 0 : Reference< XPropertySet > xQuery;
605 0 : if (CommandType::QUERY == nCommandType)
606 : {
607 : // need to extract the statement and the escape processing flag from the query object
608 0 : sal_Bool bSuccess = sal_False;
609 : try
610 : {
611 : // the concrete query
612 : Reference< XQueryDefinitionsSupplier > xSourceQuerySup(
613 0 : getDataSourceByName( sDataSourceName, getView(), comphelper::getComponentContext(getORB()), NULL ),
614 0 : UNO_QUERY_THROW );
615 0 : Reference< XNameAccess > xQueries( xSourceQuerySup->getQueryDefinitions(), UNO_SET_THROW );
616 0 : if ( xQueries->hasByName( sCommand ) )
617 : {
618 0 : xQuery.set( xQueries->getByName(sCommand), UNO_QUERY_THROW );
619 0 : bSuccess = true;
620 0 : }
621 : }
622 0 : catch(SQLException&) { throw; } // caught and handled by the outer catch
623 0 : catch( const Exception& )
624 : {
625 : DBG_UNHANDLED_EXCEPTION();
626 : }
627 :
628 0 : if (!bSuccess)
629 : {
630 : OSL_FAIL("OApplicationController::paste: could not extract the source query object!");
631 : // TODO: maybe this is worth an error message to be displayed to the user ....
632 0 : return sal_False;
633 : }
634 : }
635 :
636 :
637 0 : Reference< XNameContainer > xDestQueries(getQueryDefintions(), UNO_QUERY);
638 0 : Reference< XSingleServiceFactory > xQueryFactory(xDestQueries, UNO_QUERY);
639 0 : if (!xQueryFactory.is())
640 : {
641 : OSL_FAIL("OApplicationController::paste: invalid destination query container!");
642 0 : return sal_False;
643 : }
644 :
645 : // here we have everything needed to create a new query object ...
646 : // ... ehm, except a new name
647 0 : ensureConnection();
648 :
649 0 : DynamicTableOrQueryNameCheck aNameChecker( getConnection(), CommandType::QUERY );
650 0 : ::dbtools::SQLExceptionInfo aDummy;
651 0 : bool bNeedAskForName = ( sCommand.isEmpty() )
652 : /* we did not have a source name, so the target name was auto-generated */
653 0 : || ( !aNameChecker.isNameValid( sTargetName, aDummy ) );
654 : /* name is invalid in the target DB (e.g. because it already
655 : has a /table/ with that name) */
656 0 : if ( bNeedAskForName )
657 : {
658 0 : OSaveAsDlg aAskForName( getView(),
659 : CommandType::QUERY,
660 : comphelper::getComponentContext(getORB()),
661 0 : getConnection(),
662 : sTargetName,
663 : aNameChecker,
664 0 : SAD_ADDITIONAL_DESCRIPTION | SAD_TITLE_PASTE_AS);
665 0 : if ( RET_OK != aAskForName.Execute() )
666 : // cancelled by the user
667 0 : return sal_False;
668 0 : sTargetName = aAskForName.getName();
669 : }
670 :
671 : // create a new object
672 0 : Reference< XPropertySet > xNewQuery(xQueryFactory->createInstance(), UNO_QUERY);
673 : OSL_ENSURE(xNewQuery.is(), "OApplicationController::paste: invalid object created by factory!");
674 0 : if (xNewQuery.is())
675 : {
676 : // initialize
677 0 : if ( xQuery.is() )
678 0 : ::comphelper::copyProperties(xQuery,xNewQuery);
679 : else
680 : {
681 0 : xNewQuery->setPropertyValue(PROPERTY_COMMAND,makeAny(sCommand));
682 0 : xNewQuery->setPropertyValue(PROPERTY_ESCAPE_PROCESSING,makeAny(bEscapeProcessing));
683 : }
684 : // insert
685 0 : xDestQueries->insertByName( sTargetName, makeAny(xNewQuery) );
686 0 : xNewQuery.set(xDestQueries->getByName( sTargetName),UNO_QUERY);
687 0 : if ( xQuery.is() && xNewQuery.is() )
688 : {
689 0 : Reference<XColumnsSupplier> xSrcColSup(xQuery,UNO_QUERY);
690 0 : Reference<XColumnsSupplier> xDstColSup(xNewQuery,UNO_QUERY);
691 0 : if ( xSrcColSup.is() && xDstColSup.is() )
692 : {
693 0 : Reference<XNameAccess> xSrcNameAccess = xSrcColSup->getColumns();
694 0 : Reference<XNameAccess> xDstNameAccess = xDstColSup->getColumns();
695 0 : Reference<XDataDescriptorFactory> xFac(xDstNameAccess,UNO_QUERY);
696 0 : Reference<XAppend> xAppend(xFac,UNO_QUERY);
697 0 : if ( xSrcNameAccess.is() && xDstNameAccess.is() && xSrcNameAccess->hasElements() && xAppend.is() )
698 : {
699 0 : Reference<XPropertySet> xDstProp(xFac->createDataDescriptor());
700 :
701 0 : Sequence< ::rtl::OUString> aSeq = xSrcNameAccess->getElementNames();
702 0 : const ::rtl::OUString* pIter = aSeq.getConstArray();
703 0 : const ::rtl::OUString* pEnd = pIter + aSeq.getLength();
704 0 : for( ; pIter != pEnd ; ++pIter)
705 : {
706 0 : Reference<XPropertySet> xSrcProp(xSrcNameAccess->getByName(*pIter),UNO_QUERY);
707 0 : ::comphelper::copyProperties(xSrcProp,xDstProp);
708 0 : xAppend->appendByDescriptor(xDstProp);
709 0 : }
710 0 : }
711 0 : }
712 : }
713 0 : }
714 : }
715 : else
716 : OSL_TRACE("There should be a sequence in it!");
717 0 : return sal_True;
718 : }
719 0 : else if ( _rPasteData.has(daComponent) ) // forms or reports
720 : {
721 0 : Reference<XContent> xContent;
722 0 : _rPasteData[daComponent] >>= xContent;
723 0 : return insertHierachyElement(_eType,_sParentFolder,Reference<XNameAccess>(xContent,UNO_QUERY).is(),xContent,_bMove);
724 : }
725 : }
726 0 : catch(const SQLException&) { showError( SQLExceptionInfo( ::cppu::getCaughtException() ) ); }
727 0 : catch(const Exception& )
728 : {
729 : DBG_UNHANDLED_EXCEPTION();
730 : }
731 0 : return sal_False;
732 : }
733 : // -----------------------------------------------------------------------------
734 0 : Reference<XNameContainer> OApplicationController::getQueryDefintions() const
735 : {
736 0 : Reference<XQueryDefinitionsSupplier> xSet(m_xDataSource,UNO_QUERY);
737 0 : Reference<XNameContainer> xNames;
738 0 : if ( xSet.is() )
739 : {
740 0 : xNames.set(xSet->getQueryDefinitions(),UNO_QUERY);
741 : }
742 0 : return xNames;
743 : }
744 : // -----------------------------------------------------------------------------
745 0 : void OApplicationController::getSupportedFormats(ElementType _eType,::std::vector<SotFormatStringId>& _rFormatIds) const
746 : {
747 0 : switch( _eType )
748 : {
749 : case E_TABLE:
750 0 : _rFormatIds.push_back(SOT_FORMATSTR_ID_DBACCESS_TABLE);
751 0 : _rFormatIds.push_back(SOT_FORMAT_RTF);
752 0 : _rFormatIds.push_back(SOT_FORMATSTR_ID_HTML);
753 : // run through
754 : case E_QUERY:
755 0 : _rFormatIds.push_back(SOT_FORMATSTR_ID_DBACCESS_QUERY);
756 0 : break;
757 : default:
758 0 : break;
759 : }
760 0 : }
761 : // -----------------------------------------------------------------------------
762 0 : sal_Bool OApplicationController::isTableFormat() const
763 : {
764 0 : return m_aTableCopyHelper.isTableFormat(getViewClipboard());
765 : }
766 : // -----------------------------------------------------------------------------
767 0 : IMPL_LINK( OApplicationController, OnAsyncDrop, void*, /*NOTINTERESTEDIN*/ )
768 : {
769 0 : m_nAsyncDrop = 0;
770 0 : SolarMutexGuard aSolarGuard;
771 0 : ::osl::MutexGuard aGuard( getMutex() );
772 :
773 :
774 0 : if ( m_aAsyncDrop.nType == E_TABLE )
775 : {
776 0 : SharedConnection xConnection( ensureConnection() );
777 0 : if ( xConnection.is() )
778 0 : m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDatabaseName(), xConnection );
779 : }
780 : else
781 : {
782 0 : if ( paste(m_aAsyncDrop.nType,m_aAsyncDrop.aDroppedData,m_aAsyncDrop.aUrl,m_aAsyncDrop.nAction == DND_ACTION_MOVE)
783 : && m_aAsyncDrop.nAction == DND_ACTION_MOVE )
784 : {
785 0 : Reference<XContent> xContent;
786 0 : m_aAsyncDrop.aDroppedData[daComponent] >>= xContent;
787 0 : ::std::vector< ::rtl::OUString> aList;
788 0 : sal_Int32 nIndex = 0;
789 0 : ::rtl::OUString sName = xContent->getIdentifier()->getContentIdentifier();
790 0 : ::rtl::OUString sErase = sName.getToken(0,'/',nIndex); // we don't want to have the "private:forms" part
791 0 : if ( nIndex != -1 )
792 : {
793 0 : aList.push_back(sName.copy(sErase.getLength() + 1));
794 0 : deleteObjects( m_aAsyncDrop.nType, aList, false );
795 0 : }
796 : }
797 : }
798 :
799 0 : m_aAsyncDrop.aDroppedData.clear();
800 :
801 0 : return 0L;
802 : }
803 : //........................................................................
804 : } // namespace dbaui
805 : //........................................................................
806 :
807 :
808 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|