1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include "helpinterceptor.hxx" 32 #include "helpdispatch.hxx" 33 #include "newhelp.hxx" 34 #include <sfx2/sfxuno.hxx> 35 #include <tools/urlobj.hxx> 36 #include <tools/debug.hxx> 37 #include <com/sun/star/beans/PropertyValue.hpp> 38 #include <com/sun/star/frame/XNotifyingDispatch.hpp> 39 #include <cppuhelper/interfacecontainer.h> 40 #include <vcl/window.hxx> 41 #include <limits.h> 42 43 using namespace ::com::sun::star::beans; 44 using namespace ::com::sun::star::frame; 45 using namespace ::com::sun::star::uno; 46 using namespace ::com::sun::star::util; 47 using namespace ::com::sun::star::lang; 48 49 extern void AppendConfigToken_Impl( String& rURL, sal_Bool bQuestionMark ); // sfxhelp.cxx 50 51 // class HelpInterceptor_Impl -------------------------------------------- 52 53 HelpInterceptor_Impl::HelpInterceptor_Impl() : 54 55 m_pHistory ( NULL ), 56 m_nCurPos ( 0 ) 57 58 { 59 } 60 61 // ----------------------------------------------------------------------- 62 63 HelpInterceptor_Impl::~HelpInterceptor_Impl() 64 { 65 for ( sal_uInt16 i = 0; m_pHistory && i < m_pHistory->Count(); ++i ) 66 delete m_pHistory->GetObject(i); 67 delete m_pHistory; 68 } 69 70 // ----------------------------------------------------------------------- 71 72 void HelpInterceptor_Impl::addURL( const String& rURL ) 73 { 74 if ( !m_pHistory ) 75 m_pHistory = new HelpHistoryList_Impl; 76 sal_uIntPtr nCount = m_pHistory->Count(); 77 if ( nCount && m_nCurPos < ( nCount - 1 ) ) 78 { 79 for ( sal_uIntPtr i = nCount - 1; i > m_nCurPos; i-- ) 80 delete m_pHistory->Remove(i); 81 } 82 Reference<XFrame> xFrame(m_xIntercepted, UNO_QUERY); 83 Reference<XController> xController; 84 if(xFrame.is()) 85 xController = xFrame->getController(); 86 Any aViewData; 87 if(xController.is() && m_pHistory->Count()) 88 { 89 m_pHistory->GetObject(m_nCurPos)->aViewData = xController->getViewData(); 90 } 91 92 m_aCurrentURL = rURL; 93 Any aEmptyViewData; 94 m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL, aEmptyViewData ), LIST_APPEND ); 95 m_nCurPos = m_pHistory->Count() - 1; 96 // TODO ? 97 if ( m_xListener.is() ) 98 { 99 ::com::sun::star::frame::FeatureStateEvent aEvent; 100 URL aURL; 101 aURL.Complete = rURL; 102 aEvent.FeatureURL = aURL; 103 aEvent.Source = (::com::sun::star::frame::XDispatch*)this; 104 m_xListener->statusChanged( aEvent ); 105 } 106 107 m_pWindow->UpdateToolbox(); 108 } 109 110 // ----------------------------------------------------------------------- 111 112 void HelpInterceptor_Impl::setInterception( Reference< XFrame > xFrame ) 113 { 114 m_xIntercepted = Reference< XDispatchProviderInterception>( xFrame, UNO_QUERY ); 115 116 if ( m_xIntercepted.is() ) 117 m_xIntercepted->registerDispatchProviderInterceptor( (XDispatchProviderInterceptor*)this ); 118 } 119 120 // ----------------------------------------------------------------------- 121 122 void HelpInterceptor_Impl::SetStartURL( const String& rURL ) 123 { 124 DBG_ASSERT( !m_pHistory, "invalid history" ); 125 if ( !m_pHistory ) 126 { 127 m_pHistory = new HelpHistoryList_Impl; 128 Any aEmptyViewData; 129 m_pHistory->Insert( new HelpHistoryEntry_Impl( rURL, aEmptyViewData ), ((sal_uIntPtr)0x0) ); 130 m_nCurPos = m_pHistory->Count() - 1; 131 132 m_pWindow->UpdateToolbox(); 133 } 134 m_aCurrentURL = rURL; 135 } 136 137 sal_Bool HelpInterceptor_Impl::HasHistoryPred() const 138 { 139 return m_pHistory && ( m_nCurPos > 0 ); 140 } 141 142 sal_Bool HelpInterceptor_Impl::HasHistorySucc() const 143 { 144 return m_pHistory && ( m_nCurPos < ( m_pHistory->Count() - 1 ) ); 145 } 146 147 148 // ----------------------------------------------------------------------- 149 // XDispatchProvider 150 151 Reference< XDispatch > SAL_CALL HelpInterceptor_Impl::queryDispatch( 152 153 const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags ) 154 155 throw( RuntimeException ) 156 157 { 158 Reference< XDispatch > xResult; 159 if ( m_xSlaveDispatcher.is() ) 160 xResult = m_xSlaveDispatcher->queryDispatch( aURL, aTargetFrameName, nSearchFlags ); 161 162 // INetURLObject aObj( aURL.Complete ); 163 // sal_Bool bHelpURL = ( aObj.GetProtocol() == INET_PROT_VND_SUN_STAR_HELP ); 164 sal_Bool bHelpURL = aURL.Complete.toAsciiLowerCase().match(rtl::OUString::createFromAscii("vnd.sun.star.help"),0); 165 166 if ( bHelpURL ) 167 { 168 DBG_ASSERT( xResult.is(), "invalid dispatch" ); 169 HelpDispatch_Impl* pHelpDispatch = new HelpDispatch_Impl( *this, xResult ); 170 xResult = Reference< XDispatch >( static_cast< ::cppu::OWeakObject* >(pHelpDispatch), UNO_QUERY ); 171 } 172 173 return xResult; 174 } 175 176 // ----------------------------------------------------------------------- 177 178 Sequence < Reference < XDispatch > > SAL_CALL HelpInterceptor_Impl::queryDispatches( 179 180 const Sequence< DispatchDescriptor >& aDescripts ) 181 182 throw( RuntimeException ) 183 184 { 185 Sequence< Reference< XDispatch > > aReturn( aDescripts.getLength() ); 186 Reference< XDispatch >* pReturn = aReturn.getArray(); 187 const DispatchDescriptor* pDescripts = aDescripts.getConstArray(); 188 for ( sal_Int16 i = 0; i < aDescripts.getLength(); ++i, ++pReturn, ++pDescripts ) 189 { 190 *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags ); 191 } 192 return aReturn; 193 } 194 195 // ----------------------------------------------------------------------- 196 // XDispatchProviderInterceptor 197 198 Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getSlaveDispatchProvider() 199 200 throw( RuntimeException ) 201 202 { 203 return m_xSlaveDispatcher; 204 } 205 206 // ----------------------------------------------------------------------- 207 208 void SAL_CALL HelpInterceptor_Impl::setSlaveDispatchProvider( const Reference< XDispatchProvider >& xNewSlave ) 209 210 throw( RuntimeException ) 211 212 { 213 m_xSlaveDispatcher = xNewSlave; 214 } 215 216 // ----------------------------------------------------------------------- 217 218 Reference< XDispatchProvider > SAL_CALL HelpInterceptor_Impl::getMasterDispatchProvider() 219 220 throw( RuntimeException ) 221 222 { 223 return m_xMasterDispatcher; 224 } 225 226 // ----------------------------------------------------------------------- 227 228 void SAL_CALL HelpInterceptor_Impl::setMasterDispatchProvider( const Reference< XDispatchProvider >& xNewMaster ) 229 230 throw( RuntimeException ) 231 232 { 233 m_xMasterDispatcher = xNewMaster; 234 } 235 236 // ----------------------------------------------------------------------- 237 // XInterceptorInfo 238 239 Sequence< ::rtl::OUString > SAL_CALL HelpInterceptor_Impl::getInterceptedURLs() 240 241 throw( RuntimeException ) 242 243 { 244 Sequence< ::rtl::OUString > aURLList( 1 ); 245 aURLList[0] = DEFINE_CONST_UNICODE("vnd.sun.star.help://*"); 246 return aURLList;; 247 } 248 249 // ----------------------------------------------------------------------- 250 // XDispatch 251 252 void SAL_CALL HelpInterceptor_Impl::dispatch( 253 const URL& aURL, const Sequence< ::com::sun::star::beans::PropertyValue >& ) throw( RuntimeException ) 254 { 255 sal_Bool bBack = ( String( DEFINE_CONST_UNICODE(".uno:Backward") ) == String( aURL.Complete ) ); 256 if ( bBack || String( DEFINE_CONST_UNICODE(".uno:Forward") ) == String( aURL.Complete ) ) 257 { 258 if ( m_pHistory ) 259 { 260 if(m_pHistory->Count() > m_nCurPos) 261 { 262 Reference<XFrame> xFrame(m_xIntercepted, UNO_QUERY); 263 Reference<XController> xController; 264 if(xFrame.is()) 265 xController = xFrame->getController(); 266 if(xController.is()) 267 { 268 m_pHistory->GetObject(m_nCurPos)->aViewData = xController->getViewData(); 269 } 270 } 271 272 sal_uIntPtr nPos = ( bBack && m_nCurPos > 0 ) ? --m_nCurPos 273 : ( !bBack && m_nCurPos < m_pHistory->Count() - 1 ) 274 ? ++m_nCurPos 275 : ULONG_MAX; 276 277 if ( nPos < ULONG_MAX ) 278 { 279 HelpHistoryEntry_Impl* pEntry = m_pHistory->GetObject( nPos ); 280 if ( pEntry ) 281 m_pWindow->loadHelpContent(pEntry->aURL, sal_False); // false => dont add item to history again! 282 } 283 284 m_pWindow->UpdateToolbox(); 285 } 286 } 287 } 288 289 // ----------------------------------------------------------------------- 290 291 void SAL_CALL HelpInterceptor_Impl::addStatusListener( 292 const Reference< XStatusListener >& xControl, const URL& ) throw( RuntimeException ) 293 { 294 DBG_ASSERT( !m_xListener.is(), "listener already exists" ); 295 m_xListener = xControl; 296 } 297 298 // ----------------------------------------------------------------------- 299 300 void SAL_CALL HelpInterceptor_Impl::removeStatusListener( 301 const Reference< XStatusListener >&, const URL&) throw( RuntimeException ) 302 { 303 m_xListener = 0; 304 } 305 306 // HelpListener_Impl ----------------------------------------------------- 307 308 HelpListener_Impl::HelpListener_Impl( HelpInterceptor_Impl* pInter ) 309 { 310 pInterceptor = pInter; 311 pInterceptor->addStatusListener( this, ::com::sun::star::util::URL() ); 312 } 313 314 // ----------------------------------------------------------------------- 315 316 void SAL_CALL HelpListener_Impl::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) 317 318 throw( ::com::sun::star::uno::RuntimeException ) 319 320 { 321 INetURLObject aObj( Event.FeatureURL.Complete ); 322 aFactory = aObj.GetHost(); 323 aChangeLink.Call( this ); 324 } 325 326 // ----------------------------------------------------------------------- 327 328 void SAL_CALL HelpListener_Impl::disposing( const ::com::sun::star::lang::EventObject& ) 329 330 throw( ::com::sun::star::uno::RuntimeException ) 331 332 { 333 pInterceptor->removeStatusListener( this, ::com::sun::star::util::URL() ); 334 pInterceptor = NULL; 335 } 336 /*-- 05.09.2002 12:17:59--------------------------------------------------- 337 338 -----------------------------------------------------------------------*/ 339 HelpStatusListener_Impl::HelpStatusListener_Impl( 340 Reference < XDispatch > aDispatch, URL& rURL) 341 { 342 aDispatch->addStatusListener(this, rURL); 343 } 344 /*-- 05.09.2002 12:17:59--------------------------------------------------- 345 346 -----------------------------------------------------------------------*/ 347 HelpStatusListener_Impl::~HelpStatusListener_Impl() 348 { 349 if(xDispatch.is()) 350 xDispatch->removeStatusListener(this, com::sun::star::util::URL()); 351 } 352 /*-- 05.09.2002 12:17:59--------------------------------------------------- 353 354 -----------------------------------------------------------------------*/ 355 void HelpStatusListener_Impl::statusChanged( 356 const FeatureStateEvent& rEvent ) throw( RuntimeException ) 357 { 358 aStateEvent = rEvent; 359 } 360 /*-- 05.09.2002 12:18:00--------------------------------------------------- 361 362 -----------------------------------------------------------------------*/ 363 void HelpStatusListener_Impl::disposing( const EventObject& ) throw( RuntimeException ) 364 { 365 xDispatch->removeStatusListener(this, com::sun::star::util::URL()); 366 xDispatch = 0; 367 } 368