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( 2 ); 190 191 // Add key modifier to argument list 192 aArgs[0].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" )); 193 aArgs[0].Value <<= KeyModifier; 194 // Add "Referer" to identify the source of this request 195 aArgs[1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Referer" )); 196 aArgs[1].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:user" )); 197 198 aTargetURL.Complete = aCommandURL; 199 xURLTransformer->parseStrict( aTargetURL ); 200 201 // Execute dispatch asynchronously 202 ExecuteInfo* pExecuteInfo = new ExecuteInfo; 203 pExecuteInfo->xDispatch = xDispatch; 204 pExecuteInfo->aTargetURL = aTargetURL; 205 pExecuteInfo->aArgs = aArgs; 206 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653# 207 UiEventLogHelper(::rtl::OUString::createFromAscii("GenericToolbarController")).log( m_xServiceManager, m_xFrame, aTargetURL, aArgs); 208 Application::PostUserEvent( STATIC_LINK(0, GenericToolbarController , ExecuteHdl_Impl), pExecuteInfo ); 209 } 210 } 211 212 void GenericToolbarController::statusChanged( const FeatureStateEvent& Event ) 213 throw ( RuntimeException ) 214 { 215 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); 216 217 if ( m_bDisposed ) 218 return; 219 220 if ( m_pToolbar ) 221 { 222 m_pToolbar->EnableItem( m_nID, Event.IsEnabled ); 223 224 sal_uInt16 nItemBits = m_pToolbar->GetItemBits( m_nID ); 225 nItemBits &= ~TIB_CHECKABLE; 226 TriState eTri = STATE_NOCHECK; 227 228 sal_Bool bValue = sal_Bool(); 229 rtl::OUString aStrValue; 230 ItemStatus aItemState; 231 Visibility aItemVisibility; 232 233 if (( Event.State >>= bValue ) && !m_bEnumCommand ) 234 { 235 // Boolean, treat it as checked/unchecked 236 if ( m_bMadeInvisible ) 237 m_pToolbar->ShowItem( m_nID, sal_True ); 238 m_pToolbar->CheckItem( m_nID, bValue ); 239 if ( bValue ) 240 eTri = STATE_CHECK; 241 nItemBits |= TIB_CHECKABLE; 242 } 243 else if ( Event.State >>= aStrValue ) 244 { 245 if ( m_bEnumCommand ) 246 { 247 if ( aStrValue == m_aEnumCommand ) 248 bValue = sal_True; 249 else 250 bValue = sal_False; 251 252 m_pToolbar->CheckItem( m_nID, bValue ); 253 if ( bValue ) 254 eTri = STATE_CHECK; 255 nItemBits |= TIB_CHECKABLE; 256 } 257 else 258 { 259 // Replacement for place holders 260 if ( aStrValue.matchAsciiL( "($1)", 4 )) 261 { 262 String aResStr = String( FwkResId( STR_UPDATEDOC )); 263 rtl::OUString aTmp( aResStr ); 264 aTmp += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); 265 aTmp += aStrValue.copy( 4 ); 266 aStrValue = aTmp; 267 } 268 else if ( aStrValue.matchAsciiL( "($2)", 4 )) 269 { 270 String aResStr = String( FwkResId( STR_CLOSEDOC_ANDRETURN )); 271 rtl::OUString aTmp( aResStr ); 272 aTmp += aStrValue.copy( 4 ); 273 aStrValue = aTmp; 274 } 275 else if ( aStrValue.matchAsciiL( "($3)", 4 )) 276 { 277 String aResStr = String( FwkResId( STR_SAVECOPYDOC )); 278 rtl::OUString aTmp( aResStr ); 279 aTmp += aStrValue.copy( 4 ); 280 aStrValue = aTmp; 281 } 282 ::rtl::OUString aText( MnemonicGenerator::EraseAllMnemonicChars( aStrValue ) ); 283 m_pToolbar->SetItemText( m_nID, aText ); 284 m_pToolbar->SetQuickHelpText( m_nID, aText ); 285 } 286 287 if ( m_bMadeInvisible ) 288 m_pToolbar->ShowItem( m_nID, sal_True ); 289 } 290 else if (( Event.State >>= aItemState ) && !m_bEnumCommand ) 291 { 292 eTri = STATE_DONTKNOW; 293 nItemBits |= TIB_CHECKABLE; 294 if ( m_bMadeInvisible ) 295 m_pToolbar->ShowItem( m_nID, sal_True ); 296 } 297 else if ( Event.State >>= aItemVisibility ) 298 { 299 m_pToolbar->ShowItem( m_nID, aItemVisibility.bVisible ); 300 m_bMadeInvisible = !aItemVisibility.bVisible; 301 } 302 else if ( m_bMadeInvisible ) 303 m_pToolbar->ShowItem( m_nID, sal_True ); 304 305 m_pToolbar->SetItemState( m_nID, eTri ); 306 m_pToolbar->SetItemBits( m_nID, nItemBits ); 307 } 308 } 309 310 IMPL_STATIC_LINK_NOINSTANCE( GenericToolbarController, ExecuteHdl_Impl, ExecuteInfo*, pExecuteInfo ) 311 { 312 const sal_uInt32 nRef = Application::ReleaseSolarMutex(); 313 try 314 { 315 // Asynchronous execution as this can lead to our own destruction! 316 // Framework can recycle our current frame and the layout manager disposes all user interface 317 // elements if a component gets detached from its frame! 318 pExecuteInfo->xDispatch->dispatch( pExecuteInfo->aTargetURL, pExecuteInfo->aArgs ); 319 } 320 catch ( Exception& ) 321 { 322 } 323 324 Application::AcquireSolarMutex( nRef ); 325 delete pExecuteInfo; 326 return 0; 327 } 328 329 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 ) 330 { 331 } 332 333 MenuToolbarController::~MenuToolbarController() 334 { 335 try 336 { 337 if ( m_xMenuManager.is() ) 338 m_xMenuManager->dispose(); 339 } 340 catch( Exception& ) {} 341 if ( pMenu ) 342 { 343 delete pMenu; 344 pMenu = NULL; 345 } 346 347 } 348 349 class Toolbarmenu : public PopupMenu 350 { 351 public: 352 Toolbarmenu(); 353 ~Toolbarmenu(); 354 }; 355 356 Toolbarmenu::Toolbarmenu() 357 { 358 OSL_TRACE("**** contstructing Toolbarmenu 0x%x", this ); 359 } 360 361 Toolbarmenu::~Toolbarmenu() 362 { 363 OSL_TRACE("**** destructing Toolbarmenu 0x%x", this ); 364 } 365 366 void SAL_CALL MenuToolbarController::click() throw (RuntimeException) 367 { 368 createPopupWindow(); 369 } 370 371 Reference< XWindow > SAL_CALL 372 MenuToolbarController::createPopupWindow() throw (::com::sun::star::uno::RuntimeException) 373 { 374 if ( !pMenu ) 375 { 376 Reference< XDispatchProvider > xDispatch; 377 Reference< XURLTransformer > xURLTransformer( m_xServiceManager->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ))), UNO_QUERY ); 378 pMenu = new Toolbarmenu(); 379 m_xMenuManager.set( new MenuBarManager( m_xServiceManager, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, sal_True, sal_True ) ); 380 if ( m_xMenuManager.is() ) 381 { 382 MenuBarManager* pMgr = dynamic_cast< MenuBarManager* >( m_xMenuManager.get() ); 383 pMgr->SetItemContainer( m_xMenuDesc ); 384 } 385 } 386 387 if ( !pMenu || !m_pToolbar ) 388 return NULL; 389 390 OSL_ENSURE ( pMenu->GetItemCount(), "Empty PopupMenu!" ); 391 392 ::Rectangle aRect( m_pToolbar->GetItemRect( m_nID ) ); 393 pMenu->Execute( m_pToolbar, aRect, POPUPMENU_EXECUTE_DOWN ); 394 395 return NULL; 396 } 397 } // namespace 398 399