1*96de5490SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*96de5490SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*96de5490SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*96de5490SAndrew Rist  * distributed with this work for additional information
6*96de5490SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*96de5490SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*96de5490SAndrew Rist  * "License"); you may not use this file except in compliance
9*96de5490SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*96de5490SAndrew Rist  *
11*96de5490SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*96de5490SAndrew Rist  *
13*96de5490SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*96de5490SAndrew Rist  * software distributed under the License is distributed on an
15*96de5490SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*96de5490SAndrew Rist  * KIND, either express or implied.  See the License for the
17*96de5490SAndrew Rist  * specific language governing permissions and limitations
18*96de5490SAndrew Rist  * under the License.
19*96de5490SAndrew Rist  *
20*96de5490SAndrew Rist  *************************************************************/
21*96de5490SAndrew Rist 
22*96de5490SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "subcomponentmanager.hxx"
25cdf0e10cSrcweir #include "AppController.hxx"
26cdf0e10cSrcweir #include "dbustrings.hrc"
27cdf0e10cSrcweir 
28cdf0e10cSrcweir /** === begin UNO includes === **/
29cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp>
30cdf0e10cSrcweir #include <com/sun/star/frame/XModel.hpp>
31cdf0e10cSrcweir #include <com/sun/star/frame/XModel2.hpp>
32cdf0e10cSrcweir #include <com/sun/star/util/XCloseable.hpp>
33cdf0e10cSrcweir #include <com/sun/star/awt/XTopWindow.hpp>
34cdf0e10cSrcweir #include <com/sun/star/embed/XComponentSupplier.hpp>
35cdf0e10cSrcweir #include <com/sun/star/ucb/XCommandProcessor.hpp>
36cdf0e10cSrcweir #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
37cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
38cdf0e10cSrcweir /** === end UNO includes === **/
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include <tools/diagnose_ex.h>
41cdf0e10cSrcweir #include <vcl/svapp.hxx>
42cdf0e10cSrcweir #include <vos/mutex.hxx>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir #include <hash_map>
45cdf0e10cSrcweir #include <algorithm>
46cdf0e10cSrcweir #include <functional>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir //......................................................................................................................
49cdf0e10cSrcweir namespace dbaui
50cdf0e10cSrcweir {
51cdf0e10cSrcweir //......................................................................................................................
52cdf0e10cSrcweir 
53cdf0e10cSrcweir 	/** === begin UNO using === **/
54cdf0e10cSrcweir 	using ::com::sun::star::uno::Reference;
55cdf0e10cSrcweir 	using ::com::sun::star::uno::XInterface;
56cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY;
57cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY_THROW;
58cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_SET_THROW;
59cdf0e10cSrcweir 	using ::com::sun::star::uno::Exception;
60cdf0e10cSrcweir 	using ::com::sun::star::uno::RuntimeException;
61cdf0e10cSrcweir 	using ::com::sun::star::uno::Any;
62cdf0e10cSrcweir 	using ::com::sun::star::uno::makeAny;
63cdf0e10cSrcweir 	using ::com::sun::star::uno::Sequence;
64cdf0e10cSrcweir 	using ::com::sun::star::uno::Type;
65cdf0e10cSrcweir     using ::com::sun::star::frame::XFrame;
66cdf0e10cSrcweir     using ::com::sun::star::frame::XController;
67cdf0e10cSrcweir     using ::com::sun::star::frame::XModel;
68cdf0e10cSrcweir     using ::com::sun::star::lang::EventObject;
69cdf0e10cSrcweir     using ::com::sun::star::lang::XComponent;
70cdf0e10cSrcweir     using ::com::sun::star::frame::XModel2;
71cdf0e10cSrcweir     using ::com::sun::star::container::XEnumeration;
72cdf0e10cSrcweir     using ::com::sun::star::util::XCloseable;
73cdf0e10cSrcweir     using ::com::sun::star::awt::XTopWindow;
74cdf0e10cSrcweir     using ::com::sun::star::embed::XComponentSupplier;
75cdf0e10cSrcweir     using ::com::sun::star::ucb::XCommandProcessor;
76cdf0e10cSrcweir     using ::com::sun::star::ucb::Command;
77cdf0e10cSrcweir     using ::com::sun::star::document::XDocumentEventBroadcaster;
78cdf0e10cSrcweir     using ::com::sun::star::beans::XPropertySet;
79cdf0e10cSrcweir     using ::com::sun::star::beans::PropertyChangeEvent;
80cdf0e10cSrcweir 	/** === end UNO using === **/
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     //==================================================================================================================
83cdf0e10cSrcweir     //= helper structs
84cdf0e10cSrcweir     //==================================================================================================================
85cdf0e10cSrcweir     namespace
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir         //..............................................................................................................
88cdf0e10cSrcweir         struct SubComponentDescriptor
89cdf0e10cSrcweir         {
90cdf0e10cSrcweir             /// the name of the sub component, empty if it is yet unsaved
91cdf0e10cSrcweir             ::rtl::OUString sName;
92cdf0e10cSrcweir             /// type of the component - an ElementType value, except for relation design
93cdf0e10cSrcweir             sal_Int32       nComponentType;
94cdf0e10cSrcweir             /// the mode in which the sub component has been opened
95cdf0e10cSrcweir             ElementOpenMode eOpenMode;
96cdf0e10cSrcweir             /// the frame which the component resides in. Must not be <NULL/>
97cdf0e10cSrcweir             Reference< XFrame >             xFrame;
98cdf0e10cSrcweir             /// the controller of the sub component. Must not be <NULL/>
99cdf0e10cSrcweir             Reference< XController >        xController;
100cdf0e10cSrcweir             /// the model of the sub component. Might be <NULL/>
101cdf0e10cSrcweir             Reference< XModel >             xModel;
102cdf0e10cSrcweir             /// the document definition which holds the component, if any; as CommandProcessor
103cdf0e10cSrcweir             Reference< XCommandProcessor >  xComponentCommandProcessor;
104cdf0e10cSrcweir             /// the document definition which holds the component, if any; as PropertySet
105cdf0e10cSrcweir             Reference< XPropertySet >       xDocumentDefinitionProperties;
106cdf0e10cSrcweir 
107cdf0e10cSrcweir             SubComponentDescriptor()
108cdf0e10cSrcweir                 :sName()
109cdf0e10cSrcweir                 ,nComponentType( -1 )
110cdf0e10cSrcweir                 ,eOpenMode( E_OPEN_NORMAL )
111cdf0e10cSrcweir                 ,xFrame()
112cdf0e10cSrcweir                 ,xController()
113cdf0e10cSrcweir                 ,xModel()
114cdf0e10cSrcweir             {
115cdf0e10cSrcweir             }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir             SubComponentDescriptor( const ::rtl::OUString& i_rName, const sal_Int32 i_nComponentType,
118cdf0e10cSrcweir                     const ElementOpenMode i_eOpenMode, const Reference< XComponent >& i_rComponent )
119cdf0e10cSrcweir                 :sName( i_rName )
120cdf0e10cSrcweir                 ,nComponentType( i_nComponentType )
121cdf0e10cSrcweir                 ,eOpenMode( i_eOpenMode )
122cdf0e10cSrcweir             {
123cdf0e10cSrcweir                 if ( !impl_constructFrom( i_rComponent ) )
124cdf0e10cSrcweir                 {
125cdf0e10cSrcweir                     // i_rComponent is neither a model, nor a controller, nor a frame
126cdf0e10cSrcweir                     // => it must be a css.sdb.DocumentDefinition
127cdf0e10cSrcweir                     Reference< XComponentSupplier > xCompSupp( i_rComponent, UNO_QUERY_THROW );
128cdf0e10cSrcweir                     Reference< XComponent > xComponent( xCompSupp->getComponent(), UNO_QUERY_THROW );
129cdf0e10cSrcweir                     if ( !impl_constructFrom( xComponent ) )
130cdf0e10cSrcweir                         throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal component type." ) ), NULL );
131cdf0e10cSrcweir                     xComponentCommandProcessor.set( i_rComponent, UNO_QUERY_THROW );
132cdf0e10cSrcweir                     xDocumentDefinitionProperties.set( i_rComponent, UNO_QUERY_THROW );
133cdf0e10cSrcweir                 }
134cdf0e10cSrcweir             }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir             inline bool is() const { return xFrame.is(); }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir         private:
139cdf0e10cSrcweir             bool impl_constructFrom( const Reference< XComponent >& _rxComponent )
140cdf0e10cSrcweir             {
141cdf0e10cSrcweir                 // is it a model?
142cdf0e10cSrcweir                 xModel.set( _rxComponent, UNO_QUERY );
143cdf0e10cSrcweir                 if ( xModel.is() )
144cdf0e10cSrcweir                 {
145cdf0e10cSrcweir                     xController.set( xModel->getCurrentController() );
146cdf0e10cSrcweir                     if ( xController.is() )
147cdf0e10cSrcweir                         xFrame.set( xController->getFrame(), UNO_SET_THROW );
148cdf0e10cSrcweir                 }
149cdf0e10cSrcweir                 else
150cdf0e10cSrcweir                 {
151cdf0e10cSrcweir                     // is it a controller?
152cdf0e10cSrcweir                     xController.set( _rxComponent, UNO_QUERY );
153cdf0e10cSrcweir                     if ( xController.is() )
154cdf0e10cSrcweir                     {
155cdf0e10cSrcweir                         xFrame.set( xController->getFrame(), UNO_SET_THROW );
156cdf0e10cSrcweir                     }
157cdf0e10cSrcweir                     else
158cdf0e10cSrcweir                     {
159cdf0e10cSrcweir                         // is it a frame?
160cdf0e10cSrcweir                         xFrame.set( _rxComponent, UNO_QUERY );
161cdf0e10cSrcweir                         if ( !xFrame.is() )
162cdf0e10cSrcweir                             return false;
163cdf0e10cSrcweir 
164cdf0e10cSrcweir                         // ensure we have a controller
165cdf0e10cSrcweir                         xController.set( xFrame->getController(), UNO_SET_THROW );
166cdf0e10cSrcweir                     }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir                     // check wether there is a model (not required)
169cdf0e10cSrcweir                     xModel.set( xController->getModel() );
170cdf0e10cSrcweir                 }
171cdf0e10cSrcweir 
172cdf0e10cSrcweir                 return true;
173cdf0e10cSrcweir             }
174cdf0e10cSrcweir         };
175cdf0e10cSrcweir 
176cdf0e10cSrcweir         //..............................................................................................................
177cdf0e10cSrcweir         struct SelectSubComponent : public ::std::unary_function< SubComponentDescriptor, Reference< XComponent > >
178cdf0e10cSrcweir         {
179cdf0e10cSrcweir             Reference< XComponent > operator()( const SubComponentDescriptor _desc ) const
180cdf0e10cSrcweir             {
181cdf0e10cSrcweir                 if ( _desc.xModel.is() )
182cdf0e10cSrcweir                     return _desc.xModel.get();
183cdf0e10cSrcweir                 OSL_ENSURE( _desc.xController.is(), "SelectSubComponent::operator(): illegal component!" );
184cdf0e10cSrcweir                 return _desc.xController.get();
185cdf0e10cSrcweir             }
186cdf0e10cSrcweir         };
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         //..............................................................................................................
189cdf0e10cSrcweir         typedef ::std::vector< SubComponentDescriptor > SubComponents;
190cdf0e10cSrcweir 
191cdf0e10cSrcweir         //..............................................................................................................
192cdf0e10cSrcweir         struct SubComponentMatch : public ::std::unary_function< SubComponentDescriptor, bool >
193cdf0e10cSrcweir         {
194cdf0e10cSrcweir         public:
195cdf0e10cSrcweir             SubComponentMatch( const ::rtl::OUString& i_rName, const sal_Int32 i_nComponentType,
196cdf0e10cSrcweir                     const ElementOpenMode i_eOpenMode )
197cdf0e10cSrcweir                 :m_sName( i_rName )
198cdf0e10cSrcweir                 ,m_nComponentType( i_nComponentType )
199cdf0e10cSrcweir                 ,m_eOpenMode( i_eOpenMode )
200cdf0e10cSrcweir             {
201cdf0e10cSrcweir             }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir             bool operator()( const SubComponentDescriptor& i_rCompareWith ) const
204cdf0e10cSrcweir             {
205cdf0e10cSrcweir                 return  (   m_sName             ==  i_rCompareWith.sName          )
206cdf0e10cSrcweir                     &&  (   m_nComponentType    ==  i_rCompareWith.nComponentType )
207cdf0e10cSrcweir                     &&  (   m_eOpenMode         ==  i_rCompareWith.eOpenMode      );
208cdf0e10cSrcweir             }
209cdf0e10cSrcweir         private:
210cdf0e10cSrcweir             const ::rtl::OUString   m_sName;
211cdf0e10cSrcweir             const sal_Int32         m_nComponentType;
212cdf0e10cSrcweir             const ElementOpenMode   m_eOpenMode;
213cdf0e10cSrcweir         };
214cdf0e10cSrcweir     }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir     //==================================================================================================================
217cdf0e10cSrcweir     //= SubComponentManager_Data
218cdf0e10cSrcweir     //==================================================================================================================
219cdf0e10cSrcweir     struct SubComponentManager_Data
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         SubComponentManager_Data( OApplicationController& _rController, const ::comphelper::SharedMutex& _rMutex )
222cdf0e10cSrcweir             :m_rController( _rController )
223cdf0e10cSrcweir             ,m_aMutex( _rMutex )
224cdf0e10cSrcweir         {
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         OApplicationController&             m_rController;
228cdf0e10cSrcweir         mutable ::comphelper::SharedMutex   m_aMutex;
229cdf0e10cSrcweir         SubComponents                       m_aComponents;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir         ::osl::Mutex&   getMutex() const { return m_aMutex; }
232cdf0e10cSrcweir     };
233cdf0e10cSrcweir 
234cdf0e10cSrcweir     //==================================================================================================================
235cdf0e10cSrcweir 	//= SubComponentManager
236cdf0e10cSrcweir     //==================================================================================================================
237cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
238cdf0e10cSrcweir     SubComponentManager::SubComponentManager( OApplicationController& _rController, const ::comphelper::SharedMutex& _rMutex )
239cdf0e10cSrcweir         :m_pData( new SubComponentManager_Data( _rController, _rMutex ) )
240cdf0e10cSrcweir     {
241cdf0e10cSrcweir     }
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
244cdf0e10cSrcweir     SubComponentManager::~SubComponentManager()
245cdf0e10cSrcweir     {
246cdf0e10cSrcweir     }
247cdf0e10cSrcweir 
248cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
249cdf0e10cSrcweir     void SubComponentManager::disposing()
250cdf0e10cSrcweir     {
251cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_pData->getMutex() );
252cdf0e10cSrcweir         m_pData->m_aComponents.clear();
253cdf0e10cSrcweir     }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
256cdf0e10cSrcweir     namespace
257cdf0e10cSrcweir     {
258cdf0e10cSrcweir 	    //..............................................................................................................
259cdf0e10cSrcweir         bool lcl_fallbackToAnotherController( SubComponentDescriptor& _rCompDesc )
260cdf0e10cSrcweir         {
261cdf0e10cSrcweir             Reference< XController > xFallback;
262cdf0e10cSrcweir             OSL_PRECOND( _rCompDesc.xModel.is(), "lcl_fallbackToAnotherController: illegal call!" );
263cdf0e10cSrcweir             if ( !_rCompDesc.xModel.is() )
264cdf0e10cSrcweir                 return false;
265cdf0e10cSrcweir 
266cdf0e10cSrcweir             xFallback.set( _rCompDesc.xModel->getCurrentController() );
267cdf0e10cSrcweir             if ( xFallback == _rCompDesc.xController )
268cdf0e10cSrcweir                 // don't accept the very same controller as fallback
269cdf0e10cSrcweir                 xFallback.clear();
270cdf0e10cSrcweir 
271cdf0e10cSrcweir             if ( !xFallback.is() )
272cdf0e10cSrcweir             {
273cdf0e10cSrcweir                 // perhaps XModel2 can be of help here
274cdf0e10cSrcweir                 Reference< XModel2 > xModel2( _rCompDesc.xModel, UNO_QUERY );
275cdf0e10cSrcweir                 Reference< XEnumeration > xControllerEnum;
276cdf0e10cSrcweir                 if ( xModel2.is() )
277cdf0e10cSrcweir                     xControllerEnum = xModel2->getControllers();
278cdf0e10cSrcweir                 while ( xControllerEnum.is() && xControllerEnum->hasMoreElements() )
279cdf0e10cSrcweir                 {
280cdf0e10cSrcweir                     xFallback.set( xControllerEnum->nextElement(), UNO_QUERY );
281cdf0e10cSrcweir                     if ( xFallback == _rCompDesc.xController )
282cdf0e10cSrcweir                         xFallback.clear();
283cdf0e10cSrcweir                 }
284cdf0e10cSrcweir             }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir             if ( xFallback.is() )
287cdf0e10cSrcweir             {
288cdf0e10cSrcweir                 _rCompDesc.xController = xFallback;
289cdf0e10cSrcweir                 _rCompDesc.xFrame.set( xFallback->getFrame(), UNO_SET_THROW );
290cdf0e10cSrcweir                 return true;
291cdf0e10cSrcweir             }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir             return false;
294cdf0e10cSrcweir         }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 	    //..............................................................................................................
297cdf0e10cSrcweir         bool lcl_closeComponent( const Reference< XCommandProcessor >& _rxCommandProcessor )
298cdf0e10cSrcweir         {
299cdf0e10cSrcweir             bool bSuccess = false;
300cdf0e10cSrcweir             try
301cdf0e10cSrcweir             {
302cdf0e10cSrcweir                 Reference< XCommandProcessor > xCommandProcessor( _rxCommandProcessor, UNO_SET_THROW );
303cdf0e10cSrcweir                 sal_Int32 nCommandIdentifier = xCommandProcessor->createCommandIdentifier();
304cdf0e10cSrcweir 
305cdf0e10cSrcweir                 Command aCommand;
306cdf0e10cSrcweir                 aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "close" ) );
307cdf0e10cSrcweir                 xCommandProcessor->execute( aCommand, nCommandIdentifier, NULL );
308cdf0e10cSrcweir                 bSuccess = true;
309cdf0e10cSrcweir             }
310cdf0e10cSrcweir             catch( const Exception& )
311cdf0e10cSrcweir             {
312cdf0e10cSrcweir             	DBG_UNHANDLED_EXCEPTION();
313cdf0e10cSrcweir             }
314cdf0e10cSrcweir             return bSuccess;
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 	    //..............................................................................................................
318cdf0e10cSrcweir         bool lcl_closeComponent( const SubComponentDescriptor& _rComponent )
319cdf0e10cSrcweir         {
320cdf0e10cSrcweir             if ( _rComponent.xComponentCommandProcessor.is() )
321cdf0e10cSrcweir                 return lcl_closeComponent( _rComponent.xComponentCommandProcessor );
322cdf0e10cSrcweir 
323cdf0e10cSrcweir             Reference< XController > xController( _rComponent.xController );
324cdf0e10cSrcweir             OSL_ENSURE( xController.is(), "lcl_closeComponent: invalid controller!" );
325cdf0e10cSrcweir 
326cdf0e10cSrcweir             // suspend the controller in the document
327cdf0e10cSrcweir             if ( xController.is() )
328cdf0e10cSrcweir                 if ( !xController->suspend( sal_True ) )
329cdf0e10cSrcweir                     return false;
330cdf0e10cSrcweir 
331cdf0e10cSrcweir             bool bSuccess = false;
332cdf0e10cSrcweir             try
333cdf0e10cSrcweir             {
334cdf0e10cSrcweir                 Reference< XCloseable > xCloseable( _rComponent.xFrame, UNO_QUERY_THROW );
335cdf0e10cSrcweir                 xCloseable->close( sal_True );
336cdf0e10cSrcweir                 bSuccess = true;
337cdf0e10cSrcweir             }
338cdf0e10cSrcweir             catch( const Exception& )
339cdf0e10cSrcweir             {
340cdf0e10cSrcweir                 DBG_UNHANDLED_EXCEPTION();
341cdf0e10cSrcweir             }
342cdf0e10cSrcweir             return bSuccess;
343cdf0e10cSrcweir         }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir 	    //..............................................................................................................
346cdf0e10cSrcweir         void lcl_notifySubComponentEvent( const SubComponentManager_Data& _rData, const sal_Char* _pAsciiEventName,
347cdf0e10cSrcweir                 const SubComponentDescriptor& _rComponent )
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             try
350cdf0e10cSrcweir             {
351cdf0e10cSrcweir                 Reference< XDocumentEventBroadcaster > xBroadcaster( _rData.m_rController.getModel(), UNO_QUERY_THROW );
352cdf0e10cSrcweir                 xBroadcaster->notifyDocumentEvent(
353cdf0e10cSrcweir                     ::rtl::OUString::createFromAscii( _pAsciiEventName ),
354cdf0e10cSrcweir                     &_rData.m_rController,
355cdf0e10cSrcweir                     makeAny( _rComponent.xFrame )
356cdf0e10cSrcweir                 );
357cdf0e10cSrcweir             }
358cdf0e10cSrcweir             catch( const Exception& )
359cdf0e10cSrcweir             {
360cdf0e10cSrcweir         	    DBG_UNHANDLED_EXCEPTION();
361cdf0e10cSrcweir             }
362cdf0e10cSrcweir         }
363cdf0e10cSrcweir     }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
366cdf0e10cSrcweir     void SAL_CALL SubComponentManager::propertyChange( const PropertyChangeEvent& i_rEvent ) throw (RuntimeException)
367cdf0e10cSrcweir     {
368cdf0e10cSrcweir         if ( i_rEvent.PropertyName != PROPERTY_NAME )
369cdf0e10cSrcweir             // by definition, it's allowed to broadcast more than what we've registered for
370cdf0e10cSrcweir             return;
371cdf0e10cSrcweir 
372cdf0e10cSrcweir         // find the sub component whose name changed
373cdf0e10cSrcweir         for (   SubComponents::iterator comp = m_pData->m_aComponents.begin();
374cdf0e10cSrcweir                 comp != m_pData->m_aComponents.end();
375cdf0e10cSrcweir                 ++comp
376cdf0e10cSrcweir             )
377cdf0e10cSrcweir         {
378cdf0e10cSrcweir             if ( comp->xDocumentDefinitionProperties != i_rEvent.Source )
379cdf0e10cSrcweir                 continue;
380cdf0e10cSrcweir 
381cdf0e10cSrcweir             ::rtl::OUString sNewName;
382cdf0e10cSrcweir             OSL_VERIFY( i_rEvent.NewValue >>= sNewName );
383cdf0e10cSrcweir 
384cdf0e10cSrcweir         #if OSL_DEBUG_LEVEL > 0
385cdf0e10cSrcweir             ::rtl::OUString sOldKnownName( comp->sName );
386cdf0e10cSrcweir             ::rtl::OUString sOldName;
387cdf0e10cSrcweir             OSL_VERIFY( i_rEvent.OldValue >>= sOldName );
388cdf0e10cSrcweir             OSL_ENSURE( sOldName == sOldKnownName, "SubComponentManager::propertyChange: inconsistency in the old names!" );
389cdf0e10cSrcweir         #endif
390cdf0e10cSrcweir 
391cdf0e10cSrcweir             comp->sName = sNewName;
392cdf0e10cSrcweir             break;
393cdf0e10cSrcweir         }
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
397cdf0e10cSrcweir     void SAL_CALL SubComponentManager::disposing( const EventObject& _rSource ) throw (RuntimeException)
398cdf0e10cSrcweir     {
399cdf0e10cSrcweir         ::osl::ClearableMutexGuard aGuard( m_pData->getMutex() );
400cdf0e10cSrcweir 
401cdf0e10cSrcweir         SubComponentDescriptor aClosedComponent;
402cdf0e10cSrcweir 
403cdf0e10cSrcweir         for (   SubComponents::iterator comp = m_pData->m_aComponents.begin();
404cdf0e10cSrcweir                 comp != m_pData->m_aComponents.end();
405cdf0e10cSrcweir                 ++comp
406cdf0e10cSrcweir             )
407cdf0e10cSrcweir         {
408cdf0e10cSrcweir             bool bRemove = false;
409cdf0e10cSrcweir 
410cdf0e10cSrcweir             if ( comp->xController == _rSource.Source )
411cdf0e10cSrcweir             {
412cdf0e10cSrcweir                 if ( !comp->xModel.is() )
413cdf0e10cSrcweir                 {
414cdf0e10cSrcweir                     bRemove = true;
415cdf0e10cSrcweir                 }
416cdf0e10cSrcweir                 else
417cdf0e10cSrcweir                 {
418cdf0e10cSrcweir                     // maybe this is just one view to the sub document, and only this view is closed
419cdf0e10cSrcweir                     if ( !lcl_fallbackToAnotherController( *comp ) )
420cdf0e10cSrcweir                     {
421cdf0e10cSrcweir                         bRemove = true;
422cdf0e10cSrcweir                     }
423cdf0e10cSrcweir                 }
424cdf0e10cSrcweir             }
425cdf0e10cSrcweir             else if ( comp->xModel == _rSource.Source )
426cdf0e10cSrcweir             {
427cdf0e10cSrcweir                 bRemove = true;
428cdf0e10cSrcweir             }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir             if ( bRemove )
431cdf0e10cSrcweir             {
432cdf0e10cSrcweir                 aClosedComponent = *comp;
433cdf0e10cSrcweir                 m_pData->m_aComponents.erase( comp );
434cdf0e10cSrcweir                 break;
435cdf0e10cSrcweir             }
436cdf0e10cSrcweir         }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir         if ( aClosedComponent.is() )
439cdf0e10cSrcweir         {
440cdf0e10cSrcweir             aGuard.clear();
441cdf0e10cSrcweir             lcl_notifySubComponentEvent( *m_pData, "OnSubComponentClosed", aClosedComponent );
442cdf0e10cSrcweir         }
443cdf0e10cSrcweir     }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
446cdf0e10cSrcweir     Sequence< Reference< XComponent> > SubComponentManager::getSubComponents() const
447cdf0e10cSrcweir     {
448cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_pData->getMutex() );
449cdf0e10cSrcweir 
450cdf0e10cSrcweir         Sequence< Reference< XComponent > > aComponents( m_pData->m_aComponents.size() );
451cdf0e10cSrcweir         ::std::transform(
452cdf0e10cSrcweir             m_pData->m_aComponents.begin(),
453cdf0e10cSrcweir             m_pData->m_aComponents.end(),
454cdf0e10cSrcweir             aComponents.getArray(),
455cdf0e10cSrcweir             SelectSubComponent()
456cdf0e10cSrcweir         );
457cdf0e10cSrcweir         return aComponents;
458cdf0e10cSrcweir     }
459cdf0e10cSrcweir 
460cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
461cdf0e10cSrcweir     sal_Bool SubComponentManager::closeSubComponents()
462cdf0e10cSrcweir     {
463cdf0e10cSrcweir 	    ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
464cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( m_pData->getMutex() );
465cdf0e10cSrcweir 
466cdf0e10cSrcweir 	    try
467cdf0e10cSrcweir 	    {
468cdf0e10cSrcweir             SubComponents aWorkingCopy( m_pData->m_aComponents );
469cdf0e10cSrcweir 		    for (   SubComponents::const_iterator comp = aWorkingCopy.begin();
470cdf0e10cSrcweir                     comp != aWorkingCopy.end();
471cdf0e10cSrcweir                     ++comp
472cdf0e10cSrcweir                 )
473cdf0e10cSrcweir             {
474cdf0e10cSrcweir                 lcl_closeComponent( *comp );
475cdf0e10cSrcweir             }
476cdf0e10cSrcweir 	    }
477cdf0e10cSrcweir 	    catch ( const Exception& )
478cdf0e10cSrcweir 	    {
479cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
480cdf0e10cSrcweir 	    }
481cdf0e10cSrcweir 
482cdf0e10cSrcweir 	    return empty();
483cdf0e10cSrcweir     }
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
486cdf0e10cSrcweir     bool SubComponentManager::empty() const
487cdf0e10cSrcweir     {
488cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( m_pData->getMutex() );
489cdf0e10cSrcweir         return m_pData->m_aComponents.empty();
490cdf0e10cSrcweir     }
491cdf0e10cSrcweir 
492cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
493cdf0e10cSrcweir     void SubComponentManager::onSubComponentOpened( const ::rtl::OUString&  _rName, const sal_Int32 _nComponentType,
494cdf0e10cSrcweir         const ElementOpenMode _eOpenMode, const Reference< XComponent >& _rxComponent )
495cdf0e10cSrcweir     {
496cdf0e10cSrcweir 	    ::osl::ClearableMutexGuard aGuard( m_pData->getMutex() );
497cdf0e10cSrcweir 
498cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
499cdf0e10cSrcweir         if ( _rName.getLength() )
500cdf0e10cSrcweir         {
501cdf0e10cSrcweir             // check there does not already exist such a component
502cdf0e10cSrcweir             SubComponents::const_iterator existentPos = ::std::find_if(
503cdf0e10cSrcweir                 m_pData->m_aComponents.begin(),
504cdf0e10cSrcweir                 m_pData->m_aComponents.end(),
505cdf0e10cSrcweir                 SubComponentMatch( _rName, _nComponentType, _eOpenMode )
506cdf0e10cSrcweir             );
507cdf0e10cSrcweir             OSL_ENSURE( existentPos == m_pData->m_aComponents.end(), "already existent!" );
508cdf0e10cSrcweir         }
509cdf0e10cSrcweir #endif
510cdf0e10cSrcweir         SubComponentDescriptor aElement( _rName, _nComponentType, _eOpenMode, _rxComponent );
511cdf0e10cSrcweir         ENSURE_OR_THROW( aElement.xModel.is() || aElement.xController.is(), "illegal component" );
512cdf0e10cSrcweir 
513cdf0e10cSrcweir         m_pData->m_aComponents.push_back( aElement );
514cdf0e10cSrcweir 
515cdf0e10cSrcweir         // add as listener
516cdf0e10cSrcweir         if ( aElement.xController.is() )
517cdf0e10cSrcweir             aElement.xController->addEventListener( this );
518cdf0e10cSrcweir         if ( aElement.xModel.is() )
519cdf0e10cSrcweir             aElement.xModel->addEventListener( this );
520cdf0e10cSrcweir         if ( aElement.xDocumentDefinitionProperties.is() )
521cdf0e10cSrcweir             aElement.xDocumentDefinitionProperties->addPropertyChangeListener( PROPERTY_NAME, this );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir         // notify this to interested parties
524cdf0e10cSrcweir         aGuard.clear();
525cdf0e10cSrcweir         lcl_notifySubComponentEvent( *m_pData, "OnSubComponentOpened", aElement );
526cdf0e10cSrcweir     }
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
529cdf0e10cSrcweir     bool SubComponentManager::activateSubFrame( const ::rtl::OUString& _rName, const sal_Int32 _nComponentType,
530cdf0e10cSrcweir         const ElementOpenMode _eOpenMode, Reference< XComponent >& o_rComponent ) const
531cdf0e10cSrcweir     {
532cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( m_pData->getMutex() );
533cdf0e10cSrcweir 
534cdf0e10cSrcweir         SubComponents::const_iterator pos = ::std::find_if(
535cdf0e10cSrcweir             m_pData->m_aComponents.begin(),
536cdf0e10cSrcweir             m_pData->m_aComponents.end(),
537cdf0e10cSrcweir             SubComponentMatch( _rName, _nComponentType, _eOpenMode )
538cdf0e10cSrcweir         );
539cdf0e10cSrcweir         if ( pos == m_pData->m_aComponents.end() )
540cdf0e10cSrcweir             // no component with this name/type/open mode
541cdf0e10cSrcweir             return false;
542cdf0e10cSrcweir 
543cdf0e10cSrcweir         const Reference< XFrame > xFrame( pos->xFrame, UNO_SET_THROW );
544cdf0e10cSrcweir         const Reference< XTopWindow > xTopWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW );
545cdf0e10cSrcweir         xTopWindow->toFront();
546cdf0e10cSrcweir 
547cdf0e10cSrcweir         if ( pos->xModel.is() )
548cdf0e10cSrcweir             o_rComponent = pos->xModel.get();
549cdf0e10cSrcweir         else if ( pos->xController.is() )
550cdf0e10cSrcweir             o_rComponent = pos->xController.get();
551cdf0e10cSrcweir         else
552cdf0e10cSrcweir             o_rComponent = pos->xFrame.get();
553cdf0e10cSrcweir 
554cdf0e10cSrcweir         return true;
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
558cdf0e10cSrcweir     bool SubComponentManager::closeSubFrames( const ::rtl::OUString& i_rName, const sal_Int32 _nComponentType )
559cdf0e10cSrcweir     {
560cdf0e10cSrcweir 	    ::osl::MutexGuard aGuard( m_pData->getMutex() );
561cdf0e10cSrcweir         ENSURE_OR_RETURN_FALSE( i_rName.getLength(), "SubComponentManager::closeSubFrames: illegal name!" );
562cdf0e10cSrcweir 
563cdf0e10cSrcweir         SubComponents aWorkingCopy( m_pData->m_aComponents );
564cdf0e10cSrcweir         for (   SubComponents::const_iterator comp = aWorkingCopy.begin();
565cdf0e10cSrcweir                 comp != aWorkingCopy.end();
566cdf0e10cSrcweir                 ++comp
567cdf0e10cSrcweir             )
568cdf0e10cSrcweir         {
569cdf0e10cSrcweir             if ( ( comp->sName != i_rName ) || ( comp->nComponentType != _nComponentType ) )
570cdf0e10cSrcweir                 continue;
571cdf0e10cSrcweir 
572cdf0e10cSrcweir             if ( !lcl_closeComponent( *comp ) )
573cdf0e10cSrcweir                 return false;
574cdf0e10cSrcweir         }
575cdf0e10cSrcweir 
576cdf0e10cSrcweir         return true;
577cdf0e10cSrcweir     }
578cdf0e10cSrcweir 
579cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
580cdf0e10cSrcweir     bool SubComponentManager::lookupSubComponent( const Reference< XComponent >& i_rComponent,
581cdf0e10cSrcweir             ::rtl::OUString& o_rName, sal_Int32& o_rComponentType )
582cdf0e10cSrcweir     {
583cdf0e10cSrcweir         for (   SubComponents::const_iterator comp = m_pData->m_aComponents.begin();
584cdf0e10cSrcweir                 comp != m_pData->m_aComponents.end();
585cdf0e10cSrcweir                 ++comp
586cdf0e10cSrcweir             )
587cdf0e10cSrcweir         {
588cdf0e10cSrcweir             if  (   (   comp->xModel.is()
589cdf0e10cSrcweir                     &&  ( comp->xModel == i_rComponent )
590cdf0e10cSrcweir                     )
591cdf0e10cSrcweir                 ||  (   comp->xController.is()
592cdf0e10cSrcweir                     &&  ( comp->xController == i_rComponent )
593cdf0e10cSrcweir                     )
594cdf0e10cSrcweir                 ||  (   comp->xFrame.is()
595cdf0e10cSrcweir                     &&  ( comp->xFrame == i_rComponent )
596cdf0e10cSrcweir                     )
597cdf0e10cSrcweir                 )
598cdf0e10cSrcweir             {
599cdf0e10cSrcweir                 o_rName = comp->sName;
600cdf0e10cSrcweir                 o_rComponentType = comp->nComponentType;
601cdf0e10cSrcweir                 return true;
602cdf0e10cSrcweir             }
603cdf0e10cSrcweir         }
604cdf0e10cSrcweir         return false;
605cdf0e10cSrcweir     }
606cdf0e10cSrcweir 
607cdf0e10cSrcweir //......................................................................................................................
608cdf0e10cSrcweir } // namespace dbaui
609cdf0e10cSrcweir //......................................................................................................................
610