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 76 MacrosMenuController::~MacrosMenuController() 77 { 78 OSL_TRACE("calling dtor"); 79 } 80 81 // private function 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 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 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 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 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 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 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