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/complextoolbarcontroller.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 : : #include <com/sun/star/frame/XControlNotificationListener.hpp>
43 : :
44 : : #include <comphelper/componentcontext.hxx>
45 : : #include <svtools/toolboxcontroller.hxx>
46 : : #include <osl/mutex.hxx>
47 : : #include <vcl/svapp.hxx>
48 : : #include <vcl/mnemonic.hxx>
49 : :
50 : : using namespace ::com::sun::star;
51 : : using namespace ::com::sun::star::awt;
52 : : using namespace ::com::sun::star::uno;
53 : : using namespace ::com::sun::star::beans;
54 : : using namespace ::com::sun::star::lang;
55 : : using namespace ::com::sun::star::frame;
56 : : using namespace ::com::sun::star::frame::status;
57 : : using namespace ::com::sun::star::util;
58 : :
59 : : namespace framework
60 : : {
61 : :
62 : : // ------------------------------------------------------------------
63 : :
64 : 0 : ComplexToolbarController::ComplexToolbarController(
65 : : const Reference< XMultiServiceFactory >& rServiceManager,
66 : : const Reference< XFrame >& rFrame,
67 : : ToolBox* pToolbar,
68 : : sal_uInt16 nID,
69 : : const ::rtl::OUString& aCommand ) :
70 : : svt::ToolboxController( rServiceManager, rFrame, aCommand )
71 : : , m_pToolbar( pToolbar )
72 : : , m_nID( nID )
73 : 0 : , m_bMadeInvisible( sal_False )
74 : : {
75 [ # # ][ # # ]: 0 : m_xURLTransformer.set( URLTransformer::create(::comphelper::ComponentContext(m_xServiceManager).getUNOContext()) );
[ # # ][ # # ]
[ # # ]
76 : 0 : }
77 : :
78 : : // ------------------------------------------------------------------
79 : :
80 : 0 : ComplexToolbarController::~ComplexToolbarController()
81 : : {
82 [ # # ]: 0 : }
83 : :
84 : : // ------------------------------------------------------------------
85 : :
86 : 0 : void SAL_CALL ComplexToolbarController::dispose()
87 : : throw ( RuntimeException )
88 : : {
89 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
90 : :
91 [ # # ]: 0 : m_pToolbar->SetItemWindow( m_nID, 0 );
92 [ # # ]: 0 : svt::ToolboxController::dispose();
93 : :
94 : 0 : m_xURLTransformer.clear();
95 : 0 : m_pToolbar = 0;
96 [ # # ]: 0 : m_nID = 0;
97 : 0 : }
98 : :
99 : : // ------------------------------------------------------------------
100 : 0 : Sequence<PropertyValue> ComplexToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
101 : : {
102 : 0 : Sequence<PropertyValue> aArgs( 1 );
103 : :
104 : : // Add key modifier to argument list
105 [ # # ]: 0 : aArgs[0].Name = rtl::OUString( "KeyModifier" );
106 [ # # ][ # # ]: 0 : aArgs[0].Value <<= KeyModifier;
107 : 0 : return aArgs;
108 : : }
109 : : // -----------------------------------------------------------------------------
110 : 0 : void SAL_CALL ComplexToolbarController::execute( sal_Int16 KeyModifier )
111 : : throw ( RuntimeException )
112 : : {
113 : 0 : Reference< XDispatch > xDispatch;
114 : 0 : Reference< XURLTransformer > xURLTransformer;
115 : 0 : ::rtl::OUString aCommandURL;
116 : 0 : ::com::sun::star::util::URL aTargetURL;
117 [ # # ]: 0 : Sequence<PropertyValue> aArgs;
118 : :
119 : : {
120 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
121 : :
122 [ # # ]: 0 : if ( m_bDisposed )
123 [ # # ]: 0 : throw DisposedException();
124 : :
125 [ # # # # : 0 : if ( m_bInitialized &&
# # # # ]
[ # # ]
126 : 0 : m_xFrame.is() &&
127 : 0 : m_xServiceManager.is() &&
128 : 0 : !m_aCommandURL.isEmpty() )
129 : : {
130 [ # # ]: 0 : xURLTransformer = m_xURLTransformer;
131 [ # # ][ # # ]: 0 : xDispatch = getDispatchFromCommand( m_aCommandURL );
132 : 0 : aCommandURL = m_aCommandURL;
133 [ # # ]: 0 : aTargetURL = getInitializedURL();
134 [ # # ][ # # ]: 0 : aArgs = getExecuteArgs(KeyModifier);
[ # # ]
135 [ # # ]: 0 : }
136 : : }
137 : :
138 [ # # ][ # # ]: 0 : if ( xDispatch.is() && !aTargetURL.Complete.isEmpty() )
[ # # ]
139 : : {
140 : : // Execute dispatch asynchronously
141 [ # # ][ # # ]: 0 : ExecuteInfo* pExecuteInfo = new ExecuteInfo;
142 [ # # ]: 0 : pExecuteInfo->xDispatch = xDispatch;
143 : 0 : pExecuteInfo->aTargetURL = aTargetURL;
144 [ # # ]: 0 : pExecuteInfo->aArgs = aArgs;
145 [ # # ][ # # ]: 0 : Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController , ExecuteHdl_Impl), pExecuteInfo );
146 [ # # ]: 0 : }
147 : 0 : }
148 : :
149 : : // ------------------------------------------------------------------
150 : :
151 : 0 : void ComplexToolbarController::statusChanged( const FeatureStateEvent& Event )
152 : : throw ( RuntimeException )
153 : : {
154 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
155 : :
156 [ # # ]: 0 : if ( m_bDisposed )
157 : 0 : return;
158 : :
159 [ # # ]: 0 : if ( m_pToolbar )
160 : : {
161 [ # # ]: 0 : m_pToolbar->EnableItem( m_nID, Event.IsEnabled );
162 : :
163 [ # # ]: 0 : sal_uInt16 nItemBits = m_pToolbar->GetItemBits( m_nID );
164 : 0 : nItemBits &= ~TIB_CHECKABLE;
165 : 0 : TriState eTri = STATE_NOCHECK;
166 : :
167 : 0 : sal_Bool bValue = sal_Bool();
168 : 0 : rtl::OUString aStrValue;
169 : 0 : ItemStatus aItemState;
170 : 0 : Visibility aItemVisibility;
171 [ # # ]: 0 : ControlCommand aControlCommand;
172 : :
173 [ # # ]: 0 : if ( Event.State >>= bValue )
174 : : {
175 : : // Boolean, treat it as checked/unchecked
176 [ # # ]: 0 : if ( m_bMadeInvisible )
177 [ # # ]: 0 : m_pToolbar->ShowItem( m_nID, sal_True );
178 [ # # ]: 0 : m_pToolbar->CheckItem( m_nID, bValue );
179 [ # # ]: 0 : if ( bValue )
180 : 0 : eTri = STATE_CHECK;
181 : 0 : nItemBits |= TIB_CHECKABLE;
182 : : }
183 [ # # ]: 0 : else if ( Event.State >>= aStrValue )
184 : : {
185 [ # # ][ # # ]: 0 : ::rtl::OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) );
[ # # ][ # # ]
[ # # ]
186 [ # # ][ # # ]: 0 : m_pToolbar->SetItemText( m_nID, aText );
[ # # ]
187 [ # # ][ # # ]: 0 : m_pToolbar->SetQuickHelpText( m_nID, aText );
[ # # ]
188 : :
189 [ # # ]: 0 : if ( m_bMadeInvisible )
190 [ # # ]: 0 : m_pToolbar->ShowItem( m_nID, sal_True );
191 : : }
192 [ # # ][ # # ]: 0 : else if ( Event.State >>= aItemState )
193 : : {
194 : 0 : eTri = STATE_DONTKNOW;
195 : 0 : nItemBits |= TIB_CHECKABLE;
196 [ # # ]: 0 : if ( m_bMadeInvisible )
197 [ # # ]: 0 : m_pToolbar->ShowItem( m_nID, sal_True );
198 : : }
199 [ # # ][ # # ]: 0 : else if ( Event.State >>= aItemVisibility )
200 : : {
201 [ # # ]: 0 : m_pToolbar->ShowItem( m_nID, aItemVisibility.bVisible );
202 : 0 : m_bMadeInvisible = !aItemVisibility.bVisible;
203 : : }
204 [ # # ][ # # ]: 0 : else if ( Event.State >>= aControlCommand )
205 : : {
206 [ # # ]: 0 : executeControlCommand( aControlCommand );
207 [ # # ]: 0 : if ( m_bMadeInvisible )
208 [ # # ]: 0 : m_pToolbar->ShowItem( m_nID, sal_True );
209 : : }
210 : :
211 [ # # ]: 0 : else if ( m_bMadeInvisible )
212 [ # # ]: 0 : m_pToolbar->ShowItem( m_nID, sal_True );
213 : :
214 [ # # ]: 0 : m_pToolbar->SetItemState( m_nID, eTri );
215 [ # # ][ # # ]: 0 : m_pToolbar->SetItemBits( m_nID, nItemBits );
216 [ # # ][ # # ]: 0 : }
217 : : }
218 : :
219 : : // ------------------------------------------------------------------
220 : :
221 : 0 : IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo )
222 : : {
223 : 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
224 : : try
225 : : {
226 : : // Asynchronous execution as this can lead to our own destruction!
227 : : // Framework can recycle our current frame and the layout manager disposes all user interface
228 : : // elements if a component gets detached from its frame!
229 [ # # ][ # # ]: 0 : pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs );
230 : : }
231 : 0 : catch ( const Exception& )
232 : : {
233 : : }
234 : :
235 : 0 : Application::AcquireSolarMutex( nRef );
236 [ # # ]: 0 : delete pExecuteInfo;
237 [ # # ]: 0 : return 0;
238 : : }
239 : :
240 : : // ------------------------------------------------------------------
241 : :
242 : 0 : IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController, Notify_Impl, NotifyInfo*, pNotifyInfo )
243 : : {
244 : 0 : const sal_uInt32 nRef = Application::ReleaseSolarMutex();
245 : : try
246 : : {
247 : : // Asynchronous execution: As this can lead to our own destruction!
248 : : // Framework can recycle our current frame and the layout manager disposes all user interface
249 : : // elements if a component gets detached from its frame!
250 [ # # ]: 0 : frame::ControlEvent aEvent;
251 : 0 : aEvent.aURL = pNotifyInfo->aSourceURL;
252 : 0 : aEvent.Event = pNotifyInfo->aEventName;
253 [ # # ]: 0 : aEvent.aInformation = pNotifyInfo->aInfoSeq;
254 [ # # ][ # # ]: 0 : pNotifyInfo->xNotifyListener->controlEvent( aEvent );
[ # # ][ # # ]
255 : : }
256 : 0 : catch ( const Exception& )
257 : : {
258 : : }
259 : :
260 : 0 : Application::AcquireSolarMutex( nRef );
261 [ # # ]: 0 : delete pNotifyInfo;
262 : 0 : return 0;
263 : : }
264 : :
265 : : // ------------------------------------------------------------------
266 : :
267 : 0 : void ComplexToolbarController::addNotifyInfo(
268 : : const rtl::OUString& aEventName,
269 : : const uno::Reference< frame::XDispatch >& xDispatch,
270 : : const uno::Sequence< beans::NamedValue >& rInfo )
271 : : {
272 [ # # ]: 0 : uno::Reference< frame::XControlNotificationListener > xControlNotify( xDispatch, uno::UNO_QUERY );
273 : :
274 [ # # ]: 0 : if ( xControlNotify.is() )
275 : : {
276 : : // Execute notification asynchronously
277 [ # # ][ # # ]: 0 : NotifyInfo* pNotifyInfo = new NotifyInfo;
278 : :
279 : 0 : pNotifyInfo->aEventName = aEventName;
280 [ # # ]: 0 : pNotifyInfo->xNotifyListener = xControlNotify;
281 [ # # ]: 0 : pNotifyInfo->aSourceURL = getInitializedURL();
282 : :
283 : : // Add frame as source to the information sequence
284 : 0 : sal_Int32 nCount = rInfo.getLength();
285 [ # # ]: 0 : uno::Sequence< beans::NamedValue > aInfoSeq( rInfo );
286 [ # # ]: 0 : aInfoSeq.realloc( nCount+1 );
287 [ # # ]: 0 : aInfoSeq[nCount].Name = ::rtl::OUString( "Source" );
288 [ # # ][ # # ]: 0 : aInfoSeq[nCount].Value = uno::makeAny( getFrameInterface() );
[ # # ]
289 [ # # ]: 0 : pNotifyInfo->aInfoSeq = aInfoSeq;
290 : :
291 [ # # ][ # # ]: 0 : Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController, Notify_Impl), pNotifyInfo );
[ # # ]
292 : 0 : }
293 : 0 : }
294 : :
295 : : // --------------------------------------------------------
296 : 0 : sal_Int32 ComplexToolbarController::getFontSizePixel( const Window* pWindow )
297 : : {
298 [ # # ]: 0 : const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
299 : 0 : const Font& rFont = rSettings.GetAppFont();
300 : :
301 : : // Calculate height of the application font used by window
302 [ # # ]: 0 : sal_Int32 nHeight = sal_Int32( rFont.GetHeight() );
303 [ # # ][ # # ]: 0 : ::Size aPixelSize = pWindow->LogicToPixel( ::Size( 0, nHeight ), MAP_APPFONT );
[ # # ]
304 : 0 : return aPixelSize.Height();
305 : : }
306 : :
307 : : // --------------------------------------------------------
308 : :
309 : 0 : uno::Reference< frame::XDispatch > ComplexToolbarController::getDispatchFromCommand( const rtl::OUString& aCommand ) const
310 : : {
311 : 0 : uno::Reference< frame::XDispatch > xDispatch;
312 : :
313 [ # # ][ # # ]: 0 : if ( m_bInitialized && m_xFrame.is() && m_xServiceManager.is() && !aCommand.isEmpty() )
[ # # ][ # # ]
[ # # ]
314 : : {
315 [ # # ]: 0 : URLToDispatchMap::const_iterator pIter = m_aListenerMap.find( aCommand );
316 [ # # ][ # # ]: 0 : if ( pIter != m_aListenerMap.end() )
317 [ # # ][ # # ]: 0 : xDispatch = pIter->second;
318 : : }
319 : :
320 : 0 : return xDispatch;
321 : : }
322 : :
323 : : // --------------------------------------------------------
324 : :
325 : 0 : const ::com::sun::star::util::URL& ComplexToolbarController::getInitializedURL()
326 : : {
327 [ # # ]: 0 : if ( m_aURL.Complete.isEmpty() )
328 : : {
329 : 0 : m_aURL.Complete = m_aCommandURL;
330 : 0 : m_xURLTransformer->parseStrict( m_aURL );
331 : : }
332 : 0 : return m_aURL;
333 : : }
334 : :
335 : 0 : void ComplexToolbarController::notifyFocusGet()
336 : : {
337 : : // send focus get notification
338 [ # # ]: 0 : uno::Sequence< beans::NamedValue > aInfo;
339 : : addNotifyInfo( rtl::OUString( "FocusSet" ),
340 : : getDispatchFromCommand( m_aCommandURL ),
341 [ # # ][ # # ]: 0 : aInfo );
[ # # ]
342 : 0 : }
343 : :
344 : 0 : void ComplexToolbarController::notifyFocusLost()
345 : : {
346 : : // send focus lost notification
347 [ # # ]: 0 : uno::Sequence< beans::NamedValue > aInfo;
348 : : addNotifyInfo( rtl::OUString( "FocusLost" ),
349 : : getDispatchFromCommand( m_aCommandURL ),
350 [ # # ][ # # ]: 0 : aInfo );
[ # # ]
351 : 0 : }
352 : :
353 : 0 : void ComplexToolbarController::notifyTextChanged( const ::rtl::OUString& aText )
354 : : {
355 : : // send text changed notification
356 [ # # ]: 0 : uno::Sequence< beans::NamedValue > aInfo( 1 );
357 [ # # ]: 0 : aInfo[0].Name = rtl::OUString( "Text" );
358 [ # # ][ # # ]: 0 : aInfo[0].Value <<= aText;
359 : : addNotifyInfo( rtl::OUString( "TextChanged" ),
360 : : getDispatchFromCommand( m_aCommandURL ),
361 [ # # ][ # # ]: 0 : aInfo );
[ # # ]
362 : 0 : }
363 : :
364 : : } // namespace
365 : :
366 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|