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_GENERICTOOLBARCONTROLLER_HXX 28 #include "uielement/generictoolbarcontroller.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 50 //_________________________________________________________________________________________________________________ 51 // other includes 52 //_________________________________________________________________________________________________________________ 53 #include <svtools/toolboxcontroller.hxx> 54 #include <vos/mutex.hxx> 55 #include <vcl/svapp.hxx> 56 #ifndef _VCL_MNEMONIC_HXX_ 57 #include <vcl/mnemonic.hxx> 58 #endif 59 #include <tools/urlobj.hxx> 60 #include <classes/resource.hrc> 61 #include <classes/fwkresid.hxx> 62 #include <dispatch/uieventloghelper.hxx> 63 64 #include <framework/menuconfiguration.hxx> 65 #include <uielement/menubarmanager.hxx> 66 67 using namespace ::com::sun::star::awt; 68 using namespace ::com::sun::star::uno; 69 using namespace ::com::sun::star::beans; 70 using namespace ::com::sun::star::lang; 71 using namespace ::com::sun::star::frame; 72 using namespace ::com::sun::star::frame::status; 73 using namespace ::com::sun::star::util; 74 using namespace ::com::sun::star::container; 75 76 namespace framework 77 { 78 79 static sal_Bool isEnumCommand( const rtl::OUString& rCommand ) 80 { 81 INetURLObject aURL( rCommand ); 82 83 if (( aURL.GetProtocol() == INET_PROT_UNO ) && 84 ( aURL.GetURLPath().indexOf( '.' ) != -1)) 85 return sal_True; 86 87 return sal_False; 88 } 89 90 static rtl::OUString getEnumCommand( const rtl::OUString& rCommand ) 91 { 92 INetURLObject aURL( rCommand ); 93 94 rtl::OUString aEnumCommand; 95 String aURLPath = aURL.GetURLPath(); 96 xub_StrLen nIndex = aURLPath.Search( '.' ); 97 if (( nIndex > 0 ) && ( nIndex < aURLPath.Len() )) 98 aEnumCommand = aURLPath.Copy( nIndex+1 ); 99 100 return aEnumCommand; 101 } 102 103 static rtl::OUString getMasterCommand( const rtl::OUString& rCommand ) 104 { 105 rtl::OUString aMasterCommand( rCommand ); 106 INetURLObject aURL( rCommand ); 107 if ( aURL.GetProtocol() == INET_PROT_UNO ) 108 { 109 sal_Int32 nIndex = aURL.GetURLPath().indexOf( '.' ); 110 if ( nIndex ) 111 { 112 aURL.SetURLPath( aURL.GetURLPath().copy( 0, nIndex ) ); 113 aMasterCommand = aURL.GetMainURL( INetURLObject::NO_DECODE ); 114 } 115 } 116 return aMasterCommand; 117 } 118 119 struct ExecuteInfo 120 { 121 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > xDispatch; 122 ::com::sun::star::util::URL aTargetURL; 123 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs; 124 }; 125 126 GenericToolbarController::GenericToolbarController( const Reference< XMultiServiceFactory >& rServiceManager, 127 const Reference< XFrame >& rFrame, 128 ToolBox* pToolbar, 129 sal_uInt16 nID, 130 const ::rtl::OUString& aCommand ) : 131 svt::ToolboxController( rServiceManager, rFrame, aCommand ) 132 , m_pToolbar( pToolbar ) 133 , m_nID( nID ) 134 , m_bEnumCommand( isEnumCommand( aCommand )) 135 , m_bMadeInvisible( sal_False ) 136 , m_aEnumCommand( getEnumCommand( aCommand )) 137 { 138 if ( m_bEnumCommand ) 139 addStatusListener( getMasterCommand( aCommand ) ); 140 } 141 142 GenericToolbarController::~GenericToolbarController() 143 { 144 } 145 146 void SAL_CALL GenericToolbarController::dispose() 147 throw ( RuntimeException ) 148 { 149 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 150 151 svt::ToolboxController::dispose(); 152 153 m_pToolbar = 0; 154 m_nID = 0; 155 } 156 157 void SAL_CALL GenericToolbarController::execute( sal_Int16 KeyModifier ) 158 throw ( RuntimeException ) 159 { 160 Reference< XDispatch > xDispatch; 161 Reference< XURLTransformer > xURLTransformer; 162 ::rtl::OUString aCommandURL; 163 164 { 165 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 166 167 if ( m_bDisposed ) 168 throw DisposedException(); 169 170 if ( m_bInitialized && 171 m_xFrame.is() && 172 m_xServiceManager.is() && 173 m_aCommandURL.getLength() ) 174 { 175 xURLTransformer = Reference< XURLTransformer >( m_xServiceManager->createInstance( 176 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), 177 UNO_QUERY ); 178 179 aCommandURL = m_aCommandURL; 180 URLToDispatchMap::iterator pIter = m_aListenerMap.find( m_aCommandURL ); 181 if ( pIter != m_aListenerMap.end() ) 182 xDispatch = pIter->second; 183 } 184 } 185 186 if ( xDispatch.is() && xURLTransformer.is() ) 187 { 188 com::sun::star::util::URL aTargetURL; 189 Sequence<PropertyValue> aArgs( 1 ); 190 191 // Add key modifier to argument list 192 aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" )); 193 aArgs[0].Value <<= KeyModifier; 194 195 aTargetURL.Complete = aCommandURL; 196 xURLTransformer->parseStrict( aTargetURL ); 197 198 // Execute dispatch asynchronously 199 ExecuteInfo* pExecuteInfo = new ExecuteInfo; 200 pExecuteInfo->xDispatch = xDispatch; 201 pExecuteInfo->aTargetURL = aTargetURL; 202 pExecuteInfo->aArgs = aArgs; 203 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 204 UiEventLogHelper(::rtl::OUString::createFromAscii("GenericToolbarController")).log( m_xServiceManager, m_xFrame, aTargetURL, aArgs); 205 Application::PostUserEvent( STATIC_LINK(0, GenericToolbarController , ExecuteHdl_Impl), pExecuteInfo ); 206 } 207 } 208 209 void GenericToolbarController::statusChanged( const FeatureStateEvent& Event ) 210 throw ( RuntimeException ) 211 { 212 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 213 214 if ( m_bDisposed ) 215 return; 216 217 if ( m_pToolbar ) 218 { 219 m_pToolbar->EnableItem( m_nID, Event.IsEnabled ); 220 221 sal_uInt16 nItemBits = m_pToolbar->GetItemBits( m_nID ); 222 nItemBits &= ~TIB_CHECKABLE; 223 TriState eTri = STATE_NOCHECK; 224 225 sal_Bool bValue = sal_Bool(); 226 rtl::OUString aStrValue; 227 ItemStatus aItemState; 228 Visibility aItemVisibility; 229 230 if (( Event.State >>= bValue ) && !m_bEnumCommand ) 231 { 232 // Boolean, treat it as checked/unchecked 233 if ( m_bMadeInvisible ) 234 m_pToolbar->ShowItem( m_nID, sal_True ); 235 m_pToolbar->CheckItem( m_nID, bValue ); 236 if ( bValue ) 237 eTri = STATE_CHECK; 238 nItemBits |= TIB_CHECKABLE; 239 } 240 else if ( Event.State >>= aStrValue ) 241 { 242 if ( m_bEnumCommand ) 243 { 244 if ( aStrValue == m_aEnumCommand ) 245 bValue = sal_True; 246 else 247 bValue = sal_False; 248 249 m_pToolbar->CheckItem( m_nID, bValue ); 250 if ( bValue ) 251 eTri = STATE_CHECK; 252 nItemBits |= TIB_CHECKABLE; 253 } 254 else 255 { 256 // Replacement for place holders 257 if ( aStrValue.matchAsciiL( "($1)", 4 )) 258 { 259 String aResStr = String( FwkResId( STR_UPDATEDOC )); 260 rtl::OUString aTmp( aResStr ); 261 aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); 262 aTmp += aStrValue.copy( 4 ); 263 aStrValue = aTmp; 264 } 265 else if ( aStrValue.matchAsciiL( "($2)", 4 )) 266 { 267 String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN )); 268 rtl::OUString aTmp( aResStr ); 269 aTmp += aStrValue.copy( 4 ); 270 aStrValue = aTmp; 271 } 272 else if ( aStrValue.matchAsciiL( "($3)", 4 )) 273 { 274 String aResStr = String( FwkResId( STR_SAVECOPYDOC )); 275 rtl::OUString aTmp( aResStr ); 276 aTmp += aStrValue.copy( 4 ); 277 aStrValue = aTmp; 278 } 279 ::rtl::OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) ); 280 m_pToolbar->SetItemText( m_nID, aText ); 281 m_pToolbar->SetQuickHelpText( m_nID, aText ); 282 } 283 284 if ( m_bMadeInvisible ) 285 m_pToolbar->ShowItem( m_nID, sal_True ); 286 } 287 else if (( Event.State >>= aItemState ) && !m_bEnumCommand ) 288 { 289 eTri = STATE_DONTKNOW; 290 nItemBits |= TIB_CHECKABLE; 291 if ( m_bMadeInvisible ) 292 m_pToolbar->ShowItem( m_nID, sal_True ); 293 } 294 else if ( Event.State >>= aItemVisibility ) 295 { 296 m_pToolbar->ShowItem( m_nID, aItemVisibility.bVisible ); 297 m_bMadeInvisible = !aItemVisibility.bVisible; 298 } 299 else if ( m_bMadeInvisible ) 300 m_pToolbar->ShowItem( m_nID, sal_True ); 301 302 m_pToolbar->SetItemState( m_nID, eTri ); 303 m_pToolbar->SetItemBits( m_nID, nItemBits ); 304 } 305 } 306 307 IMPL_STATIC_LINK_NOINSTANCE( GenericToolbarController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) 308 { 309 const sal_uInt32 nRef = Application::ReleaseSolarMutex(); 310 try 311 { 312 // Asynchronous execution as this can lead to our own destruction! 313 // Framework can recycle our current frame and the layout manager disposes all user interface 314 // elements if a component gets detached from its frame! 315 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs ); 316 } 317 catch ( Exception& ) 318 { 319 } 320 321 Application::AcquireSolarMutex( nRef ); 322 delete pExecuteInfo; 323 return 0; 324 } 325 326 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 ) 327 { 328 } 329 330 MenuToolbarController::~MenuToolbarController() 331 { 332 try 333 { 334 if ( m_xMenuManager.is() ) 335 m_xMenuManager->dispose(); 336 } 337 catch( Exception& ) {} 338 if ( pMenu ) 339 { 340 delete pMenu; 341 pMenu = NULL; 342 } 343 344 } 345 346 class Toolbarmenu : public PopupMenu 347 { 348 public: 349 Toolbarmenu(); 350 ~Toolbarmenu(); 351 }; 352 353 Toolbarmenu::Toolbarmenu() 354 { 355 OSL_TRACE("**** contstructing Toolbarmenu 0x%x", this ); 356 } 357 358 Toolbarmenu::~Toolbarmenu() 359 { 360 OSL_TRACE("**** destructing Toolbarmenu 0x%x", this ); 361 } 362 363 void SAL_CALL MenuToolbarController::click() throw (RuntimeException) 364 { 365 createPopupWindow(); 366 } 367 368 Reference< XWindow > SAL_CALL 369 MenuToolbarController::createPopupWindow() throw (::com::sun::star::uno::RuntimeException) 370 { 371 if ( !pMenu ) 372 { 373 Reference< XDispatchProvider > xDispatch; 374 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY ); 375 pMenu = new Toolbarmenu(); 376 m_xMenuManager.set( new MenuBarManager( m_xServiceManager, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, sal_True, sal_True ) ); 377 if ( m_xMenuManager.is() ) 378 { 379 MenuBarManager* pMgr = dynamic_cast< MenuBarManager* >( m_xMenuManager.get() ); 380 pMgr->SetItemContainer( m_xMenuDesc ); 381 } 382 } 383 384 ::Rectangle aRect( m_pToolbar->GetItemRect( m_nID ) ); 385 pMenu->Execute( m_pToolbar, aRect, POPUPMENU_EXECUTE_DOWN ); 386 return NULL; 387 } 388 } // namespace 389 390