xref: /AOO41X/main/framework/source/uifactory/windowcontentfactorymanager.cxx (revision 6d739b60ff8f4ed2134ae1442e284f9da90334b4)
1*6d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*6d739b60SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*6d739b60SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*6d739b60SAndrew Rist  * distributed with this work for additional information
6*6d739b60SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*6d739b60SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*6d739b60SAndrew Rist  * "License"); you may not use this file except in compliance
9*6d739b60SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*6d739b60SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*6d739b60SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*6d739b60SAndrew Rist  * software distributed under the License is distributed on an
15*6d739b60SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*6d739b60SAndrew Rist  * KIND, either express or implied.  See the License for the
17*6d739b60SAndrew Rist  * specific language governing permissions and limitations
18*6d739b60SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*6d739b60SAndrew Rist  *************************************************************/
21*6d739b60SAndrew Rist 
22*6d739b60SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_framework.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //_________________________________________________________________________________________________________________
28cdf0e10cSrcweir //	my own includes
29cdf0e10cSrcweir //_________________________________________________________________________________________________________________
30cdf0e10cSrcweir #include <uifactory/windowcontentfactorymanager.hxx>
31cdf0e10cSrcweir #include <uifactory/uielementfactorymanager.hxx>
32cdf0e10cSrcweir #include <threadhelp/resetableguard.hxx>
33cdf0e10cSrcweir #include "services.h"
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //_________________________________________________________________________________________________________________
36cdf0e10cSrcweir //	interface includes
37cdf0e10cSrcweir //_________________________________________________________________________________________________________________
38cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
39cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
40cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
41cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
42cdf0e10cSrcweir #include <com/sun/star/container/XContainer.hpp>
43cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp>
44cdf0e10cSrcweir #include <com/sun/star/awt/XToolkit.hpp>
45cdf0e10cSrcweir #include <com/sun/star/awt/XControlModel.hpp>
46cdf0e10cSrcweir #include <com/sun/star/awt/XControl.hpp>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir //_________________________________________________________________________________________________________________
49cdf0e10cSrcweir //	includes of other projects
50cdf0e10cSrcweir //_________________________________________________________________________________________________________________
51cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
52cdf0e10cSrcweir #include <cppuhelper/weak.hxx>
53cdf0e10cSrcweir #include <tools/urlobj.hxx>
54cdf0e10cSrcweir #include <tools/diagnose_ex.h>
55cdf0e10cSrcweir #include <vcl/svapp.hxx>
56cdf0e10cSrcweir 
57cdf0e10cSrcweir //_________________________________________________________________________________________________________________
58cdf0e10cSrcweir //	Defines
59cdf0e10cSrcweir //_________________________________________________________________________________________________________________
60cdf0e10cSrcweir //
61cdf0e10cSrcweir 
62cdf0e10cSrcweir using namespace ::com::sun::star;
63cdf0e10cSrcweir 
64cdf0e10cSrcweir //_________________________________________________________________________________________________________________
65cdf0e10cSrcweir //	Namespace
66cdf0e10cSrcweir //_________________________________________________________________________________________________________________
67cdf0e10cSrcweir //
68cdf0e10cSrcweir 
69cdf0e10cSrcweir namespace framework
70cdf0e10cSrcweir {
71cdf0e10cSrcweir 
72cdf0e10cSrcweir //*****************************************************************************************************************
73cdf0e10cSrcweir //	XInterface, XTypeProvider, XServiceInfo
74cdf0e10cSrcweir //*****************************************************************************************************************
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(WindowContentFactoryManager,::cppu::OWeakObject,SERVICENAME_WINDOWCONTENTFACTORYMANAGER,IMPLEMENTATIONNAME_WINDOWCONTENTFACTORYMANAGER)75cdf0e10cSrcweir DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   WindowContentFactoryManager				        ,
76cdf0e10cSrcweir                                             ::cppu::OWeakObject							    ,
77cdf0e10cSrcweir                                             SERVICENAME_WINDOWCONTENTFACTORYMANAGER         ,
78cdf0e10cSrcweir 											IMPLEMENTATIONNAME_WINDOWCONTENTFACTORYMANAGER
79cdf0e10cSrcweir 										)
80cdf0e10cSrcweir 
81cdf0e10cSrcweir DEFINE_INIT_SERVICE                     (   WindowContentFactoryManager, {} )
82cdf0e10cSrcweir 
83cdf0e10cSrcweir WindowContentFactoryManager::WindowContentFactoryManager( const uno::Reference< lang::XMultiServiceFactory >& xServiceManager ) :
84cdf0e10cSrcweir     ThreadHelpBase( &Application::GetSolarMutex() ),
85cdf0e10cSrcweir     m_bConfigRead( sal_False ),
86cdf0e10cSrcweir     m_xServiceManager( xServiceManager )
87cdf0e10cSrcweir {
88cdf0e10cSrcweir     m_pConfigAccess = new ConfigurationAccess_FactoryManager( m_xServiceManager,rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.WindowContentFactories/Registered/ContentFactories" )) );
89cdf0e10cSrcweir     m_pConfigAccess->acquire();
90cdf0e10cSrcweir     m_xModuleManager = uno::Reference< frame::XModuleManager >( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), uno::UNO_QUERY );
91cdf0e10cSrcweir }
92cdf0e10cSrcweir 
~WindowContentFactoryManager()93cdf0e10cSrcweir WindowContentFactoryManager::~WindowContentFactoryManager()
94cdf0e10cSrcweir {
95cdf0e10cSrcweir     ResetableGuard aLock( m_aLock );
96cdf0e10cSrcweir 
97cdf0e10cSrcweir     // reduce reference count
98cdf0e10cSrcweir     m_pConfigAccess->release();
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
RetrieveTypeNameFromResourceURL(const rtl::OUString & aResourceURL,rtl::OUString & aType,rtl::OUString & aName)101cdf0e10cSrcweir void WindowContentFactoryManager::RetrieveTypeNameFromResourceURL( const rtl::OUString& aResourceURL, rtl::OUString& aType, rtl::OUString& aName )
102cdf0e10cSrcweir {
103cdf0e10cSrcweir     const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17;
104cdf0e10cSrcweir     const char      RESOURCEURL_PREFIX[] = "private:resource/";
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) &&
107cdf0e10cSrcweir         ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
108cdf0e10cSrcweir     {
109cdf0e10cSrcweir         rtl::OUString aTmpStr( aResourceURL.copy( RESOURCEURL_PREFIX_SIZE ));
110cdf0e10cSrcweir         sal_Int32 nToken = 0;
111cdf0e10cSrcweir         sal_Int32 nPart  = 0;
112cdf0e10cSrcweir 		do
113cdf0e10cSrcweir 		{
114cdf0e10cSrcweir 			::rtl::OUString sToken = aTmpStr.getToken( 0, '/', nToken);
115cdf0e10cSrcweir 			if ( sToken.getLength() )
116cdf0e10cSrcweir 			{
117cdf0e10cSrcweir                 if ( nPart == 0 )
118cdf0e10cSrcweir                     aType = sToken;
119cdf0e10cSrcweir                 else if ( nPart == 1 )
120cdf0e10cSrcweir                     aName = sToken;
121cdf0e10cSrcweir                 else
122cdf0e10cSrcweir                     break;
123cdf0e10cSrcweir                 nPart++;
124cdf0e10cSrcweir 			}
125cdf0e10cSrcweir 		}
126cdf0e10cSrcweir 		while( nToken >=0 );
127cdf0e10cSrcweir     }
128cdf0e10cSrcweir }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir // XSingleComponentFactory
createInstanceWithContext(const uno::Reference<uno::XComponentContext> &)131cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL WindowContentFactoryManager::createInstanceWithContext(
132cdf0e10cSrcweir     const uno::Reference< uno::XComponentContext >& /*xContext*/ )
133cdf0e10cSrcweir throw (uno::Exception, uno::RuntimeException)
134cdf0e10cSrcweir {
135cdf0e10cSrcweir /*
136cdf0e10cSrcweir     // Currently this method cannot be implemented for generic use. There is no way for external
137cdf0e10cSrcweir        code to get a handle to the dialog model.
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory > xServiceManager( xContext->getServiceManager(), uno::UNO_QUERY );
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     const ::rtl::OUString sToolkitService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit"));
142cdf0e10cSrcweir     uno::Reference< awt::XToolkit > xToolkit( xServiceManager->createInstance( sToolkitService ), uno::UNO_QUERY_THROW );
143cdf0e10cSrcweir 
144cdf0e10cSrcweir     const ::rtl::OUString sDialogModelService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlDialogModel"));
145cdf0e10cSrcweir     uno::Reference< awt::XControlModel > xDialogModel( xServiceManager->createInstance( sDialogModelService ), uno::UNO_QUERY_THROW );
146cdf0e10cSrcweir 
147cdf0e10cSrcweir     const ::rtl::OUString sDecoration(RTL_CONSTASCII_USTRINGPARAM("Decoration"));
148cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xPropSet( xDialogModel, uno::UNO_QUERY_THROW );
149cdf0e10cSrcweir     xPropSet->setPropertyValue( sDecoration, uno::makeAny(false));
150cdf0e10cSrcweir 
151cdf0e10cSrcweir     const ::rtl::OUString sDialogService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlDialog"));
152cdf0e10cSrcweir     uno::Reference< awt::XControl > xDialogControl( xServiceManager->createInstance( sDialogService ), uno::UNO_QUERY_THROW );
153cdf0e10cSrcweir 
154cdf0e10cSrcweir     xDialogControl->setModel( xDialogModel );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     uno::Reference< awt::XWindowPeer > xWindowParentPeer( xToolkit->getDesktopWindow(), uno::UNO_QUERY );
157cdf0e10cSrcweir     xDialogControl->createPeer( xToolkit, xWindowParentPeer );
158cdf0e10cSrcweir     uno::Reference< uno::XInterface > xWindow( xDialogControl->getPeer(), uno::UNO_QUERY );
159cdf0e10cSrcweir */
160cdf0e10cSrcweir     uno::Reference< uno::XInterface > xWindow;
161cdf0e10cSrcweir     return xWindow;
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
createInstanceWithArgumentsAndContext(const uno::Sequence<uno::Any> & Arguments,const uno::Reference<uno::XComponentContext> & Context)164cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL WindowContentFactoryManager::createInstanceWithArgumentsAndContext(
165cdf0e10cSrcweir     const uno::Sequence< uno::Any >& Arguments, const uno::Reference< uno::XComponentContext >& Context )
166cdf0e10cSrcweir throw (uno::Exception, uno::RuntimeException)
167cdf0e10cSrcweir {
168cdf0e10cSrcweir     uno::Reference< uno::XInterface > xWindow;
169cdf0e10cSrcweir     uno::Reference< frame::XFrame >   xFrame;
170cdf0e10cSrcweir     ::rtl::OUString                   aResourceURL;
171cdf0e10cSrcweir 
172cdf0e10cSrcweir     for (sal_Int32 i=0; i < Arguments.getLength(); i++ )
173cdf0e10cSrcweir     {
174cdf0e10cSrcweir         beans::PropertyValue aPropValue;
175cdf0e10cSrcweir         if ( Arguments[i] >>= aPropValue )
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir             if ( aPropValue.Name.equalsAscii( "Frame" ))
178cdf0e10cSrcweir                 aPropValue.Value >>= xFrame;
179cdf0e10cSrcweir             else if ( aPropValue.Name.equalsAscii( "ResourceURL" ))
180cdf0e10cSrcweir                 aPropValue.Value >>= aResourceURL;
181cdf0e10cSrcweir         }
182cdf0e10cSrcweir     }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     uno::Reference< frame::XModuleManager > xModuleManager;
185cdf0e10cSrcweir     // SAFE
186cdf0e10cSrcweir 	{
187cdf0e10cSrcweir 		ResetableGuard aLock( m_aLock );
188cdf0e10cSrcweir 		xModuleManager = m_xModuleManager;
189cdf0e10cSrcweir 	}
190cdf0e10cSrcweir     // UNSAFE
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     // Determine the module identifier
193cdf0e10cSrcweir     ::rtl::OUString aType;
194cdf0e10cSrcweir     ::rtl::OUString aName;
195cdf0e10cSrcweir     ::rtl::OUString aModuleId;
196cdf0e10cSrcweir     try
197cdf0e10cSrcweir     {
198cdf0e10cSrcweir         if ( xFrame.is() && xModuleManager.is() )
199cdf0e10cSrcweir             aModuleId = xModuleManager->identify( uno::Reference< uno::XInterface >( xFrame, uno::UNO_QUERY ) );
200cdf0e10cSrcweir     }
201cdf0e10cSrcweir     catch ( frame::UnknownModuleException& )
202cdf0e10cSrcweir     {
203cdf0e10cSrcweir     }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     RetrieveTypeNameFromResourceURL( aResourceURL, aType, aName );
206cdf0e10cSrcweir     if ( aType.getLength() > 0 &&
207cdf0e10cSrcweir          aName.getLength() > 0 &&
208cdf0e10cSrcweir          aModuleId.getLength() > 0 )
209cdf0e10cSrcweir     {
210cdf0e10cSrcweir         ::rtl::OUString                   aImplementationName;
211cdf0e10cSrcweir         uno::Reference< uno::XInterface > xHolder( static_cast<cppu::OWeakObject*>(this), uno::UNO_QUERY );
212cdf0e10cSrcweir 
213cdf0e10cSrcweir         // Detetmine the implementation name of the window content factory dependent on the
214cdf0e10cSrcweir         // module identifier, user interface element type and name
215cdf0e10cSrcweir         // SAFE
216cdf0e10cSrcweir         ResetableGuard aLock( m_aLock );
217cdf0e10cSrcweir 
218cdf0e10cSrcweir         if ( !m_bConfigRead )
219cdf0e10cSrcweir         {
220cdf0e10cSrcweir             m_bConfigRead = sal_True;
221cdf0e10cSrcweir             m_pConfigAccess->readConfigurationData();
222cdf0e10cSrcweir         }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir         aImplementationName = m_pConfigAccess->getFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
225cdf0e10cSrcweir         if ( aImplementationName.getLength() > 0 )
226cdf0e10cSrcweir         {
227cdf0e10cSrcweir             aLock.unlock();
228cdf0e10cSrcweir             // UNSAFE
229cdf0e10cSrcweir 
230cdf0e10cSrcweir             uno::Reference< lang::XMultiServiceFactory > xServiceManager( Context->getServiceManager(), uno::UNO_QUERY );
231cdf0e10cSrcweir             if ( xServiceManager.is() )
232cdf0e10cSrcweir             {
233cdf0e10cSrcweir                 uno::Reference< lang::XSingleComponentFactory > xFactory(
234cdf0e10cSrcweir                     xServiceManager->createInstance( aImplementationName ), uno::UNO_QUERY );
235cdf0e10cSrcweir                 if ( xFactory.is() )
236cdf0e10cSrcweir                 {
237cdf0e10cSrcweir                     // Be careful: We call external code. Therefore here we have to catch all exceptions
238cdf0e10cSrcweir                     try
239cdf0e10cSrcweir                     {
240cdf0e10cSrcweir                         xWindow = xFactory->createInstanceWithArgumentsAndContext( Arguments, Context );
241cdf0e10cSrcweir                     }
242cdf0e10cSrcweir                     catch ( uno::Exception& )
243cdf0e10cSrcweir                     {
244cdf0e10cSrcweir                         DBG_UNHANDLED_EXCEPTION();
245cdf0e10cSrcweir                     }
246cdf0e10cSrcweir                 }
247cdf0e10cSrcweir             }
248cdf0e10cSrcweir         }
249cdf0e10cSrcweir     }
250cdf0e10cSrcweir 
251cdf0e10cSrcweir     // UNSAFE
252cdf0e10cSrcweir     if ( !xWindow.is())
253cdf0e10cSrcweir     {
254cdf0e10cSrcweir         // Fallback: Use internal factory code to create a toolkit dialog as a content window
255cdf0e10cSrcweir         xWindow = createInstanceWithContext(Context);
256cdf0e10cSrcweir     }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir     return xWindow;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir 
261cdf0e10cSrcweir } // namespace framework
262