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 #include <uielement/macrosmenucontroller.hxx>
28 #include <uielement/menubarmanager.hxx>
29 #include <threadhelp/resetableguard.hxx>
30 #include "services.h"
31 #include <classes/resource.hrc>
32 #include <classes/fwkresid.hxx>
33 #include <framework/imageproducer.hxx>
34 #include <com/sun/star/awt/MenuItemStyle.hpp>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
38 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
39 #include <com/sun/star/frame/XModuleManager.hpp>
40 #include <comphelper/processfactory.hxx>
41 #include <vcl/svapp.hxx>
42 #include <vcl/i18nhelp.hxx>
43 #include <tools/urlobj.hxx>
44 #include <rtl/ustrbuf.hxx>
45 #include <dispatch/uieventloghelper.hxx>
46 #include "helper/mischelper.hxx"
47 #include "helpid.hrc"
48 #include <vos/mutex.hxx>
49
50 using namespace com::sun::star::uno;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::frame;
53 using namespace com::sun::star::beans;
54 using namespace com::sun::star::util;
55 using namespace com::sun::star::style;
56 using namespace com::sun::star::container;
57 using namespace ::com::sun::star::frame;
58
59 namespace framework
60 {
61 class
62 DEFINE_XSERVICEINFO_MULTISERVICE ( MacrosMenuController ,
63 OWeakObject ,
64 SERVICENAME_POPUPMENUCONTROLLER ,
65 IMPLEMENTATIONNAME_MACROSMENUCONTROLLER
66 )
67
68 DEFINE_INIT_SERVICE ( MacrosMenuController, {} )
69
70 MacrosMenuController::MacrosMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
71 svt::PopupMenuControllerBase( xServiceManager ),
72 m_xServiceManager( xServiceManager)
73 {
74 }
75
~MacrosMenuController()76 MacrosMenuController::~MacrosMenuController()
77 {
78 OSL_TRACE("calling dtor");
79 }
80
81 // private function
fillPopupMenu(Reference<css::awt::XPopupMenu> & rPopupMenu)82 void MacrosMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
83 {
84 VCLXPopupMenu* pVCLPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
85 PopupMenu* pPopupMenu = 0;
86
87 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
88
89 resetPopupMenu( rPopupMenu );
90 if ( pVCLPopupMenu )
91 pPopupMenu = (PopupMenu *)pVCLPopupMenu->GetMenu();
92
93 if (!pPopupMenu)
94 return;
95
96 // insert basic
97 String aCommand = String::CreateFromAscii( ".uno:MacroDialog" );
98 String aDisplayName = RetrieveLabelFromCommand( aCommand );
99 pPopupMenu->InsertItem( 2, aDisplayName );
100 pPopupMenu->SetItemCommand( 2, aCommand );
101
102 // insert providers but not basic or java
103 addScriptItems( pPopupMenu, 4);
104 }
105
106 // XEventListener
disposing(const EventObject &)107 void SAL_CALL MacrosMenuController::disposing( const EventObject& ) throw ( RuntimeException )
108 {
109 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
110
111 osl::MutexGuard aLock( m_aMutex );
112 OSL_TRACE("disposing");
113 m_xFrame.clear();
114 m_xDispatch.clear();
115 m_xServiceManager.clear();
116
117 if ( m_xPopupMenu.is() )
118 {
119 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
120 OSL_TRACE("removed listener");
121 }
122 m_xPopupMenu.clear();
123 }
124
125 // XStatusListener
statusChanged(const FeatureStateEvent &)126 void SAL_CALL MacrosMenuController::statusChanged( const FeatureStateEvent& ) throw ( RuntimeException )
127 {
128 osl::MutexGuard aLock( m_aMutex );
129 if ( m_xPopupMenu.is() )
130 {
131 fillPopupMenu( m_xPopupMenu );
132 }
133 }
134
135 // XMenuListener
impl_select(const Reference<XDispatch> &,const::com::sun::star::util::URL & aTargetURL)136 void MacrosMenuController::impl_select(const Reference< XDispatch >& /*_xDispatch*/,const ::com::sun::star::util::URL& aTargetURL)
137 {
138 // need to requery, since we handle more than one type of Command
139 // if we don't do this only .uno:ScriptOrganizer commands are executed
140 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
141 Reference< XDispatch > xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
142 if( xDispatch.is() )
143 {
144 ExecuteInfo* pExecuteInfo = new ExecuteInfo;
145 pExecuteInfo->xDispatch = xDispatch;
146 pExecuteInfo->aTargetURL = aTargetURL;
147 //pExecuteInfo->aArgs = aArgs;
148 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
149 UiEventLogHelper(::rtl::OUString::createFromAscii("MacrosMenuController")).log(m_xServiceManager, m_xFrame, aTargetURL, pExecuteInfo->aArgs);
150 // xDispatch->dispatch( aTargetURL, aArgs );
151 Application::PostUserEvent( STATIC_LINK(0, MacrosMenuController , ExecuteHdl_Impl), pExecuteInfo );
152 }
153 else
154 {
155 }
156 }
157
158
IMPL_STATIC_LINK_NOINSTANCE(MacrosMenuController,ExecuteHdl_Impl,ExecuteInfo *,pExecuteInfo)159 IMPL_STATIC_LINK_NOINSTANCE( MacrosMenuController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
160 {
161 try
162 {
163 // Asynchronous execution as this can lead to our own destruction!
164 // Framework can recycle our current frame and the layout manager disposes all user interface
165 // elements if a component gets detached from its frame!
166 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
167 }
168 catch ( Exception& )
169 {
170 }
171 delete pExecuteInfo;
172 return 0;
173 }
174
RetrieveLabelFromCommand(const String & aCmdURL)175 String MacrosMenuController::RetrieveLabelFromCommand( const String& aCmdURL )
176 {
177 sal_Bool bModuleIdentified = m_aModuleIdentifier.getLength() != 0;
178 return framework::RetrieveLabelFromCommand(aCmdURL,m_xServiceManager,m_xUICommandLabels,m_xFrame,m_aModuleIdentifier,bModuleIdentified,"Label");
179 }
180
addScriptItems(PopupMenu * pPopupMenu,sal_uInt16 startItemId)181 void MacrosMenuController::addScriptItems( PopupMenu* pPopupMenu, sal_uInt16 startItemId )
182 {
183 const String aCmdBase = String::CreateFromAscii( ".uno:ScriptOrganizer?ScriptOrganizer.Language:string=" );
184 const String ellipsis = String::CreateFromAscii( "..." );
185 const ::rtl::OUString providerKey =
186 ::rtl::OUString::createFromAscii("com.sun.star.script.provider.ScriptProviderFor" );
187 const ::rtl::OUString languageProviderName =
188 ::rtl::OUString::createFromAscii("com.sun.star.script.provider.LanguageScriptProvider" );
189 sal_uInt16 itemId = startItemId;
190 Reference< XContentEnumerationAccess > xEnumAccess = Reference< XContentEnumerationAccess >( m_xServiceManager, UNO_QUERY_THROW );
191 Reference< XEnumeration > xEnum = xEnumAccess->createContentEnumeration ( languageProviderName );
192
193 while ( xEnum->hasMoreElements() )
194 {
195 Reference< XServiceInfo > xServiceInfo;
196 if ( sal_False == ( xEnum->nextElement() >>= xServiceInfo ) )
197 {
198 break;
199 }
200 Sequence< ::rtl::OUString > serviceNames = xServiceInfo->getSupportedServiceNames();
201
202 if ( serviceNames.getLength() > 0 )
203 {
204 for ( sal_Int32 index = 0; index < serviceNames.getLength(); index++ )
205 {
206 if ( serviceNames[ index ].indexOf( providerKey ) == 0 )
207 {
208 ::rtl::OUString serviceName = serviceNames[ index ];
209 String aCommand = aCmdBase;
210 String aDisplayName = String( serviceName.copy( providerKey.getLength() ) );
211 if( aDisplayName.Equals( String::CreateFromAscii( "Java" ) ) || aDisplayName.Equals( String::CreateFromAscii( "Basic" ) ) )
212 {
213 // no entries for Java & Basic added elsewhere
214 break;
215 }
216 aCommand.Append( aDisplayName );
217 aDisplayName.Append( ellipsis );
218 pPopupMenu->InsertItem( itemId, aDisplayName );
219 pPopupMenu->SetItemCommand( itemId, aCommand );
220 itemId++;
221 break;
222 }
223 }
224 }
225 }
226 }
227
228 }
229