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