xref: /AOO41X/main/framework/source/uielement/generictoolbarcontroller.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 #ifndef __FRAMEWORK_UIELEMENT_GENERICTOOLBARCONTROLLER_HXX
32 #include "uielement/generictoolbarcontroller.hxx"
33 #endif
34 
35 //_________________________________________________________________________________________________________________
36 //  my own includes
37 //_________________________________________________________________________________________________________________
38 
39 #ifndef __FRAMEWORK_TOOLBAR_HXX_
40 #include "uielement/toolbar.hxx"
41 #endif
42 
43 //_________________________________________________________________________________________________________________
44 //  interface includes
45 //_________________________________________________________________________________________________________________
46 #include <com/sun/star/util/XURLTransformer.hpp>
47 #include <com/sun/star/frame/XDispatchProvider.hpp>
48 #include <com/sun/star/beans/PropertyValue.hpp>
49 #include <com/sun/star/lang/DisposedException.hpp>
50 #include <com/sun/star/frame/status/ItemStatus.hpp>
51 #include <com/sun/star/frame/status/ItemState.hpp>
52 #include <com/sun/star/frame/status/Visibility.hpp>
53 
54 //_________________________________________________________________________________________________________________
55 //  other includes
56 //_________________________________________________________________________________________________________________
57 #include <svtools/toolboxcontroller.hxx>
58 #include <vos/mutex.hxx>
59 #include <vcl/svapp.hxx>
60 #ifndef _VCL_MNEMONIC_HXX_
61 #include <vcl/mnemonic.hxx>
62 #endif
63 #include <tools/urlobj.hxx>
64 #include <classes/resource.hrc>
65 #include <classes/fwkresid.hxx>
66 #include <dispatch/uieventloghelper.hxx>
67 
68 #include <framework/menuconfiguration.hxx>
69 #include <uielement/menubarmanager.hxx>
70 
71 using namespace ::com::sun::star::awt;
72 using namespace ::com::sun::star::uno;
73 using namespace ::com::sun::star::beans;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::frame;
76 using namespace ::com::sun::star::frame::status;
77 using namespace ::com::sun::star::util;
78 using namespace ::com::sun::star::container;
79 
80 namespace framework
81 {
82 
83 static sal_Bool isEnumCommand( const rtl::OUString& rCommand )
84 {
85     INetURLObject aURL( rCommand );
86 
87     if (( aURL.GetProtocol() == INET_PROT_UNO ) &&
88         ( aURL.GetURLPath().indexOf( '.' ) != -1))
89         return sal_True;
90 
91     return sal_False;
92 }
93 
94 static rtl::OUString getEnumCommand( const rtl::OUString& rCommand )
95 {
96     INetURLObject aURL( rCommand );
97 
98     rtl::OUString   aEnumCommand;
99     String          aURLPath = aURL.GetURLPath();
100     xub_StrLen      nIndex   = aURLPath.Search( '.' );
101     if (( nIndex > 0 ) && ( nIndex < aURLPath.Len() ))
102         aEnumCommand = aURLPath.Copy( nIndex+1 );
103 
104     return aEnumCommand;
105 }
106 
107 static rtl::OUString getMasterCommand( const rtl::OUString& rCommand )
108 {
109     rtl::OUString aMasterCommand( rCommand );
110     INetURLObject aURL( rCommand );
111     if ( aURL.GetProtocol() == INET_PROT_UNO )
112     {
113         sal_Int32 nIndex = aURL.GetURLPath().indexOf( '.' );
114         if ( nIndex )
115         {
116             aURL.SetURLPath( aURL.GetURLPath().copy( 0, nIndex ) );
117             aMasterCommand = aURL.GetMainURL( INetURLObject::NO_DECODE );
118         }
119     }
120     return aMasterCommand;
121 }
122 
123 struct ExecuteInfo
124 {
125     ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch >     xDispatch;
126     ::com::sun::star::util::URL                                                aTargetURL;
127     ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >  aArgs;
128 };
129 
130 GenericToolbarController::GenericToolbarController( const Reference< XMultiServiceFactory >& rServiceManager,
131                                                     const Reference< XFrame >&               rFrame,
132                                                     ToolBox*                                 pToolbar,
133                                                     sal_uInt16                                   nID,
134                                                     const ::rtl::OUString&                          aCommand ) :
135     svt::ToolboxController( rServiceManager, rFrame, aCommand )
136     ,   m_pToolbar( pToolbar )
137     ,   m_nID( nID )
138     ,   m_bEnumCommand( isEnumCommand( aCommand ))
139     ,   m_bMadeInvisible( sal_False )
140     ,   m_aEnumCommand( getEnumCommand( aCommand ))
141 {
142     if ( m_bEnumCommand )
143         addStatusListener( getMasterCommand( aCommand ) );
144 }
145 
146 GenericToolbarController::~GenericToolbarController()
147 {
148 }
149 
150 void SAL_CALL GenericToolbarController::dispose()
151 throw ( RuntimeException )
152 {
153     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
154 
155     svt::ToolboxController::dispose();
156 
157     m_pToolbar = 0;
158     m_nID = 0;
159 }
160 
161 void SAL_CALL GenericToolbarController::execute( sal_Int16 KeyModifier )
162 throw ( RuntimeException )
163 {
164     Reference< XDispatch >       xDispatch;
165     Reference< XURLTransformer > xURLTransformer;
166     ::rtl::OUString                     aCommandURL;
167 
168     {
169         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
170 
171         if ( m_bDisposed )
172             throw DisposedException();
173 
174         if ( m_bInitialized &&
175              m_xFrame.is() &&
176              m_xServiceManager.is() &&
177              m_aCommandURL.getLength() )
178         {
179             xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance(
180                                                                 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))),
181                                                             UNO_QUERY );
182 
183             aCommandURL = m_aCommandURL;
184             URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL );
185             if ( pIter != m_aListenerMap.end() )
186                 xDispatch = pIter->second;
187         }
188     }
189 
190     if ( xDispatch.is() && xURLTransformer.is() )
191     {
192         com::sun::star::util::URL aTargetURL;
193         Sequence<PropertyValue>   aArgs( 1 );
194 
195         // Add key modifier to argument list
196         aArgs[0].Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
197         aArgs[0].Value <<= KeyModifier;
198 
199         aTargetURL.Complete = aCommandURL;
200         xURLTransformer->parseStrict( aTargetURL );
201 
202         // Execute dispatch asynchronously
203         ExecuteInfo* pExecuteInfo = new ExecuteInfo;
204         pExecuteInfo->xDispatch     = xDispatch;
205         pExecuteInfo->aTargetURL    = aTargetURL;
206         pExecuteInfo->aArgs         = aArgs;
207         if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
208             UiEventLogHelper(::rtl::OUString::createFromAscii("GenericToolbarController")).log( m_xServiceManager, m_xFrame, aTargetURL, aArgs);
209         Application::PostUserEvent( STATIC_LINK(0, GenericToolbarController , ExecuteHdl_Impl), pExecuteInfo );
210     }
211 }
212 
213 void GenericToolbarController::statusChanged( const FeatureStateEvent& Event )
214 throw ( RuntimeException )
215 {
216     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
217 
218     if ( m_bDisposed )
219         return;
220 
221     if ( m_pToolbar )
222     {
223         m_pToolbar->EnableItem( m_nID, Event.IsEnabled );
224 
225         sal_uInt16 nItemBits = m_pToolbar->GetItemBits( m_nID );
226         nItemBits &= ~TIB_CHECKABLE;
227         TriState eTri = STATE_NOCHECK;
228 
229         sal_Bool        bValue = sal_Bool();
230         rtl::OUString   aStrValue;
231         ItemStatus      aItemState;
232         Visibility      aItemVisibility;
233 
234         if (( Event.State >>= bValue ) && !m_bEnumCommand )
235         {
236             // Boolean, treat it as checked/unchecked
237             if ( m_bMadeInvisible )
238                 m_pToolbar->ShowItem( m_nID, sal_True );
239             m_pToolbar->CheckItem( m_nID, bValue );
240             if ( bValue )
241                 eTri = STATE_CHECK;
242             nItemBits |= TIB_CHECKABLE;
243         }
244         else if ( Event.State >>= aStrValue )
245         {
246             if ( m_bEnumCommand )
247             {
248                 if ( aStrValue == m_aEnumCommand )
249                     bValue = sal_True;
250                 else
251                     bValue = sal_False;
252 
253                 m_pToolbar->CheckItem( m_nID, bValue );
254                 if ( bValue )
255                     eTri = STATE_CHECK;
256                 nItemBits |= TIB_CHECKABLE;
257             }
258             else
259             {
260                 // Replacement for place holders
261                 if ( aStrValue.matchAsciiL( "($1)", 4 ))
262                 {
263 				    String aResStr = String( FwkResId( STR_UPDATEDOC ));
264                     rtl::OUString aTmp( aResStr );
265                     aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
266                     aTmp += aStrValue.copy( 4 );
267                     aStrValue = aTmp;
268                 }
269                 else if ( aStrValue.matchAsciiL( "($2)", 4 ))
270                 {
271 				    String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN ));
272                     rtl::OUString aTmp( aResStr );
273                     aTmp += aStrValue.copy( 4 );
274                     aStrValue = aTmp;
275                 }
276                 else if ( aStrValue.matchAsciiL( "($3)", 4 ))
277                 {
278 				    String aResStr = String( FwkResId( STR_SAVECOPYDOC ));
279                     rtl::OUString aTmp( aResStr );
280                     aTmp += aStrValue.copy( 4 );
281                     aStrValue = aTmp;
282                 }
283                 ::rtl::OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) );
284                 m_pToolbar->SetItemText( m_nID, aText );
285                 m_pToolbar->SetQuickHelpText( m_nID, aText );
286             }
287 
288             if ( m_bMadeInvisible )
289                 m_pToolbar->ShowItem( m_nID, sal_True );
290         }
291         else if (( Event.State >>= aItemState ) && !m_bEnumCommand )
292         {
293             eTri = STATE_DONTKNOW;
294             nItemBits |= TIB_CHECKABLE;
295             if ( m_bMadeInvisible )
296                 m_pToolbar->ShowItem( m_nID, sal_True );
297         }
298         else if ( Event.State >>= aItemVisibility )
299         {
300             m_pToolbar->ShowItem( m_nID, aItemVisibility.bVisible );
301             m_bMadeInvisible = !aItemVisibility.bVisible;
302         }
303         else if ( m_bMadeInvisible )
304             m_pToolbar->ShowItem( m_nID, sal_True );
305 
306         m_pToolbar->SetItemState( m_nID, eTri );
307         m_pToolbar->SetItemBits( m_nID, nItemBits );
308     }
309 }
310 
311 IMPL_STATIC_LINK_NOINSTANCE( GenericToolbarController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
312 {
313    const sal_uInt32 nRef = Application::ReleaseSolarMutex();
314    try
315    {
316         // Asynchronous execution as this can lead to our own destruction!
317         // Framework can recycle our current frame and the layout manager disposes all user interface
318         // elements if a component gets detached from its frame!
319         pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
320    }
321    catch ( Exception& )
322    {
323    }
324 
325    Application::AcquireSolarMutex( nRef );
326    delete pExecuteInfo;
327    return 0;
328 }
329 
330 MenuToolbarController::MenuToolbarController( const Reference< XMultiServiceFactory >& rServiceManager, const Reference< XFrame >& rFrame, ToolBox* pToolBar, sal_uInt16   nID, const rtl::OUString& aCommand, const rtl::OUString& aModuleIdentifier, const Reference< XIndexAccess >& xMenuDesc ) : GenericToolbarController( rServiceManager, rFrame, pToolBar, nID, aCommand ), m_xMenuDesc( xMenuDesc ), pMenu( NULL ), m_aModuleIdentifier( aModuleIdentifier )
331 {
332 }
333 
334 MenuToolbarController::~MenuToolbarController()
335 {
336     try
337     {
338         if ( m_xMenuManager.is() )
339             m_xMenuManager->dispose();
340     }
341     catch( Exception& ) {}
342     if ( pMenu )
343     {
344         delete pMenu;
345         pMenu = NULL;
346     }
347 
348 }
349 
350 class Toolbarmenu : public PopupMenu
351 {
352     public:
353     Toolbarmenu();
354     ~Toolbarmenu();
355 };
356 
357 Toolbarmenu::Toolbarmenu()
358 {
359     OSL_TRACE("**** contstructing Toolbarmenu 0x%x", this );
360 }
361 
362 Toolbarmenu::~Toolbarmenu()
363 {
364     OSL_TRACE("**** destructing Toolbarmenu 0x%x", this );
365 }
366 
367 void SAL_CALL MenuToolbarController::click() throw (RuntimeException)
368 {
369     createPopupWindow();
370 }
371 
372 Reference< XWindow > SAL_CALL
373 MenuToolbarController::createPopupWindow() throw (::com::sun::star::uno::RuntimeException)
374 {
375     if ( !pMenu )
376     {
377         Reference< XDispatchProvider > xDispatch;
378         Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY );
379         pMenu = new Toolbarmenu();
380         m_xMenuManager.set( new MenuBarManager( m_xServiceManager, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, sal_True, sal_True ) );
381         if ( m_xMenuManager.is() )
382         {
383             MenuBarManager* pMgr = dynamic_cast< MenuBarManager* >( m_xMenuManager.get() );
384             pMgr->SetItemContainer( m_xMenuDesc );
385         }
386     }
387 
388     ::Rectangle aRect( m_pToolbar->GetItemRect( m_nID ) );
389     pMenu->Execute( m_pToolbar, aRect, POPUPMENU_EXECUTE_DOWN );
390     return NULL;
391 }
392 } // namespace
393 
394