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