diff options
author | Release Engineers <releng@openoffice.org> | 2008-12-01 12:31:27 +0000 |
---|---|---|
committer | Release Engineers <releng@openoffice.org> | 2008-12-01 12:31:27 +0000 |
commit | 5757cee49bcedaf29943987525ce956a3a05d60e (patch) | |
tree | b339e632fb18a0efbfc0f8b24e4c57890d02b917 /dbaccess/source/ui/app | |
parent | fdfcf146a787e6c9823e1c9d40b7c4a5a3f13001 (diff) |
CWS-TOOLING: integrate CWS dba31e
2008-11-19 12:36:23 +0100 msc r263980 : i96104
2008-11-19 12:31:19 +0100 msc r263979 : i96104
2008-11-19 12:21:55 +0100 msc r263977 : i96104
2008-11-19 12:18:53 +0100 msc r263976 : i96104
2008-11-18 09:09:45 +0100 oj r263746 : disable color entry when area is set
2008-11-18 08:37:52 +0100 oj r263741 : #remove sub report entry
2008-11-17 11:20:25 +0100 fs r263708 : #i10000#
2008-11-17 11:06:52 +0100 fs r263706 : minimal version now is 3.1
2008-11-12 22:25:59 +0100 fs r263621 : #i96150#
2008-11-12 22:20:02 +0100 fs r263620 : rebased to m34
2008-11-12 21:39:41 +0100 fs r263618 : MANUAL REBASE: rebase CWS dba31d to DEV300_m34
2008-11-12 13:54:58 +0100 fs r263597 : #i96134# MediaDescriptor.URL is to be preferred over MediaDescriptor.FileName. Nonetheless, ensure both are handled
2008-11-12 13:53:40 +0100 fs r263596 : #i96134# re-enabled the code for #i41897#, a better fix is to come
2008-11-12 12:48:21 +0100 fs r263585 : #i96134# disable saving URLs of file-base databases relatively
2008-11-11 16:11:11 +0100 msc r263566 : #i96104#
2008-11-05 09:09:47 +0100 oj r263342 : #i88727# color noe added
2008-11-05 08:41:43 +0100 oj r263341 : #i77916# zoom added
2008-11-04 21:24:15 +0100 fs r263339 : disposing: call disposeAndClear without own mutex locked - some of our listeners insist on locking the SolarMutex, which sometimes led to deadlocks on the complex test cases
2008-11-04 21:23:15 +0100 fs r263338 : remove SolarMutex locking - this happned in CWS dba31c (in the CVS version), which this CWS was created from, but seems to got lost during resync
2008-11-04 20:49:50 +0100 fs r263335 : docu formatting
2008-11-04 20:06:39 +0100 fs r263334 : #i95826# use m_aMutex, not a DocumentGuard (wrongly resolved merge conflicts)
2008-11-04 17:36:29 +0100 fs r263332 : #i92688# properly revoke as XEventListener from m_xActiveController when disposing
2008-11-04 14:49:34 +0100 fs r263324 : #i92322# enable Input Required if EmptyIsNULL does not exist at the control
2008-10-31 11:10:04 +0100 oj r262857 : merge from cvs to svn
2008-10-31 09:46:45 +0100 oj r262853 : merge from cvs to svn
2008-10-31 08:46:37 +0100 oj r262849 : merge from cvs to svn
2008-10-31 08:44:24 +0100 oj r262848 : merge from cvs to svn
2008-10-31 08:43:33 +0100 oj r262847 : merge from cvs to svn
2008-10-31 08:42:28 +0100 oj r262846 : merge from cvs to svn
2008-10-31 08:41:58 +0100 oj r262845 : merge from cvs to svn
2008-10-31 08:41:32 +0100 oj r262844 : merge from cvs to svn
2008-10-28 12:19:50 +0100 oj r262733 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:42 +0100 oj r262732 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:36 +0100 oj r262731 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:31 +0100 oj r262730 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:22 +0100 oj r262729 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:18 +0100 oj r262728 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:10 +0100 oj r262727 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:06 +0100 oj r262726 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:05 +0100 oj r262725 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:19:01 +0100 oj r262724 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:50 +0100 oj r262723 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:41 +0100 oj r262722 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:40 +0100 oj r262721 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:27 +0100 oj r262720 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:10 +0100 oj r262719 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:18:01 +0100 oj r262718 : #iXXXXX#: migrate CWS dba31e to SVN
2008-10-28 12:17:39 +0100 oj r262717 : #iXXXXX#: migrate CWS dba31e to SVN
Diffstat (limited to 'dbaccess/source/ui/app')
-rw-r--r-- | dbaccess/source/ui/app/AppController.cxx | 210 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppController.hxx | 66 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppControllerDnD.cxx | 75 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppControllerGen.cxx | 181 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppDetailPageHelper.cxx | 63 | ||||
-rw-r--r-- | dbaccess/source/ui/app/AppDetailPageHelper.hxx | 12 | ||||
-rw-r--r-- | dbaccess/source/ui/app/IApplicationController.hxx | 32 | ||||
-rw-r--r-- | dbaccess/source/ui/app/makefile.mk | 5 | ||||
-rw-r--r-- | dbaccess/source/ui/app/subcomponentmanager.cxx | 432 | ||||
-rw-r--r-- | dbaccess/source/ui/app/subcomponentmanager.hxx | 115 |
10 files changed, 802 insertions, 389 deletions
diff --git a/dbaccess/source/ui/app/AppController.cxx b/dbaccess/source/ui/app/AppController.cxx index 867000b0d..a27e34588 100644 --- a/dbaccess/source/ui/app/AppController.cxx +++ b/dbaccess/source/ui/app/AppController.cxx @@ -34,6 +34,7 @@ #include "AppController.hxx" #include "dbustrings.hrc" #include "advancedsettingsdlg.hxx" +#include "subcomponentmanager.hxx" /** === begin UNO includes === **/ #include <com/sun/star/beans/NamedValue.hpp> @@ -407,7 +408,8 @@ DBG_NAME(OApplicationController) //-------------------------------------------------------------------- OApplicationController::OApplicationController(const Reference< XMultiServiceFactory >& _rxORB) :OApplicationController_CBASE( _rxORB ) - ,m_aContextMenuInterceptors( m_aMutex ) + ,m_aContextMenuInterceptors( getMutex() ) + ,m_pSubComponentManager( new SubComponentManager( getSharedMutex() ) ) ,m_aTableCopyHelper(this) ,m_pClipbordNotifier(NULL) ,m_nAsyncDrop(0) @@ -417,7 +419,7 @@ OApplicationController::OApplicationController(const Reference< XMultiServiceFac ,m_eCurrentType(E_NONE) ,m_bNeedToReconnect(sal_False) ,m_bSuspended( sal_False ) - ,m_pSelectionNotifier( new SelectionNotifier( m_aMutex, *this ) ) + ,m_pSelectionNotifier( new SelectionNotifier( getMutex(), *this ) ) { DBG_CTOR(OApplicationController,NULL); @@ -472,8 +474,7 @@ void SAL_CALL OApplicationController::disposing() ::std::for_each(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),XContainerFunctor(this)); m_aCurrentContainers.clear(); - m_aSpecialSubFrames.clear(); - m_aDocuments.clear(); + m_pSubComponentManager->disposing(); m_pSelectionNotifier->disposing(); if ( getView() ) @@ -596,7 +597,7 @@ sal_Bool OApplicationController::Construct(Window* _pParent) //-------------------------------------------------------------------- void SAL_CALL OApplicationController::disposing(const EventObject& _rSource) throw( RuntimeException ) { - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Reference<XConnection> xCon(_rSource.Source, UNO_QUERY); if ( xCon.is() ) { @@ -622,22 +623,7 @@ void SAL_CALL OApplicationController::disposing(const EventObject& _rSource) thr } else { - Reference<XComponent> xComp(_rSource.Source,UNO_QUERY); - Reference<XContainer> xContainer(_rSource.Source,UNO_QUERY); - if ( xComp.is() ) - { - TDocuments::iterator aFind = ::std::find_if(m_aDocuments.begin(),m_aDocuments.end(), - ::std::compose1(::std::bind2nd(::std::equal_to<Reference<XComponent> >(),xComp),::std::select1st<TDocuments::value_type>())); - if ( aFind != m_aDocuments.end() ) - m_aDocuments.erase(aFind); - - TFrames::iterator aFind2 = ::std::find_if(m_aSpecialSubFrames.begin(),m_aSpecialSubFrames.end(), - ::std::compose1(::std::bind2nd(::std::equal_to<Reference<XComponent> >(),xComp), - ::std::compose1(::std::select2nd<TTypeFrame>(),::std::select2nd<TFrames::value_type>()))); - if ( aFind2 != m_aSpecialSubFrames.end() ) - m_aSpecialSubFrames.erase(aFind2); - - } + Reference<XContainer> xContainer( _rSource.Source, UNO_QUERY ); if ( xContainer.is() ) { TContainerVector::iterator aFind = ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer); @@ -662,7 +648,7 @@ sal_Bool SAL_CALL OApplicationController::suspend(sal_Bool bSuspend) throw( Runt } ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); if ( getView() && getView()->IsInModalMode() ) return sal_False; @@ -1150,7 +1136,7 @@ namespace void OApplicationController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); if ( isUserDefinedFeature( _nId ) ) { @@ -1329,7 +1315,6 @@ void OApplicationController::Execute(sal_uInt16 _nId, const Sequence< PropertyVa lcl_handleException_nothrow( m_xModel, ::cppu::getCaughtException() ); } - m_sDatabaseName = ::rtl::OUString(); /*updateTitle();*/ m_bCurrentlyModified = sal_False; InvalidateFeature(ID_BROWSER_SAVEDOC); @@ -1425,7 +1410,7 @@ void OApplicationController::Execute(sal_uInt16 _nId, const Sequence< PropertyVa Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY ); Reference< XComponent > xComponent( aDesigner.createNew( xDataSource ), UNO_QUERY ); - addDocumentListener( xComponent, NULL ); + onDocumentOpened( ::rtl::OUString(), E_QUERY, E_OPEN_DESIGN, xComponent, NULL ); } } break; @@ -1466,18 +1451,17 @@ void OApplicationController::Execute(sal_uInt16 _nId, const Sequence< PropertyVa InvalidateAll(); break; case SID_DB_APP_DSRELDESIGN: - if ( !impl_activateSubFrame_throw(::rtl::OUString(),SID_DB_APP_DSRELDESIGN,E_OPEN_DESIGN) ) + if ( !m_pSubComponentManager->activateSubFrame( ::rtl::OUString(), SID_DB_APP_DSRELDESIGN, E_OPEN_DESIGN ) ) { SharedConnection xConnection( ensureConnection() ); if ( xConnection.is() ) { RelationDesigner aDesigner( getORB(), this, m_aCurrentFrame.getFrame() ); + Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY ); Reference< XComponent > xComponent( aDesigner.createNew( xDataSource ), UNO_QUERY ); - addDocumentListener( xComponent, NULL ); - m_aSpecialSubFrames.insert(TFrames::value_type(::rtl::OUString(), - TTypeFrame(TTypeOpenMode(SID_DB_APP_DSRELDESIGN,E_OPEN_DESIGN),xComponent))); - } // if ( xConnection.is() ) + onDocumentOpened( ::rtl::OUString(), SID_DB_APP_DSRELDESIGN, E_OPEN_DESIGN, xComponent, NULL ); + } } break; case SID_DB_APP_DSUSERADMIN: @@ -1676,7 +1660,7 @@ OApplicationView* OApplicationController::getContainer() const void SAL_CALL OApplicationController::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException) { ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY); if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() ) @@ -1712,7 +1696,7 @@ void SAL_CALL OApplicationController::elementInserted( const ContainerEvent& _rE void SAL_CALL OApplicationController::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException) { ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY); if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() ) @@ -1746,7 +1730,7 @@ void SAL_CALL OApplicationController::elementRemoved( const ContainerEvent& _rEv void SAL_CALL OApplicationController::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException) { ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Reference< XContainer > xContainer(_rEvent.Source, UNO_QUERY); if ( ::std::find(m_aCurrentContainers.begin(),m_aCurrentContainers.end(),xContainer) != m_aCurrentContainers.end() ) @@ -1971,16 +1955,15 @@ Reference< XComponent > OApplicationController::openElementWithArguments( const Reference< XComponent > xDefinition; xRet = aHelper->open( _sName, xDefinition, _eOpenMode, _rAdditionalArguments ); - addDocumentListener(xRet,xDefinition); + onDocumentOpened( _sName, _eType, _eOpenMode, xRet, xDefinition ); } break; case E_QUERY: case E_TABLE: { - if ( !impl_activateSubFrame_throw(_sName,_eType,_eOpenMode) ) + if ( !m_pSubComponentManager->activateSubFrame( _sName, _eType, _eOpenMode ) ) { - SharedConnection xConnection( ensureConnection() ); if ( !xConnection.is() ) break; @@ -2017,9 +2000,7 @@ Reference< XComponent > OApplicationController::openElementWithArguments( const } Reference< XComponent > xComponent( pDesigner->openExisting( aDataSource, _sName, aArguments.getPropertyValues() ), UNO_QUERY ); - addDocumentListener( xComponent, NULL ); - m_aSpecialSubFrames.insert(TFrames::value_type(_sName, - TTypeFrame(TTypeOpenMode(_eType,_eOpenMode),xComponent))); + onDocumentOpened( _sName, _eType, _eOpenMode, xComponent, NULL ); } } break; @@ -2066,7 +2047,7 @@ void OApplicationController::newElementWithPilot( ElementType _eType ) else xComponent = aHelper->newFormWithPilot(xDefinition,nCommandType,sName); - addDocumentListener(xComponent,xDefinition); + onDocumentOpened( ::rtl::OUString(), _eType, E_OPEN_DESIGN, xComponent, xDefinition ); } } break; @@ -2076,12 +2057,13 @@ void OApplicationController::newElementWithPilot( ElementType _eType ) ::std::auto_ptr<OLinkedDocumentsAccess> aHelper = getDocumentsAccess(_eType); if ( aHelper->isConnected() ) { - Reference< XComponent > xComponent,xDefinition; + Reference< XComponent > xComponent; if ( E_QUERY == _eType ) xComponent = aHelper->newQueryWithPilot(); else xComponent = aHelper->newTableWithPilot(); - addDocumentListener(xComponent,xDefinition); + + onDocumentOpened( ::rtl::OUString(), _eType, E_OPEN_DESIGN, xComponent, NULL ); } } break; @@ -2107,7 +2089,7 @@ void OApplicationController::newElement( ElementType _eType, sal_Bool _bSQLView sal_Int32 nCommandType = -1; const ::rtl::OUString sName(getCurrentlySelectedName(nCommandType)); xComponent = aHelper->newDocument(_eType == E_FORM ? ID_FORM_NEW_TEXT : ID_REPORT_NEW_TEXT,xDefinition,nCommandType,sName); - addDocumentListener(xComponent,xDefinition); + onDocumentOpened( ::rtl::OUString(), _eType, E_OPEN_DESIGN, xComponent, xDefinition ); } } break; @@ -2129,7 +2111,7 @@ void OApplicationController::newElement( ElementType _eType, sal_Bool _bSQLView Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY ); Reference< XComponent > xComponent( pDesigner->createNew( xDataSource ), UNO_QUERY ); - addDocumentListener(xComponent,NULL); + onDocumentOpened( ::rtl::OUString(), _eType, E_OPEN_DESIGN, xComponent, NULL ); } } break; @@ -2163,7 +2145,7 @@ void OApplicationController::addContainerListener(const Reference<XNameAccess>& void OApplicationController::renameEntry() { ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); OSL_ENSURE(getContainer(),"View is NULL! -> GPF"); ::std::vector< ::rtl::OUString> aList; @@ -2311,68 +2293,59 @@ void OApplicationController::renameEntry() DBG_UNHANDLED_EXCEPTION(); } } -// ----------------------------------------------------------------------------- -void OApplicationController::onEntryDeSelect(SvTreeListBox& /*_rTree*/) -{ - SelectionGuard aSelGuard( *m_pSelectionNotifier ); - InvalidateAll(); -} // ----------------------------------------------------------------------------- -void OApplicationController::onEntrySelect(SvLBoxEntry* _pEntry) +void OApplicationController::onSelectionChanged() { InvalidateAll(); + SelectionGuard aSelGuard( *m_pSelectionNotifier ); + OApplicationView* pView = getContainer(); - if ( pView ) - { - SelectionGuard aSelGuard( *m_pSelectionNotifier ); + if ( !pView ) + return; + if ( pView->getSelectionCount() == 1 ) + { const ElementType eType = pView->getElementType(); - if ( _pEntry && pView->isALeafSelected() ) + if ( pView->isALeafSelected() ) { - const ::rtl::OUString sName = pView->getQualifiedName( _pEntry ); - selectEntry(eType,sName); + const ::rtl::OUString sName = pView->getQualifiedName( NULL /* means 'first selected' */ ); + showPreviewFor( eType, sName ); } } } // ----------------------------------------------------------------------------- -void OApplicationController::selectEntry(const ElementType _eType,const ::rtl::OUString& _sName) +void OApplicationController::showPreviewFor(const ElementType _eType,const ::rtl::OUString& _sName) { OApplicationView* pView = getContainer(); - Reference< XContent> xContent; + if ( !pView ) + return; + try { switch( _eType ) { case E_FORM: case E_REPORT: - if ( _sName.getLength() ) - { - Reference< XHierarchicalNameAccess > xContainer(getElements(_eType),UNO_QUERY); - if ( xContainer.is() && xContainer->hasByHierarchicalName(_sName) ) - xContent.set(xContainer->getByHierarchicalName(_sName),UNO_QUERY); - } - break; + { + 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: - if ( pView->isPreviewEnabled() ) { SharedConnection xConnection( ensureConnection() ); if ( xConnection.is() ) - pView->showPreview(getDatabaseName(),xConnection,_sName,sal_False); + pView->showPreview( getDatabaseName(), xConnection, _sName, _eType == E_TABLE ); } return; - case E_TABLE: - { - SharedConnection xConnection( ensureConnection() ); - if ( xConnection.is() ) - { - pView->showPreview(getDatabaseName(),xConnection,_sName,_eType == E_TABLE); - return; - } - } - break; + default: + OSL_ENSURE( false, "OApplicationController::showPreviewFor: unexpected element type!" ); break; } } @@ -2384,8 +2357,6 @@ void OApplicationController::selectEntry(const ElementType _eType,const ::rtl::O { DBG_UNHANDLED_EXCEPTION(); } - - pView->showPreview(xContent); } //------------------------------------------------------------------------------ @@ -2403,21 +2374,21 @@ IMPL_LINK(OApplicationController, OnInvalidateClipboard, void*, EMPTYARG) return 0L; } // ----------------------------------------------------------------------------- -void OApplicationController::onCutEntry(SvLBoxEntry* /*_pEntry*/) +void OApplicationController::onCutEntry() { } // ----------------------------------------------------------------------------- -void OApplicationController::onCopyEntry(SvLBoxEntry* /*_pEntry*/) +void OApplicationController::onCopyEntry() { Execute(ID_BROWSER_COPY,Sequence<PropertyValue>()); } // ----------------------------------------------------------------------------- -void OApplicationController::onPasteEntry(SvLBoxEntry* /*_pEntry*/) +void OApplicationController::onPasteEntry() { Execute(ID_BROWSER_PASTE,Sequence<PropertyValue>()); } // ----------------------------------------------------------------------------- -void OApplicationController::onDeleteEntry(SvLBoxEntry* /*_pEntry*/) +void OApplicationController::onDeleteEntry() { ElementType eType = getContainer()->getElementType(); sal_uInt16 nId = 0; @@ -2796,7 +2767,7 @@ IMPL_LINK( OApplicationController, OnFirstControllerConnected, void*, /**/ ) // ----------------------------------------------------------------------------- sal_Bool SAL_CALL OApplicationController::attachModel(const Reference< XModel > & _rxModel) throw( RuntimeException ) { - ::osl::MutexGuard aGuard( m_aMutex ); + ::osl::MutexGuard aGuard( getMutex() ); Reference< XOfficeDatabaseDocument > xOfficeDoc( _rxModel, UNO_QUERY ); if ( !xOfficeDoc.is() && _rxModel.is() ) { @@ -2822,14 +2793,10 @@ sal_Bool SAL_CALL OApplicationController::attachModel(const Reference< XModel > } m_xDataSource.set(xOfficeDoc.is() ? xOfficeDoc->getDataSource() : Reference<XDataSource>(),UNO_QUERY); - if ( !m_xDataSource.is() ) - m_sDatabaseName = ::rtl::OUString(); - else + if ( m_xDataSource.is() ) { try { - m_xDataSource->getPropertyValue(PROPERTY_NAME) >>= m_sDatabaseName; - m_xDataSource->addPropertyChangeListener(PROPERTY_INFO, this); m_xDataSource->addPropertyChangeListener(PROPERTY_URL, this); m_xDataSource->addPropertyChangeListener(PROPERTY_ISPASSWORDREQUIRED, this); @@ -2920,7 +2887,7 @@ void SAL_CALL OApplicationController::removeSelectionChangeListener( const Refer ::sal_Bool SAL_CALL OApplicationController::select( const Any& _aSelection ) throw (IllegalArgumentException, RuntimeException) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Sequence< ::rtl::OUString> aSelection; if ( !_aSelection.hasValue() || !getView() ) { @@ -3048,12 +3015,30 @@ void SAL_CALL OApplicationController::removeSelectionChangeListener( const Refer Any SAL_CALL OApplicationController::getSelection( ) throw (RuntimeException) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Sequence< NamedDatabaseObject > aCurrentSelection; const ElementType eType( getContainer()->getElementType() ); if ( eType != E_NONE ) + { getContainer()->describeCurrentSelectionForType( eType, aCurrentSelection ); + if ( aCurrentSelection.getLength() == 0 ) + { // if no objects are selected, add an entry to the sequence which describes the overall category + // which is selected currently + aCurrentSelection.realloc(1); + aCurrentSelection[0].Name = getDatabaseName(); + switch ( eType ) + { + case E_TABLE: aCurrentSelection[0].Type = DatabaseObjectContainer::TABLES; break; + case E_QUERY: aCurrentSelection[0].Type = DatabaseObjectContainer::QUERIES; break; + case E_FORM: aCurrentSelection[0].Type = DatabaseObjectContainer::FORMS; break; + case E_REPORT: aCurrentSelection[0].Type = DatabaseObjectContainer::REPORTS; break; + default: + OSL_ENSURE( false, "OApplicationController::getSelection: unexpected current element type!" ); + break; + } + } + } return makeAny( aCurrentSelection ); } // ----------------------------------------------------------------------------- @@ -3083,45 +3068,6 @@ void OApplicationController::impl_migrateScripts_nothrow() } } -// ----------------------------------------------------------------------------- -bool OApplicationController::impl_activateSubFrame_throw(const ::rtl::OUString& _sName,const sal_Int32 _nKind,const ElementOpenMode _eOpenMode) const -{ - bool bFound = false; - TFrames::const_iterator aFind = m_aSpecialSubFrames.find(_sName); - for(;aFind != m_aSpecialSubFrames.end();++aFind) - { - if ( aFind->second.first.first == _nKind && aFind->second.first.second == _eOpenMode ) - { - const Reference< XFrame> xFrame(aFind->second.second,UNO_QUERY); - if ( xFrame.is() ) - { - Reference< awt::XTopWindow> xTopWindow(xFrame->getContainerWindow(),UNO_QUERY); - if ( xTopWindow.is() ) - xTopWindow->toFront(); - bFound = true; - } - break; - } // if ( aFind->second.first.first == _nKind && aFind->second.first.second == _eOpenMode ) - } - return bFound; -} -// ----------------------------------------------------------------------------- -void OApplicationController::impl_deActivateSubFrame_throw(const ::rtl::OUString& _sName,const sal_Int32 _nKind) -{ - TFrames aCopy = m_aSpecialSubFrames; - TFrames::iterator aFind = aCopy.find(_sName); - for(;aFind != aCopy.end();++aFind) - { - if ( aFind->second.first.first == _nKind ) - { - Reference< XFrame> xFrame(aFind->second.second,UNO_QUERY); - if ( xFrame.is() ) - { - ::comphelper::disposeComponent(xFrame); - } - } // if ( aFind->second.first.first == _nKind && aFind->second.first.second == _eOpenMode ) - } -} //........................................................................ } // namespace dbaui //........................................................................ diff --git a/dbaccess/source/ui/app/AppController.hxx b/dbaccess/source/ui/app/AppController.hxx index 0fc9c1359..b4bed6193 100644 --- a/dbaccess/source/ui/app/AppController.hxx +++ b/dbaccess/source/ui/app/AppController.hxx @@ -76,6 +76,9 @@ FORWARD_DECLARE_INTERFACE(ucb,XContent) namespace dbaui { //........................................................................ + + class SubComponentManager; + //==================================================================== //= OApplicationController //==================================================================== @@ -101,13 +104,6 @@ namespace dbaui typedef ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer > TContainer; typedef ::std::vector< TContainer > TContainerVector; - typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > TComponent; - typedef ::std::map< TComponent, TComponent > TDocuments; - - typedef ::std::pair< sal_Int32, ElementOpenMode > TTypeOpenMode; - typedef ::std::pair< TTypeOpenMode , TComponent > TTypeFrame; - typedef ::std::multimap< ::rtl::OUString, TTypeFrame > TFrames; - private: OTableCopyHelper::DropDescriptor m_aAsyncDrop; @@ -130,14 +126,13 @@ namespace dbaui ModelControllerConnector m_aModelConnector; TContainerVector m_aCurrentContainers; // the containers where we are listener on - TDocuments m_aDocuments; - TFrames m_aSpecialSubFrames; // contains the query, table and relation frame + ::rtl::Reference< SubComponentManager > + m_pSubComponentManager; ::dbaccess::ODsnTypeCollection m_aTypeCollection; OTableCopyHelper m_aTableCopyHelper; TransferableClipboardListener* m_pClipbordNotifier; // notifier for changes in the clipboard - mutable ::rtl::OUString m_sDatabaseName; ULONG m_nAsyncDrop; OAsyncronousLink m_aControllerConnectedEvent; OAsyncronousLink m_aSelectContainerEvent; @@ -156,23 +151,11 @@ namespace dbaui OApplicationView* getContainer() const; - /** activates the current table, query or relation design frame when existing - @param _sName the name of the component - @param _nKind the kind of the component - */ - bool impl_activateSubFrame_throw(const ::rtl::OUString& _sName,const sal_Int32 _nKind,const ElementOpenMode _eOpenMode) const; - - /** deactivates the current table or query frame when existing - @param _sName the name of the component - @param _nKind the kind of the component - */ - void impl_deActivateSubFrame_throw(const ::rtl::OUString& _sName,const sal_Int32 _nKind); - /** returns the database name @return the database name */ - inline ::rtl::OUString getDatabaseName() const { return m_sDatabaseName; } + ::rtl::OUString getDatabaseName() const; /** returns the stripped database name. @return @@ -359,14 +342,15 @@ namespace dbaui */ void askToReconnect(); - /** add event listener and remember the document - @param _xDocument - the new document, may be <NULL/> - @param _xDefinition - The defintion object. + /** remember a newly opened sub document for later access */ - void addDocumentListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _xDocument, - const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _xDefinition); + void onDocumentOpened( + const ::rtl::OUString& _rName, + const sal_Int32 _nType, + const ElementOpenMode _eMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _xDocument, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& _xDefinition + ); /** Inserts a new object into the hierachy given be the type. @param _eType @@ -408,9 +392,9 @@ namespace dbaui */ ::rtl::OUString getCurrentlySelectedName(sal_Int32& _rnCommandType) const; - /** select the give entry + /** shows the preview for the given entry */ - void selectEntry(const ElementType _eType,const ::rtl::OUString& _sName); + void showPreviewFor( const ElementType _eType,const ::rtl::OUString& _sName ); /** called when we just connected to a new, non-NULL model @@ -489,7 +473,7 @@ namespace dbaui virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL getActiveConnection() throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > > SAL_CALL getSubComponents() throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL isConnected( ) throw (::com::sun::star::uno::RuntimeException); - virtual ::sal_Bool SAL_CALL connect( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL connect( ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL closeSubComponents( ) throw (::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > SAL_CALL loadComponent( ::sal_Int32 ObjectType, const ::rtl::OUString& ObjectName, ::sal_Bool ForEditing ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > SAL_CALL loadComponentWithArguments( ::sal_Int32 ObjectType, const ::rtl::OUString& ObjectName, ::sal_Bool ForEditing, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException); @@ -505,8 +489,11 @@ namespace dbaui virtual void SAL_CALL removeSelectionChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::view::XSelectionChangeListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); /** retrieves the current connection, creates it if necessary + + If an error occurs, then this is either stored in the location pointed to by <arg>_pErrorInfo</arg>, + or, if <code>_pErrorInfo</code> is <NULL/>, then the error is displayed to the user. */ - const SharedConnection& ensureConnection(); + const SharedConnection& ensureConnection( ::dbtools::SQLExceptionInfo* _pErrorInfo = NULL ); /** retrieves the current connection */ @@ -525,12 +512,11 @@ namespace dbaui // IApplicationController virtual bool onEntryDoubleClick(SvTreeListBox& _rTree); virtual sal_Bool onContainerSelect(ElementType _eType); - virtual void onEntrySelect(SvLBoxEntry* _pEntry); - virtual void onEntryDeSelect(SvTreeListBox& _rTree); - virtual void onCutEntry(SvLBoxEntry* _pEntry); - virtual void onCopyEntry(SvLBoxEntry* _pEntry); - virtual void onPasteEntry(SvLBoxEntry* _pEntry); - virtual void onDeleteEntry(SvLBoxEntry* _pEntry); + virtual void onSelectionChanged(); + virtual void onCutEntry(); + virtual void onCopyEntry(); + virtual void onPasteEntry(); + virtual void onDeleteEntry(); virtual void previewChanged( sal_Int32 _nMode); virtual void containerFound( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainer >& _xContainer); diff --git a/dbaccess/source/ui/app/AppControllerDnD.cxx b/dbaccess/source/ui/app/AppControllerDnD.cxx index eff26fc07..623416732 100644 --- a/dbaccess/source/ui/app/AppControllerDnD.cxx +++ b/dbaccess/source/ui/app/AppControllerDnD.cxx @@ -221,6 +221,7 @@ #ifndef _VOS_MUTEX_HXX_ #include <vos/mutex.hxx> #endif +#include "subcomponentmanager.hxx" //........................................................................ namespace dbaui @@ -263,7 +264,11 @@ void OApplicationController::deleteTables(const ::std::vector< ::rtl::OUString>& sal_Int32 nResult = RET_YES; if ( bConfirm ) nResult = ::dbaui::askForUserAction(getView(),STR_TITLE_CONFIRM_DELETION ,STR_QUERY_DELETE_TABLE,_rList.size() > 1 && (aIter+1) != _rList.end(),sTableName); - if ( (RET_YES == nResult) || (RET_ALL == nResult) ) + + bool bUserConfirmedDelete = + ( RET_YES == nResult ) + || ( RET_ALL == nResult ); + if ( bUserConfirmedDelete && m_pSubComponentManager->closeSubFrames( sTableName, E_TABLE ) ) { SQLExceptionInfo aErrorInfo; try @@ -286,7 +291,6 @@ void OApplicationController::deleteTables(const ::std::vector< ::rtl::OUString>& } } } - impl_deActivateSubFrame_throw(sTableName,E_TABLE); } catch(SQLContext& e) { aErrorInfo = e; } catch(SQLWarning& e) { aErrorInfo = e; } @@ -370,8 +374,13 @@ void OApplicationController::deleteObjects( ElementType _eType, const ::std::vec bool bSuccess = false; - if ( ( eResult == svtools::QUERYDELETE_ALL ) || - ( eResult == svtools::QUERYDELETE_YES ) ) + bool bUserConfirmedDelete = + ( eResult == svtools::QUERYDELETE_ALL ) + || ( eResult == svtools::QUERYDELETE_YES ); + + if ( bUserConfirmedDelete + && ( ( _eType == E_QUERY ) ? m_pSubComponentManager->closeSubFrames( *aThisRound, _eType ) : true ) + ) { try { @@ -380,9 +389,6 @@ void OApplicationController::deleteObjects( ElementType _eType, const ::std::vec else xNames->removeByName( *aThisRound ); - if ( _eType == E_QUERY ) - impl_deActivateSubFrame_throw(*aThisRound,_eType); - bSuccess = true; // now that we removed the element, care for all it's child elements @@ -438,7 +444,7 @@ void OApplicationController::deleteObjects( ElementType _eType, const ::std::vec void OApplicationController::deleteEntries() { ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); if ( getContainer() ) { @@ -465,10 +471,10 @@ void OApplicationController::deleteEntries() } } // ----------------------------------------------------------------------------- -const SharedConnection& OApplicationController::ensureConnection() +const SharedConnection& OApplicationController::ensureConnection( ::dbtools::SQLExceptionInfo* _pErrorInfo ) { ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); if ( !m_xDataSourceConnection.is() ) { @@ -476,13 +482,34 @@ const SharedConnection& OApplicationController::ensureConnection() String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) ); sConnectingContext.SearchAndReplaceAscii("$name$", getStrippedDatabaseName()); - m_xDataSourceConnection.reset( connect( getDatabaseName(), sConnectingContext, sal_True ) ); + m_xDataSourceConnection.reset( connect( getDatabaseName(), sConnectingContext, _pErrorInfo ) ); if ( m_xDataSourceConnection.is() ) - m_xMetaData = m_xDataSourceConnection->getMetaData(); - - // otherwise we got a loop when connecting to db throws an error -// if ( !m_xDataSourceConnection.is() ) -// getContainer()->clearSelection(); + { + SQLExceptionInfo aError; + try + { + m_xMetaData = m_xDataSourceConnection->getMetaData(); + } + catch( const SQLException& ) + { + aError = ::cppu::getCaughtException(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + if ( aError.isValid() ) + { + if ( _pErrorInfo ) + { + *_pErrorInfo = aError; + } + else + { + showError( aError ); + } + } + } } return m_xDataSourceConnection; } @@ -502,8 +529,9 @@ sal_Bool OApplicationController::isConnectionReadOnly() const { bIsConnectionReadOnly = m_xMetaData->isReadOnly(); } - catch(SQLException&) + catch(const SQLException&) { + DBG_UNHANDLED_EXCEPTION(); } } // TODO check configuration @@ -562,7 +590,7 @@ Reference< XNameAccess > OApplicationController::getElements( ElementType _eType void OApplicationController::getSelectionElementNames(::std::vector< ::rtl::OUString>& _rNames) const { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); OSL_ENSURE(getContainer(),"View isn't valid! -> GPF"); @@ -595,7 +623,7 @@ TransferableHelper* OApplicationController::copyObject() try { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); ElementType eType = getContainer()->getElementType(); TransferableHelper* pData = NULL; @@ -634,7 +662,7 @@ TransferableHelper* OApplicationController::copyObject() if ( xElements.is() && !aList.empty() ) { Reference< XContent> xContent(xElements->getByHierarchicalName(*aList.begin()),UNO_QUERY); - pData = new OComponentTransferable(m_sDatabaseName,xContent); + pData = new OComponentTransferable( getDatabaseName(), xContent ); } } break; @@ -714,7 +742,8 @@ sal_Bool OApplicationController::paste( ElementType _eType,const ::svx::ODataAcc try { // the concrete query - Reference<XQueryDefinitionsSupplier> xSourceQuerySup(getDataSourceByName_displayError( sDataSourceName, getView(), getORB(), true ),UNO_QUERY); + Reference< XDataSource > xDataSource( getDataSourceByName( sDataSourceName, getView(), getORB(), NULL ) ); + Reference< XQueryDefinitionsSupplier > xSourceQuerySup( xDataSource, UNO_QUERY ); if ( xSourceQuerySup.is() ) xQueries.set(xSourceQuerySup->getQueryDefinitions(),UNO_QUERY); @@ -865,7 +894,7 @@ sal_Bool OApplicationController::isTableFormat() const sal_Bool OApplicationController::copyTagTable(OTableCopyHelper::DropDescriptor& _rDesc, sal_Bool _bCheck) { // first get the dest connection - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); SharedConnection xConnection( ensureConnection() ); if ( !xConnection.is() ) @@ -878,7 +907,7 @@ IMPL_LINK( OApplicationController, OnAsyncDrop, void*, /*NOTINTERESTEDIN*/ ) { m_nAsyncDrop = 0; ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); if ( m_aAsyncDrop.nType == E_TABLE ) diff --git a/dbaccess/source/ui/app/AppControllerGen.cxx b/dbaccess/source/ui/app/AppControllerGen.cxx index 392b48428..aad060b2d 100644 --- a/dbaccess/source/ui/app/AppControllerGen.cxx +++ b/dbaccess/source/ui/app/AppControllerGen.cxx @@ -40,6 +40,7 @@ #include "defaultobjectnamecheck.hxx" #include "dlgsave.hxx" #include "UITools.hxx" +#include "subcomponentmanager.hxx" /** === begin UNO includes === **/ #include <com/sun/star/container/XChild.hpp> @@ -216,7 +217,7 @@ void OApplicationController::openDialog( const ::rtl::OUString& _sServiceName ) try { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); WaitObject aWO(getView()); Sequence< Any > aArgs(3); @@ -306,7 +307,7 @@ void OApplicationController::openDirectSQLDialog() void SAL_CALL OApplicationController::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); if ( evt.PropertyName == PROPERTY_USER ) { m_bNeedToReconnect = sal_True; @@ -347,7 +348,7 @@ void SAL_CALL OApplicationController::propertyChange( const PropertyChangeEvent& // ----------------------------------------------------------------------------- Reference< XDataSource > SAL_CALL OApplicationController::getDataSource() throw (RuntimeException) { - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY ); return xDataSource; } @@ -355,7 +356,7 @@ Reference< XDataSource > SAL_CALL OApplicationController::getDataSource() throw // ----------------------------------------------------------------------------- Reference< XWindow > SAL_CALL OApplicationController::getApplicationMainWindow() throw (RuntimeException) { - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); Reference< XFrame > xFrame( getFrame(), UNO_QUERY_THROW ); Reference< XWindow > xWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); return xWindow; @@ -364,134 +365,47 @@ Reference< XWindow > SAL_CALL OApplicationController::getApplicationMainWindow() // ----------------------------------------------------------------------------- Sequence< Reference< XComponent > > SAL_CALL OApplicationController::getSubComponents() throw (RuntimeException) { - ::osl::MutexGuard aGuard(m_aMutex); - Sequence< Reference< XComponent > > aComponents( m_aDocuments.size() ); - ::std::transform( m_aDocuments.begin(), m_aDocuments.end(), aComponents.getArray(), ::std::select1st< TDocuments::value_type >() ); - return aComponents; + return m_pSubComponentManager->getSubComponents(); } // ----------------------------------------------------------------------------- Reference< XConnection > SAL_CALL OApplicationController::getActiveConnection() throw (RuntimeException) { - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); return m_xDataSourceConnection.getTyped(); } // ----------------------------------------------------------------------------- ::sal_Bool SAL_CALL OApplicationController::isConnected( ) throw (RuntimeException) { - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); return m_xDataSourceConnection.is(); } // ----------------------------------------------------------------------------- -::sal_Bool SAL_CALL OApplicationController::connect( ) throw (RuntimeException) +void SAL_CALL OApplicationController::connect( ) throw (SQLException, RuntimeException) { - ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); - - ensureConnection(); - return isConnected(); -} - -// ----------------------------------------------------------------------------- -namespace -{ - static Reference< XController > lcl_getController( const OApplicationController::TDocuments::iterator& _docPos ) + SQLExceptionInfo aError; + SharedConnection xConnection = ensureConnection( &aError ); + if ( !xConnection.is() ) { - Reference< XController > xController; + if ( aError.isValid() ) + aError.doThrow(); - Reference< XComponent > xComponent( _docPos->first ); - Reference< XModel > xModel( xComponent, UNO_QUERY ); - if ( xModel.is() ) - xController = xModel->getCurrentController(); - else - { - xController.set( xComponent, UNO_QUERY ); - if ( !xController.is() ) - { - Reference<XFrame> xFrame( xComponent, UNO_QUERY ); - if ( xFrame.is() ) - xController = xFrame->getController(); - } - } - return xController; + // no particular error, but nonetheless could not connect -> throw a generic exception + String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) ); + sConnectingContext.SearchAndReplaceAscii( "$name$", getStrippedDatabaseName() ); + ::dbtools::throwGenericSQLException( sConnectingContext, *this ); } } // ----------------------------------------------------------------------------- ::sal_Bool SAL_CALL OApplicationController::closeSubComponents( ) throw (RuntimeException) { - ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard( m_aMutex ); - - try - { - typedef ::std::vector< Reference< XComponent > > ComponentArray; - ComponentArray aClosedComponents; - - TDocuments aDocuments( m_aDocuments ); - for ( TDocuments::iterator doc = aDocuments.begin(); - doc != aDocuments.end(); - ++doc - ) - { - Reference< XController > xController( lcl_getController( doc ) ); - OSL_ENSURE( xController.is(), "OApplicationController::closeSubComponents: did not find the sub controller!" ); - - // suspend the controller in the document - if ( !xController.is() - || !xController->suspend( sal_True ) - ) - // break complete operation, no sense in continueing - break; - - // revoke event listener - Reference< XComponent > xDocument = doc->first; - if ( xDocument.is() ) - xDocument->removeEventListener( static_cast< XFrameActionListener* >( this ) ); - - bool bClosedSubDoc = false; - try - { - Reference< XCloseable > xCloseable( xController->getFrame(), UNO_QUERY_THROW ); - xCloseable->close( sal_True ); - bClosedSubDoc = true; - } - catch( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } - - if ( !bClosedSubDoc ) - // no sense in continueing with the other docs - break; - - aClosedComponents.push_back( doc->first ); - } - - // now remove all the components which we could successfully close - // (this might be none, or all, or something inbetween) from m_aDocuments - for ( ComponentArray::const_iterator comp = aClosedComponents.begin(); - comp != aClosedComponents.end(); - ++comp - ) - { - TDocuments::iterator pos = m_aDocuments.find( *comp ); - OSL_ENSURE( pos != m_aDocuments.end(), - "OApplicationController::closeSubComponents: closed a component which doesn't exist anymore!" ); - if ( pos !=m_aDocuments.end() ) - m_aDocuments.erase( pos ); - } - } - catch ( const Exception& ) - { - DBG_UNHANDLED_EXCEPTION(); - } - - return m_aDocuments.empty(); + return m_pSubComponentManager->closeSubComponents(); } + // ----------------------------------------------------------------------------- namespace { @@ -569,7 +483,7 @@ Reference< XComponent > SAL_CALL OApplicationController::loadComponentWithArgume const ::rtl::OUString& _ObjectName, ::sal_Bool _ForEditing, const Sequence< PropertyValue >& _Arguments ) throw (IllegalArgumentException, NoSuchElementException, SQLException, RuntimeException) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard( m_aMutex ); + ::osl::MutexGuard aGuard( getMutex() ); impl_validateObjectTypeAndName_throw( _ObjectType, _ObjectName ); @@ -601,7 +515,7 @@ void SAL_CALL OApplicationController::releaseContextMenuInterceptor( const Refer void OApplicationController::previewChanged( sal_Int32 _nMode ) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - ::osl::MutexGuard aGuard(m_aMutex); + ::osl::MutexGuard aGuard( getMutex() ); if ( m_xDataSource.is() && !isDataSourceReadOnly() ) { @@ -645,7 +559,7 @@ void OApplicationController::askToReconnect() { m_bNeedToReconnect = sal_False; sal_Bool bClear = sal_True; - if ( !m_aDocuments.empty() ) + if ( !m_pSubComponentManager->empty() ) { QueryBox aQry(getView(), ModuleRes(APP_CLOSEDOCUMENTS)); switch (aQry.Execute()) @@ -671,28 +585,53 @@ void OApplicationController::askToReconnect() } // ----------------------------------------------------------------------------- +::rtl::OUString OApplicationController::getDatabaseName() const +{ + ::rtl::OUString sDatabaseName; + try + { + if ( m_xDataSource.is() ) + { + OSL_VERIFY( m_xDataSource->getPropertyValue( PROPERTY_NAME ) >>= sDatabaseName ); + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return sDatabaseName; +} + +// ----------------------------------------------------------------------------- ::rtl::OUString OApplicationController::getStrippedDatabaseName() const { - return ::dbaui::getStrippedDatabaseName(m_xDataSource,m_sDatabaseName); + ::rtl::OUString sDatabaseName; + return ::dbaui::getStrippedDatabaseName( m_xDataSource, sDatabaseName ); } // ----------------------------------------------------------------------------- -void OApplicationController::addDocumentListener(const Reference< XComponent >& _xDocument,const Reference< XComponent >& _xDefintion) +void OApplicationController::onDocumentOpened( const ::rtl::OUString& _rName, const sal_Int32 _nType, + const ElementOpenMode _eMode, const Reference< XComponent >& _xDocument, const Reference< XComponent >& _rxDefinition ) { - if ( _xDocument.is() ) + OSL_PRECOND( _xDocument.is(), "OApplicationController::onDocumentOpened: illegal document!" ); + if ( !_xDocument.is() ) + return; + + try { - try - { - m_aDocuments[_xDocument] = _xDefintion; - _xDocument->addEventListener(static_cast<XFrameActionListener*>(this)); - Reference<XPropertySet> xProp(_xDefintion,UNO_QUERY_THROW); - if ( xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_NAME) ) - xProp->addPropertyChangeListener(PROPERTY_NAME,static_cast<XPropertyChangeListener*>(this)); - } - catch(Exception&) + m_pSubComponentManager->onSubComponentOpened( _rName, _nType, _eMode, _xDocument ); + + if ( _rxDefinition.is() ) { + Reference< XPropertySet > xProp( _rxDefinition, UNO_QUERY_THROW ); + Reference< XPropertySetInfo > xPSI( xProp->getPropertySetInfo(), UNO_SET_THROW ); + xProp->addPropertyChangeListener( PROPERTY_NAME, static_cast< XPropertyChangeListener* >( this ) ); } } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } } // ----------------------------------------------------------------------------- sal_Bool OApplicationController::insertHierachyElement(ElementType _eType,const String& _sParentFolder,sal_Bool _bCollection,const Reference<XContent>& _xContent,sal_Bool _bMove) diff --git a/dbaccess/source/ui/app/AppDetailPageHelper.cxx b/dbaccess/source/ui/app/AppDetailPageHelper.cxx index 83673dce2..5e871fa5b 100644 --- a/dbaccess/source/ui/app/AppDetailPageHelper.cxx +++ b/dbaccess/source/ui/app/AppDetailPageHelper.cxx @@ -351,10 +351,10 @@ OAppDetailPageHelper::~OAppDetailPageHelper() { if ( m_pLists[i] ) { - m_pLists[i]->clearCurrentSelectionEntry(); + m_pLists[i]->clearCurrentSelection(); m_pLists[i]->Hide(); ::std::auto_ptr<DBTreeListBox> aTemp(m_pLists[i]); - m_pLists[i]->clearCurrentSelectionEntry(); + m_pLists[i]->clearCurrentSelection(); // why a second time? m_pLists[i] = NULL; } @@ -379,9 +379,7 @@ void OAppDetailPageHelper::selectAll() int nPos = getVisibleControlIndex(); if ( nPos < E_ELEMENT_TYPE_COUNT ) { - m_pLists[nPos]->lockAutoSelect(); m_pLists[nPos]->SelectAll(TRUE); - m_pLists[nPos]->unlockAutoSelect(); } } // ----------------------------------------------------------------------------- @@ -907,8 +905,7 @@ DBTreeListBox* OAppDetailPageHelper::createTree( DBTreeListBox* _pTreeView, cons _pTreeView->SetDoubleClickHdl(LINK(this, OAppDetailPageHelper, OnEntryDoubleClick)); _pTreeView->SetEnterKeyHdl(LINK(this, OAppDetailPageHelper, OnEntryDoubleClick)); - _pTreeView->SetSelectHdl(LINK(this, OAppDetailPageHelper, OnEntrySelectHdl)); - _pTreeView->SetDeselectHdl(LINK(this, OAppDetailPageHelper, OnDeSelectHdl)); + _pTreeView->SetSelChangeHdl(LINK(this, OAppDetailPageHelper, OnEntrySelChange)); _pTreeView->setCutHandler(LINK(this, OAppDetailPageHelper, OnCutEntry)); _pTreeView->setCopyHandler(LINK(this, OAppDetailPageHelper, OnCopyEntry)); @@ -1066,48 +1063,33 @@ IMPL_LINK(OAppDetailPageHelper, OnEntryDoubleClick, SvTreeListBox*, _pTree) return bHandled ? 1L : 0L; } // ----------------------------------------------------------------------------- -IMPL_LINK(OAppDetailPageHelper, OnDeSelectHdl, SvTreeListBox*, _pTree) +IMPL_LINK(OAppDetailPageHelper, OnEntrySelChange, void*, /*NOINTERESTEDIN*/) { - OSL_ENSURE( _pTree, "OAppDetailPageHelper, OnDeSelectHdl: invalid callback!" ); - if ( _pTree != NULL ) - getBorderWin().getView()->getAppController().onEntryDeSelect( *_pTree ); + getBorderWin().getView()->getAppController().onSelectionChanged(); return 1L; } // ----------------------------------------------------------------------------- -IMPL_LINK(OAppDetailPageHelper, OnEntrySelectHdl, SvLBoxEntry*, _pEntry) +IMPL_LINK( OAppDetailPageHelper, OnCutEntry, void*, /*NOINTERESTEDIN*/ ) { - if ( 1 == getSelectionCount() ) - { - getBorderWin().getView()->getAppController().onEntrySelect(_pEntry); - } - else - { - showPreview(NULL); - } + getBorderWin().getView()->getAppController().onCutEntry(); return 1L; } // ----------------------------------------------------------------------------- -IMPL_LINK( OAppDetailPageHelper, OnCutEntry, SvLBoxEntry*, _pEntry ) +IMPL_LINK( OAppDetailPageHelper, OnCopyEntry, void*, /*NOINTERESTEDIN*/ ) { - getBorderWin().getView()->getAppController().onCutEntry(_pEntry); + getBorderWin().getView()->getAppController().onCopyEntry(); return 1L; } // ----------------------------------------------------------------------------- -IMPL_LINK( OAppDetailPageHelper, OnCopyEntry, SvLBoxEntry*, _pEntry ) +IMPL_LINK( OAppDetailPageHelper, OnPasteEntry, void*, /*NOINTERESTEDIN*/ ) { - getBorderWin().getView()->getAppController().onCopyEntry(_pEntry); + getBorderWin().getView()->getAppController().onPasteEntry(); return 1L; } // ----------------------------------------------------------------------------- -IMPL_LINK( OAppDetailPageHelper, OnPasteEntry, SvLBoxEntry*, _pEntry ) +IMPL_LINK( OAppDetailPageHelper, OnDeleteEntry, void*, /*NOINTERESTEDIN*/ ) { - getBorderWin().getView()->getAppController().onPasteEntry(_pEntry); - return 1L; -} -// ----------------------------------------------------------------------------- -IMPL_LINK( OAppDetailPageHelper, OnDeleteEntry, SvLBoxEntry*, _pEntry ) -{ - getBorderWin().getView()->getAppController().onDeleteEntry(_pEntry); + getBorderWin().getView()->getAppController().onDeleteEntry(); return 1L; } // ----------------------------------------------------------------------------- @@ -1182,16 +1164,12 @@ void OAppDetailPageHelper::switchPreview(PreviewMode _eMode,BOOL _bForce) m_aTBPreview.SetItemText(SID_DB_APP_DISABLE_PREVIEW, m_aMenu->GetItemText(nSelectedAction)); Resize(); + // simulate a selectionChanged event at the controller, to force the preview to be updated if ( isPreviewEnabled() ) { - DBTreeListBox* pTree = getCurrentView(); - if ( pTree ) + if ( getCurrentView() && getCurrentView()->FirstSelected() ) { - SvLBoxEntry* pEntry = pTree->GetSelectedEntry(); - if ( pEntry ) - { - getBorderWin().getView()->getAppController().onEntrySelect(pEntry); - } + getBorderWin().getView()->getAppController().onSelectionChanged(); } } else @@ -1255,9 +1233,12 @@ void OAppDetailPageHelper::showPreview(const Reference< XContent >& _xContent) { m_aPreview.Hide(); m_aDocumentInfo.Hide(); - DBTreeListBox* pTreeView = getCurrentView(); - if ( pTreeView ) - pTreeView->clearCurrentSelectionEntry(); + + // Why the below code? It might have side effects, as the tree view needs to know + // its current selection for other purposes than the preview, too. +// DBTreeListBox* pTreeView = getCurrentView(); +// if ( pTreeView ) +// pTreeView->clearCurrentSelection(); } } catch( const Exception& ) diff --git a/dbaccess/source/ui/app/AppDetailPageHelper.hxx b/dbaccess/source/ui/app/AppDetailPageHelper.hxx index 7307b5984..b36d5ea75 100644 --- a/dbaccess/source/ui/app/AppDetailPageHelper.hxx +++ b/dbaccess/source/ui/app/AppDetailPageHelper.hxx @@ -196,14 +196,12 @@ namespace dbaui DBTreeListBox* createSimpleTree( ULONG _nHelpId, const Image& _rImage, const Image& _rImageHC ); DECL_LINK( OnEntryDoubleClick, SvTreeListBox* ); - DECL_LINK( OnDeSelectHdl, SvTreeListBox* ); + DECL_LINK( OnEntrySelChange, void* ); - DECL_LINK( OnEntrySelectHdl, SvLBoxEntry* ); - - DECL_LINK( OnCutEntry, SvLBoxEntry* ); - DECL_LINK( OnCopyEntry, SvLBoxEntry* ); - DECL_LINK( OnPasteEntry, SvLBoxEntry* ); - DECL_LINK( OnDeleteEntry, SvLBoxEntry* ); + DECL_LINK( OnCutEntry, void* ); + DECL_LINK( OnCopyEntry, void* ); + DECL_LINK( OnPasteEntry, void* ); + DECL_LINK( OnDeleteEntry, void* ); DECL_LINK(PreviewChangeHdl, void*); // click a TB slot diff --git a/dbaccess/source/ui/app/IApplicationController.hxx b/dbaccess/source/ui/app/IApplicationController.hxx index e6344e2d1..c2b976075 100644 --- a/dbaccess/source/ui/app/IApplicationController.hxx +++ b/dbaccess/source/ui/app/IApplicationController.hxx @@ -71,37 +71,23 @@ namespace dbaui @param _pEntry the selected entry */ - virtual void onEntrySelect(SvLBoxEntry* _pEntry) = 0; + virtual void onSelectionChanged() = 0; - /** called when an entry in a tree view has been de-selected - @param _pTree - The tree list box. - */ - virtual void onEntryDeSelect(SvTreeListBox& _rTree) = 0; - - /** called when a "Cut" command is executed for a tree view entry - @param _pEntry - The entry which was cutted. + /** called when a "Cut" command is executed in a tree view */ - virtual void onCutEntry(SvLBoxEntry* _pEntry) = 0; + virtual void onCutEntry() = 0; - /** called when a "Copy" command is executed for a tree view entry - @param _pEntry - The entry which was cutted. + /** called when a "Copy" command is executed in a tree view */ - virtual void onCopyEntry(SvLBoxEntry* _pEntry) = 0; + virtual void onCopyEntry() = 0; - /** called when a "Paste" command is executed for a tree view entry - @param _pEntry - The entry which was cutted. + /** called when a "Paste" command is executed in a tree view */ - virtual void onPasteEntry(SvLBoxEntry* _pEntry) = 0; + virtual void onPasteEntry() = 0; - /** called when a "Delete" command is executed for a tree view entry - @param _pEntry - The entry which was cutted. + /** called when a "Delete" command is executed in a tree view */ - virtual void onDeleteEntry(SvLBoxEntry* _pEntry) = 0; + virtual void onDeleteEntry() = 0; /// called when the preview mode was changed virtual void previewChanged( sal_Int32 _nMode ) = 0; diff --git a/dbaccess/source/ui/app/makefile.mk b/dbaccess/source/ui/app/makefile.mk index bef4e64f6..b132816a3 100644 --- a/dbaccess/source/ui/app/makefile.mk +++ b/dbaccess/source/ui/app/makefile.mk @@ -8,7 +8,7 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.5 $ +# $Revision: 1.5.80.1 $ # # This file is part of OpenOffice.org. # @@ -51,7 +51,8 @@ EXCEPTIONSFILES=\ $(SLO)$/AppDetailPageHelper.obj \ $(SLO)$/AppSwapWindow.obj \ $(SLO)$/AppTitleWindow.obj \ - $(SLO)$/AppView.obj + $(SLO)$/AppView.obj \ + $(SLO)$/subcomponentmanager.obj SLOFILES =\ diff --git a/dbaccess/source/ui/app/subcomponentmanager.cxx b/dbaccess/source/ui/app/subcomponentmanager.cxx new file mode 100644 index 000000000..5794670c2 --- /dev/null +++ b/dbaccess/source/ui/app/subcomponentmanager.cxx @@ -0,0 +1,432 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2008 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* $RCSfile: subcomponentmanager.cxx,v $ +* +* $Revision: 1.1.2.2 $ +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#include "subcomponentmanager.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/XModel2.hpp> +#include <com/sun/star/util/XCloseable.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> + +#include <hash_map> +#include <algorithm> +#include <functional> + +//........................................................................ +namespace dbaui +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::frame::XFrame; + using ::com::sun::star::frame::XController; + using ::com::sun::star::frame::XModel; + using ::com::sun::star::lang::EventObject; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::frame::XModel2; + using ::com::sun::star::container::XEnumeration; + using ::com::sun::star::util::XCloseable; + using ::com::sun::star::awt::XTopWindow; + /** === end UNO using === **/ + + //============================================================================== + //= helper structs + //============================================================================== + namespace + { + struct SubComponentDescriptor + { + /// the frame which the component resides in. Must not be <NULL/> + Reference< XFrame > xFrame; + /// the controller of the sub component. Must not be <NULL/> + Reference< XController > xController; + /// the model of the sub component. Might be <NULL/> + Reference< XModel > xModel; + + SubComponentDescriptor() + :xFrame() + ,xController() + ,xModel() + { + } + + SubComponentDescriptor( const Reference< XComponent >& _rxComponent ) + { + xModel.set( _rxComponent, UNO_QUERY ); + + if ( xModel.is() ) + xController.set( xModel->getCurrentController(), UNO_SET_THROW ); + else + xController.set( _rxComponent, UNO_QUERY ); + + if ( xController.is() ) + xFrame.set( xController->getFrame(), UNO_SET_THROW ); + else + xFrame.set( _rxComponent, UNO_QUERY_THROW ); + + // if the given component was a frame, then ensure we have a controller + if ( xFrame.is() && !xController.is() ) + xController.set( xFrame->getController(), UNO_SET_THROW ); + + // if the component was a frame or a controller, then check wether there is a model (not required) + if ( !xModel.is() ) + xModel.set( xController->getModel() ); + } + }; + + struct SelectSubComponent : public ::std::unary_function< SubComponentDescriptor, Reference< XComponent > > + { + Reference< XComponent > operator()( const SubComponentDescriptor _desc ) const + { + if ( _desc.xModel.is() ) + return _desc.xModel.get(); + OSL_ENSURE( _desc.xController.is(), "SelectSubComponent::operator(): illegal component!" ); + return _desc.xController.get(); + } + }; + + struct SubComponentAccessor + { + /// the name of the sub component + ::rtl::OUString sName; + /// type of the component - usually an ElementType value + sal_Int32 nComponentType; + /// the mode in which the sub component has been opened + ElementOpenMode eOpenMode; + + SubComponentAccessor() + :sName() + ,nComponentType( sal_Int32( E_NONE ) ) + ,eOpenMode( E_OPEN_NORMAL ) + { + } + + SubComponentAccessor( const ::rtl::OUString& _rName, const sal_Int32 _nCompType, const ElementOpenMode _eMode ) + :sName( _rName ) + ,nComponentType( _nCompType ) + ,eOpenMode( _eMode ) + { + } + }; + + struct SubComponentAccessorHash : public ::std::unary_function< SubComponentAccessor, size_t > + { + size_t operator()( const SubComponentAccessor& _lhs ) const + { + return _lhs.sName.hashCode() + _lhs.nComponentType + size_t( _lhs.eOpenMode ); + } + }; + struct SubComponentAccessorEqual : public ::std::binary_function< SubComponentAccessor, SubComponentAccessor, bool > + { + bool operator()( const SubComponentAccessor& _lhs, const SubComponentAccessor& _rhs ) const + { + return ( _lhs.sName == _rhs.sName ) + && ( _lhs.nComponentType == _rhs.nComponentType ) + && ( _lhs.eOpenMode == _rhs.eOpenMode ); + } + }; + + typedef ::std::hash_map< SubComponentAccessor, SubComponentDescriptor, SubComponentAccessorHash, SubComponentAccessorEqual > + SubComponentMap; + + } + + //============================================================================== + //= SubComponentManager_Data + //============================================================================== + struct SubComponentManager_Data + { + SubComponentManager_Data( const ::comphelper::SharedMutex& _rMutex ) + :m_aMutex( _rMutex ) + { + } + + mutable ::comphelper::SharedMutex m_aMutex; + SubComponentMap m_aComponents; + + ::osl::Mutex& getMutex() const { return m_aMutex; } + }; + + //==================================================================== + //= SubComponentManager + //==================================================================== + //-------------------------------------------------------------------- + SubComponentManager::SubComponentManager( const ::comphelper::SharedMutex& _rMutex ) + :m_pData( new SubComponentManager_Data( _rMutex ) ) + { + } + + //-------------------------------------------------------------------- + SubComponentManager::~SubComponentManager() + { + } + + //-------------------------------------------------------------------- + void SubComponentManager::disposing() + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + m_pData->m_aComponents.clear(); + } + + //-------------------------------------------------------------------- + namespace + { + bool lcl_fallbackToAnotherController( SubComponentDescriptor& _rCompDesc ) + { + Reference< XController > xFallback; + OSL_PRECOND( _rCompDesc.xModel.is(), "lcl_fallbackToAnotherController: illegal call!" ); + if ( !_rCompDesc.xModel.is() ) + return false; + + xFallback.set( _rCompDesc.xModel->getCurrentController() ); + if ( xFallback == _rCompDesc.xController ) + // don't accept the very same controller as fallback + xFallback.clear(); + + if ( !xFallback.is() ) + { + // perhaps XModel2 can be of help here + Reference< XModel2 > xModel2( _rCompDesc.xModel, UNO_QUERY ); + Reference< XEnumeration > xControllerEnum; + if ( xModel2.is() ) + xControllerEnum = xModel2->getControllers(); + while ( xControllerEnum.is() && xControllerEnum->hasMoreElements() ) + { + xFallback.set( xControllerEnum->nextElement(), UNO_QUERY ); + if ( xFallback == _rCompDesc.xController ) + xFallback.clear(); + } + } + + if ( xFallback.is() ) + { + _rCompDesc.xController = xFallback; + _rCompDesc.xFrame.set( xFallback->getFrame(), UNO_SET_THROW ); + return true; + } + + return false; + } + + //---------------------------------------------------------------- + bool lcl_closeComponent( const SubComponentDescriptor& _rComponent ) + { + Reference< XController > xController( _rComponent.xController ); + OSL_ENSURE( xController.is(), "lcl_closeComponent: invalid controller!" ); + + // suspend the controller in the document + if ( xController.is() ) + if ( !xController->suspend( sal_True ) ) + return false; + + bool bSuccess = false; + try + { + Reference< XCloseable > xCloseable( _rComponent.xFrame, UNO_QUERY_THROW ); + xCloseable->close( sal_True ); + bSuccess = true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return bSuccess; + } + } + + //-------------------------------------------------------------------- + void SAL_CALL SubComponentManager::disposing( const EventObject& _rSource ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + for ( SubComponentMap::iterator comp = m_pData->m_aComponents.begin(); + comp != m_pData->m_aComponents.end(); + ++comp + ) + { + bool bRemove = false; + + if ( comp->second.xController == _rSource.Source ) + { + if ( !comp->second.xModel.is() ) + { + bRemove = true; + } + else + { + // maybe this is just one view to the sub document, and only this view is closed + if ( !lcl_fallbackToAnotherController( comp->second ) ) + { + bRemove = true; + } + } + } + else if ( comp->second.xModel == _rSource.Source ) + { + bRemove = true; + } + + if ( bRemove ) + { + m_pData->m_aComponents.erase( comp ); + break; + } + } + } + + //-------------------------------------------------------------------- + Sequence< Reference< XComponent> > SubComponentManager::getSubComponents() const + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + Sequence< Reference< XComponent > > aComponents( m_pData->m_aComponents.size() ); + ::std::transform( + m_pData->m_aComponents.begin(), + m_pData->m_aComponents.end(), + aComponents.getArray(), + ::std::compose1( SelectSubComponent(), ::std::select2nd< SubComponentMap::value_type >() ) + ); + return aComponents; + } + + // ----------------------------------------------------------------------------- + sal_Bool SubComponentManager::closeSubComponents() + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + try + { + typedef ::std::vector< SubComponentAccessor > ComponentAccessors; + ComponentAccessors aClosedComponents; + + SubComponentMap aComponents( m_pData->m_aComponents ); + for ( SubComponentMap::const_iterator comp = aComponents.begin(); + comp != aComponents.end(); + ++comp + ) + { + lcl_closeComponent( comp->second ); + } + } + catch ( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return empty(); + } + + // ----------------------------------------------------------------------------- + bool SubComponentManager::empty() const + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + return m_pData->m_aComponents.empty(); + } + + // ----------------------------------------------------------------------------- + void SubComponentManager::onSubComponentOpened( const ::rtl::OUString& _rName, const sal_Int32 _nComponentType, + const ElementOpenMode _eOpenMode, const Reference< XComponent >& _rxComponent ) + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + // put into map + SubComponentAccessor aKey( _rName, _nComponentType, _eOpenMode ); + SubComponentDescriptor aElement( _rxComponent ); + + m_pData->m_aComponents.insert( SubComponentMap::value_type( + aKey, aElement + ) ) ; + + // add as listener + aElement.xController->addEventListener( this ); + if ( aElement.xModel.is() ) + aElement.xModel->addEventListener( this ); + } + + // ----------------------------------------------------------------------------- + bool SubComponentManager::activateSubFrame( const ::rtl::OUString& _rName, const sal_Int32 _nComponentType, const ElementOpenMode _eOpenMode ) const + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + SubComponentAccessor aKey( _rName, _nComponentType, _eOpenMode ); + SubComponentMap::const_iterator pos = m_pData->m_aComponents.find( aKey ); + if ( pos == m_pData->m_aComponents.end() ) + // no component with this name/type/open mode + return false; + + const Reference< XFrame > xFrame( pos->second.xFrame, UNO_SET_THROW ); + const Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); + xTopWindow->toFront(); + + return true; + } + + // ----------------------------------------------------------------------------- + bool SubComponentManager::closeSubFrames( const ::rtl::OUString& _rName, const sal_Int32 _nComponentType ) + { + ::osl::MutexGuard aGuard( m_pData->getMutex() ); + + SubComponentMap aWorkingCopy( m_pData->m_aComponents ); + for ( SubComponentMap::const_iterator comp = aWorkingCopy.begin(); + comp != aWorkingCopy.end(); + ++comp + ) + { + if ( ( comp->first.sName != _rName ) || ( comp->first.nComponentType != _nComponentType ) ) + continue; + + if ( !lcl_closeComponent( comp->second ) ) + return false; + } + + return true; + } + +//........................................................................ +} // namespace dbaui +//........................................................................ diff --git a/dbaccess/source/ui/app/subcomponentmanager.hxx b/dbaccess/source/ui/app/subcomponentmanager.hxx new file mode 100644 index 000000000..af0aa3441 --- /dev/null +++ b/dbaccess/source/ui/app/subcomponentmanager.hxx @@ -0,0 +1,115 @@ +/************************************************************************* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2008 by Sun Microsystems, Inc. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* $RCSfile: subcomponentmanager.hxx,v $ +* +* $Revision: 1.1.2.2 $ +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +************************************************************************/ + +#ifndef DBACCESS_SUBCOMPONENTMANAGER_HXX +#define DBACCESS_SUBCOMPONENTMANAGER_HXX + +#include "AppElementType.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XEventListener.hpp> +#include <com/sun/star/frame/XController.hpp> +/** === end UNO includes === **/ + +#include <comphelper/sharedmutex.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <memory> + +//........................................................................ +namespace dbaui +{ +//........................................................................ + + struct SubComponentManager_Data; + //==================================================================== + //= SubComponentManager + //==================================================================== + typedef ::cppu::WeakImplHelper1 < ::com::sun::star::lang::XEventListener + > SubComponentManager_Base; + class SubComponentManager : public SubComponentManager_Base + { + public: + SubComponentManager( const ::comphelper::SharedMutex& _rMutex ); + virtual ~SubComponentManager(); + + void disposing(); + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException); + + // XDatabaseDocumentUI helpers + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> > + getSubComponents() const; + sal_Bool closeSubComponents(); + + // container access + void onSubComponentOpened( + const ::rtl::OUString& _rName, + const sal_Int32 _nComponentType, + const ElementOpenMode _eOpenMode, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& + _rxComponent + ); + bool empty() const; + + /** activates (i.e. brings to top) the frame in which the given component is loaded, if any + + @return + <TRUE/> if any only of such a frame was found, i.e. the component had already been loaded + previously + */ + bool activateSubFrame( + const ::rtl::OUString& _rName, + const sal_Int32 _nComponentType, + const ElementOpenMode _eOpenMode + ) const; + + /** closes all frames of the given component + + If a view for the component (given by name and type) has been loaded into one or more + frames (with potentially different OpenModes), then those frames are gracefully closed. + + @return + <TRUE/> if and only if closing those frames was successful, or frames for the given sub component + exist. + */ + bool closeSubFrames( + const ::rtl::OUString& _rName, + const sal_Int32 _nComponentType + ); + private: + ::std::auto_ptr< SubComponentManager_Data > m_pData; + }; + +//........................................................................ +} // namespace dbaui +//........................................................................ + +#endif // DBACCESS_SUBCOMPONENTMANAGER_HXX |