1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include "AppController.hxx"
22 #include "AppDetailView.hxx"
23 #include "AppView.hxx"
24 #include "dbaccess_slotid.hrc"
25 #include "dbu_app.hrc"
26 #include "dbustrings.hrc"
27 #include "defaultobjectnamecheck.hxx"
28 #include "dlgsave.hxx"
29 #include "UITools.hxx"
30 #include "subcomponentmanager.hxx"
32 #include <com/sun/star/container/XChild.hpp>
33 #include <com/sun/star/container/XContainer.hpp>
34 #include <com/sun/star/container/XHierarchicalNameContainer.hpp>
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/lang/XEventListener.hpp>
38 #include <com/sun/star/sdb/CommandType.hpp>
39 #include <com/sun/star/sdb/SQLContext.hpp>
40 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
41 #include <com/sun/star/sdbcx/XRename.hpp>
42 #include <com/sun/star/sdb/ErrorCondition.hpp>
43 #include <com/sun/star/sdb/application/DatabaseObject.hpp>
44 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
45 #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
46 #include <com/sun/star/ucb/Command.hpp>
47 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
48 #include <com/sun/star/ucb/XCommandProcessor.hpp>
49 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
50 #include <com/sun/star/uno/XNamingService.hpp>
51 #include <com/sun/star/util/XCloseable.hpp>
52 #include <com/sun/star/util/XRefreshable.hpp>
54 #include <cppuhelper/exc_hlp.hxx>
55 #include <comphelper/processfactory.hxx>
56 #include <connectivity/dbexception.hxx>
57 #include <connectivity/dbtools.hxx>
58 #include <connectivity/sqlerror.hxx>
59 #include <sfx2/mailmodelapi.hxx>
60 #include <svx/dbaexchange.hxx>
61 #include <toolkit/unohlp.hxx>
62 #include <tools/diagnose_ex.h>
63 #include <osl/diagnose.h>
64 #include <unotools/bootstrap.hxx>
65 #include <vcl/mnemonic.hxx>
66 #include <vcl/svapp.hxx>
67 #include <vcl/waitobj.hxx>
68 #include <osl/mutex.hxx>
70 //........................................................................
73 using namespace ::dbtools
;
74 using namespace ::connectivity
;
75 using namespace ::svx
;
76 using namespace ::com::sun::star
;
77 using namespace ::com::sun::star::uno
;
78 using namespace ::com::sun::star::awt
;
79 using namespace ::com::sun::star::util
;
80 using namespace ::com::sun::star::frame
;
81 using namespace ::com::sun::star::lang
;
82 using namespace ::com::sun::star::ui::dialogs
;
83 using namespace ::com::sun::star::sdb
;
84 using namespace ::com::sun::star::sdbc
;
85 using namespace ::com::sun::star::sdbcx
;
86 using namespace ::com::sun::star::beans
;
87 using namespace ::com::sun::star::container
;
88 using namespace ::com::sun::star::ucb
;
90 using ::com::sun::star::util::XCloseable
;
91 using ::com::sun::star::ui::XContextMenuInterceptor
;
93 namespace DatabaseObject
= ::com::sun::star::sdb::application::DatabaseObject
;
94 namespace ErrorCondition
= ::com::sun::star::sdb::ErrorCondition
;
96 //........................................................................
97 // -----------------------------------------------------------------------------
99 class CloseChecker
: public ::cppu::WeakImplHelper1
< com::sun::star::lang::XEventListener
>
109 virtual ~CloseChecker()
118 // interface XEventListener
119 virtual void SAL_CALL
disposing( const EventObject
& /*Source*/ ) throw( RuntimeException
)
125 // -----------------------------------------------------------------------------
126 void OApplicationController::convertToView(const OUString
& _sName
)
130 SharedConnection
xConnection( getConnection() );
131 Reference
< XQueriesSupplier
> xSup( xConnection
, UNO_QUERY_THROW
);
132 Reference
< XNameAccess
> xQueries( xSup
->getQueries(), UNO_QUERY_THROW
);
133 Reference
< XPropertySet
> xSourceObject( xQueries
->getByName( _sName
), UNO_QUERY_THROW
);
135 Reference
< XTablesSupplier
> xTablesSup( xConnection
, UNO_QUERY_THROW
);
136 Reference
< XNameAccess
> xTables( xTablesSup
->getTables(), UNO_QUERY_THROW
);
138 Reference
< XDatabaseMetaData
> xMeta
= xConnection
->getMetaData();
140 OUString aName
= OUString(ModuleRes(STR_TBL_TITLE
));
141 aName
= aName
.getToken(0,' ');
142 OUString aDefaultName
= ::dbaui::createDefaultName(xMeta
,xTables
,aName
);
144 DynamicTableOrQueryNameCheck
aNameChecker( xConnection
, CommandType::TABLE
);
145 OSaveAsDlg
aDlg( getView(), CommandType::TABLE
, getORB(), xConnection
, aDefaultName
, aNameChecker
);
146 if ( aDlg
.Execute() == RET_OK
)
148 OUString sName
= aDlg
.getName();
149 OUString sCatalog
= aDlg
.getCatalog();
150 OUString sSchema
= aDlg
.getSchema();
152 ::dbtools::composeTableName( xMeta
, sCatalog
, sSchema
, sName
, sal_False
, ::dbtools::eInTableDefinitions
) );
153 Reference
<XPropertySet
> xView
= ::dbaui::createView(sNewName
,xConnection
,xSourceObject
);
155 throw SQLException(OUString(ModuleRes(STR_NO_TABLE_FORMAT_INSIDE
)),*this,OUString( "S1000" ) ,0,Any());
156 getContainer()->elementAdded(E_TABLE
,sNewName
,makeAny(xView
));
159 catch(const SQLException
& )
161 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) );
163 catch( const Exception
& )
165 DBG_UNHANDLED_EXCEPTION();
168 // -----------------------------------------------------------------------------
169 void OApplicationController::pasteFormat(sal_uInt32 _nFormatId
)
175 const TransferableDataHelper
& rClipboard
= getViewClipboard();
176 ElementType eType
= getContainer()->getElementType();
177 if ( eType
== E_TABLE
)
179 m_aTableCopyHelper
.pasteTable( _nFormatId
, rClipboard
, getDatabaseName(), ensureConnection() );
182 paste( eType
, ODataAccessObjectTransferable::extractObjectDescriptor( rClipboard
) );
185 catch( const Exception
& )
187 DBG_UNHANDLED_EXCEPTION();
191 // -----------------------------------------------------------------------------
192 void OApplicationController::openDataSourceAdminDialog()
194 openDialog( OUString( "com.sun.star.sdb.DatasourceAdministrationDialog" ) );
197 // -----------------------------------------------------------------------------
198 void OApplicationController::openDialog( const OUString
& _sServiceName
)
202 SolarMutexGuard aSolarGuard
;
203 ::osl::MutexGuard
aGuard( getMutex() );
204 WaitObject
aWO(getView());
206 Sequence
< Any
> aArgs(3);
207 sal_Int32 nArgPos
= 0;
209 Reference
< ::com::sun::star::awt::XWindow
> xWindow
= getTopMostContainerWindow();
212 OSL_ENSURE( getContainer(), "OApplicationController::Construct: have no view!" );
213 if ( getContainer() )
214 xWindow
= VCLUnoHelper::GetInterface(getView()->Window::GetParent());
217 aArgs
[nArgPos
++] <<= PropertyValue( OUString("ParentWindow"),
220 PropertyState_DIRECT_VALUE
);
222 // the initial selection
223 OUString sInitialSelection
;
224 if ( getContainer() )
225 sInitialSelection
= getDatabaseName();
226 if ( !sInitialSelection
.isEmpty() )
228 aArgs
[ nArgPos
++ ] <<= PropertyValue(
229 OUString( "InitialSelection" ), 0,
230 makeAny( sInitialSelection
), PropertyState_DIRECT_VALUE
);
233 SharedConnection
xConnection( getConnection() );
234 if ( xConnection
.is() )
236 aArgs
[ nArgPos
++ ] <<= PropertyValue(
237 PROPERTY_ACTIVE_CONNECTION
, 0,
238 makeAny( xConnection
), PropertyState_DIRECT_VALUE
);
240 aArgs
.realloc( nArgPos
);
243 Reference
< XExecutableDialog
> xAdminDialog
;
244 xAdminDialog
= Reference
< XExecutableDialog
>(
245 getORB()->getServiceManager()->createInstanceWithArgumentsAndContext(_sServiceName
, aArgs
, getORB()),
249 if (xAdminDialog
.is())
250 xAdminDialog
->execute();
252 catch( const Exception
& )
254 DBG_UNHANDLED_EXCEPTION();
257 // -----------------------------------------------------------------------------
258 void OApplicationController::openTableFilterDialog()
260 openDialog( OUString( "com.sun.star.sdb.TableFilterDialog" ) );
263 // -----------------------------------------------------------------------------
264 void OApplicationController::refreshTables()
266 if ( getContainer() && getContainer()->getDetailView() )
268 WaitObject
aWO(getView());
269 OSL_ENSURE(getContainer()->getElementType() == E_TABLE
,"Only allowed when the tables container is selected!");
272 Reference
<XRefreshable
> xRefresh(getElements(E_TABLE
),UNO_QUERY
);
276 catch(const Exception
&)
278 OSL_FAIL("Could not refresh tables!");
281 getContainer()->getDetailView()->clearPages(sal_False
);
282 getContainer()->getDetailView()->createTablesPage( ensureConnection() );
285 // -----------------------------------------------------------------------------
286 void OApplicationController::openDirectSQLDialog()
288 openDialog( SERVICE_SDB_DIRECTSQLDIALOG
);
290 // -----------------------------------------------------------------------------
291 void SAL_CALL
OApplicationController::propertyChange( const PropertyChangeEvent
& evt
) throw (RuntimeException
)
293 SolarMutexGuard aSolarGuard
;
294 ::osl::MutexGuard
aGuard( getMutex() );
295 if ( evt
.PropertyName
== PROPERTY_USER
)
297 m_bNeedToReconnect
= sal_True
;
298 InvalidateFeature(SID_DB_APP_STATUS_USERNAME
);
300 else if ( evt
.PropertyName
== PROPERTY_URL
)
302 m_bNeedToReconnect
= sal_True
;
303 InvalidateFeature(SID_DB_APP_STATUS_DBNAME
);
304 InvalidateFeature(SID_DB_APP_STATUS_TYPE
);
305 InvalidateFeature(SID_DB_APP_STATUS_HOSTNAME
);
307 else if ( PROPERTY_NAME
== evt
.PropertyName
)
309 const ElementType eType
= getContainer()->getElementType();
310 if ( eType
== E_FORM
|| eType
== E_REPORT
)
312 OUString sOldName
,sNewName
;
313 evt
.OldValue
>>= sOldName
;
314 evt
.NewValue
>>= sNewName
;
316 // if the old name is empty, then this is a newly inserted content. We're notified of it via the
317 // elementInserted method, so there's no need to handle it here.
319 if ( !sOldName
.isEmpty() )
321 Reference
<XChild
> xChild(evt
.Source
,UNO_QUERY
);
324 Reference
<XContent
> xContent(xChild
->getParent(),UNO_QUERY
);
326 sOldName
= xContent
->getIdentifier()->getContentIdentifier() + OUString("/") + sOldName
;
329 getContainer()->elementReplaced( eType
, sOldName
, sNewName
);
335 aEvt
.Source
= m_xModel
;
339 // -----------------------------------------------------------------------------
340 Reference
< XDataSource
> SAL_CALL
OApplicationController::getDataSource() throw (RuntimeException
)
342 ::osl::MutexGuard
aGuard( getMutex() );
343 Reference
< XDataSource
> xDataSource( m_xDataSource
, UNO_QUERY
);
347 // -----------------------------------------------------------------------------
348 Reference
< XWindow
> SAL_CALL
OApplicationController::getApplicationMainWindow() throw (RuntimeException
)
350 ::osl::MutexGuard
aGuard( getMutex() );
351 Reference
< XFrame
> xFrame( getFrame(), UNO_QUERY_THROW
);
352 Reference
< XWindow
> xWindow( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
356 // -----------------------------------------------------------------------------
357 Sequence
< Reference
< XComponent
> > SAL_CALL
OApplicationController::getSubComponents() throw (RuntimeException
)
359 ::osl::MutexGuard
aGuard( getMutex() );
360 return m_pSubComponentManager
->getSubComponents();
363 // -----------------------------------------------------------------------------
364 Reference
< XConnection
> SAL_CALL
OApplicationController::getActiveConnection() throw (RuntimeException
)
366 ::osl::MutexGuard
aGuard( getMutex() );
367 return m_xDataSourceConnection
.getTyped();
370 // -----------------------------------------------------------------------------
371 ::sal_Bool SAL_CALL
OApplicationController::isConnected( ) throw (RuntimeException
)
373 ::osl::MutexGuard
aGuard( getMutex() );
374 return m_xDataSourceConnection
.is();
377 // -----------------------------------------------------------------------------
378 void SAL_CALL
OApplicationController::connect( ) throw (SQLException
, RuntimeException
)
380 SQLExceptionInfo aError
;
381 SharedConnection xConnection
= ensureConnection( &aError
);
382 if ( !xConnection
.is() )
384 if ( aError
.isValid() )
387 // no particular error, but nonetheless could not connect -> throw a generic exception
388 OUString
sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE
) );
389 ::dbtools::throwGenericSQLException( sConnectingContext
.replaceFirst( "$name$", getStrippedDatabaseName() ), *this );
393 // -----------------------------------------------------------------------------
394 beans::Pair
< ::sal_Int32
, OUString
> SAL_CALL
OApplicationController::identifySubComponent( const Reference
< XComponent
>& i_rSubComponent
) throw (IllegalArgumentException
, RuntimeException
)
396 ::osl::MutexGuard
aGuard( getMutex() );
398 sal_Int32 nType
= -1;
401 if ( !m_pSubComponentManager
->lookupSubComponent( i_rSubComponent
, sName
, nType
) )
402 throw IllegalArgumentException( OUString(), *this, 1 );
404 if ( nType
== SID_DB_APP_DSRELDESIGN
)
405 // this is somewhat hacky ... we're expected to return a DatabaseObject value. However, there is no such
406 // value for the relation design. /me thinks we should change the API definition here ...
409 return beans::Pair
< ::sal_Int32
, OUString
>( nType
, sName
);
412 // -----------------------------------------------------------------------------
413 ::sal_Bool SAL_CALL
OApplicationController::closeSubComponents( ) throw (RuntimeException
)
415 SolarMutexGuard aSolarGuard
;
416 ::osl::MutexGuard
aGuard( getMutex() );
417 return m_pSubComponentManager
->closeSubComponents();
421 // -----------------------------------------------------------------------------
424 ElementType
lcl_objectType2ElementType( const sal_Int32 _nObjectType
)
426 ElementType
eType( E_NONE
);
427 switch ( _nObjectType
)
429 case DatabaseObject::TABLE
: eType
= E_TABLE
; break;
430 case DatabaseObject::QUERY
: eType
= E_QUERY
; break;
431 case DatabaseObject::FORM
: eType
= E_FORM
; break;
432 case DatabaseObject::REPORT
: eType
= E_REPORT
; break;
434 OSL_FAIL( "lcl_objectType2ElementType: unsupported object type!" );
435 // this should have been caught earlier
441 // -----------------------------------------------------------------------------
442 void OApplicationController::impl_validateObjectTypeAndName_throw( const sal_Int32 _nObjectType
, const ::boost::optional
< OUString
>& i_rObjectName
)
444 // ensure we're connected
445 if ( !isConnected() )
447 SQLError
aError( getORB() );
448 aError
.raiseException( ErrorCondition::DB_NOT_CONNECTED
, *this );
451 // ensure a proper object type
452 if ( ( _nObjectType
!= DatabaseObject::TABLE
)
453 && ( _nObjectType
!= DatabaseObject::QUERY
)
454 && ( _nObjectType
!= DatabaseObject::FORM
)
455 && ( _nObjectType
!= DatabaseObject::REPORT
)
457 throw IllegalArgumentException( OUString(), *this, 1 );
459 if ( !i_rObjectName
)
462 // ensure an existing object
463 Reference
< XNameAccess
> xContainer( getElements( lcl_objectType2ElementType( _nObjectType
) ) );
464 if ( !xContainer
.is() )
465 // all possible reasons for this (e.g. not being connected currently) should
466 // have been handled before
467 throw RuntimeException( OUString(), *this );
469 bool bExistentObject
= false;
470 switch ( _nObjectType
)
472 case DatabaseObject::TABLE
:
473 case DatabaseObject::QUERY
:
474 bExistentObject
= xContainer
->hasByName( *i_rObjectName
);
476 case DatabaseObject::FORM
:
477 case DatabaseObject::REPORT
:
479 Reference
< XHierarchicalNameAccess
> xHierarchy( xContainer
, UNO_QUERY_THROW
);
480 bExistentObject
= xHierarchy
->hasByHierarchicalName( *i_rObjectName
);
485 if ( !bExistentObject
)
486 throw NoSuchElementException( *i_rObjectName
, *this );
489 // -----------------------------------------------------------------------------
490 Reference
< XComponent
> SAL_CALL
OApplicationController::loadComponent( ::sal_Int32 _ObjectType
,
491 const OUString
& _ObjectName
, ::sal_Bool _ForEditing
) throw (IllegalArgumentException
, NoSuchElementException
, SQLException
, RuntimeException
)
493 return loadComponentWithArguments( _ObjectType
, _ObjectName
, _ForEditing
, Sequence
< PropertyValue
>() );
496 // -----------------------------------------------------------------------------
497 Reference
< XComponent
> SAL_CALL
OApplicationController::loadComponentWithArguments( ::sal_Int32 _ObjectType
,
498 const OUString
& _ObjectName
, ::sal_Bool _ForEditing
, const Sequence
< PropertyValue
>& _Arguments
) throw (IllegalArgumentException
, NoSuchElementException
, SQLException
, RuntimeException
)
500 SolarMutexGuard aSolarGuard
;
501 ::osl::MutexGuard
aGuard( getMutex() );
503 impl_validateObjectTypeAndName_throw( _ObjectType
, _ObjectName
);
505 Reference
< XComponent
> xComponent( openElementWithArguments(
507 lcl_objectType2ElementType( _ObjectType
),
508 _ForEditing
? E_OPEN_DESIGN
: E_OPEN_NORMAL
,
509 _ForEditing
? SID_DB_APP_EDIT
: SID_DB_APP_OPEN
,
510 ::comphelper::NamedValueCollection( _Arguments
)
516 // -----------------------------------------------------------------------------
517 Reference
< XComponent
> SAL_CALL
OApplicationController::createComponent( ::sal_Int32 i_nObjectType
, Reference
< XComponent
>& o_DocumentDefinition
) throw (IllegalArgumentException
, SQLException
, RuntimeException
)
519 return createComponentWithArguments( i_nObjectType
, Sequence
< PropertyValue
>(), o_DocumentDefinition
);
522 // -----------------------------------------------------------------------------
523 Reference
< XComponent
> SAL_CALL
OApplicationController::createComponentWithArguments( ::sal_Int32 i_nObjectType
, const Sequence
< PropertyValue
>& i_rArguments
, Reference
< XComponent
>& o_DocumentDefinition
) throw (IllegalArgumentException
, SQLException
, RuntimeException
)
525 SolarMutexGuard aSolarGuard
;
526 ::osl::MutexGuard
aGuard( getMutex() );
528 impl_validateObjectTypeAndName_throw( i_nObjectType
, ::boost::optional
< OUString
>() );
530 Reference
< XComponent
> xComponent( newElement(
531 lcl_objectType2ElementType( i_nObjectType
),
532 ::comphelper::NamedValueCollection( i_rArguments
),
539 // -----------------------------------------------------------------------------
540 void SAL_CALL
OApplicationController::registerContextMenuInterceptor( const Reference
< XContextMenuInterceptor
>& _Interceptor
) throw (RuntimeException
)
542 if ( _Interceptor
.is() )
543 m_aContextMenuInterceptors
.addInterface( _Interceptor
);
546 // -----------------------------------------------------------------------------
547 void SAL_CALL
OApplicationController::releaseContextMenuInterceptor( const Reference
< XContextMenuInterceptor
>& _Interceptor
) throw (RuntimeException
)
549 m_aContextMenuInterceptors
.removeInterface( _Interceptor
);
552 // -----------------------------------------------------------------------------
553 void OApplicationController::previewChanged( sal_Int32 _nMode
)
555 SolarMutexGuard aSolarGuard
;
556 ::osl::MutexGuard
aGuard( getMutex() );
558 if ( m_xDataSource
.is() && !isDataSourceReadOnly() )
562 ::comphelper::NamedValueCollection
aLayoutInfo( m_xDataSource
->getPropertyValue( PROPERTY_LAYOUTINFORMATION
) );
563 sal_Int32 nOldMode
= aLayoutInfo
.getOrDefault( "Preview", _nMode
);
564 if ( nOldMode
!= _nMode
)
566 aLayoutInfo
.put( "Preview", _nMode
);
567 m_xDataSource
->setPropertyValue( PROPERTY_LAYOUTINFORMATION
, makeAny( aLayoutInfo
.getPropertyValues() ) );
570 catch ( const Exception
& )
572 DBG_UNHANDLED_EXCEPTION();
575 InvalidateFeature(SID_DB_APP_DISABLE_PREVIEW
);
576 InvalidateFeature(SID_DB_APP_VIEW_DOCINFO_PREVIEW
);
577 InvalidateFeature(SID_DB_APP_VIEW_DOC_PREVIEW
);
579 // -----------------------------------------------------------------------------
580 void OApplicationController::askToReconnect()
582 if ( m_bNeedToReconnect
)
584 m_bNeedToReconnect
= sal_False
;
585 sal_Bool bClear
= sal_True
;
586 if ( !m_pSubComponentManager
->empty() )
588 QueryBox
aQry(getView(), ModuleRes(APP_CLOSEDOCUMENTS
));
589 switch (aQry
.Execute())
592 closeSubComponents();
601 ElementType eType
= getContainer()->getElementType();
603 getContainer()->getDetailView()->clearPages(sal_False
);
604 getContainer()->selectContainer(E_NONE
); // invalidate the old selection
605 m_eCurrentType
= E_NONE
;
606 getContainer()->selectContainer(eType
); // reselect the current one again
611 // -----------------------------------------------------------------------------
612 OUString
OApplicationController::getDatabaseName() const
614 OUString sDatabaseName
;
617 if ( m_xDataSource
.is() )
619 OSL_VERIFY( m_xDataSource
->getPropertyValue( PROPERTY_NAME
) >>= sDatabaseName
);
622 catch ( const Exception
& )
624 DBG_UNHANDLED_EXCEPTION();
626 return sDatabaseName
;
629 // -----------------------------------------------------------------------------
630 OUString
OApplicationController::getStrippedDatabaseName() const
632 OUString sDatabaseName
;
633 return ::dbaui::getStrippedDatabaseName( m_xDataSource
, sDatabaseName
);
636 // -----------------------------------------------------------------------------
637 void OApplicationController::onDocumentOpened( const OUString
& _rName
, const sal_Int32 _nType
,
638 const ElementOpenMode _eMode
, const Reference
< XComponent
>& _xDocument
, const Reference
< XComponent
>& _rxDefinition
)
640 if ( !_xDocument
.is() )
645 OSL_ENSURE( _xDocument
.is(), "OApplicationController::onDocumentOpened: is there any *valid* scenario where this fails?" );
646 m_pSubComponentManager
->onSubComponentOpened( _rName
, _nType
, _eMode
, _xDocument
.is() ? _xDocument
: _rxDefinition
);
648 if ( _rxDefinition
.is() )
650 Reference
< XPropertySet
> xProp( _rxDefinition
, UNO_QUERY_THROW
);
651 Reference
< XPropertySetInfo
> xPSI( xProp
->getPropertySetInfo(), UNO_SET_THROW
);
652 xProp
->addPropertyChangeListener( PROPERTY_NAME
, static_cast< XPropertyChangeListener
* >( this ) );
655 catch( const Exception
& )
657 DBG_UNHANDLED_EXCEPTION();
660 // -----------------------------------------------------------------------------
661 sal_Bool
OApplicationController::insertHierachyElement(ElementType _eType
,const OUString
& _sParentFolder
,sal_Bool _bCollection
,const Reference
<XContent
>& _xContent
,sal_Bool _bMove
)
663 Reference
<XHierarchicalNameContainer
> xNames(getElements(_eType
), UNO_QUERY
);
664 return dbaui::insertHierachyElement(getView()
673 // -----------------------------------------------------------------------------
674 sal_Bool
OApplicationController::isRenameDeleteAllowed(ElementType _eType
,sal_Bool _bDelete
) const
676 ElementType eType
= getContainer()->getElementType();
677 sal_Bool bEnabled
= !isDataSourceReadOnly() && eType
== _eType
;
681 if ( E_TABLE
== eType
)
682 bEnabled
= !isConnectionReadOnly() && getContainer()->isALeafSelected();
684 sal_Bool bCompareRes
= sal_False
;
686 bCompareRes
= getContainer()->getSelectionCount() > 0;
689 bCompareRes
= getContainer()->getSelectionCount() == 1;
690 if ( bEnabled
&& bCompareRes
&& E_TABLE
== eType
)
692 ::std::vector
< OUString
> aList
;
693 getSelectionElementNames(aList
);
697 Reference
< XNameAccess
> xContainer
= const_cast<OApplicationController
*>(this)->getElements(eType
);
698 bEnabled
= (xContainer
.is() && xContainer
->hasByName(*aList
.begin()));
700 bEnabled
= Reference
<XRename
>(xContainer
->getByName(*aList
.begin()),UNO_QUERY
).is();
704 bEnabled
= sal_False
;
709 bEnabled
= bEnabled
&& bCompareRes
;
713 // -----------------------------------------------------------------------------
714 void OApplicationController::onLoadedMenu(const Reference
< ::com::sun::star::frame::XLayoutManager
>& _xLayoutManager
)
717 if ( _xLayoutManager
.is() )
719 static OUString
s_sStatusbar("private:resource/statusbar/statusbar");
720 _xLayoutManager
->createElement( s_sStatusbar
);
721 _xLayoutManager
->requestElement( s_sStatusbar
);
723 if ( getContainer() )
725 // we need to share the "mnemonic space":
726 MnemonicGenerator aMnemonicGenerator
;
727 // - the menu already has mnemonics
728 SystemWindow
* pSystemWindow
= getContainer()->GetSystemWindow();
729 MenuBar
* pMenu
= pSystemWindow
? pSystemWindow
->GetMenuBar() : NULL
;
732 sal_uInt16 nMenuItems
= pMenu
->GetItemCount();
733 for ( sal_uInt16 i
= 0; i
< nMenuItems
; ++i
)
734 aMnemonicGenerator
.RegisterMnemonic( pMenu
->GetItemText( pMenu
->GetItemId( i
) ) );
736 // - the icons should use automatic ones
737 getContainer()->createIconAutoMnemonics( aMnemonicGenerator
);
738 // - as well as the entries in the task pane
739 getContainer()->setTaskExternalMnemonics( aMnemonicGenerator
);
742 Execute( SID_DB_APP_VIEW_FORMS
, Sequence
< PropertyValue
>() );
746 // -----------------------------------------------------------------------------
747 void OApplicationController::doAction(sal_uInt16 _nId
,ElementOpenMode _eOpenMode
)
749 ::std::vector
< OUString
> aList
;
750 getSelectionElementNames(aList
);
751 ElementType eType
= getContainer()->getElementType();
752 ::comphelper::NamedValueCollection aArguments
;
753 ElementOpenMode eOpenMode
= _eOpenMode
;
754 if ( eType
== E_REPORT
&& E_OPEN_FOR_MAIL
== _eOpenMode
)
756 aArguments
.put("Hidden",true);
757 eOpenMode
= E_OPEN_NORMAL
;
760 ::std::vector
< ::std::pair
< OUString
,Reference
< XModel
> > > aCompoments
;
761 ::std::vector
< OUString
>::iterator aEnd
= aList
.end();
762 for (::std::vector
< OUString
>::iterator aIter
= aList
.begin(); aIter
!= aEnd
; ++aIter
)
764 if ( SID_DB_APP_CONVERTTOVIEW
== _nId
)
765 convertToView(*aIter
);
768 Reference
< XModel
> xModel( openElementWithArguments( *aIter
, eType
, eOpenMode
, _nId
,aArguments
), UNO_QUERY
);
769 aCompoments
.push_back( ::std::pair
< OUString
, Reference
< XModel
> >( *aIter
, xModel
) );
773 // special handling for mail, if more than one document is selected attach them all
774 if ( _eOpenMode
== E_OPEN_FOR_MAIL
)
777 ::std::vector
< ::std::pair
< OUString
,Reference
< XModel
> > >::iterator componentIter
= aCompoments
.begin();
778 ::std::vector
< ::std::pair
< OUString
,Reference
< XModel
> > >::iterator componentEnd
= aCompoments
.end();
779 OUString aDocTypeString
;
780 SfxMailModel aSendMail
;
781 SfxMailModel::SendMailResult eResult
= SfxMailModel::SEND_MAIL_OK
;
782 for (; componentIter
!= componentEnd
&& SfxMailModel::SEND_MAIL_OK
== eResult
; ++componentIter
)
786 Reference
< XModel
> xModel(componentIter
->second
,UNO_QUERY
);
788 // Send document as e-Mail using stored/default type
789 eResult
= aSendMail
.AttachDocument(aDocTypeString
,xModel
,componentIter
->first
);
790 ::comphelper::disposeComponent(xModel
);
792 catch(const Exception
&)
794 DBG_UNHANDLED_EXCEPTION();
797 if ( !aSendMail
.IsEmpty() )
798 aSendMail
.Send( getFrame() );
801 // -----------------------------------------------------------------------------
802 ElementType
OApplicationController::getElementType(const Reference
< XContainer
>& _xContainer
) const
804 ElementType eRet
= E_NONE
;
805 Reference
<XServiceInfo
> xServiceInfo(_xContainer
,UNO_QUERY
);
806 if ( xServiceInfo
.is() )
808 if ( xServiceInfo
->supportsService(SERVICE_SDBCX_TABLES
) )
810 else if ( xServiceInfo
->supportsService(SERVICE_NAME_FORM_COLLECTION
) )
812 else if ( xServiceInfo
->supportsService(SERVICE_NAME_REPORT_COLLECTION
) )
820 //........................................................................
822 //........................................................................
824 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */