Quelle AppController.cxx
Sprache: C
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice :
*
* Licensed to the Apache Software Foundation ( ASF ) under one or more
* contributor license agreements . See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership . The ASF licenses this file to you under the Apache
* License , Version 2 . 0 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.apache.org/licenses/LICENSE-2.0 .
*/
#include <memory>
#include "AppController.hxx"
#include <core_resource.hxx>
#include <dbexchange.hxx>
#include <strings.hxx>
#include <advancedsettingsdlg.hxx>
#include "subcomponentmanager.hxx"
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/container/XHierarchicalNameContainer.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/sdb/ErrorMessageDialog.hpp>
#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
#include <com/sun/star/sdbc/SQLException.hpp>
#include <com/sun/star/sdbc/SQLWarning.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>
#include <com/sun/star/sdbcx/XAlterView.hpp>
#include <com/sun/star/sdbcx/XAppend.hpp>
#include <com/sun/star/sdbcx/XRename.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbcx/XViewsSupplier.hpp>
#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
#include <com/sun/star/util/XFlushable.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
#include <com/sun/star/frame/XModel2.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/sdb/application/DatabaseObject.hpp>
#include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
#include <comphelper/diagnose_ex.hxx>
#include <tools/urlobj.hxx>
#include <osl/diagnose.h>
#include <svl/filenotation.hxx>
#include <vcl/transfer.hxx>
#include <svtools/cliplistener.hxx>
#include <comphelper/interfacecontainer3.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/uno3.hxx>
#include <comphelper/types.hxx>
#include <comphelper/interaction.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <unotools/closeveto.hxx>
#include <unotools/pathoptions.hxx>
#include <unotools/moduleoptions.hxx>
#include <unotools/historyoptions.hxx>
#include <sfx2/mailmodelapi.hxx>
#include <sfx2/filedlghelper.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/QuerySaveDocument.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <connectivity/dbtools.hxx>
#include <connectivity/dbexception.hxx>
#include <svx/dbaexchange.hxx>
#include <svx/dbaobjectex.hxx>
#include <svx/svxdlg.hxx>
#include <osl/mutex.hxx>
#include "AppView.hxx"
#include <browserids.hxx>
#include <strings.hrc>
#include <defaultobjectnamecheck.hxx>
#include <databaseobjectview.hxx>
#include <dbtreelistbox.hxx>
#include "AppDetailView.hxx"
#include <linkeddocuments.hxx>
#include <UITools.hxx>
#include <dsntypes.hxx>
#include <dlgsave.hxx>
#include <dbaccess_slotid.hrc>
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
org_openoffice_comp_dbu_OApplicationController_get_implementation(
css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any>
const & )
{
return cppu::acquire(
new ::dbaui::OApplicationController(context));
}
namespace dbaui
{
using namespace ::dbtools;
using namespace ::svx;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::view;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::datatransfer;
using namespace ::com::sun::star::ui::dialogs;
using namespace ::com::sun::star::task;
using ::com::sun::star::document::XEmbeddedScripts;
using ::com::sun::star::document::XDocumentEventBroadcaster;
using ::com::sun::star::sdb::application::NamedDatabaseObject;
namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObj
ectContainer;
OUString SAL_CALL OApplicationController::getImplementationName()
{
return SERVICE_SDB_APPLICATIONCONTROLLER;
}
Sequence< OUString> SAL_CALL OApplicationController::getSupportedServiceNames()
{
return { u"com.sun.star.sdb.application.DefaultViewController" _ustr };
}
namespace {
class SelectionGuard;
}
// OApplicationController
class SelectionNotifier
{
private :
::comphelper::OInterfaceContainerHelper3<XSelectionChangeListener> m_aSelectionListeners;
::cppu::OWeakObject& m_rContext;
sal_Int32 m_nSelectionNestingLevel;
public :
SelectionNotifier( ::osl::Mutex& _rMutex, ::cppu::OWeakObject& _rContext )
:m_aSelectionListeners( _rMutex )
,m_rContext( _rContext )
,m_nSelectionNestingLevel( 0 )
{
}
SelectionNotifier(const SelectionNotifier&) = delete ;
const SelectionNotifier& operator =(const SelectionNotifier&) = delete ;
void addListener( const Reference< XSelectionChangeListener >& Listener )
{
m_aSelectionListeners.addInterface( Listener );
}
void removeListener( const Reference< XSelectionChangeListener >& Listener )
{
m_aSelectionListeners.removeInterface( Listener );
}
void disposing()
{
EventObject aEvent( m_rContext );
m_aSelectionListeners.disposeAndClear( aEvent );
}
struct SelectionGuardAccess { friend SelectionGuard; private : SelectionGuardAccess() { } };
/** enters a block which modifies the selection of our owner.
Can be called multiple times , the only important thing is to call leaveSelection
equally often .
*/
void enterSelection( SelectionGuardAccess )
{
++m_nSelectionNestingLevel;
}
/** leaves a block which modifies the selection of our owner
Must be paired with enterSelection calls .
When the last block is left , i . e . the last leaveSelection call is made on the current stack ,
then our SelectionChangeListeners are notified
*/
void leaveSelection( SelectionGuardAccess )
{
if ( --m_nSelectionNestingLevel == 0 )
{
EventObject aEvent( m_rContext );
m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent );
}
}
};
namespace {
class SelectionGuard
{
public :
explicit SelectionGuard( SelectionNotifier& _rNotifier )
:m_rNotifier( _rNotifier )
{
m_rNotifier.enterSelection( SelectionNotifier::SelectionGuardAccess() );
}
~SelectionGuard()
{
m_rNotifier.leaveSelection( SelectionNotifier::SelectionGuardAccess() );
}
SelectionGuard(const SelectionGuard&) = delete ;
const SelectionGuard& operator =(const SelectionGuard&) = delete ;
private :
SelectionNotifier& m_rNotifier;
};
}
// OApplicationController
OApplicationController::OApplicationController(const Reference< XComponentContext >& _rxORB)
:OGenericUnoController( _rxORB )
,m_aContextMenuInterceptors( getMutex() )
,m_pSubComponentManager( new SubComponentManager( *this , getSharedMutex() ) )
,m_aTypeCollection( _rxORB )
,m_aTableCopyHelper(this )
,m_nAsyncDrop(nullptr)
,m_aSelectContainerEvent( LINK( this , OApplicationController, OnSelectContainer ) )
,m_ePreviewMode(PreviewMode::NONE)
,m_eCurrentType(E_NONE)
,m_bNeedToReconnect(false )
,m_bSuspended( false )
,m_pSelectionNotifier( new SelectionNotifier( getMutex(), *this ) )
{
}
OApplicationController::~OApplicationController()
{
if ( !rBHelper.bDisposed && !rBHelper.bInDispose )
{
OSL_FAIL("Please check who doesn't dispose this component!" );
// increment ref count to prevent double call of Dtor
osl_atomic_increment( &m_refCount );
dispose();
}
clearView();
}
IMPLEMENT_FORWARD_XTYPEPROVIDER2(OApplicationController,OGenericUnoController,OApplicationController_Base)
IMPLEMENT_FORWARD_XINTERFACE2(OApplicationController,OGenericUnoController,OApplicationController_Base)
void OApplicationController::disconnect()
{
if ( m_xDataSourceConnection.is() )
stopConnectionListening( m_xDataSourceConnection );
try
{
// temporary (hopefully!) hack for #i55274#
Reference< XFlushable > xFlush( m_xDataSourceConnection, UNO_QUERY );
if ( xFlush.is() && m_xMetaData.is() && !m_xMetaData->isReadOnly() )
xFlush->flush();
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
m_xDataSourceConnection.clear();
m_xMetaData.clear();
InvalidateAll();
}
void SAL_CALL OApplicationController::disposing()
{
for ( const auto & rContainerListener : m_aCurrentContainers )
{
if ( rContainerListener.is() )
{
rContainerListener->removeContainerListener( this );
}
}
m_aCurrentContainers.clear();
m_pSubComponentManager->disposing();
m_pSelectionNotifier->disposing();
if ( getView() )
{
getContainer()->showPreview(nullptr);
m_pClipboardNotifier->ClearCallbackLink();
m_pClipboardNotifier->RemoveListener( getView() );
m_pClipboardNotifier.clear();
}
disconnect();
try
{
Reference < XFrame > xFrame;
attachFrame( xFrame );
if ( m_xDataSource.is() )
{
// Should correspond to ODatabaseSource::createArrayHelper in dbaccess/source/core/dataaccess/datasource.cxx
m_xDataSource->removePropertyChangeListener(OUString(), this );
m_xDataSource->removePropertyChangeListener(PROPERTY_INFO, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_ISPASSWORDREQUIRED, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_ISREADONLY, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_LAYOUTINFORMATION, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_NAME, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_NUMBERFORMATSSUPPLIER, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_PASSWORD, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_SETTINGS, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_SUPPRESSVERSIONCL, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_TABLEFILTER, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_TABLETYPEFILTER, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_URL, this );
m_xDataSource->removePropertyChangeListener(PROPERTY_USER, this );
m_xDataSource = nullptr;
}
Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
if ( xBroadcaster.is() )
xBroadcaster->removeModifyListener(static_cast <XModifyListener*>(this ));
if ( m_xModel.is() )
{
OUString sUrl = m_xModel->getURL();
if ( !sUrl.isEmpty() )
{
if ( ::comphelper::NamedValueCollection::getOrDefault( m_xModel->getArgs(), u"PickListEntry" , true ) )
{
OUString aFilter;
INetURLObject aURL( m_xModel->getURL() );
std::shared_ptr<const SfxFilter> pFilter = getStandardDatabaseFilter();
if ( pFilter )
aFilter = pFilter->GetFilterName();
OUString sDatabaseName;
// add to svtool history options
SvtHistoryOptions::AppendItem( EHistoryType::PickList,
aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ),
aFilter,
::dbaui::getStrippedDatabaseName(m_xDataSource, sDatabaseName),
std::nullopt, std::nullopt);
// add to recent document list
if ( aURL.GetProtocol() == INetProtocol::File )
Application::AddToRecentDocumentList( aURL.GetURLNoPass( INetURLObject::DecodeMechanism::NONE ),
pFilter ? pFilter->GetMimeType() : OUString(),
pFilter ? pFilter->GetServiceName() : OUString() );
}
}
m_xModel->disconnectController( this );
m_xModel.clear();
}
}
catch (const Exception&)
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
clearView();
OGenericUnoController::disposing(); // here the m_refCount must be equal 5
}
bool OApplicationController::Construct(vcl::Window* _pParent)
{
setView( VclPtr<OApplicationView>::Create( _pParent, getORB(), *this , m_ePreviewMode ) );
// late construction
bool bSuccess = false ;
try
{
getContainer()->Construct();
bSuccess = true ;
}
catch (const SQLException&)
{
}
catch (const Exception&)
{
OSL_FAIL("OApplicationController::Construct : the construction of UnoDataBrowserView failed !" );
}
if ( !bSuccess )
{
clearView();
return false ;
}
// now that we have a view we can create the clipboard listener
m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() );
m_aSystemClipboard.StartClipboardListening( );
m_pClipboardNotifier = new TransferableClipboardListener( LINK( this , OApplicationController, OnClipboardChanged ) );
m_pClipboardNotifier->AddListener( getView() );
OGenericUnoController::Construct( _pParent );
getView()->Show();
return true ;
}
void SAL_CALL OApplicationController::disposing(const EventObject& _rSource)
{
::osl::MutexGuard aGuard( getMutex() );
Reference<XConnection> xCon(_rSource.Source, UNO_QUERY);
if ( xCon.is() )
{
OSL_ENSURE( m_xDataSourceConnection == xCon,
"OApplicationController::disposing: which connection does this come from?" );
if ( getContainer() && getContainer()->getElementType() == E_TABLE )
getContainer()->clearPages();
if ( m_xDataSourceConnection == xCon )
{
m_xMetaData.clear();
m_xDataSourceConnection.clear();
}
}
else if ( _rSource.Source == m_xModel )
{
m_xModel.clear();
}
else if ( _rSource.Source == m_xDataSource )
{
m_xDataSource = nullptr;
}
else
{
Reference<XContainer> xContainer( _rSource.Source, UNO_QUERY );
if ( xContainer.is() )
{
TContainerVector::iterator aFind = std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer);
if ( aFind != m_aCurrentContainers.end() )
m_aCurrentContainers.erase(aFind);
}
OGenericUnoController::disposing( _rSource );
}
}
sal_Bool SAL_CALL OApplicationController::suspend(sal_Bool bSuspend)
{
// notify the OnPrepareViewClosing event (before locking any mutex)
Reference< XDocumentEventBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
if ( xBroadcaster.is() )
{
xBroadcaster->notifyDocumentEvent(
u"OnPrepareViewClosing" _ustr,
this ,
Any()
);
}
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
if ( getView() && getView()->IsInModalMode() )
return false ;
bool bCanSuspend = true ;
if ( m_bSuspended != bool (bSuspend) )
{
if ( bSuspend && !closeSubComponents() )
return false ;
Reference<XModifiable> xModi(m_xModel,UNO_QUERY);
Reference<XStorable> xStor(getModel(),UNO_QUERY);
if ( bSuspend
&& xStor.is()
&& !xStor->isReadonly()
&& ( xModi.is()
&& xModi->isModified()
)
)
{
OUString sDatabaseName;
switch (ExecuteQuerySaveDocument(getFrameWeld(), ::dbaui::getStrippedDatabaseName(m_xDataSource, sDatabaseName)))
{
case RET_YES:
Execute(ID_BROWSER_SAVEDOC,Sequence<PropertyValue>());
bCanSuspend = !xModi->isModified();
// when we save the document this must be false else some press cancel
break ;
case RET_CANCEL:
bCanSuspend = false ;
break ;
default :
break ;
}
}
}
if ( bCanSuspend )
m_bSuspended = bSuspend;
return bCanSuspend;
}
FeatureState OApplicationController::GetState(sal_uInt16 _nId) const
{
FeatureState aReturn;
aReturn.bEnabled = false ;
// check this first
if ( !getContainer() || m_bReadOnly )
return aReturn;
try
{
switch (_nId)
{
case SID_NEWDOCDIRECT:
aReturn.bEnabled = true ;
aReturn.sTitle = "private:factory/sdatabase" ;
break ;
case SID_OPENURL:
aReturn.bEnabled = true ;
if ( m_xModel.is() )
aReturn.sTitle = m_xModel->getURL();
break ;
case ID_BROWSER_COPY:
{
sal_Int32 nCount = getContainer()->getSelectionCount();
aReturn.bEnabled = nCount >= 1 ;
if ( aReturn.bEnabled && nCount == 1 && getContainer()->getElementType() == E_TABLE )
aReturn.bEnabled = getContainer()->isALeafSelected();
}
break ;
case ID_BROWSER_CUT:
aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() >= 1 ;
aReturn.bEnabled = aReturn.bEnabled && (getContainer()->getElementType() != E_TABLE || getContainer()->isCutAllowed());
break ;
case ID_BROWSER_PASTE:
switch ( getContainer()->getElementType() )
{
case E_TABLE:
aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly() && isTableFormat();
break ;
case E_QUERY:
aReturn.bEnabled = !isDataSourceReadOnly() && getViewClipboard().HasFormat(SotClipboardFormatId::DBACCESS_QUERY);
break ;
default :
aReturn.bEnabled = !isDataSourceReadOnly() && OComponentTransferable::canExtractComponentDescriptor(getViewClipboard().GetDataFlavorExVector(),getContainer()->getElementType() == E_FORM);
}
break ;
case SID_DB_APP_PASTE_SPECIAL:
aReturn.bEnabled = getContainer()->getElementType() == E_TABLE && !isDataSourceReadOnly() && !isConnectionReadOnly() && isTableFormat();
break ;
case SID_OPENDOC:
aReturn.bEnabled = true ;
break ;
case ID_BROWSER_SAVEDOC:
aReturn.bEnabled = !isDataSourceReadOnly();
break ;
case ID_BROWSER_SAVEASDOC:
aReturn.bEnabled = true ;
break ;
case ID_BROWSER_SORTUP:
aReturn.bEnabled = getContainer()->isFilled() && getContainer()->getElementCount();
aReturn.bChecked = aReturn.bEnabled && getContainer()->isSortUp();
break ;
case ID_BROWSER_SORTDOWN:
aReturn.bEnabled = getContainer()->isFilled() && getContainer()->getElementCount();
aReturn.bChecked = aReturn.bEnabled && !getContainer()->isSortUp();
break ;
case SID_NEWDOC:
case SID_APP_NEW_FORM:
case ID_DOCUMENT_CREATE_REPWIZ:
aReturn.bEnabled = !isDataSourceReadOnly() && SvtModuleOptions().IsWriterInstalled();
break ;
case SID_APP_NEW_REPORT:
aReturn.bEnabled = !isDataSourceReadOnly() && SvtModuleOptions().IsWriterInstalled();
if ( aReturn.bEnabled )
{
Reference< XContentEnumerationAccess > xEnumAccess(m_xContext->getServiceManager(), UNO_QUERY);
aReturn.bEnabled = xEnumAccess.is();
if ( aReturn.bEnabled )
{
const OUString sReportEngineServiceName = ::dbtools::getDefaultReportEngineServiceName(m_xContext);
aReturn.bEnabled = !sReportEngineServiceName.isEmpty();
if ( aReturn.bEnabled )
{
const Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(sReportEngineServiceName);
aReturn.bEnabled = xEnumDrivers.is() && xEnumDrivers->hasMoreElements();
}
}
}
break ;
case SID_DB_APP_VIEW_TABLES:
aReturn.bEnabled = true ;
aReturn.bChecked = getContainer()->getElementType() == E_TABLE;
break ;
case SID_DB_APP_VIEW_QUERIES:
aReturn.bEnabled = true ;
aReturn.bChecked = getContainer()->getElementType() == E_QUERY;
break ;
case SID_DB_APP_VIEW_FORMS:
aReturn.bEnabled = true ;
aReturn.bChecked = getContainer()->getElementType() == E_FORM;
break ;
case SID_DB_APP_VIEW_REPORTS:
aReturn.bEnabled = true ;
aReturn.bChecked = getContainer()->getElementType() == E_REPORT;
break ;
case ID_NEW_QUERY_DESIGN:
case ID_NEW_QUERY_SQL:
case ID_APP_NEW_QUERY_AUTO_PILOT:
case SID_DB_FORM_NEW_PILOT:
aReturn.bEnabled = !isDataSourceReadOnly();
break ;
case ID_NEW_VIEW_DESIGN:
case SID_DB_NEW_VIEW_SQL:
case ID_NEW_VIEW_DESIGN_AUTO_PILOT:
aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly();
if ( aReturn.bEnabled )
{
Reference<XViewsSupplier> xViewsSup( getConnection(), UNO_QUERY );
aReturn.bEnabled = xViewsSup.is();
}
break ;
case ID_NEW_TABLE_DESIGN:
case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
aReturn.bEnabled = !isDataSourceReadOnly() && !isConnectionReadOnly();
break ;
case ID_DIRECT_SQL:
aReturn.bEnabled = true ;
break ;
case SID_APP_NEW_FOLDER:
aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() <= 1 ;
if ( aReturn.bEnabled )
{
const ElementType eType = getContainer()->getElementType();
aReturn.bEnabled = eType == E_REPORT || eType == E_FORM;
}
break ;
case SID_FORM_CREATE_REPWIZ_PRE_SEL:
case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
case SID_APP_NEW_REPORT_PRE_SEL:
aReturn.bEnabled = !isDataSourceReadOnly()
&& SvtModuleOptions().IsWriterInstalled()
&& getContainer()->isALeafSelected();
if ( aReturn.bEnabled )
{
ElementType eType = getContainer()->getElementType();
aReturn.bEnabled = eType == E_QUERY || eType == E_TABLE;
if ( aReturn.bEnabled && SID_APP_NEW_REPORT_PRE_SEL == _nId )
{
Reference< XContentEnumerationAccess > xEnumAccess(m_xContext->getServiceManager(), UNO_QUERY);
aReturn.bEnabled = xEnumAccess.is();
if ( aReturn.bEnabled )
{
static constexpr OUStringLiteral s_sReportDesign = u"org.libreoffice.report.pentaho.SOReportJobFactory" ;
Reference< XEnumeration > xEnumDrivers = xEnumAccess->createContentEnumeration(s_sReportDesign);
aReturn.bEnabled = xEnumDrivers.is() && xEnumDrivers->hasMoreElements();
}
}
}
break ;
case SID_DB_APP_DELETE:
case SID_DB_APP_RENAME:
aReturn.bEnabled = isRenameDeleteAllowed(getContainer()->getElementType(), _nId == SID_DB_APP_DELETE);
break ;
case SID_DB_APP_TABLE_DELETE:
case SID_DB_APP_TABLE_RENAME:
aReturn.bEnabled = isRenameDeleteAllowed(E_TABLE, _nId == SID_DB_APP_TABLE_DELETE);
break ;
case SID_DB_APP_QUERY_DELETE:
case SID_DB_APP_QUERY_RENAME:
aReturn.bEnabled = isRenameDeleteAllowed(E_QUERY, _nId == SID_DB_APP_QUERY_DELETE);
break ;
case SID_DB_APP_FORM_DELETE:
case SID_DB_APP_FORM_RENAME:
aReturn.bEnabled = isRenameDeleteAllowed(E_FORM, _nId == SID_DB_APP_FORM_DELETE);
break ;
case SID_DB_APP_REPORT_DELETE:
case SID_DB_APP_REPORT_RENAME:
aReturn.bEnabled = isRenameDeleteAllowed(E_REPORT, _nId == SID_DB_APP_REPORT_DELETE);
break ;
case SID_SELECTALL:
aReturn.bEnabled = getContainer()->getElementCount() > 0 && getContainer()->getSelectionCount() != getContainer()->getElementCount();
break ;
case SID_DB_APP_EDIT:
case SID_DB_APP_TABLE_EDIT:
case SID_DB_APP_QUERY_EDIT:
case SID_DB_APP_FORM_EDIT:
case SID_DB_APP_REPORT_EDIT:
aReturn.bEnabled = !isDataSourceReadOnly() && getContainer()->getSelectionCount() > 0
&& getContainer()->isALeafSelected();
break ;
case SID_DB_APP_EDIT_SQL_VIEW:
if ( isDataSourceReadOnly() )
aReturn.bEnabled = false ;
else
{
switch ( getContainer()->getElementType() )
{
case E_QUERY:
aReturn.bEnabled = ( getContainer()->getSelectionCount() > 0 )
&& ( getContainer()->isALeafSelected() );
break ;
case E_TABLE:
aReturn.bEnabled = false ;
// there's one exception: views which support altering their underlying
// command can be edited in SQL view, too
if ( ( getContainer()->getSelectionCount() > 0 )
&& ( getContainer()->isALeafSelected() )
)
{
std::vector< OUString > aSelected;
getSelectionElementNames( aSelected );
bool bAlterableViews = true ;
for (auto const & selectedName : aSelected)
{
bAlterableViews &= impl_isAlterableView_nothrow(selectedName);
if (!bAlterableViews)
break ;
}
aReturn.bEnabled = bAlterableViews;
}
break ;
default :
break ;
}
}
break ;
case SID_DB_APP_OPEN:
case SID_DB_APP_TABLE_OPEN:
case SID_DB_APP_QUERY_OPEN:
case SID_DB_APP_FORM_OPEN:
case SID_DB_APP_REPORT_OPEN:
aReturn.bEnabled = getContainer()->getSelectionCount() > 0 && getContainer()->isALeafSelected();
break ;
case SID_DB_APP_DSUSERADMIN:
aReturn.bEnabled = !dbaccess::ODsnTypeCollection::isEmbeddedDatabase(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
break ;
case SID_DB_APP_DSRELDESIGN:
aReturn.bEnabled = true ;
break ;
case SID_DB_APP_TABLEFILTER:
aReturn.bEnabled = !isDataSourceReadOnly();
break ;
case SID_DB_APP_REFRESH_TABLES:
aReturn.bEnabled = getContainer()->getElementType() == E_TABLE && isConnected();
break ;
case SID_DB_APP_DSPROPS:
aReturn.bEnabled = m_xDataSource.is() && dbaccess::ODsnTypeCollection::isShowPropertiesEnabled(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
break ;
case SID_DB_APP_DSCONNECTION_TYPE:
aReturn.bEnabled = !isDataSourceReadOnly() && m_xDataSource.is() && !dbaccess::ODsnTypeCollection::isEmbeddedDatabase(::comphelper::getString(m_xDataSource->getPropertyValue(PROPERTY_URL)));
break ;
case SID_DB_APP_DSADVANCED_SETTINGS:
aReturn.bEnabled = m_xDataSource.is() && AdvancedSettingsDialog::doesHaveAnyAdvancedSettings( m_aTypeCollection.getType(::comphelper::getString( m_xDataSource->getPropertyValue( PROPERTY_URL ) )) );
break ;
case SID_DB_APP_CONVERTTOVIEW:
aReturn.bEnabled = !isDataSourceReadOnly();
if ( aReturn.bEnabled )
{
ElementType eType = getContainer()->getElementType();
aReturn.bEnabled = eType == E_QUERY && getContainer()->getSelectionCount() > 0 ;
if ( aReturn.bEnabled )
{
Reference<XViewsSupplier> xViewSup( getConnection(), UNO_QUERY );
aReturn.bEnabled = xViewSup.is() && Reference<XAppend>(xViewSup->getViews(),UNO_QUERY).is();
}
}
break ;
case SID_DB_APP_DISABLE_PREVIEW:
aReturn.bEnabled = true ;
aReturn.bChecked = getContainer()->getPreviewMode() == PreviewMode::NONE;
break ;
case SID_DB_APP_VIEW_DOCINFO_PREVIEW:
{
ElementType eType = getContainer()->getElementType();
aReturn.bEnabled = (E_REPORT == eType || E_FORM == eType);
aReturn.bChecked = getContainer()->getPreviewMode() == PreviewMode::DocumentInfo;
}
break ;
case SID_DB_APP_VIEW_DOC_PREVIEW:
aReturn.bEnabled = true ;
aReturn.bChecked = getContainer()->getPreviewMode() == PreviewMode::Document;
break ;
case ID_BROWSER_UNDO:
case SID_DB_APP_SENDREPORTTOWRITER:
case SID_DB_APP_DBADMIN:
aReturn.bEnabled = false ;
break ;
case SID_MAIL_SENDDOC:
aReturn.bEnabled = true ;
break ;
case SID_DB_APP_SENDREPORTASMAIL:
{
ElementType eType = getContainer()->getElementType();
aReturn.bEnabled = E_REPORT == eType && getContainer()->getSelectionCount() > 0 && getContainer()->isALeafSelected();
}
break ;
case SID_DB_APP_STATUS_TYPE:
aReturn.bEnabled = m_xDataSource.is();
if ( aReturn.bEnabled )
{
OUString sURL;
m_xDataSource->getPropertyValue(PROPERTY_URL) >>= sURL;
OUString sDSTypeName;
if ( dbaccess::ODsnTypeCollection::isEmbeddedDatabase( sURL ) )
{
sDSTypeName = DBA_RES(RID_STR_EMBEDDED_DATABASE);
}
else
{
sDSTypeName = m_aTypeCollection.getTypeDisplayName(sURL);
}
aReturn.sTitle = sDSTypeName;
}
break ;
case SID_DB_APP_STATUS_DBNAME:
aReturn.bEnabled = m_xDataSource.is();
if ( aReturn.bEnabled )
{
OUString sURL;
m_xDataSource->getPropertyValue(PROPERTY_URL) >>= sURL;
OUString sDatabaseName;
OUString sHostName;
sal_Int32 nPortNumber( -1 );
m_aTypeCollection.extractHostNamePort( sURL, sDatabaseName, sHostName, nPortNumber );
if ( sDatabaseName.isEmpty() )
sDatabaseName = m_aTypeCollection.cutPrefix( sURL );
if ( m_aTypeCollection.isFileSystemBased(sURL) )
{
sDatabaseName = SvtPathOptions().SubstituteVariable( sDatabaseName );
if ( !sDatabaseName.isEmpty() )
{
::svt::OFileNotation aFileNotation(sDatabaseName);
// set this decoded URL as text
sDatabaseName = aFileNotation.get(::svt::OFileNotation::N_SYSTEM);
}
}
if ( sDatabaseName.isEmpty() )
sDatabaseName = m_aTypeCollection.getTypeDisplayName( sURL );
aReturn.sTitle = sDatabaseName;
}
break ;
case SID_DB_APP_STATUS_USERNAME:
aReturn.bEnabled = m_xDataSource.is();
if ( aReturn.bEnabled )
m_xDataSource->getPropertyValue( PROPERTY_USER ) >>= aReturn.sTitle;
break ;
case SID_DB_APP_STATUS_HOSTNAME:
aReturn.bEnabled = m_xDataSource.is();
if ( aReturn.bEnabled )
{
OUString sURL;
m_xDataSource->getPropertyValue( PROPERTY_URL ) >>= sURL;
OUString sHostName, sDatabaseName;
sal_Int32 nPortNumber = -1 ;
m_aTypeCollection.extractHostNamePort( sURL, sDatabaseName, sHostName, nPortNumber );
aReturn.sTitle = sHostName;
}
break ;
default :
aReturn = OGenericUnoController::GetState(_nId);
}
}
catch (const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
return aReturn;
}
namespace
{
bool lcl_handleException_nothrow( const Reference< XModel >& _rxDocument, const Any& _rException )
{
bool bHandled = false ;
// try handling the error with an interaction handler
Reference< XInteractionHandler > xHandler = ::comphelper::NamedValueCollection::getOrDefault( _rxDocument->getArgs(), u"InteractionHandler" , Reference< XInteractionHandler >() );
if ( xHandler.is() )
{
rtl::Reference pRequest( new ::comphelper::OInteractionRequest( _rException ) );
rtl::Reference pApprove( new ::comphelper::OInteractionApprove );
pRequest->addContinuation( pApprove );
try
{
xHandler->handle( pRequest );
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
bHandled = pApprove->wasSelected();
}
return bHandled;
}
}
void OApplicationController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
{
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
if ( isUserDefinedFeature( _nId ) )
{
OGenericUnoController::Execute( _nId, aArgs );
return ;
}
if ( !getContainer() || m_bReadOnly )
return ; // return without execution
try
{
switch (_nId)
{
case ID_BROWSER_CUT:
getContainer()->cut();
break ;
case ID_BROWSER_COPY:
{
rtl::Reference<TransferableHelper> pTransfer = copyObject();
if ( pTransfer )
pTransfer->CopyToClipboard(getView());
}
break ;
case ID_BROWSER_PASTE:
{
const TransferableDataHelper& rTransferData( getViewClipboard() );
ElementType eType = getContainer()->getElementType();
switch ( eType )
{
case E_TABLE:
{
// get the selected tablename
std::vector< OUString > aList;
getSelectionElementNames( aList );
if ( !aList.empty() )
m_aTableCopyHelper.SetTableNameForAppend( *aList.begin() );
else
m_aTableCopyHelper.ResetTableNameForAppend();
m_aTableCopyHelper.pasteTable( rTransferData , getDatabaseName(), ensureConnection() );
}
break ;
case E_QUERY:
if ( rTransferData.HasFormat(SotClipboardFormatId::DBACCESS_QUERY) )
paste( E_QUERY, ODataAccessObjectTransferable::extractObjectDescriptor( rTransferData ) );
break ;
default :
{
std::vector< OUString> aList;
getSelectionElementNames(aList);
OUString sFolderNameToInsertInto;
if ( !aList.empty() )
{
Reference< XHierarchicalNameAccess > xContainer(getElements(eType),UNO_QUERY);
if ( xContainer.is()
&& xContainer->hasByHierarchicalName(*aList.begin())
&& (xContainer->getByHierarchicalName(*aList.begin()) >>= xContainer)
&& xContainer.is()
)
sFolderNameToInsertInto = *aList.begin();
}
paste( eType, OComponentTransferable::extractComponentDescriptor( rTransferData ),
sFolderNameToInsertInto );
}
break ;
}
}
break ;
case SID_DB_APP_PASTE_SPECIAL:
{
if ( !aArgs.hasElements() )
{
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
ScopedVclPtr<SfxAbstractPasteDialog> pDlg(pFact->CreatePasteDialog(getFrameWeld()));
std::vector<SotClipboardFormatId> aFormatIds;
getSupportedFormats(getContainer()->getElementType(),aFormatIds);
for (auto const & formatId : aFormatIds)
pDlg->Insert(formatId,u"" _ustr);
const TransferableDataHelper& rClipboard = getViewClipboard();
pasteFormat(pDlg->GetFormat(rClipboard.GetTransferable()));
}
else
{
for (auto & arg : aArgs)
{
if (arg.Name == "FormatStringId" )
{
sal_uInt32 nTmp;
if (arg.Value >>= nTmp)
pasteFormat(static_cast <SotClipboardFormatId>(nTmp));
break ;
}
}
}
}
break ;
case SID_NEWDOCDIRECT:
case SID_OPENDOC:
{
Reference < XDispatchProvider > xProv( getFrame(), UNO_QUERY );
if ( xProv.is() )
{
URL aURL;
OUString aTarget;
if ( _nId == SID_NEWDOCDIRECT )
{
aURL.Complete = "private:factory/sdatabase?Interactive" ;
aTarget = "_default" ;
}
else
aURL.Complete = ".uno:Open" ;
if ( m_xUrlTransformer.is() )
m_xUrlTransformer->parseStrict( aURL );
Reference < XDispatch > xDisp = xProv->queryDispatch( aURL, aTarget, 0 );
if ( xDisp.is() )
xDisp->dispatch( aURL, Sequence < PropertyValue >() );
}
}
break ;
case ID_BROWSER_SAVEDOC:
{
Reference< XStorable > xStore( m_xModel, UNO_QUERY_THROW );
try
{
xStore->store();
}
catch ( const Exception& )
{
lcl_handleException_nothrow( m_xModel, ::cppu::getCaughtException() );
}
}
break ;
case ID_BROWSER_SAVEASDOC:
{
OUString sUrl;
if ( m_xModel.is() )
sUrl = m_xModel->getURL();
::sfx2::FileDialogHelper aFileDlg(
ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
FileDialogFlags::NONE, getFrameWeld());
aFileDlg.SetContext(sfx2::FileDialogHelper::BaseSaveAs);
if (!sUrl.isEmpty())
aFileDlg.SetDisplayDirectory( sUrl );
std::shared_ptr<const SfxFilter> pFilter = getStandardDatabaseFilter();
if ( pFilter )
{
aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
aFileDlg.SetCurrentFilter(pFilter->GetUIName());
}
if ( aFileDlg.Execute() != ERRCODE_NONE )
break ;
Reference<XStorable> xStore( m_xModel, UNO_QUERY_THROW );
INetURLObject aURL( aFileDlg.GetPath() );
try
{
xStore->storeAsURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), Sequence< PropertyValue >() );
}
catch ( const Exception& )
{
lcl_handleException_nothrow( m_xModel, ::cppu::getCaughtException() );
}
/*updateTitle();*/
m_bCurrentlyModified = false ;
InvalidateFeature(ID_BROWSER_SAVEDOC);
if ( getContainer()->getElementType() == E_NONE )
{
getContainer()->selectContainer(E_NONE);
getContainer()->selectContainer(E_TABLE);
// #i95524#
getContainer()->Invalidate();
refreshTables();
}
}
break ;
case ID_BROWSER_SORTUP:
getContainer()->sortUp();
InvalidateFeature(ID_BROWSER_SORTDOWN);
break ;
case ID_BROWSER_SORTDOWN:
getContainer()->sortDown();
InvalidateFeature(ID_BROWSER_SORTUP);
break ;
case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
case ID_NEW_VIEW_DESIGN_AUTO_PILOT:
case ID_APP_NEW_QUERY_AUTO_PILOT:
case SID_DB_FORM_NEW_PILOT:
case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
case SID_APP_NEW_REPORT_PRE_SEL:
case SID_FORM_CREATE_REPWIZ_PRE_SEL:
case ID_DOCUMENT_CREATE_REPWIZ:
case SID_APP_NEW_FORM:
case SID_APP_NEW_REPORT:
case ID_NEW_QUERY_SQL:
case ID_NEW_QUERY_DESIGN:
case ID_NEW_TABLE_DESIGN:
{
ElementType eType = E_TABLE;
bool bAutoPilot = false ;
::comphelper::NamedValueCollection aCreationArgs;
switch ( _nId )
{
case SID_DB_FORM_NEW_PILOT:
case SID_FORM_CREATE_REPWIZ_PRE_SEL:
bAutoPilot = true ;
[[fallthrough]];
case SID_APP_NEW_FORM:
eType = E_FORM;
break ;
case ID_DOCUMENT_CREATE_REPWIZ:
case SID_REPORT_CREATE_REPWIZ_PRE_SEL:
bAutoPilot = true ;
[[fallthrough]];
case SID_APP_NEW_REPORT:
case SID_APP_NEW_REPORT_PRE_SEL:
eType = E_REPORT;
break ;
case ID_APP_NEW_QUERY_AUTO_PILOT:
bAutoPilot = true ;
eType = E_QUERY;
break ;
case ID_NEW_QUERY_DESIGN:
aCreationArgs.put( PROPERTY_GRAPHICAL_DESIGN, true );
[[fallthrough]];
case ID_NEW_QUERY_SQL:
eType = E_QUERY;
break ;
case ID_NEW_TABLE_DESIGN_AUTO_PILOT:
bAutoPilot = true ;
[[fallthrough]];
case ID_NEW_TABLE_DESIGN:
break ;
default :
OSL_FAIL("illegal switch call!" );
}
if ( bAutoPilot )
getContainer()->PostUserEvent( LINK( this , OApplicationController, OnCreateWithPilot ), reinterpret_cast < void * >( eType ) );
else
{
Reference< XComponent > xDocDefinition;
newElement( eType, aCreationArgs, xDocDefinition );
}
}
break ;
case SID_APP_NEW_FOLDER:
{
ElementType eType = getContainer()->getElementType();
OUString sName = getContainer()->getQualifiedName( nullptr );
insertHierarchyElement(eType,sName);
}
break ;
case ID_NEW_VIEW_DESIGN:
case SID_DB_NEW_VIEW_SQL:
{
SharedConnection xConnection( ensureConnection() );
if ( xConnection.is() )
{
QueryDesigner aDesigner( getORB(), this , getFrame(), true );
::comphelper::NamedValueCollection aCreationArgs;
aCreationArgs.put( PROPERTY_GRAPHICAL_DESIGN, ID_NEW_VIEW_DESIGN == _nId );
const Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
const Reference< XComponent > xComponent = aDesigner.createNew( xDataSource, aCreationArgs );
onDocumentOpened( OUString(), E_QUERY, ElementOpenMode::Design, xComponent, nullptr );
}
}
break ;
case SID_DB_APP_DELETE:
case SID_DB_APP_TABLE_DELETE:
case SID_DB_APP_QUERY_DELETE:
case SID_DB_APP_FORM_DELETE:
case SID_DB_APP_REPORT_DELETE:
deleteEntries();
break ;
case SID_DB_APP_RENAME:
case SID_DB_APP_TABLE_RENAME:
case SID_DB_APP_QUERY_RENAME:
case SID_DB_APP_FORM_RENAME:
case SID_DB_APP_REPORT_RENAME:
renameEntry();
break ;
case SID_DB_APP_EDIT:
case SID_DB_APP_EDIT_SQL_VIEW:
case SID_DB_APP_TABLE_EDIT:
case SID_DB_APP_QUERY_EDIT:
case SID_DB_APP_FORM_EDIT:
case SID_DB_APP_REPORT_EDIT:
doAction( _nId, ElementOpenMode::Design );
break ;
case SID_DB_APP_OPEN:
case SID_DB_APP_TABLE_OPEN:
case SID_DB_APP_QUERY_OPEN:
case SID_DB_APP_FORM_OPEN:
case SID_DB_APP_REPORT_OPEN:
case SID_DB_APP_CONVERTTOVIEW:
doAction( _nId, ElementOpenMode::Normal );
break ;
case SID_SELECTALL:
getContainer()->selectAll();
InvalidateAll();
break ;
case SID_DB_APP_DSRELDESIGN:
{
Reference< XComponent > xRelationDesigner;
if ( !m_pSubComponentManager->activateSubFrame( OUString(), SID_DB_APP_DSRELDESIGN, ElementOpenMode::Design, xRelationDesigner ) )
{
SharedConnection xConnection( ensureConnection() );
if ( xConnection.is() )
{
RelationDesigner aDesigner( getORB(), this , m_aCurrentFrame.getFrame() );
const Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
const Reference< XComponent > xComponent = aDesigner.createNew( xDataSource );
onDocumentOpened( OUString(), SID_DB_APP_DSRELDESIGN, ElementOpenMode::Design, xComponent, nullptr );
}
}
}
break ;
case SID_DB_APP_DSUSERADMIN:
{
SharedConnection xConnection( ensureConnection() );
if ( xConnection.is() )
openDialog(u"com.sun.star.sdb.UserAdministrationDialog" _ustr);
}
break ;
case SID_DB_APP_TABLEFILTER:
// opens the table filter dialog for the selected data source
openDialog( u"com.sun.star.sdb.TableFilterDialog" _ustr );
askToReconnect();
break ;
case SID_DB_APP_REFRESH_TABLES:
refreshTables();
break ;
case SID_DB_APP_DSPROPS:
// opens the administration dialog for the selected data source
openDialog( u"com.sun.star.sdb.DatasourceAdministrationDialog" _ustr );
askToReconnect();
break ;
case SID_DB_APP_DSADVANCED_SETTINGS:
openDialog(u"com.sun.star.sdb.AdvancedDatabaseSettingsDialog" _ustr);
askToReconnect();
break ;
case SID_DB_APP_DSCONNECTION_TYPE:
openDialog(u"com.sun.star.sdb.DataSourceTypeChangeDialog" _ustr);
askToReconnect();
break ;
case ID_DIRECT_SQL:
{
SharedConnection xConnection( ensureConnection() );
if ( xConnection.is() )
// opens the DirectSQLDialog to execute hand made sql statements.
openDialog( SERVICE_SDB_DIRECTSQLDIALOG );
}
break ;
case SID_DB_APP_VIEW_TABLES:
m_aSelectContainerEvent.Call( reinterpret_cast < void * >( E_TABLE ) );
break ;
case SID_DB_APP_VIEW_QUERIES:
m_aSelectContainerEvent.Call( reinterpret_cast < void * >( E_QUERY ) );
break ;
case SID_DB_APP_VIEW_FORMS:
m_aSelectContainerEvent.Call( reinterpret_cast < void * >( E_FORM ) );
break ;
case SID_DB_APP_VIEW_REPORTS:
m_aSelectContainerEvent.Call( reinterpret_cast < void * >( E_REPORT ) );
break ;
case SID_DB_APP_DISABLE_PREVIEW:
m_ePreviewMode = PreviewMode::NONE;
getContainer()->switchPreview(m_ePreviewMode);
break ;
case SID_DB_APP_VIEW_DOCINFO_PREVIEW:
m_ePreviewMode = PreviewMode::DocumentInfo;
getContainer()->switchPreview(m_ePreviewMode);
break ;
case SID_DB_APP_VIEW_DOC_PREVIEW:
m_ePreviewMode = PreviewMode::Document;
getContainer()->switchPreview(m_ePreviewMode);
break ;
case SID_MAIL_SENDDOC:
{
SfxMailModel aSendMail;
if ( aSendMail.AttachDocument(getModel(), OUString()) == SfxMailModel::SEND_MAIL_OK )
aSendMail.Send( getFrame() );
}
break ;
case SID_DB_APP_SENDREPORTASMAIL:
doAction( _nId, ElementOpenMode::Mail );
break ;
}
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
InvalidateFeature(_nId);
}
void OApplicationController::describeSupportedFeatures()
{
OGenericUnoController::describeSupportedFeatures();
implDescribeSupportedFeature( u".uno:AddDirect" _ustr, SID_NEWDOCDIRECT, CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:Save" _ustr, ID_BROWSER_SAVEDOC, CommandGroup::DOCUMENT );
implDescribeSupportedFeature( u".uno:SaveAs" _ustr, ID_BROWSER_SAVEASDOC, CommandGroup::DOCUMENT );
implDescribeSupportedFeature( u".uno:SendMail" _ustr, SID_MAIL_SENDDOC, CommandGroup::DOCUMENT );
implDescribeSupportedFeature( u".uno:DBSendReportAsMail" _ustr,SID_DB_APP_SENDREPORTASMAIL,
CommandGroup::DOCUMENT );
implDescribeSupportedFeature( u".uno:DBSendReportToWriter" _ustr,SID_DB_APP_SENDREPORTTOWRITER,
CommandGroup::DOCUMENT );
implDescribeSupportedFeature( u".uno:DBNewForm" _ustr, SID_APP_NEW_FORM, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewFolder" _ustr, SID_APP_NEW_FOLDER, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewFormAutoPilot" _ustr, SID_DB_FORM_NEW_PILOT, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewFormAutoPilotWithPreSelection" _ustr,
SID_FORM_CREATE_REPWIZ_PRE_SEL,
CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:DBNewReport" _ustr, SID_APP_NEW_REPORT, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewReportAutoPilot" _ustr,
ID_DOCUMENT_CREATE_REPWIZ, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewReportAutoPilotWithPreSelection" _ustr,
SID_REPORT_CREATE_REPWIZ_PRE_SEL,
CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:DBNewQuery" _ustr, ID_NEW_QUERY_DESIGN, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewQuerySql" _ustr, ID_NEW_QUERY_SQL, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewQueryAutoPilot" _ustr,ID_APP_NEW_QUERY_AUTO_PILOT,
CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewTable" _ustr, ID_NEW_TABLE_DESIGN, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewTableAutoPilot" _ustr,ID_NEW_TABLE_DESIGN_AUTO_PILOT,
CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewView" _ustr, ID_NEW_VIEW_DESIGN, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBNewViewSQL" _ustr, SID_DB_NEW_VIEW_SQL, CommandGroup::INSERT );
implDescribeSupportedFeature( u".uno:DBDelete" _ustr, SID_DB_APP_DELETE, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:Delete" _ustr, SID_DB_APP_DELETE, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBRename" _ustr, SID_DB_APP_RENAME, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBEdit" _ustr, SID_DB_APP_EDIT, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBEditSqlView" _ustr, SID_DB_APP_EDIT_SQL_VIEW, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBOpen" _ustr, SID_DB_APP_OPEN, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBTableDelete" _ustr, SID_DB_APP_TABLE_DELETE, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBTableRename" _ustr, SID_DB_APP_TABLE_RENAME, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBTableEdit" _ustr, SID_DB_APP_TABLE_EDIT, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBTableOpen" _ustr, SID_DB_APP_TABLE_OPEN, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBQueryDelete" _ustr, SID_DB_APP_QUERY_DELETE, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBQueryRename" _ustr, SID_DB_APP_QUERY_RENAME, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBQueryEdit" _ustr, SID_DB_APP_QUERY_EDIT, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBQueryOpen" _ustr, SID_DB_APP_QUERY_OPEN, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBFormDelete" _ustr, SID_DB_APP_FORM_DELETE, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBFormRename" _ustr, SID_DB_APP_FORM_RENAME, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBFormEdit" _ustr, SID_DB_APP_FORM_EDIT, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBFormOpen" _ustr, SID_DB_APP_FORM_OPEN, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBReportDelete" _ustr, SID_DB_APP_REPORT_DELETE, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBReportRename" _ustr, SID_DB_APP_REPORT_RENAME, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBReportEdit" _ustr, SID_DB_APP_REPORT_EDIT, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBReportOpen" _ustr, SID_DB_APP_REPORT_OPEN, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:SelectAll" _ustr, SID_SELECTALL, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:Undo" _ustr, ID_BROWSER_UNDO, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:Sortup" _ustr, ID_BROWSER_SORTUP, CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:SortDown" _ustr, ID_BROWSER_SORTDOWN, CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:DBRelationDesign" _ustr, SID_DB_APP_DSRELDESIGN, CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:DBUserAdmin" _ustr, SID_DB_APP_DSUSERADMIN, CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:DBTableFilter" _ustr, SID_DB_APP_TABLEFILTER, CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:DBDSProperties" _ustr, SID_DB_APP_DSPROPS, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBDSConnectionType" _ustr, SID_DB_APP_DSCONNECTION_TYPE,
CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBDSAdvancedSettings" _ustr,
SID_DB_APP_DSADVANCED_SETTINGS,
CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:PasteSpecial" _ustr, SID_DB_APP_PASTE_SPECIAL, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBConvertToView" _ustr, SID_DB_APP_CONVERTTOVIEW, CommandGroup::EDIT );
implDescribeSupportedFeature( u".uno:DBRefreshTables" _ustr, SID_DB_APP_REFRESH_TABLES, CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:DBDirectSQL" _ustr, ID_DIRECT_SQL, CommandGroup::APPLICATION );
implDescribeSupportedFeature( u".uno:DBViewTables" _ustr, SID_DB_APP_VIEW_TABLES, CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:DBViewQueries" _ustr, SID_DB_APP_VIEW_QUERIES, CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:DBViewForms" _ustr, SID_DB_APP_VIEW_FORMS, CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:DBViewReports" _ustr, SID_DB_APP_VIEW_REPORTS, CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:DBDisablePreview" _ustr, SID_DB_APP_DISABLE_PREVIEW,CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:DBShowDocInfoPreview" _ustr,
SID_DB_APP_VIEW_DOCINFO_PREVIEW,
CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:DBShowDocPreview" _ustr, SID_DB_APP_VIEW_DOC_PREVIEW,
CommandGroup::VIEW );
implDescribeSupportedFeature( u".uno:OpenUrl" _ustr, SID_OPENURL, CommandGroup::APPLICATION );
// this one should not appear under Tools->Customize->Keyboard
implDescribeSupportedFeature( u".uno:DBNewReportWithPreSelection" _ustr,
SID_APP_NEW_REPORT_PRE_SEL );
implDescribeSupportedFeature( u".uno:DBDSImport" _ustr, SID_DB_APP_DSIMPORT);
implDescribeSupportedFeature( u".uno:DBDSExport" _ustr, SID_DB_APP_DSEXPORT);
implDescribeSupportedFeature( u".uno:DBDBAdmin" _ustr, SID_DB_APP_DBADMIN);
// status info
implDescribeSupportedFeature( u".uno:DBStatusType" _ustr, SID_DB_APP_STATUS_TYPE);
implDescribeSupportedFeature( u".uno:DBStatusDBName" _ustr, SID_DB_APP_STATUS_DBNAME);
implDescribeSupportedFeature( u".uno:DBStatusUserName" _ustr, SID_DB_APP_STATUS_USERNAME);
implDescribeSupportedFeature( u".uno:DBStatusHostName" _ustr, SID_DB_APP_STATUS_HOSTNAME);
}
OApplicationView* OApplicationController::getContainer() const
{
return static_cast < OApplicationView* >( getView() );
}
// css::container::XContainerListener
void SAL_CALL OApplicationController::elementInserted( const ContainerEvent& _rEvent )
{
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
if ( std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) == m_aCurrentContainers.end() )
return ;
OSL_ENSURE(getContainer(),"View is NULL! -> GPF" );
if ( !getContainer() )
return ;
OUString sName;
_rEvent.Accessor >>= sName;
ElementType eType = getElementType(xContainer);
switch ( eType )
{
case E_TABLE:
ensureConnection();
break ;
case E_FORM:
case E_REPORT:
{
Reference< XContainer > xSubContainer(_rEvent.Element,UNO_QUERY);
if ( xSubContainer.is() )
containerFound(xSubContainer);
}
break ;
default :
break ;
}
getContainer()->elementAdded(eType,sName,_rEvent.Element);
}
void SAL_CALL OApplicationController::elementRemoved( const ContainerEvent& _rEvent )
{
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
if ( std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) == m_aCurrentContainers.end() )
return ;
OSL_ENSURE(getContainer(),"View is NULL! -> GPF" );
OUString sName;
_rEvent.Accessor >>= sName;
ElementType eType = getElementType(xContainer);
switch ( eType )
{
case E_TABLE:
ensureConnection();
break ;
case E_FORM:
case E_REPORT:
{
Reference<XContent> xContent(xContainer,UNO_QUERY);
if ( xContent.is() )
{
sName = xContent->getIdentifier()->getContentIdentifier() + "/" + sName;
}
}
break ;
default :
break ;
}
getContainer()->elementRemoved(eType,sName);
}
void SAL_CALL OApplicationController::elementReplaced( const ContainerEvent& _rEvent )
{
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY);
if ( std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) == m_aCurrentContainers.end() )
return ;
OSL_ENSURE(getContainer(),"View is NULL! -> GPF" );
OUString sName;
try
{
_rEvent.Accessor >>= sName;
Reference<XPropertySet> xProp(_rEvent.Element,UNO_QUERY);
ElementType eType = getElementType(xContainer);
switch ( eType )
{
case E_TABLE:
{
ensureConnection();
if ( xProp.is() && m_xMetaData.is() )
//TODO: tdf#133497 "OApplicationController::elementReplaced effectively does
// nothing":
(void ) ::dbaui::composeTableName( m_xMetaData, xProp, ::dbtools::EComposeRule::InDataManipulation, false );
}
break ;
case E_FORM:
case E_REPORT:
{
Reference<XContent> xContent(xContainer,UNO_QUERY);
if ( xContent.is() )
{
sName = xContent->getIdentifier()->getContentIdentifier() + "/" + sName;
}
}
break ;
default :
break ;
}
// getContainer()->elementReplaced(getContainer()->getElementType(),sName,sNewName);
}
catch ( Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
namespace
{
OUString lcl_getToolBarResource(ElementType _eType)
{
OUString sToolbar;
switch (_eType)
{
case E_TABLE:
sToolbar = "private:resource/toolbar/tableobjectbar" ;
break ;
case E_QUERY:
sToolbar = "private:resource/toolbar/queryobjectbar" ;
break ;
case E_FORM:
sToolbar = "private:resource/toolbar/formobjectbar" ;
break ;
case E_REPORT:
sToolbar = "private:resource/toolbar/reportobjectbar" ;
break ;
case E_NONE:
break ;
default :
OSL_FAIL("Invalid ElementType!" );
break ;
}
return sToolbar;
}
}
bool OApplicationController::onContainerSelect(ElementType _eType)
{
OSL_ENSURE(getContainer(),"View is NULL! -> GPF" );
if ( m_eCurrentType != _eType && _eType != E_NONE )
{
SelectionGuard aSelGuard( *m_pSelectionNotifier );
if ( _eType == E_TABLE )
{
try
{
SharedConnection xConnection( ensureConnection() );
if ( xConnection.is() && getContainer()->getDetailView() )
{
getContainer()->getDetailView()->createTablesPage(xConnection);
Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY);
if ( xTabSup.is() )
addContainerListener(xTabSup->getTables());
}
else
{
return false ;
}
}
catch ( const Exception& )
{
return false ;
}
}
else if ( _eType == E_QUERY )
{
// tdf#126578: retrieve connection to be able to call "Create as View"
ensureConnection();
}
Reference< XLayoutManager > xLayoutManager = getLayoutManager( getFrame() );
if ( xLayoutManager.is() )
{
OUString sToolbar = lcl_getToolBarResource(_eType);
OUString sDestroyToolbar = lcl_getToolBarResource(m_eCurrentType);
xLayoutManager->lock();
xLayoutManager->destroyElement( sDestroyToolbar );
if ( !sToolbar.isEmpty() )
{
xLayoutManager->createElement( sToolbar );
xLayoutManager->requestElement( sToolbar );
}
xLayoutManager->unlock();
xLayoutManager->doLayout();
}
if ( _eType != E_TABLE && getContainer()->getDetailView() )
{
Reference< XNameAccess > xContainer = getElements(_eType);
addContainerListener(xContainer);
getContainer()->getDetailView()->createPage(_eType,xContainer);
}
SelectionByElementType::const_iterator pendingSelection = m_aPendingSelection.find( _eType );
if ( pendingSelection != m_aPendingSelection.end() )
{
getContainer()->selectElements( comphelper::containerToSequence(pendingSelection->second) );
m_aPendingSelection.erase( pendingSelection );
}
InvalidateAll();
}
m_eCurrentType = _eType;
return true ;
}
bool OApplicationController::onEntryDoubleClick(const weld::TreeView& rTreeView)
{
OApplicationView* pContainer = getContainer();
if (!pContainer)
return false ; // not handled
std::unique_ptr<weld::TreeIter> xHdlEntry = rTreeView.make_iterator();
if (!rTreeView.get_cursor(xHdlEntry.get()))
return false ;
if (!pContainer->isLeaf(rTreeView, *xHdlEntry))
return false ; // not handled
try
{
// opens a new frame with either the table or the query or report or form or view
openElementWithArguments(
getContainer()->getQualifiedName(xHdlEntry.get()),
getContainer()->getElementType(),
ElementOpenMode::Normal,
0 ,
::comphelper::NamedValueCollection() );
return true ; // handled
}
catch (const Exception&)
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
return false ; // not handled
}
bool OApplicationController::impl_isAlterableView_nothrow( const OUString& _rTableOrViewName ) const
{
OSL_PRECOND( m_xDataSourceConnection.is(), "OApplicationController::impl_isAlterableView_nothrow: no connection!" );
bool bIsAlterableView( false );
try
{
Reference< XViewsSupplier > xViewsSupp( m_xDataSourceConnection, UNO_QUERY );
Reference< XNameAccess > xViews;
if ( xViewsSupp.is() )
xViews = xViewsSupp->getViews();
Reference< XAlterView > xAsAlterableView;
if ( xViews.is() && xViews->hasByName( _rTableOrViewName ) )
xAsAlterableView.set( xViews->getByName( _rTableOrViewName ), UNO_QUERY );
bIsAlterableView = xAsAlterableView.is();
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
return bIsAlterableView;
}
Reference< XComponent > OApplicationController::openElementWithArguments( const OUString& _sName, ElementType _eType,
ElementOpenMode _eOpenMode, sal_uInt16 _nInstigatorCommand, const ::comphelper::NamedValueCollection& _rAdditionalArguments )
{
OSL_PRECOND( getContainer(), "OApplicationController::openElementWithArguments: no view!" );
if ( !getContainer() )
return nullptr;
Reference< XComponent > xRet;
if ( _eOpenMode == ElementOpenMode::Design )
{
// https://bz.apache.org/ooo/show_bug.cgi?id=30382
getContainer()->showPreview(nullptr);
}
bool isStandaloneDocument = false ;
switch ( _eType )
{
case E_REPORT:
if ( _eOpenMode != ElementOpenMode::Design )
{
// reports which are opened in a mode other than design are no sub components of our application
// component, but standalone documents.
isStandaloneDocument = true ;
}
[[fallthrough]];
case E_FORM:
{
if ( isStandaloneDocument || !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) )
{
std::unique_ptr< OLinkedDocumentsAccess > aHelper = getDocumentsAccess( _eType );
if ( !aHelper->isConnected() )
break ;
Reference< XComponent > xDefinition;
xRet = aHelper->open( _sName, xDefinition, _eOpenMode, _rAdditionalArguments );
if ( !isStandaloneDocument )
onDocumentOpened( _sName, _eType, _eOpenMode, xRet, xDefinition );
}
}
break ;
case E_QUERY:
case E_TABLE:
{
if ( !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode, xRet ) )
{
SharedConnection xConnection( ensureConnection() );
if ( !xConnection.is() )
break ;
std::unique_ptr< DatabaseObjectView > pDesigner;
::comphelper::NamedValueCollection aArguments( _rAdditionalArguments );
Any aDataSource;
if ( _eOpenMode == ElementOpenMode::Design )
{
bool bAddViewTypeArg = false ;
if ( _eType == E_TABLE )
{
if ( impl_isAlterableView_nothrow( _sName ) )
{
pDesigner.reset( new QueryDesigner( getORB(), this , m_aCurrentFrame.getFrame(), true ) );
bAddViewTypeArg = true ;
}
else
{
pDesigner.reset( new TableDesigner( getORB(), this , m_aCurrentFrame.getFrame() ) );
}
}
else if ( _eType == E_QUERY )
{
pDesigner.reset( new QueryDesigner( getORB(), this , m_aCurrentFrame.getFrame(), false ) );
bAddViewTypeArg = true ;
}
aDataSource <<= m_xDataSource;
if ( bAddViewTypeArg )
{
const bool bQueryGraphicalMode =( _nInstigatorCommand != SID_DB_APP_EDIT_SQL_VIEW );
aArguments.put( PROPERTY_GRAPHICAL_DESIGN, bQueryGraphicalMode );
}
}
else
{
pDesigner.reset( new ResultSetBrowser( getORB(), this , m_aCurrentFrame.getFrame(), _eType == E_TABLE ) );
if ( !aArguments.has( PROPERTY_SHOWMENU ) )
aArguments.put( PROPERTY_SHOWMENU, Any( true ) );
aDataSource <<= getDatabaseName();
}
xRet.set( pDesigner->openExisting( aDataSource, _sName, aArguments ) );
onDocumentOpened( _sName, _eType, _eOpenMode, xRet, nullptr );
}
}
break ;
default :
OSL_FAIL( "OApplicationController::openElement: illegal object type!" );
break ;
}
return xRet;
}
IMPL_LINK( OApplicationController, OnSelectContainer, void *, _pType, void )
{
ElementType eType = static_cast <ElementType>(reinterpret_cast < sal_IntPtr >( _pType ));
if (getContainer())
getContainer()->selectContainer(eType);
}
IMPL_LINK( OApplicationController, OnCreateWithPilot, void *, _pType, void )
{
ElementType eType = static_cast <ElementType>(reinterpret_cast < sal_IntPtr >( _pType ));
newElementWithPilot( eType );
}
void OApplicationController::newElementWithPilot( ElementType _eType )
{
utl::CloseVeto aKeepDoc( getFrame() );
// prevent the document being closed while the wizard is open
OSL_ENSURE( getContainer(), "OApplicationController::newElementWithPilot: without a view?" );
switch ( _eType )
{
case E_REPORT:
case E_FORM:
{
std::unique_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess(_eType);
if ( aHelper->isConnected() )
{
sal_Int32 nCommandType = -1 ;
const OUString sCurrentSelected( getCurrentlySelectedName( nCommandType ) );
if ( E_REPORT == _eType )
aHelper->newReportWithPilot( nCommandType, sCurrentSelected );
else
aHelper->newFormWithPilot( nCommandType, sCurrentSelected );
}
}
break ;
case E_QUERY:
case E_TABLE:
{
std::unique_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess(_eType);
if ( aHelper->isConnected() )
{
if ( E_QUERY == _eType )
aHelper->newQueryWithPilot();
else
aHelper->newTableWithPilot();
}
}
break ;
case E_NONE:
break ;
}
// no need for onDocumentOpened, the table wizard opens the created table by using
// XDatabaseDocumentUI::loadComponent method.
}
Reference< XComponent > OApplicationController::newElement( ElementType _eType, const ::comphelper::NamedValueCollection& i_rAdditionalArguments,
Reference< XComponent >& o_rDocumentDefinition )
{
OSL_ENSURE(getContainer(),"View is NULL! -> GPF" );
Reference< XComponent > xComponent;
o_rDocumentDefinition.clear();
switch ( _eType )
{
case E_FORM:
case E_REPORT:
{
std::unique_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess( _eType );
if ( !aHelper->isConnected() )
break ;
xComponent = aHelper->newDocument( _eType == E_FORM ? ID_FORM_NEW_TEXT : ID_REPORT_NEW_TEXT, i_rAdditionalArguments, o_rDocumentDefinition );
}
break ;
case E_QUERY:
case E_TABLE:
{
std::unique_ptr< DatabaseObjectView > pDesigner;
SharedConnection xConnection( ensureConnection() );
if ( !xConnection.is() )
break ;
if ( _eType == E_TABLE )
{
pDesigner.reset( new TableDesigner( getORB(), this , getFrame() ) );
}
else if ( _eType == E_QUERY )
{
pDesigner.reset( new QueryDesigner( getORB(), this , getFrame(), false ) );
}
Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY );
xComponent = pDesigner->createNew( xDataSource, i_rAdditionalArguments );
}
break ;
default :
OSL_FAIL( "OApplicationController::newElement: illegal type!" );
break ;
}
if ( xComponent.is() )
onDocumentOpened( OUString(), _eType, ElementOpenMode::Design, xComponent, o_rDocumentDefinition );
return xComponent;
}
void OApplicationController::addContainerListener(const Reference<XNameAccess>& _xCollection)
{
try
{
Reference< XContainer > xCont(_xCollection, UNO_QUERY);
if ( xCont.is() )
{
// add as listener to get notified if elements are inserted or removed
TContainerVector::const_iterator aFind = std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xCont);
if ( aFind == m_aCurrentContainers.end() )
{
xCont->addContainerListener(this );
m_aCurrentContainers.push_back(xCont);
}
}
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
void OApplicationController::renameEntry()
{
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
OSL_ENSURE(getContainer(),"View is NULL! -> GPF" );
std::vector< OUString> aList;
getSelectionElementNames(aList);
Reference< XNameAccess > xContainer = getElements(getContainer()->getElementType());
OSL_ENSURE(aList.size() == 1 ,"Invalid rename call here. More than one element!" );
if ( aList.empty() )
return ;
try
{
if ( xContainer.is() )
{
std::unique_ptr< IObjectNameCheck > pNameChecker;
std::unique_ptr<OSaveAsDlg> xDialog;
Reference<XRename> xRename;
const ElementType eType = getContainer()->getElementType();
switch ( eType )
{
case E_FORM:
case E_REPORT:
{
Reference<XHierarchicalNameContainer> xHNames(xContainer, UNO_QUERY);
if ( xHNames.is() )
{
OUString sLabel;
if ( eType == E_FORM )
sLabel = DBA_RES(STR_FRM_LABEL);
else
sLabel = DBA_RES(STR_RPT_LABEL);
OUString sName = *aList.begin();
if ( xHNames->hasByHierarchicalName(sName) )
{
xRename.set(xHNames->getByHierarchicalName(sName),UNO_QUERY);
Reference<XChild> xChild(xRename,UNO_QUERY);
if ( xChild.is() )
{
Reference<XHierarchicalNameContainer> xParent(xChild->getParent(),UNO_QUERY);
if ( xParent.is() )
{
xHNames = std::move(xParent);
Reference<XPropertySet>(xRename,UNO_QUERY_THROW)->getPropertyValue(PROPERTY_NAME) >>= sName;
}
}
pNameChecker.reset( new HierarchicalNameCheck( xHNames, OUString() ) );
xDialog.reset(new OSaveAsDlg(
getFrameWeld(), getORB(), sName, sLabel, *pNameChecker, SADFlags::TitleRename));
}
}
}
break ;
case E_TABLE:
ensureConnection();
if ( !getConnection().is() )
break ;
[[fallthrough]];
case E_QUERY:
if ( xContainer->hasByName(*aList.begin()) )
{
xRename.set(xContainer->getByName(*aList.begin()),UNO_QUERY);
sal_Int32 nCommandType = eType == E_QUERY ? CommandType::QUERY : CommandType::TABLE;
ensureConnection();
pNameChecker.reset( new DynamicTableOrQueryNameCheck( getConnection(), nCommandType ) );
xDialog.reset(new OSaveAsDlg(getFrameWeld(), nCommandType, getORB(), getConnection(),
*aList.begin(), *pNameChecker, SADFlags::TitleRename));
}
break ;
default :
break ;
}
if (xRename.is() && xDialog)
{
bool bTryAgain = true ;
while ( bTryAgain )
{
if (xDialog->run() == RET_OK)
{
try
{
OUString sNewName;
if ( eType == E_TABLE )
{
OUString sName = xDialog->getName();
OUString sCatalog = xDialog->getCatalog();
OUString sSchema = xDialog->getSchema();
sNewName = ::dbtools::composeTableName( m_xMetaData, sCatalog, sSchema, sName, false , ::dbtools::EComposeRule::InDataManipulation );
}
else
sNewName = xDialog->getName();
OUString sOldName = *aList.begin();
if ( eType == E_FORM || eType == E_REPORT )
{
Reference<XContent> xContent(xRename,UNO_QUERY);
if ( xContent.is() )
{
sOldName = xContent->getIdentifier()->getContentIdentifier();
}
}
xRename->rename(sNewName);
if ( eType == E_TABLE )
{
Reference<XPropertySet> xProp(xRename,UNO_QUERY);
sNewName = ::dbaui::composeTableName( m_xMetaData, xProp, ::dbtools::EComposeRule::InDataManipulation, false );
}
getContainer()->elementReplaced( eType , sOldName, sNewName );
bTryAgain = false ;
}
catch (const SQLException& )
{
showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
}
catch (const ElementExistException& e)
{
OUString sMsg(DBA_RES(STR_NAME_ALREADY_EXISTS));
showError(SQLExceptionInfo(SQLException(sMsg.replaceAll("#" , e.Message), e.Context, u"S1000" _ustr, 0 , Any())));
}
catch (const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
else
bTryAgain = false ;
}
}
}
}
catch (const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
void OApplicationController::onSelectionChanged()
{
InvalidateAll();
SelectionGuard aSelGuard( *m_pSelectionNotifier );
OApplicationView* pView = getContainer();
if ( !pView )
return ;
if ( pView->getSelectionCount() == 1 )
{
const ElementType eType = pView->getElementType();
if ( pView->isALeafSelected() )
{
const OUString sName = pView->getQualifiedName( nullptr /* means 'first selected' */ );
showPreviewFor( eType, sName );
}
}
}
void OApplicationController::showPreviewFor(const ElementType _eType,const OUString& _sName)
{
if ( m_ePreviewMode == PreviewMode::NONE )
return ;
OApplicationView* pView = getContainer();
if ( !pView )
return ;
try
{
switch ( _eType )
{
case E_FORM:
case E_REPORT:
{
Reference< XHierarchicalNameAccess > xContainer( getElements( _eType ), UNO_QUERY_THROW );
Reference< XContent> xContent( xContainer->getByHierarchicalName( _sName ), UNO_QUERY_THROW );
pView->showPreview( xContent );
}
break ;
case E_TABLE:
case E_QUERY:
{
SharedConnection xConnection( ensureConnection() );
if ( xConnection.is() )
pView->showPreview( getDatabaseName(), xConnection, _sName, _eType == E_TABLE );
}
return ;
default :
OSL_FAIL( "OApplicationController::showPreviewFor: unexpected element type!" );
break ;
}
}
catch ( const SQLException& )
{
showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
}
catch (const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper*, void )
{
OnInvalidateClipboard();
}
void OApplicationController::OnInvalidateClipboard()
{
InvalidateFeature(ID_BROWSER_CUT);
InvalidateFeature(ID_BROWSER_COPY);
InvalidateFeature(ID_BROWSER_PASTE);
InvalidateFeature(SID_DB_APP_PASTE_SPECIAL);
}
void OApplicationController::onCopyEntry()
{
Execute(ID_BROWSER_COPY,Sequence<PropertyValue>());
}
void OApplicationController::onPasteEntry()
{
Execute(ID_BROWSER_PASTE,Sequence<PropertyValue>());
}
void OApplicationController::onDeleteEntry()
{
ElementType eType = getContainer()->getElementType();
sal_uInt16 nId = 0 ;
switch (eType)
{
case E_TABLE:
nId = SID_DB_APP_TABLE_DELETE;
break ;
case E_QUERY:
nId = SID_DB_APP_QUERY_DELETE;
break ;
case E_FORM:
nId = SID_DB_APP_FORM_DELETE;
break ;
case E_REPORT:
nId = SID_DB_APP_REPORT_DELETE;
break ;
default :
OSL_FAIL("Invalid ElementType!" );
break ;
}
executeChecked(nId,Sequence<PropertyValue>());
}
OUString OApplicationController::getContextMenuResourceName() const
{
return u"edit" _ustr;
}
IController& OApplicationController::getCommandController()
{
return *this ;
}
::comphelper::OInterfaceContainerHelper2* OApplicationController::getContextMenuInterceptors()
{
return &m_aContextMenuInterceptors;
}
Any OApplicationController::getCurrentSelection(weld::TreeView& rControl) const
{
Sequence< NamedDatabaseObject > aSelection;
getContainer()->describeCurrentSelectionForControl(rControl, aSelection);
return Any( aSelection );
}
vcl::Window* OApplicationController::getMenuParent() const
{
return getContainer()->getMenuParent();
}
void OApplicationController::adjustMenuPosition(const weld::TreeView& rControl, ::Point& rPos) const
{
getContainer()->adjustMenuPosition(rControl, rPos);
}
bool OApplicationController::requestQuickHelp(const void * /*pUserData*/, OUString& /*rText*/) const
{
return false ;
}
bool OApplicationController::requestDrag(const weld::TreeIter& /*rEntry*/)
{
bool bSuccess = false ;
OApplicationView* pContainer = getContainer();
if (pContainer && pContainer->getSelectionCount())
{
try
{
if (getContainer()->getDetailView())
{
TreeListBox* pTreeListBox = getContainer()->getDetailView()->getTreeWindow();
ElementType eType = getContainer()->getElementType();
if (eType == E_TABLE || eType == E_QUERY)
{
ODataClipboard& rExchange = static_cast <ODataClipboard&>(pTreeListBox->GetDataTransfer());
bSuccess = copySQLObject(rExchange);
}
else
{
svx::OComponentTransferable& rExchange = static_cast <svx::OComponentTransferable&>(pTreeListBox->GetDataTransfer());
bSuccess = copyDocObject(rExchange);
}
}
}
catch (const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
return bSuccess;
}
sal_Int8 OApplicationController::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors )
{
sal_Int8 nActionAskedFor = _rEvt.mnAction;
// check if we're a table or query container
OApplicationView* pView = getContainer();
if ( !pView || isDataSourceReadOnly() )
return DND_ACTION_NONE;
ElementType eType = pView->getElementType();
if ( eType == E_NONE || (eType == E_TABLE && isConnectionReadOnly()) )
return DND_ACTION_NONE;
// check for the concrete type
if (std::any_of(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(eType)))
return DND_ACTION_COPY;
if ( eType != E_FORM && eType != E_REPORT )
return DND_ACTION_NONE;
sal_Int8 nAction = OComponentTransferable::canExtractComponentDescriptor(_rFlavors,eType == E_FORM) ? DND_ACTION_COPY : DND_ACTION_NONE;
if ( nAction == DND_ACTION_NONE )
return DND_ACTION_NONE;
auto xHitEntry = pView->getEntry(_rEvt.maPosPixel);
if (xHitEntry)
{
OUString sName = pView->getQualifiedName(xHitEntry.get());
if ( !sName.isEmpty() )
{
Reference< XHierarchicalNameAccess > xContainer(getElements(pView->getElementType()),UNO_QUERY);
if ( xContainer.is() && xContainer->hasByHierarchicalName(sName) )
{
Reference< XHierarchicalNameAccess > xHitObject(xContainer->getByHierarchicalName(sName),UNO_QUERY);
if ( xHitObject.is() )
nAction = nActionAskedFor & DND_ACTION_COPYMOVE;
}
else
nAction = DND_ACTION_NONE;
}
}
return nAction;
}
sal_Int8 OApplicationController::executeDrop( const ExecuteDropEvent& _rEvt )
{
OApplicationView* pView = getContainer();
if ( !pView || pView->getElementType() == E_NONE )
{
OSL_FAIL("OApplicationController::executeDrop: what the hell did queryDrop do?" );
// queryDrop should not have allowed us to reach this situation...
return DND_ACTION_NONE;
}
// a TransferableDataHelper for accessing the dropped data
TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable);
// reset the data of the previous async drop (if any)
if ( m_nAsyncDrop )
Application::RemoveUserEvent(m_nAsyncDrop);
m_nAsyncDrop = nullptr;
m_aAsyncDrop.aDroppedData.clear();
m_aAsyncDrop.nType = pView->getElementType();
m_aAsyncDrop.nAction = _rEvt.mnAction;
m_aAsyncDrop.bError = false ;
m_aAsyncDrop.bHtml = false ;
m_aAsyncDrop.aUrl.clear();
// loop through the available formats and see what we can do...
// first we have to check if it is our own format, if not we have to copy the stream :-(
if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) )
{
m_aAsyncDrop.aDroppedData = ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData);
// asynchron because we some dialogs and we aren't allowed to show them while in D&D
m_nAsyncDrop = Application::PostUserEvent(LINK(this , OApplicationController, OnAsyncDrop));
return DND_ACTION_COPY;
}
else if ( OComponentTransferable::canExtractComponentDescriptor(aDroppedData.GetDataFlavorExVector(),m_aAsyncDrop.nType == E_FORM) )
{
m_aAsyncDrop.aDroppedData = OComponentTransferable::extractComponentDescriptor(aDroppedData);
auto xHitEntry = pView->getEntry(_rEvt.maPosPixel);
if ( xHitEntry )
m_aAsyncDrop.aUrl = pView->getQualifiedName(xHitEntry.get());
sal_Int8 nAction = _rEvt.mnAction;
Reference<XContent> xContent;
m_aAsyncDrop.aDroppedData[DataAccessDescriptorProperty::Component] >>= xContent;
if ( xContent.is() )
{
OUString sName = xContent->getIdentifier()->getContentIdentifier();
sName = sName.copy(sName.indexOf('/' ) + 1 );
if ( m_aAsyncDrop.aUrl.getLength() >= sName.getLength() && m_aAsyncDrop.aUrl.startsWith(sName) )
{
m_aAsyncDrop.aDroppedData.clear();
return DND_ACTION_NONE;
}
// check if move is allowed, if another object with the same name exists only copy is allowed
Reference< XHierarchicalNameAccess > xContainer(getElements(m_aAsyncDrop.nType),UNO_QUERY);
Reference<XNameAccess> xNameAccess(xContainer,UNO_QUERY);
if ( !m_aAsyncDrop.aUrl.isEmpty() && xContainer.is() && xContainer->hasByHierarchicalName(m_aAsyncDrop.aUrl) )
xNameAccess.set(xContainer->getByHierarchicalName(m_aAsyncDrop.aUrl),UNO_QUERY);
if ( xNameAccess.is() )
{
Reference<XPropertySet> xProp(xContent,UNO_QUERY);
if ( xProp.is() )
{
xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
if ( xNameAccess.is() && xNameAccess->hasByName(sName) )
nAction &= ~DND_ACTION_MOVE;
}
else
nAction &= ~DND_ACTION_MOVE;
}
}
if ( nAction != DND_ACTION_NONE )
{
m_aAsyncDrop.nAction = nAction;
// asynchron because we some dialogs and we aren't allowed to show them while in D&D
m_nAsyncDrop = Application::PostUserEvent(LINK(this , OApplicationController, OnAsyncDrop));
}
else
m_aAsyncDrop.aDroppedData.clear();
return nAction;
}
else
{
SharedConnection xConnection( ensureConnection() );
if ( xConnection.is() && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xConnection ) )
{
// asynchron because we some dialogs and we aren't allowed to show them while in D&D
m_nAsyncDrop = Application::PostUserEvent(LINK(this , OApplicationController, OnAsyncDrop));
return DND_ACTION_COPY;
}
}
return DND_ACTION_NONE;
}
Reference< XModel > SAL_CALL OApplicationController::getModel()
{
return m_xModel;
}
void OApplicationController::onAttachedFrame()
{
sal_Int32 nConnectedControllers( 0 );
try
{
Reference< XModel2 > xModel( m_xModel, UNO_QUERY_THROW );
Reference< XEnumeration > xEnumControllers( xModel->getControllers(), UNO_SET_THROW );
while ( xEnumControllers->hasMoreElements() )
{
Reference< XController > xController( xEnumControllers->nextElement(), UNO_QUERY_THROW );
++nConnectedControllers;
}
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
if ( nConnectedControllers > 1 )
{ // we are not the first connected controller, there were already others
return ;
}
OnFirstControllerConnected();
}
void OApplicationController::OnFirstControllerConnected()
{
if ( !m_xModel.is() )
{
OSL_FAIL( "OApplicationController::OnFirstControllerConnected: too late!" );
}
// if we have forms or reports which contain macros/scripts, then show a warning
// which suggests the user to migrate them to the database document
Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
if ( xDocumentScripts.is() )
{
// no need to show this warning, obviously the document supports embedding scripts
// into itself, so there are no "old-style" forms/reports which have macros/scripts
// themselves
return ;
}
try
{
// If the migration just happened, but was not successful, the document is reloaded.
// In this case, we should not show the warning, again.
if ( ::comphelper::NamedValueCollection::getOrDefault( m_xModel->getArgs(), u"SuppressMigrationWarning" , false ) )
return ;
// also, if the document is read-only, then no migration is possible, and the
// respective menu entry is hidden. So, don't show the warning in this case, too.
if ( Reference< XStorable >( m_xModel, UNO_QUERY_THROW )->isReadonly() )
return ;
SQLException aDetail(DBA_RES(STR_SUB_DOCS_WITH_SCRIPTS_DETAIL), {}, {}, 0 , {});
SQLWarning aWarning(DBA_RES(STR_SUB_DOCS_WITH_SCRIPTS), {}, {}, 0 , css::uno::Any(aDetail));
Reference< XExecutableDialog > xDialog = ErrorMessageDialog::create( getORB(), u"" _ustr, nullptr, Any( aWarning ) );
xDialog->execute();
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
void SAL_CALL OApplicationController::attachFrame( const Reference< XFrame > & i_rxFrame )
{
SolarMutexGuard aSolarGuard; // avoid deadlock in XModel calls
::osl::MutexGuard aGuard( getMutex() );
OGenericUnoController::attachFrame( i_rxFrame );
if ( getFrame().is() )
onAttachedFrame();
}
sal_Bool SAL_CALL OApplicationController::attachModel(const Reference< XModel > & _rxModel)
{
::osl::MutexGuard aGuard( getMutex() );
const Reference< XOfficeDatabaseDocument > xOfficeDoc( _rxModel, UNO_QUERY );
const Reference< XModifiable > xDocModify( _rxModel, UNO_QUERY );
if ( ( !xOfficeDoc.is() || !xDocModify.is() ) && _rxModel.is() )
{
OSL_FAIL( "OApplicationController::attachModel: invalid model!" );
return false ;
}
if ( m_xModel.is() && ( m_xModel != _rxModel ) && ( _rxModel.is() ) )
{
OSL_ENSURE( false , "OApplicationController::attachModel: missing implementation: setting a new model while we have another one!" );
// we'd need to completely update our view here, close sub components, and the like
return false ;
}
const OUString aPropertyNames[] =
{
PROPERTY_URL, PROPERTY_USER
};
// disconnect from old model
try
{
if ( m_xDataSource.is() )
{
for (const auto & aPropertyName : aPropertyNames)
{
m_xDataSource->removePropertyChangeListener( aPropertyName, this );
}
}
Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
if ( xBroadcaster.is() )
xBroadcaster->removeModifyListener( this );
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
m_xModel = _rxModel;
m_xDataSource.set( xOfficeDoc.is() ? xOfficeDoc->getDataSource() : Reference< XDataSource >(), UNO_QUERY );
// connect to new model
try
{
if ( m_xDataSource.is() )
{
for (const auto & aPropertyName : aPropertyNames)
{
m_xDataSource->addPropertyChangeListener( aPropertyName, this );
}
}
Reference< XModifyBroadcaster > xBroadcaster( m_xModel, UNO_QUERY_THROW );
xBroadcaster->addModifyListener( this );
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
// initial preview mode
if ( !m_xDataSource )
return true ;
try
{
// to get the 'modified' for the data source
::comphelper::NamedValueCollection aLayoutInfo( m_xDataSource->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) );
if ( aLayoutInfo.has( INFO_PREVIEW ) )
{
const sal_Int32 nPreviewMode( aLayoutInfo.getOrDefault( INFO_PREVIEW, sal_Int32(0 ) ) );
m_ePreviewMode = static_cast < PreviewMode >( nPreviewMode );
if ( getView() )
getContainer()->switchPreview( m_ePreviewMode );
}
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
return true ;
}
void OApplicationController::containerFound( const Reference< XContainer >& _xContainer)
{
try
{
if ( _xContainer.is() )
{
m_aCurrentContainers.push_back(_xContainer);
_xContainer->addContainerListener(this );
}
}
catch (const Exception&)
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
OUString OApplicationController::getCurrentlySelectedName(sal_Int32& _rnCommandType) const
{
_rnCommandType = ( (getContainer()->getElementType() == E_QUERY)
? CommandType::QUERY : ( (getContainer()->getElementType() == E_TABLE) ? CommandType::TABLE : -1 ));
OUString sName;
if ( _rnCommandType != -1 )
{
try
{
sName = getContainer()->getQualifiedName( nullptr );
OSL_ENSURE( !sName.isEmpty(), "OApplicationController::getCurrentlySelectedName: no name given!" );
}
catch ( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess" );
}
}
return sName;
}
void SAL_CALL OApplicationController::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& Listener )
{
m_pSelectionNotifier->addListener( Listener );
}
void SAL_CALL OApplicationController::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& Listener )
{
m_pSelectionNotifier->removeListener( Listener );
}
sal_Bool SAL_CALL OApplicationController::select( const Any& _aSelection )
{
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
Sequence< OUString> aSelection;
if ( !_aSelection.hasValue() || !getView() )
{
getContainer()->selectElements(aSelection);
return true ;
}
// BEGIN compatibility
Sequence< NamedValue > aCurrentSelection;
if ( (_aSelection >>= aCurrentSelection) && aCurrentSelection.hasElements() )
{
ElementType eType = E_NONE;
for (auto & item : aCurrentSelection)
{
if (item.Name == "Type" )
{
sal_Int32 nType = 0 ;
item.Value >>= nType;
if ( nType < DatabaseObject::TABLE || nType > DatabaseObject::REPORT )
throw IllegalArgumentException();
eType = static_cast < ElementType >( nType );
}
else if (item.Name == "Selection" )
item.Value >>= aSelection;
}
m_aSelectContainerEvent.CancelCall(); // just in case the async select request was running
getContainer()->selectContainer(eType);
getContainer()->selectElements(aSelection);
return true ;
}
// END compatibility
Sequence< NamedDatabaseObject > aSelectedObjects;
if ( !( _aSelection >>= aSelectedObjects ) )
{
aSelectedObjects.realloc( 1 );
if ( !( _aSelection >>= aSelectedObjects.getArray()[0 ] ) )
throw IllegalArgumentException();
}
SelectionByElementType aSelectedElements;
ElementType eSelectedCategory = E_NONE;
for (sal_Int32 i = 0 ; i < aSelectedObjects.getLength(); ++i)
{
switch (aSelectedObjects[i].Type)
{
case DatabaseObject::TABLE:
case DatabaseObjectContainer::SCHEMA:
case DatabaseObjectContainer::CATALOG:
aSelectedElements[E_TABLE].push_back(aSelectedObjects[i].Name);
break ;
case DatabaseObject::QUERY:
aSelectedElements[E_QUERY].push_back(aSelectedObjects[i].Name);
break ;
case DatabaseObject::FORM:
case DatabaseObjectContainer::FORMS_FOLDER:
aSelectedElements[E_FORM].push_back(aSelectedObjects[i].Name);
break ;
case DatabaseObject::REPORT:
case DatabaseObjectContainer::REPORTS_FOLDER:
aSelectedElements[E_REPORT].push_back(aSelectedObjects[i].Name);
break ;
case DatabaseObjectContainer::TABLES:
case DatabaseObjectContainer::QUERIES:
case DatabaseObjectContainer::FORMS:
case DatabaseObjectContainer::REPORTS:
if ( eSelectedCategory != E_NONE )
throw IllegalArgumentException(DBA_RES(RID_STR_NO_DIFF_CAT), *this , i);
eSelectedCategory =
( aSelectedObjects[i].Type == DatabaseObjectContainer::TABLES ) ? E_TABLE
: ( aSelectedObjects[i].Type == DatabaseObjectContainer::QUERIES ) ? E_QUERY
: ( aSelectedObjects[i].Type == DatabaseObjectContainer::FORMS ) ? E_FORM
: ( aSelectedObjects[i].Type == DatabaseObjectContainer::REPORTS ) ? E_REPORT
: E_NONE;
break ;
default :
case DatabaseObjectContainer::DATA_SOURCE:
{
OUString sMessage(
DBA_RES(RID_STR_UNSUPPORTED_OBJECT_TYPE).
replaceFirst("$type$" , OUString::number(aSelectedObjects[i].Type)));
throw IllegalArgumentException(sMessage, *this , i);
}
}
}
for (auto const & selectedElement : aSelectedElements)
{
if ( selectedElement.first == m_eCurrentType )
{
getContainer()->selectElements( comphelper::containerToSequence(selectedElement.second) );
}
else
{
m_aPendingSelection[ selectedElement.first ] = selectedElement.second;
}
}
m_aSelectContainerEvent.CancelCall(); // just in case the async select request was running
getContainer()->selectContainer( eSelectedCategory );
return true ;
}
Any SAL_CALL OApplicationController::getSelection( )
{
SolarMutexGuard aSolarGuard;
::osl::MutexGuard aGuard( getMutex() );
Sequence< NamedDatabaseObject > aCurrentSelection;
const ElementType eType( getContainer()->getElementType() );
if ( eType != E_NONE )
{
getContainer()->describeCurrentSelectionForType( eType, aCurrentSelection );
if ( !aCurrentSelection.hasElements() )
{ // if no objects are selected, add an entry to the sequence which describes the overall category
// which is selected currently
aCurrentSelection.realloc(1 );
auto pCurrentSelection = aCurrentSelection.getArray();
pCurrentSelection[0 ].Name = getDatabaseName();
switch ( eType )
{
case E_TABLE: pCurrentSelection[0 ].Type = DatabaseObjectContainer::TABLES; break ;
case E_QUERY: pCurrentSelection[0 ].Type = DatabaseObjectContainer::QUERIES; break ;
case E_FORM: pCurrentSelection[0 ].Type = DatabaseObjectContainer::FORMS; break ;
case E_REPORT: pCurrentSelection[0 ].Type = DatabaseObjectContainer::REPORTS; break ;
default :
OSL_FAIL( "OApplicationController::getSelection: unexpected current element type!" );
break ;
}
}
}
return Any( aCurrentSelection );
}
} // namespace dbaui
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=97 H=99 G=97
¤ Dauer der Verarbeitung: 0.59 Sekunden
(vorverarbeitet am 2026-10-01)
¤
*© Formatika GbR, Deutschland
2026-10-10
Neuigkeiten
Aktuelles
Motto des Tages
letze Version des Elbe Quellennavigators
Jenseits des Üblichen ....
Besucher
Statistik
#Sources=1126864
#Domains=1897691