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