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 #include <uifactory/addonstoolboxfactory.hxx>
27 
28 //_________________________________________________________________________________________________________________
29 //	my own includes
30 //_________________________________________________________________________________________________________________
31 #include <uielement/addonstoolbarwrapper.hxx>
32 #include <threadhelp/resetableguard.hxx>
33 
34 //_________________________________________________________________________________________________________________
35 //	interface includes
36 //_________________________________________________________________________________________________________________
37 #include <com/sun/star/util/XURLTransformer.hpp>
38 #include <com/sun/star/frame/XFrame.hpp>
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/lang/XInitialization.hpp>
41 #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
42 
43 #ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONMANAGERSUPLLIER_HPP_
44 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
45 #endif
46 
47 //_________________________________________________________________________________________________________________
48 //	includes of other projects
49 //_________________________________________________________________________________________________________________
50 #include <vcl/svapp.hxx>
51 #include <tools/urlobj.hxx>
52 #include <rtl/ustrbuf.hxx>
53 
54 //_________________________________________________________________________________________________________________
55 //	Defines
56 //_________________________________________________________________________________________________________________
57 //
58 
59 using namespace com::sun::star::uno;
60 using namespace com::sun::star::lang;
61 using namespace com::sun::star::frame;
62 using namespace com::sun::star::beans;
63 using namespace com::sun::star::util;
64 using namespace ::com::sun::star::ui;
65 
66 namespace framework
67 {
68 
69 //*****************************************************************************************************************
70 //	XInterface, XTypeProvider, XServiceInfo
71 //*****************************************************************************************************************
DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(AddonsToolBoxFactory,::cppu::OWeakObject,SERVICENAME_TOOLBARFACTORY,IMPLEMENTATIONNAME_ADDONSTOOLBARFACTORY)72 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   AddonsToolBoxFactory				            ,
73                                             ::cppu::OWeakObject							    ,
74                                             SERVICENAME_TOOLBARFACTORY	                    ,
75 											IMPLEMENTATIONNAME_ADDONSTOOLBARFACTORY
76 										)
77 
78 DEFINE_INIT_SERVICE                     (   AddonsToolBoxFactory, {} )
79 
80 AddonsToolBoxFactory::AddonsToolBoxFactory(
81     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
82     ThreadHelpBase( &Application::GetSolarMutex() )
83     , m_xServiceManager( xServiceManager )
84     , m_xModuleManager( xServiceManager->createInstance(SERVICENAME_MODULEMANAGER),UNO_QUERY )
85 {
86 }
87 
~AddonsToolBoxFactory()88 AddonsToolBoxFactory::~AddonsToolBoxFactory()
89 {
90 }
91 
IsCorrectContext(const::rtl::OUString & rModuleIdentifier,const rtl::OUString & aContextList)92 static sal_Bool IsCorrectContext( const ::rtl::OUString& rModuleIdentifier, const rtl::OUString& aContextList )
93 {
94     if ( aContextList.getLength() == 0 )
95         return sal_True;
96 
97     if ( rModuleIdentifier.getLength() > 0 )
98     {
99         sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
100         return ( nIndex >= 0 );
101     }
102 
103 	return sal_False;
104 }
105 
hasButtonsInContext(const Sequence<Sequence<PropertyValue>> & rPropSeqSeq,const Reference<XFrame> & rFrame)106 sal_Bool AddonsToolBoxFactory::hasButtonsInContext(
107     const Sequence< Sequence< PropertyValue > >& rPropSeqSeq,
108     const Reference< XFrame >& rFrame )
109 {
110     ::rtl::OUString aModuleIdentifier;
111     try
112     {
113         aModuleIdentifier = m_xModuleManager->identify( rFrame );
114     }
115     catch ( RuntimeException& )
116     {
117         throw;
118     }
119     catch ( Exception& )
120     {
121     }
122 
123     // Check before we create a toolbar that we have at least one button in
124     // the current frame context.
125     for ( sal_uInt32 i = 0; i < (sal_uInt32)rPropSeqSeq.getLength(); i++ )
126     {
127         sal_Bool    bIsButton( sal_True );
128         sal_Bool    bIsCorrectContext( sal_False );
129         sal_uInt32  nPropChecked( 0 );
130 
131         const Sequence< PropertyValue >& rPropSeq = rPropSeqSeq[i];
132         for ( sal_uInt32 j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
133         {
134             if ( rPropSeq[j].Name.equalsAsciiL( "Context", 7 ))
135             {
136                 ::rtl::OUString aContextList;
137                 if ( rPropSeq[j].Value >>= aContextList )
138                     bIsCorrectContext = IsCorrectContext( aModuleIdentifier, aContextList );
139                 nPropChecked++;
140             }
141             else if ( rPropSeq[j].Name.equalsAsciiL( "URL", 3 ))
142             {
143                 ::rtl::OUString aURL;
144                 rPropSeq[j].Value >>= aURL;
145                 bIsButton = !aURL.equalsAsciiL( "private:separator", 17 );
146                 nPropChecked++;
147             }
148 
149             if ( nPropChecked == 2 )
150                 break;
151         }
152 
153         if ( bIsButton && bIsCorrectContext )
154             return sal_True;
155     }
156 
157     return sal_False;
158 }
159 
160 // XUIElementFactory
createUIElement(const::rtl::OUString & ResourceURL,const Sequence<PropertyValue> & Args)161 Reference< XUIElement > SAL_CALL AddonsToolBoxFactory::createUIElement(
162     const ::rtl::OUString& ResourceURL,
163     const Sequence< PropertyValue >& Args )
164 throw ( ::com::sun::star::container::NoSuchElementException,
165         ::com::sun::star::lang::IllegalArgumentException,
166         ::com::sun::star::uno::RuntimeException )
167 {
168     // SAFE
169     ResetableGuard aLock( m_aLock );
170 
171     Sequence< Sequence< PropertyValue > >   aConfigData;
172     Reference< XFrame >                     xFrame;
173     rtl::OUString                           aResourceURL( ResourceURL );
174 
175     for ( sal_Int32 n = 0; n < Args.getLength(); n++ )
176     {
177         if ( Args[n].Name.equalsAscii( "ConfigurationData" ))
178             Args[n].Value >>= aConfigData;
179         else if ( Args[n].Name.equalsAscii( "Frame" ))
180             Args[n].Value >>= xFrame;
181         else if ( Args[n].Name.equalsAscii( "ResourceURL" ))
182             Args[n].Value >>= aResourceURL;
183     }
184 
185     if ( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" ))) != 0 )
186         throw IllegalArgumentException();
187 
188     // Identify frame and determine module identifier to look for context based buttons
189     Reference< ::com::sun::star::ui::XUIElement > xToolBar;
190     if ( xFrame.is() &&
191          ( aConfigData.getLength()> 0 ) &&
192          hasButtonsInContext( aConfigData, xFrame ))
193     {
194         PropertyValue aPropValue;
195         Sequence< Any > aPropSeq( 3 );
196         aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
197         aPropValue.Value <<= xFrame;
198         aPropSeq[0] <<= aPropValue;
199         aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" ));
200         aPropValue.Value <<= aConfigData;
201         aPropSeq[1] <<= aPropValue;
202         aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" ));
203         aPropValue.Value <<= aResourceURL;
204         aPropSeq[2] <<= aPropValue;
205 
206         vos::OGuard	aGuard( Application::GetSolarMutex() );
207         AddonsToolBarWrapper* pToolBarWrapper = new AddonsToolBarWrapper( m_xServiceManager );
208         xToolBar = Reference< ::com::sun::star::ui::XUIElement >( (OWeakObject *)pToolBarWrapper, UNO_QUERY );
209         Reference< XInitialization > xInit( xToolBar, UNO_QUERY );
210         xInit->initialize( aPropSeq );
211     }
212 
213     return xToolBar;
214 }
215 
216 }
217 
218