Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <uielement/addonstoolbarwrapper.hxx>
21 :
22 : #include <com/sun/star/util/XURLTransformer.hpp>
23 : #include <com/sun/star/frame/ModuleManager.hpp>
24 : #include <com/sun/star/frame/XModuleManager2.hpp>
25 : #include <com/sun/star/frame/XFrame.hpp>
26 : #include <com/sun/star/lang/XInitialization.hpp>
27 : #include <com/sun/star/lang/XServiceInfo.hpp>
28 : #include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp>
29 : #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
30 : #include <com/sun/star/ui/XUIElementFactory.hpp>
31 :
32 : #include <cppuhelper/implbase2.hxx>
33 : #include <cppuhelper/supportsservice.hxx>
34 : #include <vcl/svapp.hxx>
35 : #include <rtl/ref.hxx>
36 : #include <rtl/ustrbuf.hxx>
37 :
38 : #include <macros/generic.hxx>
39 : #include <macros/xinterface.hxx>
40 : #include <macros/xtypeprovider.hxx>
41 : #include <macros/xserviceinfo.hxx>
42 : #include <services.h>
43 :
44 : using namespace com::sun::star::uno;
45 : using namespace com::sun::star::lang;
46 : using namespace com::sun::star::frame;
47 : using namespace com::sun::star::beans;
48 : using namespace com::sun::star::util;
49 : using namespace ::com::sun::star::ui;
50 : using namespace framework;
51 :
52 : namespace {
53 :
54 : class AddonsToolBarFactory : public ::cppu::WeakImplHelper2< css::lang::XServiceInfo ,
55 : css::ui::XUIElementFactory >
56 : {
57 : public:
58 : AddonsToolBarFactory( const css::uno::Reference< css::uno::XComponentContext >& xContext );
59 : virtual ~AddonsToolBarFactory();
60 :
61 0 : virtual OUString SAL_CALL getImplementationName()
62 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
63 : {
64 0 : return OUString("com.sun.star.comp.framework.AddonsToolBarFactory");
65 : }
66 :
67 0 : virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
68 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
69 : {
70 0 : return cppu::supportsService(this, ServiceName);
71 : }
72 :
73 0 : virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
74 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
75 : {
76 0 : css::uno::Sequence< OUString > aSeq(1);
77 0 : aSeq[0] = "com.sun.star.ui.ToolBarFactory";
78 0 : return aSeq;
79 : }
80 :
81 : // XUIElementFactory
82 : virtual css::uno::Reference< css::ui::XUIElement > SAL_CALL createUIElement( const OUString& ResourceURL, const css::uno::Sequence< css::beans::PropertyValue >& Args ) throw ( css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
83 :
84 : bool hasButtonsInContext( const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > >& rPropSeq,
85 : const css::uno::Reference< css::frame::XFrame >& rFrame );
86 :
87 : private:
88 : css::uno::Reference< css::uno::XComponentContext > m_xContext;
89 : css::uno::Reference< css::frame::XModuleManager2 > m_xModuleManager;
90 : };
91 :
92 6568 : AddonsToolBarFactory::AddonsToolBarFactory(
93 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ) :
94 : m_xContext( xContext )
95 6568 : , m_xModuleManager( ModuleManager::create( xContext ) )
96 : {
97 6568 : }
98 :
99 13136 : AddonsToolBarFactory::~AddonsToolBarFactory()
100 : {
101 13136 : }
102 :
103 8068 : static bool IsCorrectContext( const OUString& rModuleIdentifier, const OUString& aContextList )
104 : {
105 8068 : if ( aContextList.isEmpty() )
106 0 : return true;
107 :
108 8068 : if ( !rModuleIdentifier.isEmpty() )
109 : {
110 8068 : sal_Int32 nIndex = aContextList.indexOf( rModuleIdentifier );
111 8068 : return ( nIndex >= 0 );
112 : }
113 :
114 0 : return false;
115 : }
116 :
117 3289 : bool AddonsToolBarFactory::hasButtonsInContext(
118 : const Sequence< Sequence< PropertyValue > >& rPropSeqSeq,
119 : const Reference< XFrame >& rFrame )
120 : {
121 3289 : OUString aModuleIdentifier;
122 : try
123 : {
124 3289 : aModuleIdentifier = m_xModuleManager->identify( rFrame );
125 : }
126 0 : catch ( const RuntimeException& )
127 : {
128 0 : throw;
129 : }
130 0 : catch ( const Exception& )
131 : {
132 : }
133 :
134 : // Check before we create a toolbar that we have at least one button in
135 : // the current frame context.
136 8599 : for ( sal_uInt32 i = 0; i < (sal_uInt32)rPropSeqSeq.getLength(); i++ )
137 : {
138 8068 : bool bIsButton( true );
139 8068 : bool bIsCorrectContext( false );
140 8068 : sal_uInt32 nPropChecked( 0 );
141 :
142 8068 : const Sequence< PropertyValue >& rPropSeq = rPropSeqSeq[i];
143 40340 : for ( sal_uInt32 j = 0; j < (sal_uInt32)rPropSeq.getLength(); j++ )
144 : {
145 40340 : if ( rPropSeq[j].Name == "Context" )
146 : {
147 8068 : OUString aContextList;
148 8068 : if ( rPropSeq[j].Value >>= aContextList )
149 8068 : bIsCorrectContext = IsCorrectContext( aModuleIdentifier, aContextList );
150 8068 : nPropChecked++;
151 : }
152 32272 : else if ( rPropSeq[j].Name == "URL" )
153 : {
154 8068 : OUString aURL;
155 8068 : rPropSeq[j].Value >>= aURL;
156 8068 : bIsButton = aURL != "private:separator";
157 8068 : nPropChecked++;
158 : }
159 :
160 40340 : if ( nPropChecked == 2 )
161 8068 : break;
162 : }
163 :
164 8068 : if ( bIsButton && bIsCorrectContext )
165 2758 : return true;
166 : }
167 :
168 531 : return false;
169 : }
170 :
171 : // XUIElementFactory
172 6568 : Reference< XUIElement > SAL_CALL AddonsToolBarFactory::createUIElement(
173 : const OUString& ResourceURL,
174 : const Sequence< PropertyValue >& Args )
175 : throw ( ::com::sun::star::container::NoSuchElementException,
176 : ::com::sun::star::lang::IllegalArgumentException,
177 : ::com::sun::star::uno::RuntimeException, std::exception )
178 : {
179 6568 : SolarMutexGuard g;
180 :
181 13136 : Sequence< Sequence< PropertyValue > > aConfigData;
182 13136 : Reference< XFrame > xFrame;
183 13136 : OUString aResourceURL( ResourceURL );
184 :
185 19704 : for ( sal_Int32 n = 0; n < Args.getLength(); n++ )
186 : {
187 13136 : if ( Args[n].Name == "ConfigurationData" )
188 6568 : Args[n].Value >>= aConfigData;
189 6568 : else if ( Args[n].Name == "Frame" )
190 6568 : Args[n].Value >>= xFrame;
191 0 : else if ( Args[n].Name == "ResourceURL" )
192 0 : Args[n].Value >>= aResourceURL;
193 : }
194 :
195 6568 : if ( !aResourceURL.startsWith("private:resource/toolbar/addon_") )
196 0 : throw IllegalArgumentException();
197 :
198 : // Identify frame and determine module identifier to look for context based buttons
199 6568 : Reference< ::com::sun::star::ui::XUIElement > xToolBar;
200 16425 : if ( xFrame.is() &&
201 9857 : ( aConfigData.getLength()> 0 ) &&
202 3289 : hasButtonsInContext( aConfigData, xFrame ))
203 : {
204 2758 : PropertyValue aPropValue;
205 5516 : Sequence< Any > aPropSeq( 3 );
206 2758 : aPropValue.Name = "Frame";
207 2758 : aPropValue.Value <<= xFrame;
208 2758 : aPropSeq[0] <<= aPropValue;
209 2758 : aPropValue.Name = "ConfigurationData";
210 2758 : aPropValue.Value <<= aConfigData;
211 2758 : aPropSeq[1] <<= aPropValue;
212 2758 : aPropValue.Name = "ResourceURL";
213 2758 : aPropValue.Value <<= aResourceURL;
214 2758 : aPropSeq[2] <<= aPropValue;
215 :
216 5516 : SolarMutexGuard aGuard;
217 2758 : AddonsToolBarWrapper* pToolBarWrapper = new AddonsToolBarWrapper( m_xContext );
218 2758 : xToolBar = Reference< ::com::sun::star::ui::XUIElement >( static_cast<OWeakObject *>(pToolBarWrapper), UNO_QUERY );
219 5516 : Reference< XInitialization > xInit( xToolBar, UNO_QUERY );
220 5516 : xInit->initialize( aPropSeq );
221 : }
222 :
223 13136 : return xToolBar;
224 : }
225 :
226 : }
227 :
228 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
229 6568 : com_sun_star_comp_framework_AddonsToolBarFactory_get_implementation(
230 : css::uno::XComponentContext *context,
231 : css::uno::Sequence<css::uno::Any> const &)
232 : {
233 6568 : return cppu::acquire(new AddonsToolBarFactory(context));
234 : }
235 :
236 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|