1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "uielement/complextoolbarcontroller.hxx"
23 #include <com/sun/star/util/URLTransformer.hpp>
24 #include <com/sun/star/util/XURLTransformer.hpp>
25 #include <com/sun/star/frame/XDispatchProvider.hpp>
26 #include <com/sun/star/beans/PropertyValue.hpp>
27 #include <com/sun/star/lang/DisposedException.hpp>
28 #include <com/sun/star/frame/status/ItemStatus.hpp>
29 #include <com/sun/star/frame/status/ItemState.hpp>
30 #include <com/sun/star/frame/status/Visibility.hpp>
31 #include <com/sun/star/frame/XControlNotificationListener.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <svtools/toolboxcontroller.hxx>
35 #include <osl/mutex.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/mnemonic.hxx>
38 #include <vcl/toolbox.hxx>
40 using namespace ::com::sun::star
;
41 using namespace ::com::sun::star::awt
;
42 using namespace ::com::sun::star::uno
;
43 using namespace ::com::sun::star::beans
;
44 using namespace ::com::sun::star::lang
;
45 using namespace ::com::sun::star::frame
;
46 using namespace ::com::sun::star::frame::status
;
47 using namespace ::com::sun::star::util
;
52 // ------------------------------------------------------------------
54 ComplexToolbarController::ComplexToolbarController(
55 const Reference
< XComponentContext
>& rxContext
,
56 const Reference
< XFrame
>& rFrame
,
59 const OUString
& aCommand
) :
60 svt::ToolboxController( rxContext
, rFrame
, aCommand
)
61 , m_pToolbar( pToolbar
)
63 , m_bMadeInvisible( sal_False
)
65 m_xURLTransformer
.set( URLTransformer::create(m_xContext
) );
68 // ------------------------------------------------------------------
70 ComplexToolbarController::~ComplexToolbarController()
74 // ------------------------------------------------------------------
76 void SAL_CALL
ComplexToolbarController::dispose()
77 throw ( RuntimeException
)
79 SolarMutexGuard aSolarMutexGuard
;
81 m_pToolbar
->SetItemWindow( m_nID
, 0 );
82 svt::ToolboxController::dispose();
84 m_xURLTransformer
.clear();
89 // ------------------------------------------------------------------
90 Sequence
<PropertyValue
> ComplexToolbarController::getExecuteArgs(sal_Int16 KeyModifier
) const
92 Sequence
<PropertyValue
> aArgs( 1 );
94 // Add key modifier to argument list
95 aArgs
[0].Name
= OUString( "KeyModifier" );
96 aArgs
[0].Value
<<= KeyModifier
;
99 // -----------------------------------------------------------------------------
100 void SAL_CALL
ComplexToolbarController::execute( sal_Int16 KeyModifier
)
101 throw ( RuntimeException
)
103 Reference
< XDispatch
> xDispatch
;
104 Reference
< XURLTransformer
> xURLTransformer
;
105 OUString aCommandURL
;
106 ::com::sun::star::util::URL aTargetURL
;
107 Sequence
<PropertyValue
> aArgs
;
110 SolarMutexGuard aSolarMutexGuard
;
113 throw DisposedException();
115 if ( m_bInitialized
&&
117 !m_aCommandURL
.isEmpty() )
119 xURLTransformer
= m_xURLTransformer
;
120 xDispatch
= getDispatchFromCommand( m_aCommandURL
);
121 aCommandURL
= m_aCommandURL
;
122 aTargetURL
= getInitializedURL();
123 aArgs
= getExecuteArgs(KeyModifier
);
127 if ( xDispatch
.is() && !aTargetURL
.Complete
.isEmpty() )
129 // Execute dispatch asynchronously
130 ExecuteInfo
* pExecuteInfo
= new ExecuteInfo
;
131 pExecuteInfo
->xDispatch
= xDispatch
;
132 pExecuteInfo
->aTargetURL
= aTargetURL
;
133 pExecuteInfo
->aArgs
= aArgs
;
134 Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController
, ExecuteHdl_Impl
), pExecuteInfo
);
138 // ------------------------------------------------------------------
140 void ComplexToolbarController::statusChanged( const FeatureStateEvent
& Event
)
141 throw ( RuntimeException
)
143 SolarMutexGuard aSolarMutexGuard
;
150 m_pToolbar
->EnableItem( m_nID
, Event
.IsEnabled
);
152 sal_uInt16 nItemBits
= m_pToolbar
->GetItemBits( m_nID
);
153 nItemBits
&= ~TIB_CHECKABLE
;
154 TriState eTri
= STATE_NOCHECK
;
156 sal_Bool bValue
= sal_Bool();
158 ItemStatus aItemState
;
159 Visibility aItemVisibility
;
160 ControlCommand aControlCommand
;
162 if ( Event
.State
>>= bValue
)
164 // Boolean, treat it as checked/unchecked
165 if ( m_bMadeInvisible
)
166 m_pToolbar
->ShowItem( m_nID
, sal_True
);
167 m_pToolbar
->CheckItem( m_nID
, bValue
);
170 nItemBits
|= TIB_CHECKABLE
;
172 else if ( Event
.State
>>= aStrValue
)
174 OUString
aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue
) );
175 m_pToolbar
->SetItemText( m_nID
, aText
);
176 m_pToolbar
->SetQuickHelpText( m_nID
, aText
);
178 if ( m_bMadeInvisible
)
179 m_pToolbar
->ShowItem( m_nID
, sal_True
);
181 else if ( Event
.State
>>= aItemState
)
183 eTri
= STATE_DONTKNOW
;
184 nItemBits
|= TIB_CHECKABLE
;
185 if ( m_bMadeInvisible
)
186 m_pToolbar
->ShowItem( m_nID
, sal_True
);
188 else if ( Event
.State
>>= aItemVisibility
)
190 m_pToolbar
->ShowItem( m_nID
, aItemVisibility
.bVisible
);
191 m_bMadeInvisible
= !aItemVisibility
.bVisible
;
193 else if ( Event
.State
>>= aControlCommand
)
195 executeControlCommand( aControlCommand
);
196 if ( m_bMadeInvisible
)
197 m_pToolbar
->ShowItem( m_nID
, sal_True
);
200 else if ( m_bMadeInvisible
)
201 m_pToolbar
->ShowItem( m_nID
, sal_True
);
203 m_pToolbar
->SetItemState( m_nID
, eTri
);
204 m_pToolbar
->SetItemBits( m_nID
, nItemBits
);
208 // ------------------------------------------------------------------
210 IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController
, ExecuteHdl_Impl
, ExecuteInfo
*, pExecuteInfo
)
212 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
215 // Asynchronous execution as this can lead to our own destruction!
216 // Framework can recycle our current frame and the layout manager disposes all user interface
217 // elements if a component gets detached from its frame!
218 pExecuteInfo
->xDispatch
->dispatch( pExecuteInfo
->aTargetURL
, pExecuteInfo
->aArgs
);
220 catch ( const Exception
& )
224 Application::AcquireSolarMutex( nRef
);
229 // ------------------------------------------------------------------
231 IMPL_STATIC_LINK_NOINSTANCE( ComplexToolbarController
, Notify_Impl
, NotifyInfo
*, pNotifyInfo
)
233 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
236 // Asynchronous execution: As this can lead to our own destruction!
237 // Framework can recycle our current frame and the layout manager disposes all user interface
238 // elements if a component gets detached from its frame!
239 frame::ControlEvent aEvent
;
240 aEvent
.aURL
= pNotifyInfo
->aSourceURL
;
241 aEvent
.Event
= pNotifyInfo
->aEventName
;
242 aEvent
.aInformation
= pNotifyInfo
->aInfoSeq
;
243 pNotifyInfo
->xNotifyListener
->controlEvent( aEvent
);
245 catch ( const Exception
& )
249 Application::AcquireSolarMutex( nRef
);
254 // ------------------------------------------------------------------
256 void ComplexToolbarController::addNotifyInfo(
257 const OUString
& aEventName
,
258 const uno::Reference
< frame::XDispatch
>& xDispatch
,
259 const uno::Sequence
< beans::NamedValue
>& rInfo
)
261 uno::Reference
< frame::XControlNotificationListener
> xControlNotify( xDispatch
, uno::UNO_QUERY
);
263 if ( xControlNotify
.is() )
265 // Execute notification asynchronously
266 NotifyInfo
* pNotifyInfo
= new NotifyInfo
;
268 pNotifyInfo
->aEventName
= aEventName
;
269 pNotifyInfo
->xNotifyListener
= xControlNotify
;
270 pNotifyInfo
->aSourceURL
= getInitializedURL();
272 // Add frame as source to the information sequence
273 sal_Int32 nCount
= rInfo
.getLength();
274 uno::Sequence
< beans::NamedValue
> aInfoSeq( rInfo
);
275 aInfoSeq
.realloc( nCount
+1 );
276 aInfoSeq
[nCount
].Name
= OUString( "Source" );
277 aInfoSeq
[nCount
].Value
= uno::makeAny( getFrameInterface() );
278 pNotifyInfo
->aInfoSeq
= aInfoSeq
;
280 Application::PostUserEvent( STATIC_LINK(0, ComplexToolbarController
, Notify_Impl
), pNotifyInfo
);
284 // --------------------------------------------------------
285 sal_Int32
ComplexToolbarController::getFontSizePixel( const Window
* pWindow
)
287 const StyleSettings
& rSettings
= Application::GetSettings().GetStyleSettings();
288 const Font
& rFont
= rSettings
.GetAppFont();
290 // Calculate height of the application font used by window
291 sal_Int32 nHeight
= sal_Int32( rFont
.GetHeight() );
292 ::Size aPixelSize
= pWindow
->LogicToPixel( ::Size( 0, nHeight
), MAP_APPFONT
);
293 return aPixelSize
.Height();
296 // --------------------------------------------------------
298 uno::Reference
< frame::XDispatch
> ComplexToolbarController::getDispatchFromCommand( const OUString
& aCommand
) const
300 uno::Reference
< frame::XDispatch
> xDispatch
;
302 if ( m_bInitialized
&& m_xFrame
.is() && !aCommand
.isEmpty() )
304 URLToDispatchMap::const_iterator pIter
= m_aListenerMap
.find( aCommand
);
305 if ( pIter
!= m_aListenerMap
.end() )
306 xDispatch
= pIter
->second
;
312 // --------------------------------------------------------
314 const ::com::sun::star::util::URL
& ComplexToolbarController::getInitializedURL()
316 if ( m_aURL
.Complete
.isEmpty() )
318 m_aURL
.Complete
= m_aCommandURL
;
319 m_xURLTransformer
->parseStrict( m_aURL
);
324 void ComplexToolbarController::notifyFocusGet()
326 // send focus get notification
327 uno::Sequence
< beans::NamedValue
> aInfo
;
328 addNotifyInfo( OUString( "FocusSet" ),
329 getDispatchFromCommand( m_aCommandURL
),
333 void ComplexToolbarController::notifyFocusLost()
335 // send focus lost notification
336 uno::Sequence
< beans::NamedValue
> aInfo
;
337 addNotifyInfo( OUString( "FocusLost" ),
338 getDispatchFromCommand( m_aCommandURL
),
342 void ComplexToolbarController::notifyTextChanged( const OUString
& aText
)
344 // send text changed notification
345 uno::Sequence
< beans::NamedValue
> aInfo( 1 );
346 aInfo
[0].Name
= OUString( "Text" );
347 aInfo
[0].Value
<<= aText
;
348 addNotifyInfo( OUString( "TextChanged" ),
349 getDispatchFromCommand( m_aCommandURL
),
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */