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