1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_framework.hxx" 30*cdf0e10cSrcweir #include <dispatch/helpagentdispatcher.hxx> 31*cdf0e10cSrcweir #include <threadhelp/readguard.hxx> 32*cdf0e10cSrcweir #include <threadhelp/writeguard.hxx> 33*cdf0e10cSrcweir #include <com/sun/star/awt/XWindow2.hpp> 34*cdf0e10cSrcweir #include <com/sun/star/awt/PosSize.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/awt/Size.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp> 37*cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx> 38*cdf0e10cSrcweir #include <svtools/helpopt.hxx> 39*cdf0e10cSrcweir #include <vcl/svapp.hxx> 40*cdf0e10cSrcweir #include <vcl/help.hxx> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir namespace css = ::com::sun::star; 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir //........................................................................ 45*cdf0e10cSrcweir namespace framework 46*cdf0e10cSrcweir { 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir //----------------------------------------------- 49*cdf0e10cSrcweir DEFINE_XINTERFACE_4(HelpAgentDispatcher , 50*cdf0e10cSrcweir OWeakObject , 51*cdf0e10cSrcweir DIRECT_INTERFACE (css::lang::XTypeProvider ), 52*cdf0e10cSrcweir DIRECT_INTERFACE (css::frame::XDispatch ), 53*cdf0e10cSrcweir DIRECT_INTERFACE (css::awt::XWindowListener), 54*cdf0e10cSrcweir DIRECT_INTERFACE (css::lang::XEventListener)) 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir //----------------------------------------------- 57*cdf0e10cSrcweir DEFINE_XTYPEPROVIDER_2(HelpAgentDispatcher , 58*cdf0e10cSrcweir css::lang::XTypeProvider, 59*cdf0e10cSrcweir css::frame::XDispatch ) 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir //-------------------------------------------------------------------- 62*cdf0e10cSrcweir HelpAgentDispatcher::HelpAgentDispatcher( const css::uno::Reference< css::frame::XFrame >& xParentFrame) 63*cdf0e10cSrcweir : ThreadHelpBase (&Application::GetSolarMutex()) 64*cdf0e10cSrcweir , m_sCurrentURL ( ) 65*cdf0e10cSrcweir , m_xContainerWindow( ) 66*cdf0e10cSrcweir , m_xAgentWindow ( ) 67*cdf0e10cSrcweir , m_aTimer ( ) 68*cdf0e10cSrcweir , m_xSelfHold ( ) 69*cdf0e10cSrcweir { 70*cdf0e10cSrcweir // It's required that this class has to be contructed with a valid frame. 71*cdf0e10cSrcweir // And "valid" means: the frame must already bound to a valid container window. 72*cdf0e10cSrcweir m_xContainerWindow = xParentFrame->getContainerWindow(); 73*cdf0e10cSrcweir } 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir //-------------------------------------------------------------------- 76*cdf0e10cSrcweir HelpAgentDispatcher::~HelpAgentDispatcher() 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir implts_stopTimer(); 79*cdf0e10cSrcweir implts_ignoreCurrentURL(); 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir // Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly. 82*cdf0e10cSrcweir css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY); 83*cdf0e10cSrcweir if (xAgentWindow.is()) 84*cdf0e10cSrcweir xAgentWindow->dispose(); 85*cdf0e10cSrcweir } 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir //-------------------------------------------------------------------- 88*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::dispatch(const css::util::URL& aURL , 89*cdf0e10cSrcweir const css::uno::Sequence< css::beans::PropertyValue >&) 90*cdf0e10cSrcweir throw(css::uno::RuntimeException) 91*cdf0e10cSrcweir { 92*cdf0e10cSrcweir // silently drop the request if the new URL was marked to be ignored next time. 93*cdf0e10cSrcweir sal_Int32 nAllowedToIgnore = SvtHelpOptions().getAgentIgnoreURLCounter(aURL.Complete); 94*cdf0e10cSrcweir if (nAllowedToIgnore < 1) 95*cdf0e10cSrcweir return; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir // stop the expiration timer for the old URL 98*cdf0e10cSrcweir // The timer will add the old URL to the list of ignorable URLs. 99*cdf0e10cSrcweir // So m_sCurrentURL must be set AFTER the timer was stopped !!! 100*cdf0e10cSrcweir implts_stopTimer(); 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir // SAFE -> 103*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 104*cdf0e10cSrcweir m_sCurrentURL = aURL.Complete; 105*cdf0e10cSrcweir aWriteLock.unlock(); 106*cdf0e10cSrcweir // <- SAFE 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir // start the expiration timer for the new URL 109*cdf0e10cSrcweir implts_startTimer(); 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir // make sure the agent window is shown 112*cdf0e10cSrcweir implts_showAgentWindow(); 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir //-------------------------------------------------------------------- 116*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, 117*cdf0e10cSrcweir const css::util::URL&) 118*cdf0e10cSrcweir throw(css::uno::RuntimeException) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir // no status available 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir //-------------------------------------------------------------------- 124*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, 125*cdf0e10cSrcweir const css::util::URL&) 126*cdf0e10cSrcweir throw(css::uno::RuntimeException) 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir // no status available 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir //-------------------------------------------------------------------- 132*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::windowResized(const css::awt::WindowEvent&) 133*cdf0e10cSrcweir throw(css::uno::RuntimeException) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir implts_positionAgentWindow(); 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir //-------------------------------------------------------------------- 139*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::windowMoved(const css::awt::WindowEvent&) 140*cdf0e10cSrcweir throw(css::uno::RuntimeException) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir implts_positionAgentWindow(); 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir //-------------------------------------------------------------------- 146*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::windowShown(const css::lang::EventObject&) 147*cdf0e10cSrcweir throw(css::uno::RuntimeException) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir implts_showAgentWindow(); 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir //-------------------------------------------------------------------- 153*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::windowHidden(const css::lang::EventObject&) 154*cdf0e10cSrcweir throw(css::uno::RuntimeException) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir implts_hideAgentWindow(); 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir //-------------------------------------------------------------------- 160*cdf0e10cSrcweir void SAL_CALL HelpAgentDispatcher::disposing(const css::lang::EventObject& aEvent) 161*cdf0e10cSrcweir throw(css::uno::RuntimeException) 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir // SAFE -> 164*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir // Already disposed ?! 167*cdf0e10cSrcweir if (! m_xContainerWindow.is()) 168*cdf0e10cSrcweir return; 169*cdf0e10cSrcweir // Wrong broadcaster ?! 170*cdf0e10cSrcweir if (aEvent.Source != m_xContainerWindow) 171*cdf0e10cSrcweir return; 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW); 174*cdf0e10cSrcweir m_xSelfHold.clear(); 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir aWriteLock.unlock(); 177*cdf0e10cSrcweir // <- SAFE 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir implts_stopTimer(); 180*cdf0e10cSrcweir implts_hideAgentWindow(); 181*cdf0e10cSrcweir implts_ignoreCurrentURL(); 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir // SAFE -> 184*cdf0e10cSrcweir aWriteLock.lock(); 185*cdf0e10cSrcweir m_xContainerWindow.clear(); 186*cdf0e10cSrcweir css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY); 187*cdf0e10cSrcweir m_xAgentWindow.clear(); 188*cdf0e10cSrcweir aWriteLock.unlock(); 189*cdf0e10cSrcweir // <- SAFE 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir // Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly. 192*cdf0e10cSrcweir if (xAgentWindow.is()) 193*cdf0e10cSrcweir xAgentWindow->dispose(); 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir //-------------------------------------------------------------------- 197*cdf0e10cSrcweir void HelpAgentDispatcher::helpRequested() 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir implts_stopTimer(); 200*cdf0e10cSrcweir implts_hideAgentWindow(); 201*cdf0e10cSrcweir implts_acceptCurrentURL(); 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir //----------------------------------------------- 205*cdf0e10cSrcweir void HelpAgentDispatcher::closeAgent() 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir implts_stopTimer(); 208*cdf0e10cSrcweir implts_hideAgentWindow(); 209*cdf0e10cSrcweir implts_ignoreCurrentURL(); 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir //-------------------------------------------------------------------- 213*cdf0e10cSrcweir void HelpAgentDispatcher::implts_acceptCurrentURL() 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir // SAFE -> 216*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir ::rtl::OUString sAcceptedURL = m_sCurrentURL; 219*cdf0e10cSrcweir m_sCurrentURL = ::rtl::OUString(); 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir aWriteLock.unlock(); 222*cdf0e10cSrcweir // <- SAFE 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir // We must make sure that this URL isnt marked as ignored by the user. 225*cdf0e10cSrcweir // Otherwhise the user wont see the corresponding help content in the future. 226*cdf0e10cSrcweir SvtHelpOptions().resetAgentIgnoreURLCounter(sAcceptedURL); 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir // show the right help content 229*cdf0e10cSrcweir // SOLAR SAFE -> 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir ::vos::OGuard aSolarLock(Application::GetSolarMutex()); 232*cdf0e10cSrcweir Help* pHelp = Application::GetHelp(); 233*cdf0e10cSrcweir if (pHelp) 234*cdf0e10cSrcweir pHelp->Start(sAcceptedURL, NULL); 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir // <- SOLAR SAFE 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir //-------------------------------------------------------------------- 240*cdf0e10cSrcweir void HelpAgentDispatcher::implts_ignoreCurrentURL() 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir // SAFE -> 243*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir ::rtl::OUString sIgnoredURL = m_sCurrentURL; 246*cdf0e10cSrcweir m_sCurrentURL = ::rtl::OUString(); 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir aWriteLock.unlock(); 249*cdf0e10cSrcweir // <- SAFE 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir if (sIgnoredURL.getLength()) 252*cdf0e10cSrcweir SvtHelpOptions().decAgentIgnoreURLCounter(sIgnoredURL); 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir //-------------------------------------------------------------------- 256*cdf0e10cSrcweir void HelpAgentDispatcher::implts_stopTimer() 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir // SAFE -> 259*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 260*cdf0e10cSrcweir m_xSelfHold.clear(); 261*cdf0e10cSrcweir aWriteLock.unlock(); 262*cdf0e10cSrcweir // <- SAFE 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir // SOLAR SAFE -> 265*cdf0e10cSrcweir // Timer access needs no "own lock" ! It lives if we live ... 266*cdf0e10cSrcweir // But it requires locking of the solar mutex ... because it's a vcl based timer. 267*cdf0e10cSrcweir { 268*cdf0e10cSrcweir ::vos::OGuard aSolarLock(Application::GetSolarMutex()); 269*cdf0e10cSrcweir if (! m_aTimer.IsActive()) 270*cdf0e10cSrcweir return; 271*cdf0e10cSrcweir m_aTimer.Stop(); 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir // <- SOLAR SAFE 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir //-------------------------------------------------------------------- 277*cdf0e10cSrcweir void HelpAgentDispatcher::implts_startTimer() 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir // SOLAR SAFE -> 280*cdf0e10cSrcweir // Timer access needs no "own lock" ! It lives if we live ... 281*cdf0e10cSrcweir // But it requires locking of the solar mutex ... because it's a vcl based timer. 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir ::vos::OGuard aSolarLock(Application::GetSolarMutex()); 284*cdf0e10cSrcweir if (m_aTimer.IsActive()) 285*cdf0e10cSrcweir return; 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir // <- SOLAR SAFE 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir // SAFE -> 290*cdf0e10cSrcweir // Timer uses pointer to this help agent dispatcher ... 291*cdf0e10cSrcweir // But normaly we are ref counted. So we must make sure that this 292*cdf0e10cSrcweir // dispatcher isnt killed during the timer runs .-) 293*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 294*cdf0e10cSrcweir m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW); 295*cdf0e10cSrcweir aWriteLock.unlock(); 296*cdf0e10cSrcweir // <- SAFE 297*cdf0e10cSrcweir 298*cdf0e10cSrcweir sal_Int32 nTime = SvtHelpOptions().GetHelpAgentTimeoutPeriod(); 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir // SOLAR SAFE -> 301*cdf0e10cSrcweir // Timer access needs no "own lock" ! It lives if we live ... 302*cdf0e10cSrcweir // But it requires locking of the solar mutex ... because it's a vcl based timer. 303*cdf0e10cSrcweir { 304*cdf0e10cSrcweir ::vos::OGuard aSolarLock(Application::GetSolarMutex()); 305*cdf0e10cSrcweir m_aTimer.SetTimeout(nTime*1000); // sec => ms ! 306*cdf0e10cSrcweir m_aTimer.Start(); 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir //----------------------------------------------- 311*cdf0e10cSrcweir IMPL_LINK(HelpAgentDispatcher, implts_timerExpired, void*,) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir // This method is called by using a pointer to us. 314*cdf0e10cSrcweir // But we must be aware that we can be destroyed hardly 315*cdf0e10cSrcweir // if our uno reference will be gone! 316*cdf0e10cSrcweir // => Hold this object alive till this method finish its work. 317*cdf0e10cSrcweir // SAFE -> 318*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 319*cdf0e10cSrcweir css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW); 320*cdf0e10cSrcweir m_xSelfHold.clear(); 321*cdf0e10cSrcweir aWriteLock.unlock(); 322*cdf0e10cSrcweir // <- SAFE 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir implts_hideAgentWindow(); 325*cdf0e10cSrcweir implts_ignoreCurrentURL(); 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir return 0; 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir //-------------------------------------------------------------------- 331*cdf0e10cSrcweir void HelpAgentDispatcher::implts_showAgentWindow() 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir // SAFE -> 334*cdf0e10cSrcweir ReadGuard aReadLock(m_aLock); 335*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow2 > xContainerWindow(m_xContainerWindow, css::uno::UNO_QUERY_THROW); 336*cdf0e10cSrcweir aReadLock.unlock(); 337*cdf0e10cSrcweir // <- SAFE 338*cdf0e10cSrcweir 339*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow(); 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir if ( 342*cdf0e10cSrcweir (xContainerWindow.is() ) && 343*cdf0e10cSrcweir (xAgentWindow.is() ) && 344*cdf0e10cSrcweir (xContainerWindow->isVisible()) 345*cdf0e10cSrcweir ) 346*cdf0e10cSrcweir { 347*cdf0e10cSrcweir // make sure that agent window resists at the right place .-) 348*cdf0e10cSrcweir implts_positionAgentWindow(); 349*cdf0e10cSrcweir xAgentWindow->setVisible(sal_True); 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir //-------------------------------------------------------------------- 354*cdf0e10cSrcweir void HelpAgentDispatcher::implts_hideAgentWindow() 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow(); 357*cdf0e10cSrcweir if (xAgentWindow.is()) 358*cdf0e10cSrcweir xAgentWindow->setVisible(sal_False); 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir //-------------------------------------------------------------------- 362*cdf0e10cSrcweir void HelpAgentDispatcher::implts_positionAgentWindow() 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir // SAFE -> 365*cdf0e10cSrcweir ReadGuard aReadLock(m_aLock); 366*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; 367*cdf0e10cSrcweir aReadLock.unlock(); 368*cdf0e10cSrcweir // <- SAFE 369*cdf0e10cSrcweir 370*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow(); 371*cdf0e10cSrcweir if ( 372*cdf0e10cSrcweir (! xContainerWindow.is()) || 373*cdf0e10cSrcweir (! xAgentWindow.is() ) 374*cdf0e10cSrcweir ) 375*cdf0e10cSrcweir return; 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir ::svt::HelpAgentWindow* pAgentWindow = (::svt::HelpAgentWindow*)VCLUnoHelper::GetWindow(xAgentWindow); 378*cdf0e10cSrcweir const css::awt::Rectangle aContainerSize = xContainerWindow->getPosSize(); 379*cdf0e10cSrcweir const Size aAgentSize = pAgentWindow->getPreferredSizePixel(); 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir sal_Int32 nW = aAgentSize.Width() ; 382*cdf0e10cSrcweir sal_Int32 nH = aAgentSize.Height(); 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir if (nW < 1) 385*cdf0e10cSrcweir nW = 100; 386*cdf0e10cSrcweir if (nH < 1) 387*cdf0e10cSrcweir nH = 100; 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir sal_Int32 nX = aContainerSize.Width - nW; 390*cdf0e10cSrcweir sal_Int32 nY = aContainerSize.Height - nH; 391*cdf0e10cSrcweir 392*cdf0e10cSrcweir // TODO: use a surrogate if the container window is too small to contain the full-sized agent window 393*cdf0e10cSrcweir xAgentWindow->setPosSize(nX, nY, nW, nH, css::awt::PosSize::POSSIZE); 394*cdf0e10cSrcweir } 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir //-------------------------------------------------------------------- 397*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > HelpAgentDispatcher::implts_ensureAgentWindow() 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir // SAFE -> 400*cdf0e10cSrcweir ReadGuard aReadLock(m_aLock); 401*cdf0e10cSrcweir if (m_xAgentWindow.is()) 402*cdf0e10cSrcweir return m_xAgentWindow; 403*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; 404*cdf0e10cSrcweir aReadLock.unlock(); 405*cdf0e10cSrcweir // <- SAFE 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir if (!xContainerWindow.is()) 408*cdf0e10cSrcweir return css::uno::Reference< css::awt::XWindow >(); 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir ::svt::HelpAgentWindow* pAgentWindow = 0; 411*cdf0e10cSrcweir // SOLAR SAFE -> 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir ::vos::OGuard aSolarLock(Application::GetSolarMutex()); 414*cdf0e10cSrcweir // create the agent window 415*cdf0e10cSrcweir Window* pContainerWindow = VCLUnoHelper::GetWindow(xContainerWindow); 416*cdf0e10cSrcweir pAgentWindow = new ::svt::HelpAgentWindow(pContainerWindow); 417*cdf0e10cSrcweir pAgentWindow->setCallback(this); 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir // <- SOLAR SAFE 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir // SAFE -> 422*cdf0e10cSrcweir WriteGuard aWriteLock(m_aLock); 423*cdf0e10cSrcweir m_xAgentWindow = VCLUnoHelper::GetInterface(pAgentWindow); 424*cdf0e10cSrcweir css::uno::Reference< css::awt::XWindow > xAgentWindow = m_xAgentWindow; 425*cdf0e10cSrcweir aWriteLock.unlock(); 426*cdf0e10cSrcweir // <- SAFE 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir // add as window listener to the container window so we can maintain the property position of the agent window 429*cdf0e10cSrcweir xContainerWindow->addWindowListener(this); 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir // SOLAR SAFE -> 432*cdf0e10cSrcweir { 433*cdf0e10cSrcweir ::vos::OGuard aSolarLock(Application::GetSolarMutex()); 434*cdf0e10cSrcweir // establish callback for our internal used timer. 435*cdf0e10cSrcweir // Note: Its only active, if the timer will be started ... 436*cdf0e10cSrcweir m_aTimer.SetTimeoutHdl(LINK(this, HelpAgentDispatcher, implts_timerExpired)); 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir // <- SOLAR SAFE 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir return xAgentWindow; 441*cdf0e10cSrcweir } 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir } // namespace framework 444*cdf0e10cSrcweir 445