Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / ui / app / AppController.cxx
blob45ca8dca147692b2bed31ff86f949b30dfe350d8
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 "dbustrings.hrc"
22 #include "advancedsettingsdlg.hxx"
23 #include "subcomponentmanager.hxx"
24 #include "uiservices.hxx"
26 #include <com/sun/star/beans/NamedValue.hpp>
27 #include <com/sun/star/container/XChild.hpp>
28 #include <com/sun/star/container/XContainer.hpp>
29 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
30 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
31 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
32 #include <com/sun/star/container/XNameContainer.hpp>
33 #include <com/sun/star/frame/FrameSearchFlag.hpp>
34 #include <com/sun/star/frame/XStorable.hpp>
35 #include <com/sun/star/sdb/CommandType.hpp>
36 #include <com/sun/star/sdb/ErrorMessageDialog.hpp>
37 #include <com/sun/star/sdb/SQLContext.hpp>
38 #include <com/sun/star/sdb/XBookmarksSupplier.hpp>
39 #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
40 #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
41 #include <com/sun/star/sdbc/XDataSource.hpp>
42 #include <com/sun/star/sdbcx/XAlterView.hpp>
43 #include <com/sun/star/sdbcx/XAppend.hpp>
44 #include <com/sun/star/sdbcx/XRename.hpp>
45 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
46 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
47 #include <com/sun/star/sdb/application/MacroMigrationWizard.hpp>
48 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
49 #include <com/sun/star/uno/XNamingService.hpp>
50 #include <com/sun/star/util/XFlushable.hpp>
51 #include <com/sun/star/util/XModifiable.hpp>
52 #include <com/sun/star/util/XModifyBroadcaster.hpp>
53 #include <com/sun/star/util/XNumberFormatter.hpp>
54 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
55 #include <com/sun/star/document/XEmbeddedScripts.hpp>
56 #include <com/sun/star/frame/XModel2.hpp>
57 #include <com/sun/star/awt/XTopWindow.hpp>
58 #include <com/sun/star/task/XInteractionHandler.hpp>
59 #include <com/sun/star/sdb/application/DatabaseObject.hpp>
60 #include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
61 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
62 #include <com/sun/star/container/XHierarchicalName.hpp>
63 #include <tools/diagnose_ex.h>
64 #include <osl/diagnose.h>
66 #include <svl/urihelper.hxx>
67 #include <svl/filenotation.hxx>
68 #include <svtools/treelistbox.hxx>
69 #include <svtools/transfer.hxx>
70 #include <svtools/cliplistener.hxx>
71 #include <svtools/svlbitm.hxx>
72 #include <svtools/insdlg.hxx>
74 #include <comphelper/sequence.hxx>
75 #include <comphelper/uno3.hxx>
76 #include <comphelper/types.hxx>
77 #include <comphelper/interaction.hxx>
78 #include <comphelper/processfactory.hxx>
80 #include <vcl/msgbox.hxx>
81 #include <vcl/stdtext.hxx>
82 #include <vcl/svapp.hxx>
83 #include <vcl/menu.hxx>
84 #include <vcl/lstbox.hxx>
86 #include <unotools/closeveto.hxx>
87 #include <unotools/pathoptions.hxx>
88 #include <unotools/tempfile.hxx>
89 #include <unotools/moduleoptions.hxx>
90 #include <unotools/historyoptions.hxx>
92 #include <sfx2/mailmodelapi.hxx>
93 #include <sfx2/filedlghelper.hxx>
94 #include <sfx2/docfilt.hxx>
95 #include <sfx2/QuerySaveDocument.hxx>
97 #include <cppuhelper/typeprovider.hxx>
98 #include <cppuhelper/exc_hlp.hxx>
100 #include <connectivity/dbtools.hxx>
101 #include <connectivity/dbexception.hxx>
103 #include <svx/dbaexchange.hxx>
104 #include <svx/dbaobjectex.hxx>
105 #include <svx/svxdlg.hxx>
107 #include <osl/mutex.hxx>
108 #include "AppView.hxx"
109 #include "browserids.hxx"
110 #include "dbu_reghelper.hxx"
111 #include "dbu_app.hrc"
112 #include "defaultobjectnamecheck.hxx"
113 #include "databaseobjectview.hxx"
114 #include "listviewitems.hxx"
115 #include "AppDetailView.hxx"
116 #include "linkeddocuments.hxx"
117 #include "sqlmessage.hxx"
118 #include "UITools.hxx"
119 #include "dsntypes.hxx"
120 #include "dbaccess_helpid.hrc"
121 #include "dlgsave.hxx"
122 #include "dbaccess_slotid.hrc"
124 #include <algorithm>
125 #include <functional>
127 #include <boost/noncopyable.hpp>
129 extern "C" void SAL_CALL createRegistryInfo_ODBApplication()
131 static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OApplicationController > aAutoRegistration;
134 namespace dbaui
136 using namespace ::dbtools;
137 using namespace ::svx;
138 using namespace ::com::sun::star;
139 using namespace ::com::sun::star::uno;
140 using namespace ::com::sun::star::ucb;
141 using namespace ::com::sun::star::view;
142 using namespace ::com::sun::star::util;
143 using namespace ::com::sun::star::beans;
144 using namespace ::com::sun::star::lang;
145 using namespace ::com::sun::star::frame;
146 using namespace ::com::sun::star::container;
147 using namespace ::com::sun::star::sdb;
148 using namespace ::com::sun::star::sdbc;
149 using namespace ::com::sun::star::sdbcx;
150 using namespace ::com::sun::star::datatransfer;
151 using namespace ::com::sun::star::ui::dialogs;
152 using namespace ::com::sun::star::task;
153 using ::com::sun::star::document::XEmbeddedScripts;
154 using ::com::sun::star::document::XDocumentEventBroadcaster;
155 using ::com::sun::star::document::DocumentEvent;
156 using ::com::sun::star::sdb::application::NamedDatabaseObject;
158 namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
159 namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer;
161 OUString SAL_CALL OApplicationController::getImplementationName() throw( RuntimeException, std::exception )
163 return getImplementationName_Static();
166 OUString OApplicationController::getImplementationName_Static() throw( RuntimeException )
168 return OUString(SERVICE_SDB_APPLICATIONCONTROLLER);
171 Sequence< OUString> OApplicationController::getSupportedServiceNames_Static() throw( RuntimeException )
173 Sequence< OUString> aSupported(1);
174 aSupported[0] = "com.sun.star.sdb.application.DefaultViewController";
175 return aSupported;
178 Sequence< OUString> SAL_CALL OApplicationController::getSupportedServiceNames() throw(RuntimeException, std::exception)
180 return getSupportedServiceNames_Static();
183 Reference< XInterface > SAL_CALL OApplicationController::Create(const Reference<XMultiServiceFactory >& _rxFactory)
185 return *(new OApplicationController( comphelper::getComponentContext(_rxFactory)));
188 struct XContainerFunctor : public ::std::unary_function< OApplicationController::TContainerVector::value_type , bool>
190 Reference<XContainerListener> m_xContainerListener;
191 XContainerFunctor( const Reference<XContainerListener>& _xContainerListener)
192 : m_xContainerListener(_xContainerListener){}
194 bool operator() (const OApplicationController::TContainerVector::value_type& lhs) const
196 if ( lhs.is() )
197 lhs->removeContainerListener(m_xContainerListener);
198 return true;
202 // OApplicationController
203 class SelectionNotifier : public ::boost::noncopyable
205 private:
206 ::cppu::OInterfaceContainerHelper m_aSelectionListeners;
207 ::cppu::OWeakObject& m_rContext;
208 sal_Int32 m_nSelectionNestingLevel;
210 public:
211 SelectionNotifier( ::osl::Mutex& _rMutex, ::cppu::OWeakObject& _rContext )
212 :m_aSelectionListeners( _rMutex )
213 ,m_rContext( _rContext )
214 ,m_nSelectionNestingLevel( 0 )
218 void addListener( const Reference< XSelectionChangeListener >& _Listener )
220 m_aSelectionListeners.addInterface( _Listener );
223 void removeListener( const Reference< XSelectionChangeListener >& _Listener )
225 m_aSelectionListeners.removeInterface( _Listener );
228 void disposing()
230 EventObject aEvent( m_rContext );
231 m_aSelectionListeners.disposeAndClear( aEvent );
234 ~SelectionNotifier()
238 struct SelectionGuardAccess { friend class SelectionGuard; private: SelectionGuardAccess() { } };
240 /** enters a block which modifies the selection of our owner.
242 Can be called multiple times, the only important thing is to call leaveSelection
243 equally often.
245 void enterSelection( SelectionGuardAccess )
247 ++m_nSelectionNestingLevel;
250 /** leaves a block which modifies the selection of our owner
252 Must be paired with enterSelection calls.
254 When the last block is left, i.e. the last leaveSelection call is made on the current stack,
255 then our SelectionChangeListeners are notified
257 void leaveSelection( SelectionGuardAccess )
259 if ( --m_nSelectionNestingLevel == 0 )
261 EventObject aEvent( m_rContext );
262 m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
267 class SelectionGuard : public ::boost::noncopyable
269 public:
270 SelectionGuard( SelectionNotifier& _rNotifier )
271 :m_rNotifier( _rNotifier )
273 m_rNotifier.enterSelection( SelectionNotifier::SelectionGuardAccess() );
276 ~SelectionGuard()
278 m_rNotifier.leaveSelection( SelectionNotifier::SelectionGuardAccess() );
281 private:
282 SelectionNotifier& m_rNotifier;
285 // OApplicationController
286 OApplicationController::OApplicationController(const Reference< XComponentContext >& _rxORB)
287 :OApplicationController_CBASE( _rxORB )
288 ,m_aContextMenuInterceptors( getMutex() )
289 ,m_pSubComponentManager( new SubComponentManager( *this, getSharedMutex() ) )
290 ,m_aTypeCollection( _rxORB )
291 ,m_aTableCopyHelper(this)
292 ,m_pClipbordNotifier(NULL)
293 ,m_nAsyncDrop(0)
294 ,m_aSelectContainerEvent( LINK( this, OApplicationController, OnSelectContainer ) )
295 ,m_ePreviewMode(E_PREVIEWNONE)
296 ,m_eCurrentType(E_NONE)
297 ,m_bNeedToReconnect(false)
298 ,m_bSuspended( false )
299 ,m_pSelectionNotifier( new SelectionNotifier( getMutex(), *this ) )
303 OApplicationController::~OApplicationController()
305 if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
307 OSL_FAIL("Please check who doesn't dispose this component!");
308 // increment ref count to prevent double call of Dtor
309 osl_atomic_increment( &m_refCount );
310 dispose();
312 clearView();
315 IMPLEMENT_FORWARD_XTYPEPROVIDER2(OApplicationController,OApplicationController_CBASE,OApplicationController_Base)
316 IMPLEMENT_FORWARD_XINTERFACE2(OApplicationController,OApplicationController_CBASE,OApplicationController_Base)
317 void OApplicationController::disconnect()
319 if ( m_xDataSourceConnection.is() )
320 stopConnectionListening( m_xDataSourceConnection );
324 // temporary (hopefully!) hack for #i55274#
325 Reference< XFlushable > xFlush( m_xDataSourceConnection, UNO_QUERY );
326 if ( xFlush.is() && m_xMetaData.is() && !m_xMetaData->isReadOnly() )
327 xFlush->flush();
329 catch( const Exception& )
331 DBG_UNHANDLED_EXCEPTION();
334 m_xDataSourceConnection.clear();
335 m_xMetaData.clear();
337 InvalidateAll();
340 void SAL_CALL OApplicationController::disposing()
342 ::std::for_each(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),XContainerFunctor(this));
343 m_aCurrentContainers.clear();
344 m_pSubComponentManager->disposing();
345 m_pSelectionNotifier->disposing();
347 if ( getView() )
349 getContainer()->showPreview(NULL);
350 m_pClipbordNotifier->ClearCallbackLink();
351 m_pClipbordNotifier->AddRemoveListener( getView(), false );
352 m_pClipbordNotifier->release();
353 m_pClipbordNotifier = NULL;
356 disconnect();
359 Reference < XFrame > xFrame;
360 attachFrame( xFrame );
362 if ( m_xDataSource.is() )
364 m_xDataSource->removePropertyChangeListener(OUString(), this);
365 m_xDataSource->removePropertyChangeListener(PROPERTY_INFO, this);
366 m_xDataSource->removePropertyChangeListener(PROPERTY_URL, this);
367 m_xDataSource->removePropertyChangeListener(PROPERTY_ISPASSWORDREQUIRED, this);
368 m_xDataSource->removePropertyChangeListener(PROPERTY_LAYOUTINFORMATION, this);
369 m_xDataSource->removePropertyChangeListener(PROPERTY_SUPPRESSVERSIONCL, this);
370 m_xDataSource->removePropertyChangeListener(PROPERTY_TABLEFILTER, this);
371 m_xDataSource->removePropertyChangeListener(PROPERTY_TABLETYPEFILTER, this);
372 m_xDataSource->removePropertyChangeListener(PROPERTY_USER, this);
373 // otherwise we may delete our datasource twice
374 Reference<XPropertySet> xProp = m_xDataSource;
375 m_xDataSource = NULL;
378 Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
379 if ( xBroadcaster.is() )
380 xBroadcaster->removeModifyListener(static_cast<XModifyListener*>(this));
382 if ( m_xModel.is() )
384 OUString sUrl = m_xModel->getURL();
385 if ( !sUrl.isEmpty() )
387 ::comphelper::NamedValueCollection aArgs( m_xModel->getArgs() );
388 if ( aArgs.getOrDefault( "PickListEntry", true ) )
390 OUString aFilter;
391 INetURLObject aURL( m_xModel->getURL() );
392 const SfxFilter* pFilter = getStandardDatabaseFilter();
393 if ( pFilter )
394 aFilter = pFilter->GetFilterName();
396 // add to svtool history options
397 SvtHistoryOptions().AppendItem( ePICKLIST,
398 aURL.GetURLNoPass( INetURLObject::NO_DECODE ),
399 aFilter,
400 getStrippedDatabaseName(),
401 OUString(),
402 boost::none);
404 // add to recent document list
405 if ( aURL.GetProtocol() == INetProtocol::File )
406 Application::AddToRecentDocumentList( aURL.GetURLNoPass( INetURLObject::NO_DECODE ),
407 (pFilter) ? pFilter->GetMimeType() : OUString(),
408 (pFilter) ? pFilter->GetServiceName() : OUString() );
412 m_xModel->disconnectController( this );
414 m_xModel.clear();
417 catch(const Exception&)
419 DBG_UNHANDLED_EXCEPTION();
422 clearView();
423 OApplicationController_CBASE::disposing(); // here the m_refCount must be equal 5
426 bool OApplicationController::Construct(vcl::Window* _pParent)
428 setView( VclPtr<OApplicationView>::Create( _pParent, getORB(), *this, m_ePreviewMode ) );
429 getView()->SetUniqueId(UID_APP_VIEW);
431 // late construction
432 bool bSuccess = false;
435 getContainer()->Construct();
436 bSuccess = true;
438 catch(const SQLException&)
441 catch(const Exception&)
443 OSL_FAIL("OApplicationController::Construct : the construction of UnoDataBrowserView failed !");
446 if ( !bSuccess )
448 clearView();
449 return false;
452 // now that we have a view we can create the clipboard listener
453 m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() );
454 m_aSystemClipboard.StartClipboardListening( );
456 m_pClipbordNotifier = new TransferableClipboardListener( LINK( this, OApplicationController, OnClipboardChanged ) );
457 m_pClipbordNotifier->acquire();
458 m_pClipbordNotifier->AddRemoveListener( getView(), true );
460 OApplicationController_CBASE::Construct( _pParent );
461 getView()->Show();
463 return true;
466 void SAL_CALL OApplicationController::disposing(const EventObject& _rSource) throw( RuntimeException, std::exception )
468 ::osl::MutexGuard aGuard( getMutex() );
469 Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
470 if ( xCon.is() )
472 OSL_ENSURE( m_xDataSourceConnection == xCon,
473 "OApplicationController::disposing: which connection does this come from?" );
475 if ( getContainer() && getContainer()->getElementType() == E_TABLE )
476 getContainer()->clearPages();
477 if ( m_xDataSourceConnection == xCon )
479 m_xMetaData.clear();
480 m_xDataSourceConnection.clear();
483 else if ( _rSource.Source == m_xModel )
485 m_xModel.clear();
487 else if ( _rSource.Source == m_xDataSource )
489 m_xDataSource = NULL;
491 else
493 Reference<XContainer> xContainer( _rSource.Source, UNO_QUERY );
494 if ( xContainer.is() )
496 TContainerVector::iterator aFind = ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer);
497 if ( aFind != m_aCurrentContainers.end() )
498 m_aCurrentContainers.erase(aFind);
500 OApplicationController_CBASE::disposing( _rSource );
504 sal_Bool SAL_CALL OApplicationController::suspend(sal_Bool bSuspend) throw( RuntimeException, std::exception )
506 // notify the OnPrepareViewClosing event (before locking any mutex)
507 Reference< XDocumentEventBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
508 if ( xBroadcaster.is() )
510 xBroadcaster->notifyDocumentEvent(
511 OUString("OnPrepareViewClosing"),
512 this,
513 Any()
517 SolarMutexGuard aSolarGuard;
518 ::osl::MutexGuard aGuard( getMutex() );
520 if ( getView() && getView()->IsInModalMode() )
521 return sal_False;
523 bool bCanSuspend = true;
525 if ( m_bSuspended != bool(bSuspend) )
527 if ( bSuspend && !closeSubComponents() )
528 return sal_False;
530 Reference<XModifiable> xModi(m_xModel,UNO_QUERY);
531 Reference<XStorable> xStor(getModel(),UNO_QUERY);
533 if ( bSuspend
534 && xStor.is()
535 && !xStor->isReadonly()
536 && ( xModi.is()
537 && xModi->isModified()
541 switch (ExecuteQuerySaveDocument(getView(),getStrippedDatabaseName()))
543 case RET_YES:
544 Execute(ID_BROWSER_SAVEDOC,Sequence<PropertyValue>());
545 bCanSuspend = !xModi->isModified();
546 // when we save the document this must be false else some press cancel
547 break;
548 case RET_CANCEL:
549 bCanSuspend = false;
550 default:
551 break;
556 if ( bCanSuspend )
557 m_bSuspended = bSuspend;
559 return bCanSuspend;
562 FeatureState OApplicationController::GetState(sal_uInt16 _nId) const
564 FeatureState aReturn;
565 aReturn.bEnabled = false;
566 // check this first
567 if ( !getContainer() || m_bReadOnly )
568 return aReturn;
572 switch (_nId)
574 case SID_OPENURL:
575 aReturn.bEnabled = true;
576 if ( m_xModel.is() )
577 aReturn.sTitle = m_xModel->getURL();
578 break;
579 case ID_BROWSER_COPY:
581 sal_Int32 nCount = getContainer()->getSelectionCount();
582 aReturn.bEnabled = nCount >= 1;
583 if ( aReturn.bEnabled && nCount == 1 && getContainer()->getElementType() == E_TABLE )
584 aReturn.bEnabled = getContainer()->isALeafSelected();
586 break;
587 case ID_BROWSER_CUT:
588 aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() >= 1;
589 aReturn.bEnabled = aReturn.bEnabled && ( !(ID_BROWSER_CUT == _nId && getContainer()->getElementType() == E_TABLE) || getContainer()->isCutAllowed() );
590 break;
591 case ID_BROWSER_PASTE:
592 switch( getContainer()->getElementType() )
594 case E_TABLE:
595 aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly() && isTableFormat();
596 break;
597 case E_QUERY:
598 aReturn.bEnabled = !isDataSourceReadOnly() && getViewClipboard().HasFormat(SotClipboardFormatId::DBACCESS_QUERY);
599 break;
600 default:
601 aReturn.bEnabled = !isDataSourceReadOnly() && OComponentTransferable::canExtractComponentDescriptor(getViewClipboard().GetDataFlavorExVector(),getContainer()->getElementType() == E_FORM);
603 break;
604 case SID_DB_APP_PASTE_SPECIAL:
605 aReturn.bEnabled = getContainer()->getElementType() == E_TABLE && !isDataSourceReadOnly() && !isConnectionReadOnly() && isTableFormat();
606 break;
607 case SID_OPENDOC:
608 aReturn.bEnabled = true;
609 break;
610 case ID_BROWSER_SAVEDOC:
611 aReturn.bEnabled = !isDataSourceReadOnly() && m_xDocumentModify.is() && m_xDocumentModify->isModified();
612 break;
613 case ID_BROWSER_SAVEASDOC:
614 aReturn.bEnabled = true;
615 break;
616 case ID_BROWSER_SORTUP:
617 aReturn.bEnabled = getContainer()->isFilled() && getContainer()->getElementCount();
618 aReturn.bChecked = aReturn.bEnabled && getContainer()->isSortUp();
619 break;
620 case ID_BROWSER_SORTDOWN:
621 aReturn.bEnabled = getContainer()->isFilled() && getContainer()->getElementCount();
622 aReturn.bChecked = aReturn.bEnabled && !getContainer()->isSortUp();
623 break;
625 case SID_NEWDOC:
626 case SID_APP_NEW_FORM:
627 case ID_DOCUMENT_CREATE_REPWIZ:
628 aReturn.bEnabled = !isDataSourceReadOnly() && SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
629 break;
630 case SID_APP_NEW_REPORT:
631 aReturn.bEnabled = !isDataSourceReadOnly()
632 && SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
633 if ( aReturn.bEnabled )
635 Reference< XContentEnumerationAccess > xEnumAccess(m_xContext->getServiceManager(), UNO_QUERY);
636 aReturn.bEnabled = xEnumAccess.is();
637 if ( aReturn.bEnabled )
639 const OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_xContext);
640 aReturn.bEnabled = !sReportEngineServiceName.isEmpty();
641 if ( aReturn.bEnabled )
643 const Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(sReportEngineServiceName);
644 aReturn.bEnabled = xEnumDrivers.is() && xEnumDrivers->hasMoreElements();
648 break;
649 case SID_DB_APP_VIEW_TABLES:
650 aReturn.bEnabled = true;
651 aReturn.bChecked = getContainer()->getElementType() == E_TABLE;
652 break;
653 case SID_DB_APP_VIEW_QUERIES:
654 aReturn.bEnabled = true;
655 aReturn.bChecked = getContainer()->getElementType() == E_QUERY;
656 break;
657 case SID_DB_APP_VIEW_FORMS:
658 aReturn.bEnabled = true;
659 aReturn.bChecked = getContainer()->getElementType() == E_FORM;
660 break;
661 case SID_DB_APP_VIEW_REPORTS:
662 aReturn.bEnabled = true;
663 aReturn.bChecked = getContainer()->getElementType() == E_REPORT;
664 break;
665 case ID_NEW_QUERY_DESIGN:
666 case ID_NEW_QUERY_SQL:
667 case ID_APP_NEW_QUERY_AUTO_PILOT:
668 case SID_DB_FORM_NEW_PILOT:
669 aReturn.bEnabled = !isDataSourceReadOnly();
670 break;
671 case ID_NEW_VIEW_DESIGN:
672 case SID_DB_NEW_VIEW_SQL:
673 case ID_NEW_VIEW_DESIGN_AUTO_PILOT:
674 aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly();
675 if ( aReturn.bEnabled )
677 Reference<XViewsSupplier> xViewsSup( getConnection(), UNO_QUERY );
678 aReturn.bEnabled = xViewsSup.is();
680 break;
681 case ID_NEW_TABLE_DESIGN:
682 case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
683 aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly();
684 break;
685 case ID_DIRECT_SQL:
686 aReturn.bEnabled = true;
687 break;
688 case ID_MIGRATE_SCRIPTS:
690 // Our document supports embedding scripts into it, if and only if there are no
691 // forms/reports with macros/scripts into them. So, we need to enable migration
692 // if and only if the database document does *not* support embedding scripts.
693 bool bAvailable =
694 !Reference< XEmbeddedScripts >( m_xModel, UNO_QUERY ).is()
695 && !Reference< XStorable >( m_xModel, UNO_QUERY_THROW )->isReadonly();
696 aReturn.bEnabled = bAvailable;
697 if ( !bAvailable )
698 aReturn.bInvisible = true;
700 break;
701 case SID_APP_NEW_FOLDER:
702 aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() <= 1;
703 if ( aReturn.bEnabled )
705 const ElementType eType = getContainer()->getElementType();
706 aReturn.bEnabled = eType == E_REPORT || eType == E_FORM;
708 break;
709 case SID_FORM_CREATE_REPWIZ_PRE_SEL:
710 case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
711 case SID_APP_NEW_REPORT_PRE_SEL:
712 aReturn.bEnabled = !isDataSourceReadOnly()
713 && SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::WRITER)
714 && getContainer()->isALeafSelected();
715 if ( aReturn.bEnabled )
717 ElementType eType = getContainer()->getElementType();
718 aReturn.bEnabled = eType == E_QUERY || eType == E_TABLE;
719 if ( aReturn.bEnabled && SID_APP_NEW_REPORT_PRE_SEL == _nId )
721 Reference< XContentEnumerationAccess > xEnumAccess(m_xContext->getServiceManager(), UNO_QUERY);
722 aReturn.bEnabled = xEnumAccess.is();
723 if ( aReturn.bEnabled )
725 static const char s_sReportDesign[] = "org.libreoffice.report.pentaho.SOReportJobFactory";
726 Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(s_sReportDesign);
727 aReturn.bEnabled = xEnumDrivers.is() && xEnumDrivers->hasMoreElements();
731 break;
732 case SID_DB_APP_DELETE:
733 case SID_DB_APP_RENAME:
734 aReturn.bEnabled = isRenameDeleteAllowed(getContainer()->getElementType(), _nId == SID_DB_APP_DELETE);
735 break;
736 case SID_DB_APP_TABLE_DELETE:
737 case SID_DB_APP_TABLE_RENAME:
738 aReturn.bEnabled = isRenameDeleteAllowed(E_TABLE, _nId == SID_DB_APP_TABLE_DELETE);
739 break;
740 case SID_DB_APP_QUERY_DELETE:
741 case SID_DB_APP_QUERY_RENAME:
742 aReturn.bEnabled = isRenameDeleteAllowed(E_QUERY, _nId == SID_DB_APP_QUERY_DELETE);
743 break;
744 case SID_DB_APP_FORM_DELETE:
745 case SID_DB_APP_FORM_RENAME:
746 aReturn.bEnabled = isRenameDeleteAllowed(E_FORM, _nId == SID_DB_APP_FORM_DELETE);
747 break;
748 case SID_DB_APP_REPORT_DELETE:
749 case SID_DB_APP_REPORT_RENAME:
750 aReturn.bEnabled = isRenameDeleteAllowed(E_REPORT, _nId == SID_DB_APP_REPORT_DELETE);
751 break;
753 case SID_SELECTALL:
754 aReturn.bEnabled = getContainer()->getElementCount() > 0 && getContainer()->getSelectionCount() != getContainer()->getElementCount();
755 break;
756 case SID_DB_APP_EDIT:
757 case SID_DB_APP_TABLE_EDIT:
758 case SID_DB_APP_QUERY_EDIT:
759 case SID_DB_APP_FORM_EDIT:
760 case SID_DB_APP_REPORT_EDIT:
761 aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() > 0
762 && getContainer()->isALeafSelected();
763 break;
764 case SID_DB_APP_EDIT_SQL_VIEW:
765 if ( isDataSourceReadOnly() )
766 aReturn.bEnabled = false;
767 else
769 switch ( getContainer()->getElementType() )
771 case E_QUERY:
772 aReturn.bEnabled = ( getContainer()->getSelectionCount() > 0 )
773 && ( getContainer()->isALeafSelected() );
774 break;
775 case E_TABLE:
776 aReturn.bEnabled = false;
777 // there's one exception: views which support altering their underlying
778 // command can be edited in SQL view, too
779 if ( ( getContainer()->getSelectionCount() > 0 )
780 && ( getContainer()->isALeafSelected() )
783 ::std::vector< OUString > aSelected;
784 getSelectionElementNames( aSelected );
785 bool bAlterableViews = true;
786 for ( ::std::vector< OUString >::const_iterator selectedName = aSelected.begin();
787 bAlterableViews && ( selectedName != aSelected.end() ) ;
788 ++selectedName
791 bAlterableViews &= impl_isAlterableView_nothrow( *selectedName );
793 aReturn.bEnabled = bAlterableViews;
795 break;
796 default:
797 break;
800 break;
801 case SID_DB_APP_OPEN:
802 case SID_DB_APP_TABLE_OPEN:
803 case SID_DB_APP_QUERY_OPEN:
804 case SID_DB_APP_FORM_OPEN:
805 case SID_DB_APP_REPORT_OPEN:
806 aReturn.bEnabled = getContainer()->getSelectionCount() > 0 && getContainer()->isALeafSelected();
807 break;
808 case SID_DB_APP_DSUSERADMIN:
809 aReturn.bEnabled = !dbaccess::ODsnTypeCollection::isEmbeddedDatabase(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
810 break;
811 case SID_DB_APP_DSRELDESIGN:
812 aReturn.bEnabled = true;
813 break;
814 case SID_DB_APP_TABLEFILTER:
815 aReturn.bEnabled = !isDataSourceReadOnly();
816 break;
817 case SID_DB_APP_REFRESH_TABLES:
818 aReturn.bEnabled = getContainer()->getElementType() == E_TABLE && isConnected();
819 break;
820 case SID_DB_APP_DSPROPS:
821 aReturn.bEnabled = m_xDataSource.is() && dbaccess::ODsnTypeCollection::isShowPropertiesEnabled(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
822 break;
823 case SID_DB_APP_DSCONNECTION_TYPE:
824 aReturn.bEnabled = !isDataSourceReadOnly() && m_xDataSource.is() && !dbaccess::ODsnTypeCollection::isEmbeddedDatabase(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
825 break;
826 case SID_DB_APP_DSADVANCED_SETTINGS:
827 aReturn.bEnabled = m_xDataSource.is() && AdvancedSettingsDialog::doesHaveAnyAdvancedSettings( m_aTypeCollection.getType(::comphelper::getString( m_xDataSource->getPropertyValue( PROPERTY_URL ) )) );
828 break;
829 case SID_DB_APP_CONVERTTOVIEW:
830 aReturn.bEnabled = !isDataSourceReadOnly();
831 if ( aReturn.bEnabled )
833 ElementType eType = getContainer()->getElementType();
834 aReturn.bEnabled = eType == E_QUERY && getContainer()->getSelectionCount() > 0;
835 if ( aReturn.bEnabled )
837 Reference<XViewsSupplier> xViewSup( getConnection(), UNO_QUERY );
838 aReturn.bEnabled = xViewSup.is() && Reference<XAppend>(xViewSup->getViews(),UNO_QUERY).is();
841 break;
842 case SID_DB_APP_DISABLE_PREVIEW:
843 aReturn.bEnabled = true;
844 aReturn.bChecked = getContainer()->getPreviewMode() == E_PREVIEWNONE;
845 break;
846 case SID_DB_APP_VIEW_DOCINFO_PREVIEW:
848 ElementType eType = getContainer()->getElementType();
849 aReturn.bEnabled = (E_REPORT == eType || E_FORM == eType);
850 aReturn.bChecked = getContainer()->getPreviewMode() == E_DOCUMENTINFO;
852 break;
853 case SID_DB_APP_VIEW_DOC_PREVIEW:
854 aReturn.bEnabled = true;
855 aReturn.bChecked = getContainer()->getPreviewMode() == E_DOCUMENT;
856 break;
857 case ID_BROWSER_UNDO:
858 aReturn.bEnabled = false;
859 break;
860 case SID_MAIL_SENDDOC:
861 aReturn.bEnabled = true;
862 break;
863 case SID_DB_APP_SENDREPORTASMAIL:
865 ElementType eType = getContainer()->getElementType();
866 aReturn.bEnabled = E_REPORT == eType && getContainer()->getSelectionCount() > 0 && getContainer()->isALeafSelected();
868 break;
869 case SID_DB_APP_SENDREPORTTOWRITER:
870 case SID_DB_APP_DBADMIN:
871 aReturn.bEnabled = false;
872 break;
873 case SID_DB_APP_STATUS_TYPE:
874 aReturn.bEnabled = m_xDataSource.is();
875 if ( aReturn.bEnabled )
877 OUString sURL;
878 m_xDataSource->getPropertyValue(PROPERTY_URL) >>= sURL;
879 OUString sDSTypeName;
880 if ( dbaccess::ODsnTypeCollection::isEmbeddedDatabase( sURL ) )
882 sDSTypeName = OUString( ModuleRes( RID_STR_EMBEDDED_DATABASE ) );
884 else
886 sDSTypeName = m_aTypeCollection.getTypeDisplayName(sURL);
888 aReturn.sTitle = sDSTypeName;
890 break;
891 case SID_DB_APP_STATUS_DBNAME:
892 aReturn.bEnabled = m_xDataSource.is();
893 if ( aReturn.bEnabled )
895 OUString sURL;
896 m_xDataSource->getPropertyValue(PROPERTY_URL) >>= sURL;
897 OUString sDatabaseName;
898 OUString sHostName;
899 sal_Int32 nPortNumber( -1 );
901 m_aTypeCollection.extractHostNamePort( sURL, sDatabaseName, sHostName, nPortNumber );
903 if ( sDatabaseName.isEmpty() )
904 sDatabaseName = m_aTypeCollection.cutPrefix( sURL );
905 if ( m_aTypeCollection.isFileSystemBased(sURL) )
907 sDatabaseName = SvtPathOptions().SubstituteVariable( sDatabaseName );
908 if ( !sDatabaseName.isEmpty() )
910 ::svt::OFileNotation aFileNotation(sDatabaseName);
911 // set this decoded URL as text
912 sDatabaseName = aFileNotation.get(::svt::OFileNotation::N_SYSTEM);
916 if ( sDatabaseName.isEmpty() )
917 sDatabaseName = m_aTypeCollection.getTypeDisplayName( sURL );
919 aReturn.sTitle = sDatabaseName;
921 break;
922 case SID_DB_APP_STATUS_USERNAME:
923 aReturn.bEnabled = m_xDataSource.is();
924 if ( aReturn.bEnabled )
925 m_xDataSource->getPropertyValue( PROPERTY_USER ) >>= aReturn.sTitle;
926 break;
927 case SID_DB_APP_STATUS_HOSTNAME:
928 aReturn.bEnabled = m_xDataSource.is();
929 if ( aReturn.bEnabled )
931 OUString sURL;
932 m_xDataSource->getPropertyValue( PROPERTY_URL ) >>= sURL;
934 OUString sHostName, sDatabaseName;
935 sal_Int32 nPortNumber = -1;
936 m_aTypeCollection.extractHostNamePort( sURL, sDatabaseName, sHostName, nPortNumber );
937 aReturn.sTitle = sHostName;
939 break;
940 default:
941 aReturn = OApplicationController_CBASE::GetState(_nId);
944 catch(const Exception& )
946 DBG_UNHANDLED_EXCEPTION();
948 return aReturn;
951 namespace
953 bool lcl_handleException_nothrow( const Reference< XModel >& _rxDocument, const Any& _rException )
955 bool bHandled = false;
957 // try handling the error with an interaction handler
958 ::comphelper::NamedValueCollection aArgs( _rxDocument->getArgs() );
959 Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
960 if ( xHandler.is() )
962 Reference< ::comphelper::OInteractionRequest > pRequest( new ::comphelper::OInteractionRequest( _rException ) );
963 Reference< ::comphelper::OInteractionApprove > pApprove( new ::comphelper::OInteractionApprove );
964 pRequest->addContinuation( pApprove.get() );
968 xHandler->handle( pRequest.get() );
970 catch( const Exception& )
972 DBG_UNHANDLED_EXCEPTION();
975 bHandled = pApprove->wasSelected();
977 return bHandled;
981 void OApplicationController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
983 SolarMutexGuard aSolarGuard;
984 ::osl::MutexGuard aGuard( getMutex() );
986 if ( isUserDefinedFeature( _nId ) )
988 OApplicationController_CBASE::Execute( _nId, aArgs );
989 return;
992 if ( !getContainer() || m_bReadOnly )
993 return; // return without execution
997 switch(_nId)
999 case ID_BROWSER_CUT:
1000 getContainer()->cut();
1001 break;
1002 case ID_BROWSER_COPY:
1004 TransferableHelper* pTransfer = copyObject( );
1005 Reference< XTransferable> aEnsureDelete = pTransfer;
1007 if ( pTransfer )
1008 pTransfer->CopyToClipboard(getView());
1010 break;
1011 case ID_BROWSER_PASTE:
1013 const TransferableDataHelper& rTransferData( getViewClipboard() );
1014 ElementType eType = getContainer()->getElementType();
1016 switch( eType )
1018 case E_TABLE:
1020 // get the selected tablename
1021 ::std::vector< OUString > aList;
1022 getSelectionElementNames( aList );
1023 if ( !aList.empty() )
1024 m_aTableCopyHelper.SetTableNameForAppend( *aList.begin() );
1025 else
1026 m_aTableCopyHelper.ResetTableNameForAppend();
1028 m_aTableCopyHelper.pasteTable( rTransferData , getDatabaseName(), ensureConnection() );
1030 break;
1032 case E_QUERY:
1033 if ( rTransferData.HasFormat(SotClipboardFormatId::DBACCESS_QUERY) )
1034 paste( E_QUERY, ODataAccessObjectTransferable::extractObjectDescriptor( rTransferData ) );
1035 break;
1036 default:
1038 ::std::vector< OUString> aList;
1039 getSelectionElementNames(aList);
1040 OUString sFolderNameToInsertInto;
1041 if ( !aList.empty() )
1043 Reference< XHierarchicalNameAccess > xContainer(getElements(eType),UNO_QUERY);
1044 if ( xContainer.is()
1045 && xContainer->hasByHierarchicalName(*aList.begin())
1046 && (xContainer->getByHierarchicalName(*aList.begin()) >>= xContainer)
1047 && xContainer.is()
1049 sFolderNameToInsertInto = *aList.begin();
1051 paste( eType, OComponentTransferable::extractComponentDescriptor( rTransferData ),
1052 sFolderNameToInsertInto );
1054 break;
1057 break;
1058 case SID_DB_APP_PASTE_SPECIAL:
1060 if ( !aArgs.getLength() )
1062 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
1063 ::std::unique_ptr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog( getView() ));
1064 ::std::vector<SotClipboardFormatId> aFormatIds;
1065 getSupportedFormats(getContainer()->getElementType(),aFormatIds);
1066 const ::std::vector<SotClipboardFormatId>::iterator aEnd = aFormatIds.end();
1067 OUString sEmpty;
1068 for (::std::vector<SotClipboardFormatId>::iterator aIter = aFormatIds.begin();aIter != aEnd; ++aIter)
1069 pDlg->Insert(*aIter,sEmpty);
1071 const TransferableDataHelper& rClipboard = getViewClipboard();
1072 pasteFormat(pDlg->GetFormat(rClipboard.GetTransferable()));
1074 else
1076 const PropertyValue* pIter = aArgs.getConstArray();
1077 const PropertyValue* pEnd = pIter + aArgs.getLength();
1078 for( ; pIter != pEnd ; ++pIter)
1080 if ( pIter->Name == "FormatStringId" )
1082 sal_uLong nTmp;
1083 if ( pIter->Value >>= nTmp )
1084 pasteFormat(static_cast<SotClipboardFormatId>(nTmp));
1085 break;
1090 break;
1091 case SID_OPENDOC:
1093 Reference < XDispatchProvider > xProv( getFrame(), UNO_QUERY );
1094 if ( xProv.is() )
1096 URL aURL;
1097 switch(_nId)
1099 case SID_OPENDOC:
1100 aURL.Complete = ".uno:Open";
1101 break;
1104 if ( m_xUrlTransformer.is() )
1105 m_xUrlTransformer->parseStrict( aURL );
1106 Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
1107 if ( xDisp.is() )
1108 xDisp->dispatch( aURL, Sequence < PropertyValue >() );
1111 break;
1112 case ID_BROWSER_SAVEDOC:
1114 Reference< XStorable > xStore( m_xModel, UNO_QUERY_THROW );
1117 xStore->store();
1119 catch( const Exception& )
1121 lcl_handleException_nothrow( m_xModel, ::cppu::getCaughtException() );
1124 break;
1126 case ID_BROWSER_SAVEASDOC:
1128 OUString sUrl;
1129 if ( m_xModel.is() )
1130 sUrl = m_xModel->getURL();
1131 if ( sUrl.isEmpty() )
1132 sUrl = SvtPathOptions().GetWorkPath();
1134 ::sfx2::FileDialogHelper aFileDlg(
1135 ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
1136 0, getView());
1137 aFileDlg.SetDisplayDirectory( sUrl );
1139 const SfxFilter* pFilter = getStandardDatabaseFilter();
1140 if ( pFilter )
1142 aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
1143 aFileDlg.SetCurrentFilter(pFilter->GetUIName());
1146 if ( aFileDlg.Execute() != ERRCODE_NONE )
1147 break;
1149 Reference<XStorable> xStore( m_xModel, UNO_QUERY_THROW );
1150 INetURLObject aURL( aFileDlg.GetPath() );
1153 xStore->storeAsURL( aURL.GetMainURL( INetURLObject::NO_DECODE ), Sequence< PropertyValue >() );
1155 catch( const Exception& )
1157 lcl_handleException_nothrow( m_xModel, ::cppu::getCaughtException() );
1160 /*updateTitle();*/
1161 m_bCurrentlyModified = false;
1162 InvalidateFeature(ID_BROWSER_SAVEDOC);
1163 if ( getContainer()->getElementType() == E_NONE )
1165 getContainer()->selectContainer(E_NONE);
1166 getContainer()->selectContainer(E_TABLE);
1167 // #i95524#
1168 getContainer()->Invalidate();
1169 refreshTables();
1173 break;
1174 case ID_BROWSER_SORTUP:
1175 getContainer()->sortUp();
1176 InvalidateFeature(ID_BROWSER_SORTDOWN);
1177 break;
1178 case ID_BROWSER_SORTDOWN:
1179 getContainer()->sortDown();
1180 InvalidateFeature(ID_BROWSER_SORTUP);
1181 break;
1183 case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
1184 case ID_NEW_VIEW_DESIGN_AUTO_PILOT:
1185 case ID_APP_NEW_QUERY_AUTO_PILOT:
1186 case SID_DB_FORM_NEW_PILOT:
1187 case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
1188 case SID_APP_NEW_REPORT_PRE_SEL:
1189 case SID_FORM_CREATE_REPWIZ_PRE_SEL:
1190 case ID_DOCUMENT_CREATE_REPWIZ:
1191 case SID_APP_NEW_FORM:
1192 case SID_APP_NEW_REPORT:
1193 case ID_NEW_QUERY_SQL:
1194 case ID_NEW_QUERY_DESIGN:
1195 case ID_NEW_TABLE_DESIGN:
1197 ElementType eType = E_TABLE;
1198 bool bAutoPilot = false;
1199 ::comphelper::NamedValueCollection aCreationArgs;
1201 switch( _nId )
1203 case SID_DB_FORM_NEW_PILOT:
1204 case SID_FORM_CREATE_REPWIZ_PRE_SEL:
1205 bAutoPilot = true;
1206 // run through
1207 case SID_APP_NEW_FORM:
1208 eType = E_FORM;
1209 break;
1210 case ID_DOCUMENT_CREATE_REPWIZ:
1211 case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
1212 bAutoPilot = true;
1213 // run through
1214 case SID_APP_NEW_REPORT:
1215 case SID_APP_NEW_REPORT_PRE_SEL:
1216 eType = E_REPORT;
1217 break;
1218 case ID_APP_NEW_QUERY_AUTO_PILOT:
1219 bAutoPilot = true;
1220 eType = E_QUERY;
1221 break;
1222 case ID_NEW_QUERY_DESIGN:
1223 aCreationArgs.put( OUString(PROPERTY_GRAPHICAL_DESIGN), sal_True );
1224 // run through
1225 case ID_NEW_QUERY_SQL:
1226 eType = E_QUERY;
1227 break;
1228 case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
1229 bAutoPilot = true;
1230 // run through
1231 case ID_NEW_TABLE_DESIGN:
1232 break;
1233 default:
1234 OSL_FAIL("illegal switch call!");
1236 if ( bAutoPilot )
1237 getContainer()->PostUserEvent( LINK( this, OApplicationController, OnCreateWithPilot ), reinterpret_cast< void* >( eType ) );
1238 else
1240 Reference< XComponent > xDocDefinition;
1241 newElement( eType, aCreationArgs, xDocDefinition );
1244 break;
1245 case SID_APP_NEW_FOLDER:
1247 ElementType eType = getContainer()->getElementType();
1248 OUString sName = getContainer()->getQualifiedName( NULL );
1249 insertHierachyElement(eType,sName);
1251 break;
1252 case ID_NEW_VIEW_DESIGN:
1253 case SID_DB_NEW_VIEW_SQL:
1255 SharedConnection xConnection( ensureConnection() );
1256 if ( xConnection.is() )
1258 QueryDesigner aDesigner( getORB(), this, getFrame(), true );
1260 ::comphelper::NamedValueCollection aCreationArgs;
1261 aCreationArgs.put( OUString(PROPERTY_GRAPHICAL_DESIGN), ID_NEW_VIEW_DESIGN == _nId );
1263 const Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
1264 const Reference< XComponent > xComponent( aDesigner.createNew( xDataSource, aCreationArgs ), UNO_QUERY );
1265 onDocumentOpened( OUString(), E_QUERY, E_OPEN_DESIGN, xComponent, NULL );
1268 break;
1269 case SID_DB_APP_DELETE:
1270 case SID_DB_APP_TABLE_DELETE:
1271 case SID_DB_APP_QUERY_DELETE:
1272 case SID_DB_APP_FORM_DELETE:
1273 case SID_DB_APP_REPORT_DELETE:
1274 deleteEntries();
1275 break;
1276 case SID_DB_APP_RENAME:
1277 case SID_DB_APP_TABLE_RENAME:
1278 case SID_DB_APP_QUERY_RENAME:
1279 case SID_DB_APP_FORM_RENAME:
1280 case SID_DB_APP_REPORT_RENAME:
1281 renameEntry();
1282 break;
1283 case SID_DB_APP_EDIT:
1284 case SID_DB_APP_EDIT_SQL_VIEW:
1285 case SID_DB_APP_TABLE_EDIT:
1286 case SID_DB_APP_QUERY_EDIT:
1287 case SID_DB_APP_FORM_EDIT:
1288 case SID_DB_APP_REPORT_EDIT:
1289 doAction( _nId, E_OPEN_DESIGN );
1290 break;
1291 case SID_DB_APP_OPEN:
1292 case SID_DB_APP_TABLE_OPEN:
1293 case SID_DB_APP_QUERY_OPEN:
1294 case SID_DB_APP_FORM_OPEN:
1295 case SID_DB_APP_REPORT_OPEN:
1296 doAction( _nId, E_OPEN_NORMAL );
1297 break;
1298 case SID_DB_APP_CONVERTTOVIEW:
1299 doAction( _nId, E_OPEN_NORMAL );
1300 break;
1301 case SID_SELECTALL:
1302 getContainer()->selectAll();
1303 InvalidateAll();
1304 break;
1305 case SID_DB_APP_DSRELDESIGN:
1307 Reference< XComponent > xRelationDesigner;
1308 if ( !m_pSubComponentManager->activateSubFrame( OUString(), SID_DB_APP_DSRELDESIGN, E_OPEN_DESIGN, xRelationDesigner ) )
1310 SharedConnection xConnection( ensureConnection() );
1311 if ( xConnection.is() )
1313 RelationDesigner aDesigner( getORB(), this, m_aCurrentFrame.getFrame() );
1315 const Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
1316 const Reference< XComponent > xComponent( aDesigner.createNew( xDataSource ), UNO_QUERY );
1317 onDocumentOpened( OUString(), SID_DB_APP_DSRELDESIGN, E_OPEN_DESIGN, xComponent, NULL );
1321 break;
1322 case SID_DB_APP_DSUSERADMIN:
1324 SharedConnection xConnection( ensureConnection() );
1325 if ( xConnection.is() )
1326 openDialog(OUString("com.sun.star.sdb.UserAdministrationDialog"));
1328 break;
1329 case SID_DB_APP_TABLEFILTER:
1330 openTableFilterDialog();
1331 askToReconnect();
1332 break;
1333 case SID_DB_APP_REFRESH_TABLES:
1334 refreshTables();
1335 break;
1336 case SID_DB_APP_DSPROPS:
1337 openDataSourceAdminDialog();
1338 askToReconnect();
1339 break;
1340 case SID_DB_APP_DSADVANCED_SETTINGS:
1341 openDialog(OUString("com.sun.star.sdb.AdvancedDatabaseSettingsDialog"));
1342 askToReconnect();
1343 break;
1344 case SID_DB_APP_DSCONNECTION_TYPE:
1345 openDialog(OUString("com.sun.star.sdb.DataSourceTypeChangeDialog"));
1346 askToReconnect();
1347 break;
1348 case ID_DIRECT_SQL:
1350 SharedConnection xConnection( ensureConnection() );
1351 if ( xConnection.is() )
1352 openDirectSQLDialog();
1354 break;
1355 case ID_MIGRATE_SCRIPTS:
1356 impl_migrateScripts_nothrow();
1357 break;
1358 case SID_DB_APP_VIEW_TABLES:
1359 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_TABLE ) );
1360 break;
1361 case SID_DB_APP_VIEW_QUERIES:
1362 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_QUERY ) );
1363 break;
1364 case SID_DB_APP_VIEW_FORMS:
1365 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_FORM ) );
1366 break;
1367 case SID_DB_APP_VIEW_REPORTS:
1368 m_aSelectContainerEvent.Call( reinterpret_cast< void* >( E_REPORT ) );
1369 break;
1370 case SID_DB_APP_DISABLE_PREVIEW:
1371 m_ePreviewMode = E_PREVIEWNONE;
1372 getContainer()->switchPreview(m_ePreviewMode);
1373 break;
1374 case SID_DB_APP_VIEW_DOCINFO_PREVIEW:
1375 m_ePreviewMode = E_DOCUMENTINFO;
1376 getContainer()->switchPreview(m_ePreviewMode);
1377 break;
1378 case SID_DB_APP_VIEW_DOC_PREVIEW:
1379 m_ePreviewMode = E_DOCUMENT;
1380 getContainer()->switchPreview(m_ePreviewMode);
1381 break;
1382 case SID_MAIL_SENDDOC:
1384 SfxMailModel aSendMail;
1385 if ( aSendMail.AttachDocument(OUString(),getModel(), OUString()) == SfxMailModel::SEND_MAIL_OK )
1386 aSendMail.Send( getFrame() );
1388 break;
1389 case SID_DB_APP_SENDREPORTASMAIL:
1390 doAction( _nId, E_OPEN_FOR_MAIL );
1391 break;
1394 catch( const Exception& )
1396 DBG_UNHANDLED_EXCEPTION();
1398 InvalidateFeature(_nId);
1401 void OApplicationController::describeSupportedFeatures()
1403 OApplicationController_CBASE::describeSupportedFeatures();
1405 implDescribeSupportedFeature( ".uno:Save", ID_BROWSER_SAVEDOC, CommandGroup::DOCUMENT );
1406 implDescribeSupportedFeature( ".uno:SaveAs", ID_BROWSER_SAVEASDOC, CommandGroup::DOCUMENT );
1407 implDescribeSupportedFeature( ".uno:SendMail", SID_MAIL_SENDDOC, CommandGroup::DOCUMENT );
1408 implDescribeSupportedFeature( ".uno:DBSendReportAsMail",SID_DB_APP_SENDREPORTASMAIL,
1409 CommandGroup::DOCUMENT );
1410 implDescribeSupportedFeature( ".uno:DBSendReportToWriter",SID_DB_APP_SENDREPORTTOWRITER,
1411 CommandGroup::DOCUMENT );
1412 implDescribeSupportedFeature( ".uno:DBNewForm", SID_APP_NEW_FORM, CommandGroup::INSERT );
1413 implDescribeSupportedFeature( ".uno:DBNewFolder", SID_APP_NEW_FOLDER, CommandGroup::INSERT );
1414 implDescribeSupportedFeature( ".uno:DBNewFormAutoPilot", SID_DB_FORM_NEW_PILOT, CommandGroup::INSERT );
1415 implDescribeSupportedFeature( ".uno:DBNewFormAutoPilotWithPreSelection",
1416 SID_FORM_CREATE_REPWIZ_PRE_SEL,
1417 CommandGroup::APPLICATION );
1419 implDescribeSupportedFeature( ".uno:DBNewReport", SID_APP_NEW_REPORT, CommandGroup::INSERT );
1420 implDescribeSupportedFeature( ".uno:DBNewReportAutoPilot",
1421 ID_DOCUMENT_CREATE_REPWIZ, CommandGroup::INSERT );
1422 implDescribeSupportedFeature( ".uno:DBNewReportAutoPilotWithPreSelection",
1423 SID_REPORT_CREATE_REPWIZ_PRE_SEL,
1424 CommandGroup::APPLICATION );
1425 implDescribeSupportedFeature( ".uno:DBNewQuery", ID_NEW_QUERY_DESIGN, CommandGroup::INSERT );
1426 implDescribeSupportedFeature( ".uno:DBNewQuerySql", ID_NEW_QUERY_SQL, CommandGroup::INSERT );
1427 implDescribeSupportedFeature( ".uno:DBNewQueryAutoPilot",ID_APP_NEW_QUERY_AUTO_PILOT,
1428 CommandGroup::INSERT );
1429 implDescribeSupportedFeature( ".uno:DBNewTable", ID_NEW_TABLE_DESIGN, CommandGroup::INSERT );
1430 implDescribeSupportedFeature( ".uno:DBNewTableAutoPilot",ID_NEW_TABLE_DESIGN_AUTO_PILOT,
1431 CommandGroup::INSERT );
1432 implDescribeSupportedFeature( ".uno:DBNewView", ID_NEW_VIEW_DESIGN, CommandGroup::INSERT );
1433 implDescribeSupportedFeature( ".uno:DBNewViewSQL", SID_DB_NEW_VIEW_SQL, CommandGroup::INSERT );
1435 implDescribeSupportedFeature( ".uno:DBDelete", SID_DB_APP_DELETE, CommandGroup::EDIT );
1436 implDescribeSupportedFeature( ".uno:Delete", SID_DB_APP_DELETE, CommandGroup::EDIT );
1437 implDescribeSupportedFeature( ".uno:DBRename", SID_DB_APP_RENAME, CommandGroup::EDIT );
1438 implDescribeSupportedFeature( ".uno:DBEdit", SID_DB_APP_EDIT, CommandGroup::EDIT );
1439 implDescribeSupportedFeature( ".uno:DBEditSqlView", SID_DB_APP_EDIT_SQL_VIEW, CommandGroup::EDIT );
1440 implDescribeSupportedFeature( ".uno:DBOpen", SID_DB_APP_OPEN, CommandGroup::EDIT );
1442 implDescribeSupportedFeature( ".uno:DBTableDelete", SID_DB_APP_TABLE_DELETE, CommandGroup::EDIT );
1443 implDescribeSupportedFeature( ".uno:DBTableRename", SID_DB_APP_TABLE_RENAME, CommandGroup::EDIT );
1444 implDescribeSupportedFeature( ".uno:DBTableEdit", SID_DB_APP_TABLE_EDIT, CommandGroup::EDIT );
1445 implDescribeSupportedFeature( ".uno:DBTableOpen", SID_DB_APP_TABLE_OPEN, CommandGroup::EDIT );
1447 implDescribeSupportedFeature( ".uno:DBQueryDelete", SID_DB_APP_QUERY_DELETE, CommandGroup::EDIT );
1448 implDescribeSupportedFeature( ".uno:DBQueryRename", SID_DB_APP_QUERY_RENAME, CommandGroup::EDIT );
1449 implDescribeSupportedFeature( ".uno:DBQueryEdit", SID_DB_APP_QUERY_EDIT, CommandGroup::EDIT );
1450 implDescribeSupportedFeature( ".uno:DBQueryOpen", SID_DB_APP_QUERY_OPEN, CommandGroup::EDIT );
1452 implDescribeSupportedFeature( ".uno:DBFormDelete", SID_DB_APP_FORM_DELETE, CommandGroup::EDIT );
1453 implDescribeSupportedFeature( ".uno:DBFormRename", SID_DB_APP_FORM_RENAME, CommandGroup::EDIT );
1454 implDescribeSupportedFeature( ".uno:DBFormEdit", SID_DB_APP_FORM_EDIT, CommandGroup::EDIT );
1455 implDescribeSupportedFeature( ".uno:DBFormOpen", SID_DB_APP_FORM_OPEN, CommandGroup::EDIT );
1457 implDescribeSupportedFeature( ".uno:DBReportDelete", SID_DB_APP_REPORT_DELETE, CommandGroup::EDIT );
1458 implDescribeSupportedFeature( ".uno:DBReportRename", SID_DB_APP_REPORT_RENAME, CommandGroup::EDIT );
1459 implDescribeSupportedFeature( ".uno:DBReportEdit", SID_DB_APP_REPORT_EDIT, CommandGroup::EDIT );
1460 implDescribeSupportedFeature( ".uno:DBReportOpen", SID_DB_APP_REPORT_OPEN, CommandGroup::EDIT );
1462 implDescribeSupportedFeature( ".uno:SelectAll", SID_SELECTALL, CommandGroup::EDIT );
1463 implDescribeSupportedFeature( ".uno:Undo", ID_BROWSER_UNDO, CommandGroup::EDIT );
1465 implDescribeSupportedFeature( ".uno:Sortup", ID_BROWSER_SORTUP, CommandGroup::VIEW );
1466 implDescribeSupportedFeature( ".uno:SortDown", ID_BROWSER_SORTDOWN, CommandGroup::VIEW );
1467 implDescribeSupportedFeature( ".uno:DBRelationDesign", SID_DB_APP_DSRELDESIGN, CommandGroup::APPLICATION );
1468 implDescribeSupportedFeature( ".uno:DBUserAdmin", SID_DB_APP_DSUSERADMIN, CommandGroup::APPLICATION );
1469 implDescribeSupportedFeature( ".uno:DBTableFilter", SID_DB_APP_TABLEFILTER, CommandGroup::APPLICATION );
1470 implDescribeSupportedFeature( ".uno:DBDSProperties", SID_DB_APP_DSPROPS, CommandGroup::EDIT );
1471 implDescribeSupportedFeature( ".uno:DBDSConnectionType", SID_DB_APP_DSCONNECTION_TYPE,
1472 CommandGroup::EDIT );
1473 implDescribeSupportedFeature( ".uno:DBDSAdvancedSettings",
1474 SID_DB_APP_DSADVANCED_SETTINGS,
1475 CommandGroup::EDIT );
1476 implDescribeSupportedFeature( ".uno:PasteSpecial", SID_DB_APP_PASTE_SPECIAL, CommandGroup::EDIT );
1477 implDescribeSupportedFeature( ".uno:DBConvertToView", SID_DB_APP_CONVERTTOVIEW, CommandGroup::EDIT );
1478 implDescribeSupportedFeature( ".uno:DBRefreshTables", SID_DB_APP_REFRESH_TABLES, CommandGroup::APPLICATION );
1479 implDescribeSupportedFeature( ".uno:DBDirectSQL", ID_DIRECT_SQL, CommandGroup::APPLICATION );
1480 implDescribeSupportedFeature( ".uno:DBMigrateScripts", ID_MIGRATE_SCRIPTS, CommandGroup::APPLICATION );
1481 implDescribeSupportedFeature( ".uno:DBViewTables", SID_DB_APP_VIEW_TABLES, CommandGroup::VIEW );
1482 implDescribeSupportedFeature( ".uno:DBViewQueries", SID_DB_APP_VIEW_QUERIES, CommandGroup::VIEW );
1483 implDescribeSupportedFeature( ".uno:DBViewForms", SID_DB_APP_VIEW_FORMS, CommandGroup::VIEW );
1484 implDescribeSupportedFeature( ".uno:DBViewReports", SID_DB_APP_VIEW_REPORTS, CommandGroup::VIEW );
1485 implDescribeSupportedFeature( ".uno:DBDisablePreview", SID_DB_APP_DISABLE_PREVIEW,CommandGroup::VIEW );
1486 implDescribeSupportedFeature( ".uno:DBShowDocInfoPreview",
1487 SID_DB_APP_VIEW_DOCINFO_PREVIEW,
1488 CommandGroup::VIEW );
1489 implDescribeSupportedFeature( ".uno:DBShowDocPreview", SID_DB_APP_VIEW_DOC_PREVIEW,
1490 CommandGroup::VIEW );
1492 implDescribeSupportedFeature( ".uno:OpenUrl", SID_OPENURL, CommandGroup::APPLICATION );
1494 // this one should not appear under Tools->Customize->Keyboard
1495 implDescribeSupportedFeature( ".uno:DBNewReportWithPreSelection",
1496 SID_APP_NEW_REPORT_PRE_SEL,CommandGroup::INTERNAL );
1497 implDescribeSupportedFeature( ".uno:DBDSImport", SID_DB_APP_DSIMPORT, CommandGroup::INTERNAL);
1498 implDescribeSupportedFeature( ".uno:DBDSExport", SID_DB_APP_DSEXPORT, CommandGroup::INTERNAL);
1499 implDescribeSupportedFeature( ".uno:DBDBAdmin", SID_DB_APP_DBADMIN, CommandGroup::INTERNAL);
1501 // status info
1502 implDescribeSupportedFeature( ".uno:DBStatusType", SID_DB_APP_STATUS_TYPE, CommandGroup::INTERNAL);
1503 implDescribeSupportedFeature( ".uno:DBStatusDBName", SID_DB_APP_STATUS_DBNAME, CommandGroup::INTERNAL);
1504 implDescribeSupportedFeature( ".uno:DBStatusUserName", SID_DB_APP_STATUS_USERNAME, CommandGroup::INTERNAL);
1505 implDescribeSupportedFeature( ".uno:DBStatusHostName", SID_DB_APP_STATUS_HOSTNAME, CommandGroup::INTERNAL);
1508 OApplicationView* OApplicationController::getContainer() const
1510 return static_cast< OApplicationView* >( getView() );
1513 // ::com::sun::star::container::XContainerListener
1514 void SAL_CALL OApplicationController::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
1516 SolarMutexGuard aSolarGuard;
1517 ::osl::MutexGuard aGuard( getMutex() );
1519 Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
1520 if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() )
1522 OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1523 if ( getContainer() )
1525 OUString sName;
1526 _rEvent.Accessor >>= sName;
1527 ElementType eType = getElementType(xContainer);
1529 switch( eType )
1531 case E_TABLE:
1532 ensureConnection();
1533 break;
1534 case E_FORM:
1535 case E_REPORT:
1537 Reference< XContainer > xSubContainer(_rEvent.Element,UNO_QUERY);
1538 if ( xSubContainer.is() )
1539 containerFound(xSubContainer);
1541 break;
1542 default:
1543 break;
1545 getContainer()->elementAdded(eType,sName,_rEvent.Element);
1550 void SAL_CALL OApplicationController::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
1552 SolarMutexGuard aSolarGuard;
1553 ::osl::MutexGuard aGuard( getMutex() );
1555 Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
1556 if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() )
1558 OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1559 OUString sName;
1560 _rEvent.Accessor >>= sName;
1561 ElementType eType = getElementType(xContainer);
1562 switch( eType )
1564 case E_TABLE:
1565 ensureConnection();
1566 break;
1567 case E_FORM:
1568 case E_REPORT:
1570 Reference<XContent> xContent(xContainer,UNO_QUERY);
1571 if ( xContent.is() )
1573 sName = xContent->getIdentifier()->getContentIdentifier() + "/" + sName;
1576 break;
1577 default:
1578 break;
1580 getContainer()->elementRemoved(eType,sName);
1584 void SAL_CALL OApplicationController::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException, std::exception)
1586 SolarMutexGuard aSolarGuard;
1587 ::osl::MutexGuard aGuard( getMutex() );
1589 Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
1590 if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() )
1592 OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1593 OUString sName;
1596 _rEvent.Accessor >>= sName;
1597 Reference<XConnection> xConnection;
1598 Reference<XPropertySet> xProp(_rEvent.Element,UNO_QUERY);
1599 OUString sNewName;
1601 ElementType eType = getElementType(xContainer);
1602 switch( eType )
1604 case E_TABLE:
1606 ensureConnection();
1607 if ( xProp.is() && m_xMetaData.is() )
1608 sNewName = ::dbaui::composeTableName( m_xMetaData, xProp, ::dbtools::eInDataManipulation, false, false, false );
1610 break;
1611 case E_FORM:
1612 case E_REPORT:
1614 Reference<XContent> xContent(xContainer,UNO_QUERY);
1615 if ( xContent.is() )
1617 sName = xContent->getIdentifier()->getContentIdentifier() + "/" + sName;
1620 break;
1621 default:
1622 break;
1624 // getContainer()->elementReplaced(getContainer()->getElementType(),sName,sNewName);
1626 catch( Exception& )
1628 DBG_UNHANDLED_EXCEPTION();
1633 namespace
1635 OUString lcl_getToolBarResource(ElementType _eType)
1637 OUString sToolbar;
1638 switch(_eType)
1640 case E_TABLE:
1641 sToolbar = "private:resource/toolbar/tableobjectbar";
1642 break;
1643 case E_QUERY:
1644 sToolbar = "private:resource/toolbar/queryobjectbar";
1645 break;
1646 case E_FORM:
1647 sToolbar = "private:resource/toolbar/formobjectbar";
1648 break;
1649 case E_REPORT:
1650 sToolbar = "private:resource/toolbar/reportobjectbar";
1651 break;
1652 case E_NONE:
1653 break;
1654 default:
1655 OSL_FAIL("Invalid ElementType!");
1656 break;
1658 return sToolbar;
1662 bool OApplicationController::onContainerSelect(ElementType _eType)
1664 OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1666 if ( m_eCurrentType != _eType && _eType != E_NONE )
1668 SelectionGuard aSelGuard( *m_pSelectionNotifier );
1670 if ( _eType == E_TABLE )
1674 SharedConnection xConnection( ensureConnection() );
1675 if ( xConnection.is() && getContainer()->getDetailView() )
1677 getContainer()->getDetailView()->createTablesPage(xConnection);
1678 Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
1679 if ( xTabSup.is() )
1680 addContainerListener(xTabSup->getTables());
1682 else
1684 return false;
1687 catch( const Exception& )
1689 return false;
1692 Reference< XLayoutManager > xLayoutManager = getLayoutManager( getFrame() );
1693 if ( xLayoutManager.is() )
1695 OUString sToolbar = lcl_getToolBarResource(_eType);
1696 OUString sDestroyToolbar = lcl_getToolBarResource(m_eCurrentType);
1698 xLayoutManager->lock();
1699 xLayoutManager->destroyElement( sDestroyToolbar );
1700 if ( !sToolbar.isEmpty() )
1702 xLayoutManager->createElement( sToolbar );
1703 xLayoutManager->requestElement( sToolbar );
1705 xLayoutManager->unlock();
1706 xLayoutManager->doLayout();
1709 if ( _eType != E_TABLE && getContainer()->getDetailView() )
1711 Reference< XNameAccess > xContainer = getElements(_eType);
1712 addContainerListener(xContainer);
1713 getContainer()->getDetailView()->createPage(_eType,xContainer);
1716 SelectionByElementType::iterator pendingSelection = m_aPendingSelection.find( _eType );
1717 if ( pendingSelection != m_aPendingSelection.end() )
1719 Sequence< OUString > aSelected( pendingSelection->second.size() );
1720 ::std::copy( pendingSelection->second.begin(), pendingSelection->second.end(), aSelected.getArray() );
1721 getContainer()->selectElements( aSelected );
1723 m_aPendingSelection.erase( pendingSelection );
1726 InvalidateAll();
1728 m_eCurrentType = _eType;
1730 return true;
1733 bool OApplicationController::onEntryDoubleClick( SvTreeListBox& _rTree )
1735 if ( getContainer() && getContainer()->isLeaf( _rTree.GetHdlEntry() ) )
1739 openElement(
1740 getContainer()->getQualifiedName( _rTree.GetHdlEntry() ),
1741 getContainer()->getElementType(),
1742 E_OPEN_NORMAL
1744 return true; // handled
1746 catch(const Exception&)
1748 DBG_UNHANDLED_EXCEPTION();
1751 return false; // not handled
1754 bool OApplicationController::impl_isAlterableView_nothrow( const OUString& _rTableOrViewName ) const
1756 OSL_PRECOND( m_xDataSourceConnection.is(), "OApplicationController::impl_isAlterableView_nothrow: no connection!" );
1758 bool bIsAlterableView( false );
1761 Reference< XViewsSupplier > xViewsSupp( m_xDataSourceConnection, UNO_QUERY );
1762 Reference< XNameAccess > xViews;
1763 if ( xViewsSupp.is() )
1764 xViews = xViewsSupp->getViews();
1766 Reference< XAlterView > xAsAlterableView;
1767 if ( xViews.is() && xViews->hasByName( _rTableOrViewName ) )
1768 xAsAlterableView.set( xViews->getByName( _rTableOrViewName ), UNO_QUERY );
1770 bIsAlterableView = xAsAlterableView.is();
1772 catch( const Exception& )
1774 DBG_UNHANDLED_EXCEPTION();
1776 return bIsAlterableView;
1779 Reference< XComponent > OApplicationController::openElement(const OUString& _sName, ElementType _eType,
1780 ElementOpenMode _eOpenMode, sal_uInt16 _nInstigatorCommand )
1782 return openElementWithArguments( _sName, _eType, _eOpenMode, _nInstigatorCommand, ::comphelper::NamedValueCollection() );
1785 Reference< XComponent > OApplicationController::openElementWithArguments( const OUString& _sName, ElementType _eType,
1786 ElementOpenMode _eOpenMode, sal_uInt16 _nInstigatorCommand, const ::comphelper::NamedValueCollection& _rAdditionalArguments )
1788 OSL_PRECOND( getContainer(), "OApplicationController::openElementWithArguments: no view!" );
1789 if ( !getContainer() )
1790 return NULL;
1792 Reference< XComponent > xRet;
1793 if ( _eOpenMode == E_OPEN_DESIGN )
1795 // OJ: http://www.openoffice.org/issues/show_bug.cgi?id=30382
1796 getContainer()->showPreview(NULL);
1799 bool isStandaloneDocument = false;
1800 switch ( _eType )
1802 case E_REPORT:
1803 if ( _eOpenMode != E_OPEN_DESIGN )
1805 // reports which are opened in a mode other than design are no sub components of our application
1806 // component, but standalone documents.
1807 isStandaloneDocument = true;
1809 // NO break!
1810 case E_FORM:
1812 if ( isStandaloneDocument || !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) )
1814 ::std::unique_ptr< OLinkedDocumentsAccess > aHelper = getDocumentsAccess( _eType );
1815 if ( !aHelper->isConnected() )
1816 break;
1818 Reference< XComponent > xDefinition;
1819 xRet = aHelper->open( _sName, xDefinition, _eOpenMode, _rAdditionalArguments );
1821 if ( !isStandaloneDocument )
1822 onDocumentOpened( _sName, _eType, _eOpenMode, xRet, xDefinition );
1825 break;
1827 case E_QUERY:
1828 case E_TABLE:
1830 if ( !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) )
1832 SharedConnection xConnection( ensureConnection() );
1833 if ( !xConnection.is() )
1834 break;
1836 ::std::unique_ptr< DatabaseObjectView > pDesigner;
1837 ::comphelper::NamedValueCollection aArguments( _rAdditionalArguments );
1839 Any aDataSource;
1840 if ( _eOpenMode == E_OPEN_DESIGN )
1842 bool bAddViewTypeArg = false;
1844 if ( _eType == E_TABLE )
1846 if ( impl_isAlterableView_nothrow( _sName ) )
1848 pDesigner.reset( new QueryDesigner( getORB(), this, m_aCurrentFrame.getFrame(), true ) );
1849 bAddViewTypeArg = true;
1851 else
1853 pDesigner.reset( new TableDesigner( getORB(), this, m_aCurrentFrame.getFrame() ) );
1856 else if ( _eType == E_QUERY )
1858 pDesigner.reset( new QueryDesigner( getORB(), this, m_aCurrentFrame.getFrame(), false ) );
1859 bAddViewTypeArg = true;
1861 aDataSource <<= m_xDataSource;
1863 if ( bAddViewTypeArg )
1865 const bool bQueryGraphicalMode =( _nInstigatorCommand != SID_DB_APP_EDIT_SQL_VIEW );
1866 aArguments.put( OUString(PROPERTY_GRAPHICAL_DESIGN), bQueryGraphicalMode );
1870 else
1872 pDesigner.reset( new ResultSetBrowser( getORB(), this, m_aCurrentFrame.getFrame(), _eType == E_TABLE ) );
1874 if ( !aArguments.has( OUString(PROPERTY_SHOWMENU) ) )
1875 aArguments.put( OUString(PROPERTY_SHOWMENU), makeAny( true ) );
1877 aDataSource <<= getDatabaseName();
1880 xRet.set( pDesigner->openExisting( aDataSource, _sName, aArguments ) );
1881 onDocumentOpened( _sName, _eType, _eOpenMode, xRet, NULL );
1884 break;
1886 default:
1887 OSL_FAIL( "OApplicationController::openElement: illegal object type!" );
1888 break;
1890 return xRet;
1893 IMPL_LINK( OApplicationController, OnSelectContainer, void*, _pType )
1895 ElementType eType = (ElementType)reinterpret_cast< sal_IntPtr >( _pType );
1896 if (getContainer())
1897 getContainer()->selectContainer(eType);
1898 return 0L;
1901 IMPL_LINK( OApplicationController, OnCreateWithPilot, void*, _pType )
1903 ElementType eType = (ElementType)reinterpret_cast< sal_IntPtr >( _pType );
1904 newElementWithPilot( eType );
1905 return 0L;
1908 void OApplicationController::newElementWithPilot( ElementType _eType )
1910 utl::CloseVeto aKeepDoc( getFrame() );
1911 // prevent the document being closed while the wizard is open
1913 OSL_ENSURE( getContainer(), "OApplicationController::newElementWithPilot: without a view?" );
1915 switch ( _eType )
1917 case E_REPORT:
1918 case E_FORM:
1920 ::std::unique_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess(_eType);
1921 if ( aHelper->isConnected() )
1923 sal_Int32 nCommandType = -1;
1924 const OUString sCurrentSelected( getCurrentlySelectedName( nCommandType ) );
1925 if ( E_REPORT == _eType )
1926 aHelper->newReportWithPilot( nCommandType, sCurrentSelected );
1927 else
1928 aHelper->newFormWithPilot( nCommandType, sCurrentSelected );
1931 break;
1932 case E_QUERY:
1933 case E_TABLE:
1935 ::std::unique_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess(_eType);
1936 if ( aHelper->isConnected() )
1938 if ( E_QUERY == _eType )
1939 aHelper->newQueryWithPilot();
1940 else
1941 aHelper->newTableWithPilot();
1944 break;
1945 case E_NONE:
1946 break;
1949 // no need for onDocumentOpened, the table wizard opens the created table by using
1950 // XDatabaseDocumentUI::loadComponent method.
1953 Reference< XComponent > OApplicationController::newElement( ElementType _eType, const ::comphelper::NamedValueCollection& i_rAdditionalArguments,
1954 Reference< XComponent >& o_rDocumentDefinition )
1956 OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
1958 Reference< XComponent > xComponent;
1959 o_rDocumentDefinition.clear();
1961 switch ( _eType )
1963 case E_FORM:
1964 case E_REPORT:
1966 ::std::unique_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess( _eType );
1967 if ( !aHelper->isConnected() )
1968 break;
1970 xComponent = aHelper->newDocument( _eType == E_FORM ? ID_FORM_NEW_TEXT : ID_REPORT_NEW_TEXT, i_rAdditionalArguments, o_rDocumentDefinition );
1972 break;
1974 case E_QUERY:
1975 case E_TABLE:
1977 ::std::unique_ptr< DatabaseObjectView > pDesigner;
1978 SharedConnection xConnection( ensureConnection() );
1979 if ( !xConnection.is() )
1980 break;
1982 if ( _eType == E_TABLE )
1984 pDesigner.reset( new TableDesigner( getORB(), this, getFrame() ) );
1986 else if ( _eType == E_QUERY )
1988 pDesigner.reset( new QueryDesigner( getORB(), this, getFrame(), false ) );
1991 Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
1992 xComponent.set( pDesigner->createNew( xDataSource, i_rAdditionalArguments ), UNO_QUERY );
1994 break;
1996 default:
1997 OSL_FAIL( "OApplicationController::newElement: illegal type!" );
1998 break;
2001 if ( xComponent.is() )
2002 onDocumentOpened( OUString(), _eType, E_OPEN_DESIGN, xComponent, o_rDocumentDefinition );
2004 return xComponent;
2007 void OApplicationController::addContainerListener(const Reference<XNameAccess>& _xCollection)
2011 Reference< XContainer > xCont(_xCollection, UNO_QUERY);
2012 if ( xCont.is() )
2014 // add as listener to get notified if elements are inserted or removed
2015 TContainerVector::iterator aFind = ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xCont);
2016 if ( aFind == m_aCurrentContainers.end() )
2018 xCont->addContainerListener(this);
2019 m_aCurrentContainers.push_back(xCont);
2023 catch( const Exception& )
2025 DBG_UNHANDLED_EXCEPTION();
2029 void OApplicationController::renameEntry()
2031 SolarMutexGuard aSolarGuard;
2032 ::osl::MutexGuard aGuard( getMutex() );
2034 OSL_ENSURE(getContainer(),"View is NULL! -> GPF");
2035 ::std::vector< OUString> aList;
2036 getSelectionElementNames(aList);
2038 Reference< XNameAccess > xContainer = getElements(getContainer()->getElementType());
2039 OSL_ENSURE(aList.size() == 1,"Invalid rename call here. More than one element!");
2040 if ( aList.empty() )
2041 return;
2045 if ( xContainer.is() )
2047 ::std::unique_ptr< IObjectNameCheck > pNameChecker;
2048 VclPtr< OSaveAsDlg > aDialog;
2050 Reference<XRename> xRename;
2051 const ElementType eType = getContainer()->getElementType();
2052 switch( eType )
2054 case E_FORM:
2055 case E_REPORT:
2057 Reference<XHierarchicalNameContainer> xHNames(xContainer, UNO_QUERY);
2058 if ( xHNames.is() )
2060 OUString sLabel;
2061 if ( eType == E_FORM )
2062 sLabel = OUString(ModuleRes( STR_FRM_LABEL ));
2063 else
2064 sLabel = OUString(ModuleRes( STR_RPT_LABEL ));
2066 OUString sName = *aList.begin();
2067 if ( xHNames->hasByHierarchicalName(sName) )
2069 xRename.set(xHNames->getByHierarchicalName(sName),UNO_QUERY);
2070 Reference<XChild> xChild(xRename,UNO_QUERY);
2071 if ( xChild.is() )
2073 Reference<XHierarchicalNameContainer> xParent(xChild->getParent(),UNO_QUERY);
2074 if ( xParent.is() )
2076 xHNames = xParent;
2077 Reference<XPropertySet>(xRename,UNO_QUERY)->getPropertyValue(PROPERTY_NAME) >>= sName;
2080 pNameChecker.reset( new HierarchicalNameCheck( xHNames.get(), OUString() ) );
2081 aDialog.reset( VclPtr<OSaveAsDlg>::Create(
2083 getView(), getORB(), sName, sLabel, *pNameChecker, SAD_TITLE_RENAME ) );
2087 break;
2088 case E_TABLE:
2089 ensureConnection();
2090 if ( !getConnection().is() )
2091 break;
2092 // NO break
2093 case E_QUERY:
2094 if ( xContainer->hasByName(*aList.begin()) )
2096 xRename.set(xContainer->getByName(*aList.begin()),UNO_QUERY);
2097 sal_Int32 nCommandType = eType == E_QUERY ? CommandType::QUERY : CommandType::TABLE;
2099 ensureConnection();
2100 pNameChecker.reset( new DynamicTableOrQueryNameCheck( getConnection(), nCommandType ) );
2101 aDialog.reset( VclPtr<OSaveAsDlg>::Create(
2103 getView(), nCommandType, getORB(), getConnection(),
2104 *aList.begin(), *pNameChecker, SAD_TITLE_RENAME ) );
2106 break;
2107 default:
2108 break;
2111 if ( xRename.is() && aDialog.get() )
2114 bool bTryAgain = true;
2115 while( bTryAgain )
2117 if ( aDialog->Execute() == RET_OK )
2121 OUString sNewName;
2122 if ( eType == E_TABLE )
2124 OUString sName = aDialog->getName();
2125 OUString sCatalog = aDialog->getCatalog();
2126 OUString sSchema = aDialog->getSchema();
2128 sNewName = ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sName, false, ::dbtools::eInDataManipulation );
2130 else
2131 sNewName = aDialog->getName();
2133 OUString sOldName = *aList.begin();
2134 if ( eType == E_FORM || eType == E_REPORT )
2136 Reference<XContent> xContent(xRename,UNO_QUERY);
2137 if ( xContent.is() )
2139 sOldName = xContent->getIdentifier()->getContentIdentifier();
2143 xRename->rename(sNewName);
2145 if ( eType == E_TABLE )
2147 Reference<XPropertySet> xProp(xRename,UNO_QUERY);
2148 sNewName = ::dbaui::composeTableName( m_xMetaData, xProp, ::dbtools::eInDataManipulation, false, false, false );
2150 getContainer()->elementReplaced( eType , sOldName, sNewName );
2152 bTryAgain = false;
2154 catch(const SQLException& )
2156 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
2159 catch(const ElementExistException& e)
2161 OUString sStatus("S1000");
2162 OUString sMsg = OUString( ModuleRes( STR_NAME_ALREADY_EXISTS ) );
2163 showError(SQLExceptionInfo(SQLException(sMsg.replaceAll(OUString('#'), e.Message), e.Context, sStatus, 0, Any())));
2165 catch(const Exception& )
2167 DBG_UNHANDLED_EXCEPTION();
2170 else
2171 bTryAgain = false;
2176 catch(const Exception& )
2178 DBG_UNHANDLED_EXCEPTION();
2182 void OApplicationController::onSelectionChanged()
2184 InvalidateAll();
2186 SelectionGuard aSelGuard( *m_pSelectionNotifier );
2188 OApplicationView* pView = getContainer();
2189 if ( !pView )
2190 return;
2192 if ( pView->getSelectionCount() == 1 )
2194 const ElementType eType = pView->getElementType();
2195 if ( pView->isALeafSelected() )
2197 const OUString sName = pView->getQualifiedName( NULL /* means 'first selected' */ );
2198 showPreviewFor( eType, sName );
2203 void OApplicationController::showPreviewFor(const ElementType _eType,const OUString& _sName)
2205 if ( m_ePreviewMode == E_PREVIEWNONE )
2206 return;
2208 OApplicationView* pView = getContainer();
2209 if ( !pView )
2210 return;
2214 switch( _eType )
2216 case E_FORM:
2217 case E_REPORT:
2219 Reference< XHierarchicalNameAccess > xContainer( getElements( _eType ), UNO_QUERY_THROW );
2220 Reference< XContent> xContent( xContainer->getByHierarchicalName( _sName ), UNO_QUERY_THROW );
2221 pView->showPreview( xContent );
2223 break;
2225 case E_TABLE:
2226 case E_QUERY:
2228 SharedConnection xConnection( ensureConnection() );
2229 if ( xConnection.is() )
2230 pView->showPreview( getDatabaseName(), xConnection, _sName, _eType == E_TABLE );
2232 return;
2234 default:
2235 OSL_FAIL( "OApplicationController::showPreviewFor: unexpected element type!" );
2236 break;
2239 catch( const SQLException& )
2241 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
2243 catch(const Exception& )
2245 DBG_UNHANDLED_EXCEPTION();
2249 IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged)
2251 OnInvalidateClipboard();
2252 return 0L;
2255 void OApplicationController::OnInvalidateClipboard()
2257 InvalidateFeature(ID_BROWSER_CUT);
2258 InvalidateFeature(ID_BROWSER_COPY);
2259 InvalidateFeature(ID_BROWSER_PASTE);
2260 InvalidateFeature(SID_DB_APP_PASTE_SPECIAL);
2263 void OApplicationController::onCutEntry()
2267 void OApplicationController::onCopyEntry()
2269 Execute(ID_BROWSER_COPY,Sequence<PropertyValue>());
2272 void OApplicationController::onPasteEntry()
2274 Execute(ID_BROWSER_PASTE,Sequence<PropertyValue>());
2277 void OApplicationController::onDeleteEntry()
2279 ElementType eType = getContainer()->getElementType();
2280 sal_uInt16 nId = 0;
2281 switch(eType)
2283 case E_TABLE:
2284 nId = SID_DB_APP_TABLE_DELETE;
2285 break;
2286 case E_QUERY:
2287 nId = SID_DB_APP_QUERY_DELETE;
2288 break;
2289 case E_FORM:
2290 nId = SID_DB_APP_FORM_DELETE;
2291 break;
2292 case E_REPORT:
2293 nId = SID_DB_APP_REPORT_DELETE;
2294 break;
2295 default:
2296 OSL_FAIL("Invalid ElementType!");
2297 break;
2299 executeChecked(nId,Sequence<PropertyValue>());
2302 void OApplicationController::executeUnChecked(const URL& _rCommand, const Sequence< PropertyValue>& aArgs)
2304 OApplicationController_CBASE::executeUnChecked( _rCommand, aArgs );
2307 void OApplicationController::executeChecked(const URL& _rCommand, const Sequence< PropertyValue>& aArgs)
2309 OApplicationController_CBASE::executeChecked( _rCommand, aArgs );
2312 void OApplicationController::executeUnChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue>& aArgs)
2314 OApplicationController_CBASE::executeUnChecked( _nCommandId, aArgs );
2317 void OApplicationController::executeChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue>& aArgs)
2319 OApplicationController_CBASE::executeChecked( _nCommandId, aArgs );
2322 bool OApplicationController::isCommandEnabled(sal_uInt16 _nCommandId) const
2324 return OApplicationController_CBASE::isCommandEnabled( _nCommandId );
2327 bool OApplicationController::isCommandEnabled( const OUString& _rCompleteCommandURL ) const
2329 return OApplicationController_CBASE::isCommandEnabled( _rCompleteCommandURL );
2332 sal_uInt16 OApplicationController::registerCommandURL( const OUString& _rCompleteCommandURL )
2334 return OApplicationController_CBASE::registerCommandURL( _rCompleteCommandURL );
2337 void OApplicationController::notifyHiContrastChanged()
2339 OApplicationController_CBASE::notifyHiContrastChanged();
2342 Reference< XController > OApplicationController::getXController() throw( RuntimeException )
2344 return OApplicationController_CBASE::getXController();
2347 bool OApplicationController::interceptUserInput( const NotifyEvent& _rEvent )
2349 return OApplicationController_CBASE::interceptUserInput( _rEvent );
2352 PopupMenu* OApplicationController::getContextMenu( Control& /*_rControl*/ ) const
2354 return new PopupMenu( ModuleRes( RID_MENU_APP_EDIT ) );
2357 IController& OApplicationController::getCommandController()
2359 return *static_cast< IApplicationController* >( this );
2362 ::cppu::OInterfaceContainerHelper* OApplicationController::getContextMenuInterceptors()
2364 return &m_aContextMenuInterceptors;
2367 Any OApplicationController::getCurrentSelection( Control& _rControl ) const
2369 Sequence< NamedDatabaseObject > aSelection;
2370 getContainer()->describeCurrentSelectionForControl( _rControl, aSelection );
2371 return makeAny( aSelection );
2374 bool OApplicationController::requestQuickHelp( const SvTreeListEntry* /*_pEntry*/, OUString& /*_rText*/ ) const
2376 return false;
2379 bool OApplicationController::requestDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
2381 TransferableHelper* pTransfer = NULL;
2382 if ( getContainer() && getContainer()->getSelectionCount() )
2386 pTransfer = copyObject( );
2387 Reference< XTransferable> xEnsureDelete = pTransfer;
2389 if ( pTransfer && getContainer()->getDetailView() )
2391 ElementType eType = getContainer()->getElementType();
2392 pTransfer->StartDrag( getContainer()->getDetailView()->getTreeWindow(), ((eType == E_FORM || eType == E_REPORT) ? DND_ACTION_COPYMOVE : DND_ACTION_COPY) );
2395 catch(const Exception& )
2397 DBG_UNHANDLED_EXCEPTION();
2401 return NULL != pTransfer;
2404 sal_Int8 OApplicationController::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors )
2406 sal_Int8 nActionAskedFor = _rEvt.mnAction;
2407 // check if we're a table or query container
2408 OApplicationView* pView = getContainer();
2409 if ( pView && !isDataSourceReadOnly() )
2411 ElementType eType = pView->getElementType();
2412 if ( eType != E_NONE && (eType != E_TABLE || !isConnectionReadOnly()) )
2414 // check for the concrete type
2415 if(::std::any_of(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(eType,true)))
2416 return DND_ACTION_COPY;
2417 if ( eType == E_FORM || eType == E_REPORT )
2419 sal_Int8 nAction = OComponentTransferable::canExtractComponentDescriptor(_rFlavors,eType == E_FORM) ? DND_ACTION_COPY : DND_ACTION_NONE;
2420 if ( nAction != DND_ACTION_NONE )
2422 SvTreeListEntry* pHitEntry = pView->getEntry(_rEvt.maPosPixel);
2423 OUString sName;
2424 if ( pHitEntry )
2426 sName = pView->getQualifiedName( pHitEntry );
2427 if ( !sName.isEmpty() )
2429 Reference< XHierarchicalNameAccess > xContainer(getElements(pView->getElementType()),UNO_QUERY);
2430 if ( xContainer.is() && xContainer->hasByHierarchicalName(sName) )
2432 Reference< XHierarchicalNameAccess > xHitObject(xContainer->getByHierarchicalName(sName),UNO_QUERY);
2433 if ( xHitObject.is() )
2434 nAction = nActionAskedFor & DND_ACTION_COPYMOVE;
2436 else
2437 nAction = DND_ACTION_NONE;
2441 return nAction;
2446 return DND_ACTION_NONE;
2449 sal_Int8 OApplicationController::executeDrop( const ExecuteDropEvent& _rEvt )
2451 OApplicationView* pView = getContainer();
2452 if ( !pView || pView->getElementType() == E_NONE )
2454 OSL_FAIL("OApplicationController::executeDrop: what the hell did queryDrop do?");
2455 // queryDrop should not have allowed us to reach this situation ....
2456 return DND_ACTION_NONE;
2459 // a TransferableDataHelper for accessing the dropped data
2460 TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable);
2462 // reset the data of the previous async drop (if any)
2463 if ( m_nAsyncDrop )
2464 Application::RemoveUserEvent(m_nAsyncDrop);
2466 m_nAsyncDrop = 0;
2467 m_aAsyncDrop.aDroppedData.clear();
2468 m_aAsyncDrop.nType = pView->getElementType();
2469 m_aAsyncDrop.nAction = _rEvt.mnAction;
2470 m_aAsyncDrop.bError = false;
2471 m_aAsyncDrop.bHtml = false;
2472 m_aAsyncDrop.aUrl.clear();
2474 // loop through the available formats and see what we can do ...
2475 // first we have to check if it is our own format, if not we have to copy the stream :-(
2476 if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) )
2478 m_aAsyncDrop.aDroppedData = ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData);
2480 // asynchron because we some dialogs and we aren't allowed to show them while in D&D
2481 m_nAsyncDrop = Application::PostUserEvent(LINK(this, OApplicationController, OnAsyncDrop));
2482 return DND_ACTION_COPY;
2484 else if ( OComponentTransferable::canExtractComponentDescriptor(aDroppedData.GetDataFlavorExVector(),m_aAsyncDrop.nType == E_FORM) )
2486 m_aAsyncDrop.aDroppedData = OComponentTransferable::extractComponentDescriptor(aDroppedData);
2487 SvTreeListEntry* pHitEntry = pView->getEntry(_rEvt.maPosPixel);
2488 if ( pHitEntry )
2489 m_aAsyncDrop.aUrl = pView->getQualifiedName( pHitEntry );
2491 sal_Int8 nAction = _rEvt.mnAction;
2492 Reference<XContent> xContent;
2493 m_aAsyncDrop.aDroppedData[daComponent] >>= xContent;
2494 if ( xContent.is() )
2496 OUString sName = xContent->getIdentifier()->getContentIdentifier();
2497 sal_Int32 nIndex = 0;
2498 sName = sName.copy(sName.getToken(0,'/',nIndex).getLength() + 1);
2499 if ( m_aAsyncDrop.aUrl.getLength() >= sName.getLength() && m_aAsyncDrop.aUrl.startsWith(sName) )
2501 m_aAsyncDrop.aDroppedData.clear();
2502 return DND_ACTION_NONE;
2505 // check if move is allowed, if another object with the same name exists only copy is allowed
2506 Reference< XHierarchicalNameAccess > xContainer(getElements(m_aAsyncDrop.nType),UNO_QUERY);
2507 Reference<XNameAccess> xNameAccess(xContainer,UNO_QUERY);
2509 if ( !m_aAsyncDrop.aUrl.isEmpty() && xContainer.is() && xContainer->hasByHierarchicalName(m_aAsyncDrop.aUrl) )
2510 xNameAccess.set(xContainer->getByHierarchicalName(m_aAsyncDrop.aUrl),UNO_QUERY);
2512 if ( xNameAccess.is() )
2514 Reference<XPropertySet> xProp(xContent,UNO_QUERY);
2515 if ( xProp.is() )
2517 xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
2518 if ( xNameAccess.is() && xNameAccess->hasByName(sName) )
2519 nAction &= ~DND_ACTION_MOVE;
2521 else
2522 nAction &= ~DND_ACTION_MOVE;
2525 if ( nAction != DND_ACTION_NONE )
2527 m_aAsyncDrop.nAction = nAction;
2528 // asynchron because we some dialogs and we aren't allowed to show them while in D&D
2529 m_nAsyncDrop = Application::PostUserEvent(LINK(this, OApplicationController, OnAsyncDrop));
2531 else
2532 m_aAsyncDrop.aDroppedData.clear();
2533 return nAction;
2535 else
2537 SharedConnection xConnection( ensureConnection() );
2538 if ( xConnection.is() && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xConnection ) )
2540 // asynchron because we some dialogs and we aren't allowed to show them while in D&D
2541 m_nAsyncDrop = Application::PostUserEvent(LINK(this, OApplicationController, OnAsyncDrop));
2542 return DND_ACTION_COPY;
2546 return DND_ACTION_NONE;
2549 Reference< XModel > SAL_CALL OApplicationController::getModel() throw( RuntimeException, std::exception )
2551 return m_xModel;
2554 void OApplicationController::onAttachedFrame()
2556 sal_Int32 nConnectedControllers( 0 );
2559 Reference< XModel2 > xModel( m_xModel, UNO_QUERY_THROW );
2560 Reference< XEnumeration > xEnumControllers( xModel->getControllers(), UNO_SET_THROW );
2561 while ( xEnumControllers->hasMoreElements() )
2563 Reference< XController > xController( xEnumControllers->nextElement(), UNO_QUERY_THROW );
2564 ++nConnectedControllers;
2567 catch( const Exception& )
2569 DBG_UNHANDLED_EXCEPTION();
2572 if ( nConnectedControllers > 1 )
2573 { // we are not the first connected controller, there were already others
2574 return;
2577 OnFirstControllerConnected();
2580 void OApplicationController::OnFirstControllerConnected()
2582 if ( !m_xModel.is() )
2584 OSL_FAIL( "OApplicationController::OnFirstControllerConnected: too late!" );
2587 // if we have forms or reports which contain macros/scripts, then show a warning
2588 // which suggests the user to migrate them to the database document
2589 Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
2590 if ( xDocumentScripts.is() )
2592 // no need to show this warning, obviously the document supports embedding scripts
2593 // into itself, so there are no "old-style" forms/reports which have macros/scripts
2594 // themselves
2595 return;
2600 // If the migration just happened, but was not successful, the document is reloaded.
2601 // In this case, we should not show the warning, again.
2602 ::comphelper::NamedValueCollection aModelArgs( m_xModel->getArgs() );
2603 if ( aModelArgs.getOrDefault( "SuppressMigrationWarning", sal_False ) )
2604 return;
2606 // also, if the document is read-only, then no migration is possible, and the
2607 // respective menu entry is hidden. So, don't show the warning in this case, too.
2608 if ( Reference< XStorable >( m_xModel, UNO_QUERY_THROW )->isReadonly() )
2609 return;
2611 SQLWarning aWarning;
2612 aWarning.Message = OUString( ModuleRes( STR_SUB_DOCS_WITH_SCRIPTS ) );
2613 SQLException aDetail;
2614 aDetail.Message = OUString( ModuleRes( STR_SUB_DOCS_WITH_SCRIPTS_DETAIL ) );
2615 aWarning.NextException <<= aDetail;
2617 Reference< XExecutableDialog > xDialog = ErrorMessageDialog::create( getORB(), "", NULL, makeAny( aWarning ) );
2618 xDialog->execute();
2620 catch( const Exception& )
2622 DBG_UNHANDLED_EXCEPTION();
2625 return;
2628 void SAL_CALL OApplicationController::attachFrame( const Reference< XFrame > & i_rxFrame ) throw( RuntimeException, std::exception )
2630 ::osl::MutexGuard aGuard( getMutex() );
2632 OApplicationController_CBASE::attachFrame( i_rxFrame );
2633 if ( getFrame().is() )
2634 onAttachedFrame();
2637 sal_Bool SAL_CALL OApplicationController::attachModel(const Reference< XModel > & _rxModel) throw( RuntimeException, std::exception )
2639 ::osl::MutexGuard aGuard( getMutex() );
2640 const Reference< XOfficeDatabaseDocument > xOfficeDoc( _rxModel, UNO_QUERY );
2641 const Reference< XModifiable > xDocModify( _rxModel, UNO_QUERY );
2642 if ( ( !xOfficeDoc.is() || !xDocModify.is() ) && _rxModel.is() )
2644 OSL_FAIL( "OApplicationController::attachModel: invalid model!" );
2645 return sal_False;
2648 if ( m_xModel.is() && ( m_xModel != _rxModel ) && ( _rxModel.is() ) )
2650 OSL_ENSURE( false, "OApplicationController::attachModel: missing implementation: setting a new model while we have another one!" );
2651 // we'd need to completely update our view here, close sub components, and the like
2652 return sal_False;
2655 const OUString aPropertyNames[] =
2657 OUString(PROPERTY_URL), OUString(PROPERTY_USER)
2660 // disconnect from old model
2663 if ( m_xDataSource.is() )
2665 for ( size_t i=0; i < sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i )
2667 m_xDataSource->removePropertyChangeListener( aPropertyNames[i], this );
2671 Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
2672 if ( xBroadcaster.is() )
2673 xBroadcaster->removeModifyListener( this );
2675 catch( const Exception& )
2677 DBG_UNHANDLED_EXCEPTION();
2680 m_xModel = _rxModel;
2681 m_xDocumentModify = xDocModify;
2682 m_xDataSource.set( xOfficeDoc.is() ? xOfficeDoc->getDataSource() : Reference< XDataSource >(), UNO_QUERY );
2684 // connect to new model
2687 if ( m_xDataSource.is() )
2689 for ( size_t i=0; i < sizeof( aPropertyNames ) / sizeof( aPropertyNames[0] ); ++i )
2691 m_xDataSource->addPropertyChangeListener( aPropertyNames[i], this );
2695 Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY_THROW );
2696 xBroadcaster->addModifyListener( this );
2699 catch( const Exception& )
2701 DBG_UNHANDLED_EXCEPTION();
2704 // initial preview mode
2705 if ( m_xDataSource.is() )
2709 // to get the 'modified' for the data source
2710 ::comphelper::NamedValueCollection aLayoutInfo( m_xDataSource->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) );
2711 if ( aLayoutInfo.has( OUString(INFO_PREVIEW) ) )
2713 const sal_Int32 nPreviewMode( aLayoutInfo.getOrDefault( OUString(INFO_PREVIEW), (sal_Int32)0 ) );
2714 m_ePreviewMode = static_cast< PreviewMode >( nPreviewMode );
2715 if ( getView() )
2716 getContainer()->switchPreview( m_ePreviewMode );
2719 catch( const Exception& )
2721 DBG_UNHANDLED_EXCEPTION();
2725 return sal_True;
2728 void OApplicationController::containerFound( const Reference< XContainer >& _xContainer)
2732 if ( _xContainer.is() )
2734 m_aCurrentContainers.push_back(_xContainer);
2735 _xContainer->addContainerListener(this);
2738 catch(const Exception&)
2740 DBG_UNHANDLED_EXCEPTION();
2744 OUString OApplicationController::getCurrentlySelectedName(sal_Int32& _rnCommandType) const
2746 _rnCommandType = ( (getContainer()->getElementType() == E_QUERY)
2747 ? CommandType::QUERY : ( (getContainer()->getElementType() == E_TABLE) ? CommandType::TABLE : -1 ));
2749 OUString sName;
2750 if ( _rnCommandType != -1 )
2754 sName = getContainer()->getQualifiedName( NULL );
2755 OSL_ENSURE( !sName.isEmpty(), "OApplicationController::getCurrentlySelectedName: no name given!" );
2757 catch( const Exception& )
2759 DBG_UNHANDLED_EXCEPTION();
2762 return sName;
2765 void SAL_CALL OApplicationController::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& _Listener ) throw (RuntimeException, std::exception)
2767 m_pSelectionNotifier->addListener( _Listener );
2770 void SAL_CALL OApplicationController::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& _Listener ) throw (RuntimeException, std::exception)
2772 m_pSelectionNotifier->removeListener( _Listener );
2775 sal_Bool SAL_CALL OApplicationController::select( const Any& _aSelection ) throw (IllegalArgumentException, RuntimeException, std::exception)
2777 SolarMutexGuard aSolarGuard;
2778 ::osl::MutexGuard aGuard( getMutex() );
2779 Sequence< OUString> aSelection;
2780 if ( !_aSelection.hasValue() || !getView() )
2782 getContainer()->selectElements(aSelection);
2783 return sal_True;
2786 // BEGIN compatibility
2787 Sequence< NamedValue > aCurrentSelection;
2788 if ( (_aSelection >>= aCurrentSelection) && aCurrentSelection.getLength() )
2790 ElementType eType = E_NONE;
2791 const NamedValue* pIter = aCurrentSelection.getConstArray();
2792 const NamedValue* pEnd = pIter + aCurrentSelection.getLength();
2793 for(;pIter != pEnd;++pIter)
2795 if ( pIter->Name == "Type" )
2797 sal_Int32 nType = 0;
2798 pIter->Value >>= nType;
2799 if ( nType < DatabaseObject::TABLE || nType > DatabaseObject::REPORT )
2800 throw IllegalArgumentException();
2801 eType = static_cast< ElementType >( nType );
2803 else if ( pIter->Name == "Selection" )
2804 pIter->Value >>= aSelection;
2807 m_aSelectContainerEvent.CancelCall(); // just in case the async select request was running
2808 getContainer()->selectContainer(eType);
2809 getContainer()->selectElements(aSelection);
2810 return sal_True;
2812 // END compatibility
2814 Sequence< NamedDatabaseObject > aSelectedObjects;
2815 if ( !( _aSelection >>= aSelectedObjects ) )
2817 aSelectedObjects.realloc( 1 );
2818 if ( !( _aSelection >>= aSelectedObjects[0] ) )
2819 throw IllegalArgumentException();
2822 SelectionByElementType aSelectedElements;
2823 ElementType eSelectedCategory = E_NONE;
2824 for ( const NamedDatabaseObject* pObject = aSelectedObjects.getConstArray();
2825 pObject != aSelectedObjects.getConstArray() + aSelectedObjects.getLength();
2826 ++pObject
2829 switch ( pObject->Type )
2831 case DatabaseObject::TABLE:
2832 case DatabaseObjectContainer::SCHEMA:
2833 case DatabaseObjectContainer::CATALOG:
2834 aSelectedElements[ E_TABLE ].push_back( pObject->Name );
2835 break;
2836 case DatabaseObject::QUERY:
2837 aSelectedElements[ E_QUERY ].push_back( pObject->Name );
2838 break;
2839 case DatabaseObject::FORM:
2840 case DatabaseObjectContainer::FORMS_FOLDER:
2841 aSelectedElements[ E_FORM ].push_back( pObject->Name );
2842 break;
2843 case DatabaseObject::REPORT:
2844 case DatabaseObjectContainer::REPORTS_FOLDER:
2845 aSelectedElements[ E_REPORT ].push_back( pObject->Name );
2846 break;
2847 case DatabaseObjectContainer::TABLES:
2848 case DatabaseObjectContainer::QUERIES:
2849 case DatabaseObjectContainer::FORMS:
2850 case DatabaseObjectContainer::REPORTS:
2851 if ( eSelectedCategory != E_NONE )
2852 throw IllegalArgumentException(
2853 OUString(ModuleRes(RID_STR_NO_DIFF_CAT)),
2854 *this, sal_Int16( pObject - aSelectedObjects.getConstArray() ) );
2855 eSelectedCategory =
2856 ( pObject->Type == DatabaseObjectContainer::TABLES ) ? E_TABLE
2857 : ( pObject->Type == DatabaseObjectContainer::QUERIES ) ? E_QUERY
2858 : ( pObject->Type == DatabaseObjectContainer::FORMS ) ? E_FORM
2859 : ( pObject->Type == DatabaseObjectContainer::REPORTS ) ? E_REPORT
2860 : E_NONE;
2861 break;
2863 default:
2864 case DatabaseObjectContainer::DATA_SOURCE:
2866 OUString sMessage(
2867 OUString(ModuleRes(RID_STR_UNSUPPORTED_OBJECT_TYPE)).
2868 replaceFirst("$type$", OUString::number(pObject->Type)));
2869 throw IllegalArgumentException(sMessage, *this, sal_Int16( pObject - aSelectedObjects.getConstArray() ));
2874 for ( SelectionByElementType::const_iterator sel = aSelectedElements.begin();
2875 sel != aSelectedElements.end();
2876 ++sel
2879 if ( sel->first == m_eCurrentType )
2881 Sequence< OUString > aSelected( sel->second.size() );
2882 ::std::copy( sel->second.begin(), sel->second.end(), aSelected.getArray() );
2883 getContainer()->selectElements( aSelected );
2885 else
2887 m_aPendingSelection[ sel->first ] = sel->second;
2891 m_aSelectContainerEvent.CancelCall(); // just in case the async select request was running
2892 getContainer()->selectContainer( eSelectedCategory );
2894 return sal_True;
2897 Any SAL_CALL OApplicationController::getSelection( ) throw (RuntimeException, std::exception)
2899 SolarMutexGuard aSolarGuard;
2900 ::osl::MutexGuard aGuard( getMutex() );
2902 Sequence< NamedDatabaseObject > aCurrentSelection;
2903 const ElementType eType( getContainer()->getElementType() );
2904 if ( eType != E_NONE )
2906 getContainer()->describeCurrentSelectionForType( eType, aCurrentSelection );
2907 if ( aCurrentSelection.getLength() == 0 )
2908 { // if no objects are selected, add an entry to the sequence which describes the overall category
2909 // which is selected currently
2910 aCurrentSelection.realloc(1);
2911 aCurrentSelection[0].Name = getDatabaseName();
2912 switch ( eType )
2914 case E_TABLE: aCurrentSelection[0].Type = DatabaseObjectContainer::TABLES; break;
2915 case E_QUERY: aCurrentSelection[0].Type = DatabaseObjectContainer::QUERIES; break;
2916 case E_FORM: aCurrentSelection[0].Type = DatabaseObjectContainer::FORMS; break;
2917 case E_REPORT: aCurrentSelection[0].Type = DatabaseObjectContainer::REPORTS; break;
2918 default:
2919 OSL_FAIL( "OApplicationController::getSelection: unexpected current element type!" );
2920 break;
2924 return makeAny( aCurrentSelection );
2927 void OApplicationController::impl_migrateScripts_nothrow()
2931 Reference< XExecutableDialog > xDialog = css::sdb::application::MacroMigrationWizard::createWithDocument( getORB(), Reference< XOfficeDatabaseDocument >( m_xModel, UNO_QUERY_THROW ) );
2932 xDialog->execute();
2934 catch( const Exception& )
2936 DBG_UNHANDLED_EXCEPTION();
2940 } // namespace dbaui
2942 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */