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