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