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 throw (uno::Exception, uno::RuntimeException)
134 {
135 /*
136 // Currently this method cannot be implemented for generic use. There is no way for external
137 code to get a handle to the dialog model.
138
139 uno::Reference< lang::XMultiServiceFactory > xServiceManager( xContext->getServiceManager(), uno::UNO_QUERY );
140
141 const ::rtl::OUString sToolkitService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit"));
142 uno::Reference< awt::XToolkit > xToolkit( xServiceManager->createInstance( sToolkitService ), uno::UNO_QUERY_THROW );
143
144 const ::rtl::OUString sDialogModelService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlDialogModel"));
145 uno::Reference< awt::XControlModel > xDialogModel( xServiceManager->createInstance( sDialogModelService ), uno::UNO_QUERY_THROW );
146
147 const ::rtl::OUString sDecoration(RTL_CONSTASCII_USTRINGPARAM("Decoration"));
148 uno::Reference< beans::XPropertySet > xPropSet( xDialogModel, uno::UNO_QUERY_THROW );
149 xPropSet->setPropertyValue( sDecoration, uno::makeAny(false));
150
151 const ::rtl::OUString sDialogService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlDialog"));
152 uno::Reference< awt::XControl > xDialogControl( xServiceManager->createInstance( sDialogService ), uno::UNO_QUERY_THROW );
153
154 xDialogControl->setModel( xDialogModel );
155
156 uno::Reference< awt::XWindowPeer > xWindowParentPeer( xToolkit->getDesktopWindow(), uno::UNO_QUERY );
157 xDialogControl->createPeer( xToolkit, xWindowParentPeer );
158 uno::Reference< uno::XInterface > xWindow( xDialogControl->getPeer(), uno::UNO_QUERY );
159 */
160 uno::Reference< uno::XInterface > xWindow;
161 return xWindow;
162 }
163
createInstanceWithArgumentsAndContext(const uno::Sequence<uno::Any> & Arguments,const uno::Reference<uno::XComponentContext> & Context)164 uno::Reference< uno::XInterface > SAL_CALL WindowContentFactoryManager::createInstanceWithArgumentsAndContext(
165 const uno::Sequence< uno::Any >& Arguments, const uno::Reference< uno::XComponentContext >& Context )
166 throw (uno::Exception, uno::RuntimeException)
167 {
168 uno::Reference< uno::XInterface > xWindow;
169 uno::Reference< frame::XFrame > xFrame;
170 ::rtl::OUString aResourceURL;
171
172 for (sal_Int32 i=0; i < Arguments.getLength(); i++ )
173 {
174 beans::PropertyValue aPropValue;
175 if ( Arguments[i] >>= aPropValue )
176 {
177 if ( aPropValue.Name.equalsAscii( "Frame" ))
178 aPropValue.Value >>= xFrame;
179 else if ( aPropValue.Name.equalsAscii( "ResourceURL" ))
180 aPropValue.Value >>= aResourceURL;
181 }
182 }
183
184 uno::Reference< frame::XModuleManager > xModuleManager;
185 // SAFE
186 {
187 ResetableGuard aLock( m_aLock );
188 xModuleManager = m_xModuleManager;
189 }
190 // UNSAFE
191
192 // Determine the module identifier
193 ::rtl::OUString aType;
194 ::rtl::OUString aName;
195 ::rtl::OUString aModuleId;
196 try
197 {
198 if ( xFrame.is() && xModuleManager.is() )
199 aModuleId = xModuleManager->identify( uno::Reference< uno::XInterface >( xFrame, uno::UNO_QUERY ) );
200 }
201 catch ( frame::UnknownModuleException& )
202 {
203 }
204
205 RetrieveTypeNameFromResourceURL( aResourceURL, aType, aName );
206 if ( aType.getLength() > 0 &&
207 aName.getLength() > 0 &&
208 aModuleId.getLength() > 0 )
209 {
210 ::rtl::OUString aImplementationName;
211 uno::Reference< uno::XInterface > xHolder( static_cast<cppu::OWeakObject*>(this), uno::UNO_QUERY );
212
213 // Detetmine the implementation name of the window content factory dependent on the
214 // module identifier, user interface element type and name
215 // SAFE
216 ResetableGuard aLock( m_aLock );
217
218 if ( !m_bConfigRead )
219 {
220 m_bConfigRead = sal_True;
221 m_pConfigAccess->readConfigurationData();
222 }
223
224 aImplementationName = m_pConfigAccess->getFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
225 if ( aImplementationName.getLength() > 0 )
226 {
227 aLock.unlock();
228 // UNSAFE
229
230 uno::Reference< lang::XMultiServiceFactory > xServiceManager( Context->getServiceManager(), uno::UNO_QUERY );
231 if ( xServiceManager.is() )
232 {
233 uno::Reference< lang::XSingleComponentFactory > xFactory(
234 xServiceManager->createInstance( aImplementationName ), uno::UNO_QUERY );
235 if ( xFactory.is() )
236 {
237 // Be careful: We call external code. Therefore here we have to catch all exceptions
238 try
239 {
240 xWindow = xFactory->createInstanceWithArgumentsAndContext( Arguments, Context );
241 }
242 catch ( uno::Exception& )
243 {
244 DBG_UNHANDLED_EXCEPTION();
245 }
246 }
247 }
248 }
249 }
250
251 // UNSAFE
252 if ( !xWindow.is())
253 {
254 // Fallback: Use internal factory code to create a toolkit dialog as a content window
255 xWindow = createInstanceWithContext(Context);
256 }
257
258 return xWindow;
259 }
260
261 } // namespace framework
262