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