LCOV - code coverage report
Current view: top level - vcl/source/app - help.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 26 355 7.3 %
Date: 2015-06-13 12:38:46 Functions: 9 45 20.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <comphelper/string.hxx>
      21             : 
      22             : #include "tools/debug.hxx"
      23             : #include "tools/diagnose_ex.h"
      24             : #include "tools/time.hxx"
      25             : 
      26             : #include "vcl/window.hxx"
      27             : #include "vcl/event.hxx"
      28             : #include "vcl/svapp.hxx"
      29             : #include "vcl/wrkwin.hxx"
      30             : #include "vcl/help.hxx"
      31             : #include "vcl/settings.hxx"
      32             : 
      33             : #include "helpwin.hxx"
      34             : #include "svdata.hxx"
      35             : 
      36             : #define HELPWINSTYLE_QUICK      0
      37             : #define HELPWINSTYLE_BALLOON    1
      38             : 
      39             : #define HELPTEXTMARGIN_QUICK    3
      40             : #define HELPTEXTMARGIN_BALLOON  6
      41             : 
      42             : #define HELPDELAY_NORMAL        1
      43             : #define HELPDELAY_SHORT         2
      44             : #define HELPDELAY_NONE          3
      45             : 
      46             : #define HELPTEXTMAXLEN        150
      47             : 
      48         208 : Help::Help()
      49             : {
      50         208 : }
      51             : 
      52         119 : Help::~Help()
      53             : {
      54         119 : }
      55             : 
      56           0 : bool Help::Start( const OUString&, const vcl::Window* )
      57             : {
      58           0 :     return false;
      59             : }
      60             : 
      61           0 : bool Help::SearchKeyword( const OUString& )
      62             : {
      63           0 :     return false;
      64             : }
      65             : 
      66           0 : OUString Help::GetHelpText( const OUString&, const vcl::Window* )
      67             : {
      68           0 :     return OUString();
      69             : }
      70             : 
      71         208 : void Help::EnableContextHelp()
      72             : {
      73         208 :     ImplGetSVData()->maHelpData.mbContextHelp = true;
      74         208 : }
      75             : 
      76           0 : void Help::DisableContextHelp()
      77             : {
      78           0 :     ImplGetSVData()->maHelpData.mbContextHelp = false;
      79           0 : }
      80             : 
      81           0 : bool Help::IsContextHelpEnabled()
      82             : {
      83           0 :     return ImplGetSVData()->maHelpData.mbContextHelp;
      84             : }
      85             : 
      86         208 : void Help::EnableExtHelp()
      87             : {
      88         208 :     ImplGetSVData()->maHelpData.mbExtHelp = true;
      89         208 : }
      90             : 
      91           0 : void Help::DisableExtHelp()
      92             : {
      93           0 :     ImplGetSVData()->maHelpData.mbExtHelp = false;
      94           0 : }
      95             : 
      96           0 : bool Help::IsExtHelpEnabled()
      97             : {
      98           0 :     return ImplGetSVData()->maHelpData.mbExtHelp;
      99             : }
     100             : 
     101           0 : bool Help::StartExtHelp()
     102             : {
     103           0 :     ImplSVData* pSVData = ImplGetSVData();
     104             : 
     105           0 :     if ( pSVData->maHelpData.mbExtHelp && !pSVData->maHelpData.mbExtHelpMode )
     106             :     {
     107           0 :         pSVData->maHelpData.mbExtHelpMode = true;
     108           0 :         pSVData->maHelpData.mbOldBalloonMode = pSVData->maHelpData.mbBalloonHelp;
     109           0 :         pSVData->maHelpData.mbBalloonHelp = true;
     110           0 :         if ( pSVData->maWinData.mpAppWin )
     111           0 :             pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
     112           0 :         return true;
     113             :     }
     114             : 
     115           0 :     return false;
     116             : }
     117             : 
     118           0 : bool Help::EndExtHelp()
     119             : {
     120           0 :     ImplSVData* pSVData = ImplGetSVData();
     121             : 
     122           0 :     if ( pSVData->maHelpData.mbExtHelp && pSVData->maHelpData.mbExtHelpMode )
     123             :     {
     124           0 :         pSVData->maHelpData.mbExtHelpMode = false;
     125           0 :         pSVData->maHelpData.mbBalloonHelp = pSVData->maHelpData.mbOldBalloonMode;
     126           0 :         if ( pSVData->maWinData.mpAppWin )
     127           0 :             pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
     128           0 :         return true;
     129             :     }
     130             : 
     131           0 :     return false;
     132             : }
     133             : 
     134           0 : void Help::EnableBalloonHelp()
     135             : {
     136           0 :     ImplGetSVData()->maHelpData.mbBalloonHelp = true;
     137           0 : }
     138             : 
     139         208 : void Help::DisableBalloonHelp()
     140             : {
     141         208 :     ImplGetSVData()->maHelpData.mbBalloonHelp = false;
     142         208 : }
     143             : 
     144         208 : bool Help::IsBalloonHelpEnabled()
     145             : {
     146         208 :     return ImplGetSVData()->maHelpData.mbBalloonHelp;
     147             : }
     148             : 
     149           0 : bool Help::ShowBalloon( vcl::Window* pParent,
     150             :                         const Point& rScreenPos,
     151             :                         const OUString& rHelpText )
     152             : {
     153             :     ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, QuickHelpFlags::NONE,
     154           0 :                         rHelpText, OUString(), rScreenPos );
     155             : 
     156           0 :     return true;
     157             : }
     158             : 
     159           0 : bool Help::ShowBalloon( vcl::Window* pParent,
     160             :                         const Point& rScreenPos, const Rectangle& rRect,
     161             :                         const OUString& rHelpText )
     162             : {
     163             :     ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, QuickHelpFlags::NONE,
     164           0 :                         rHelpText, OUString(), rScreenPos, &rRect );
     165             : 
     166           0 :     return true;
     167             : }
     168             : 
     169         416 : void Help::EnableQuickHelp()
     170             : {
     171         416 :     ImplGetSVData()->maHelpData.mbQuickHelp = true;
     172         416 : }
     173             : 
     174           0 : void Help::DisableQuickHelp()
     175             : {
     176           0 :     ImplGetSVData()->maHelpData.mbQuickHelp = false;
     177           0 : }
     178             : 
     179         208 : bool Help::IsQuickHelpEnabled()
     180             : {
     181         208 :     return ImplGetSVData()->maHelpData.mbQuickHelp;
     182             : }
     183             : 
     184           0 : bool Help::ShowQuickHelp( vcl::Window* pParent,
     185             :                           const Rectangle& rScreenRect,
     186             :                           const OUString& rHelpText,
     187             :                           const OUString& rLongHelpText,
     188             :                           QuickHelpFlags nStyle )
     189             : {
     190             :     ImplShowHelpWindow( pParent, HELPWINSTYLE_QUICK, nStyle,
     191             :                         rHelpText, rLongHelpText,
     192           0 :                         pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect );
     193           0 :     return true;
     194             : }
     195             : 
     196           0 : void Help::HideBalloonAndQuickHelp()
     197             : {
     198           0 :     HelpTextWindow const * pHelpWin = ImplGetSVData()->maHelpData.mpHelpWin;
     199           0 :     bool const bIsVisible = ( pHelpWin != NULL ) && pHelpWin->IsVisible();
     200           0 :     ImplDestroyHelpWindow( bIsVisible );
     201           0 : }
     202             : 
     203           0 : sal_uIntPtr Help::ShowTip( vcl::Window* pParent, const Rectangle& rScreenRect,
     204             :                      const OUString& rText, QuickHelpFlags nStyle )
     205             : {
     206           0 :     sal_uInt16 nHelpWinStyle = ( nStyle & QuickHelpFlags::TipStyleBalloon ) ? HELPWINSTYLE_BALLOON : HELPWINSTYLE_QUICK;
     207           0 :     VclPtrInstance<HelpTextWindow> pHelpWin( pParent, rText, nHelpWinStyle, nStyle );
     208             : 
     209           0 :     sal_uIntPtr nId = reinterpret_cast< sal_uIntPtr >( pHelpWin.get() );
     210           0 :     UpdateTip( nId, pParent, rScreenRect, rText );
     211             : 
     212           0 :     pHelpWin->ShowHelp( HELPDELAY_NONE );
     213           0 :     return nId;
     214             : }
     215             : 
     216           0 : void Help::UpdateTip( sal_uIntPtr nId, vcl::Window* pParent, const Rectangle& rScreenRect, const OUString& rText )
     217             : {
     218           0 :     HelpTextWindow* pHelpWin = reinterpret_cast< HelpTextWindow* >( nId );
     219           0 :     ENSURE_OR_RETURN_VOID( pHelpWin != NULL, "Help::UpdateTip: invalid ID!" );
     220             : 
     221           0 :     Size aSz = pHelpWin->CalcOutSize();
     222           0 :     pHelpWin->SetOutputSizePixel( aSz );
     223           0 :     ImplSetHelpWindowPos( pHelpWin, pHelpWin->GetWinStyle(), pHelpWin->GetStyle(),
     224           0 :         pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect );
     225             : 
     226           0 :     pHelpWin->SetHelpText( rText );
     227           0 :     pHelpWin->Invalidate();
     228             : }
     229             : 
     230           0 : void Help::HideTip( sal_uLong nId )
     231             : {
     232           0 :     VclPtr<HelpTextWindow> pHelpWin = reinterpret_cast<HelpTextWindow*>(nId);
     233           0 :     vcl::Window* pFrameWindow = pHelpWin->ImplGetFrameWindow();
     234           0 :     pHelpWin->Hide();
     235             :     // trigger update, so that a Paint is instantly triggered since we do not save the background
     236           0 :     pFrameWindow->ImplUpdateAll();
     237           0 :     pHelpWin.disposeAndClear();
     238           0 :     ImplGetSVData()->maHelpData.mnLastHelpHideTime = tools::Time::GetSystemTicks();
     239           0 : }
     240             : 
     241           0 : HelpTextWindow::HelpTextWindow( vcl::Window* pParent, const OUString& rText, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle ) :
     242             :     FloatingWindow( pParent, WB_SYSTEMWINDOW|WB_TOOLTIPWIN ), // #105827# if we change the parent, mirroring will not work correctly when positioning this window
     243           0 :     maHelpText( rText )
     244             : {
     245           0 :     SetType( WINDOW_HELPTEXTWINDOW );
     246           0 :     ImplSetMouseTransparent( true );
     247           0 :     mnHelpWinStyle = nHelpWinStyle;
     248           0 :     mnStyle = nStyle;
     249             : //  on windows this will raise the application window, because help windows are system windows now
     250             : //  EnableAlwaysOnTop();
     251           0 :     EnableSaveBackground();
     252             : 
     253           0 :     if( mnStyle & QuickHelpFlags::BiDiRtl )
     254             :     {
     255           0 :         ComplexTextLayoutMode nLayoutMode = GetLayoutMode();
     256           0 :         nLayoutMode |= TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
     257           0 :         SetLayoutMode( nLayoutMode );
     258             :     }
     259           0 :     SetHelpText( rText );
     260           0 :     Window::SetHelpText( rText );
     261             : 
     262           0 :     ImplSVData* pSVData = ImplGetSVData();
     263           0 :     if ( pSVData->maHelpData.mbSetKeyboardHelp )
     264           0 :         pSVData->maHelpData.mbKeyboardHelp = true;
     265             : 
     266           0 :     const HelpSettings& rHelpSettings = pParent->GetSettings().GetHelpSettings();
     267           0 :     maShowTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
     268           0 :     maHideTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
     269           0 :     maHideTimer.SetTimeout( rHelpSettings.GetTipTimeout() );
     270           0 : }
     271             : 
     272           0 : void HelpTextWindow::ApplySettings(vcl::RenderContext& rRenderContext)
     273             : {
     274           0 :     const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
     275           0 :     SetPointFont(rRenderContext, rStyleSettings.GetHelpFont());
     276           0 :     rRenderContext.SetTextColor(rStyleSettings.GetHelpTextColor());
     277           0 :     rRenderContext.SetTextAlign(ALIGN_TOP);
     278             : 
     279           0 :     if (rRenderContext.IsNativeControlSupported(CTRL_TOOLTIP, PART_ENTIRE_CONTROL))
     280             :     {
     281           0 :         EnableChildTransparentMode(true);
     282           0 :         SetParentClipMode(ParentClipMode::NoClip);
     283           0 :         SetPaintTransparent(true);
     284           0 :         rRenderContext.SetBackground();
     285             :     }
     286             :     else
     287           0 :         rRenderContext.SetBackground(Wallpaper(rStyleSettings.GetHelpColor()));
     288             : 
     289           0 :     if (rStyleSettings.GetHelpColor().IsDark())
     290           0 :         rRenderContext.SetLineColor(COL_WHITE);
     291             :     else
     292           0 :         rRenderContext.SetLineColor(COL_BLACK);
     293           0 :     rRenderContext.SetFillColor();
     294           0 : }
     295             : 
     296           0 : HelpTextWindow::~HelpTextWindow()
     297             : {
     298           0 :     disposeOnce();
     299           0 : }
     300             : 
     301           0 : void HelpTextWindow::dispose()
     302             : {
     303           0 :     maShowTimer.Stop();
     304           0 :     maHideTimer.Stop();
     305             : 
     306           0 :     if( this == ImplGetSVData()->maHelpData.mpHelpWin )
     307           0 :         ImplGetSVData()->maHelpData.mpHelpWin = NULL;
     308           0 :     FloatingWindow::dispose();
     309           0 : }
     310             : 
     311           0 : void HelpTextWindow::SetHelpText( const OUString& rHelpText )
     312             : {
     313           0 :     maHelpText = rHelpText;
     314           0 :     if ( mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN)
     315             :     {
     316           0 :         Size aSize;
     317           0 :         aSize.Height() = GetTextHeight();
     318           0 :         if ( mnStyle & QuickHelpFlags::CtrlText )
     319           0 :             aSize.Width() = GetCtrlTextWidth( maHelpText );
     320             :         else
     321           0 :             aSize.Width() = GetTextWidth( maHelpText );
     322           0 :         maTextRect = Rectangle( Point( HELPTEXTMARGIN_QUICK, HELPTEXTMARGIN_QUICK ), aSize );
     323             :     }
     324             :     else // HELPWINSTYLE_BALLOON
     325             :     {
     326           0 :         Point       aTmpPoint;
     327           0 :         sal_Int32 nCharsInLine = 35 + ((maHelpText.getLength()/100)*5);
     328             :         // average width to have all windows consistent
     329           0 :         OUStringBuffer aBuf;
     330           0 :         comphelper::string::padToLength(aBuf, nCharsInLine, 'x');
     331           0 :         OUString aXXX = aBuf.makeStringAndClear();
     332           0 :         long nWidth = GetTextWidth( aXXX );
     333           0 :         Size aTmpSize( nWidth, 0x7FFFFFFF );
     334           0 :         Rectangle aTry1( aTmpPoint, aTmpSize );
     335             :         DrawTextFlags nDrawFlags = DrawTextFlags::MultiLine | DrawTextFlags::WordBreak |
     336           0 :                             DrawTextFlags::Left | DrawTextFlags::Top;
     337           0 :         if ( mnStyle & QuickHelpFlags::CtrlText )
     338           0 :             nDrawFlags |= DrawTextFlags::Mnemonic;
     339           0 :         Rectangle aTextRect = GetTextRect( aTry1, maHelpText, nDrawFlags );
     340             : 
     341             :         // get a better width later...
     342           0 :         maTextRect = aTextRect;
     343             : 
     344             :         // safety distance...
     345           0 :         maTextRect.SetPos( Point( HELPTEXTMARGIN_BALLOON, HELPTEXTMARGIN_BALLOON ) );
     346             :     }
     347             : 
     348           0 :     Size aSize( CalcOutSize() );
     349           0 :     SetOutputSizePixel( aSize );
     350           0 : }
     351             : 
     352           0 : void HelpTextWindow::ImplShow()
     353             : {
     354           0 :     ImplDelData aDogTag( this );
     355           0 :     Show( true, ShowFlags::NoActivate );
     356           0 :     if( !aDogTag.IsDead() )
     357           0 :     Update();
     358           0 : }
     359             : 
     360           0 : void HelpTextWindow::Paint( vcl::RenderContext& rRenderContext, const Rectangle& )
     361             : {
     362             :     // paint native background
     363           0 :     bool bNativeOK = false;
     364           0 :     if (rRenderContext.IsNativeControlSupported(CTRL_TOOLTIP, PART_ENTIRE_CONTROL))
     365             :     {
     366             :         // #i46472# workaround gcc3.3 temporary problem
     367           0 :         Rectangle aCtrlRegion(Point(0, 0), GetOutputSizePixel());
     368           0 :         ImplControlValue aControlValue;
     369             :         bNativeOK = rRenderContext.DrawNativeControl(CTRL_TOOLTIP, PART_ENTIRE_CONTROL, aCtrlRegion,
     370           0 :                                                      ControlState::NONE, aControlValue, OUString());
     371             :     }
     372             : 
     373             :     // paint text
     374           0 :     if (mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN)
     375             :     {
     376           0 :         if ( mnStyle & QuickHelpFlags::CtrlText )
     377           0 :             rRenderContext.DrawCtrlText(maTextRect.TopLeft(), maHelpText);
     378             :         else
     379           0 :             rRenderContext.DrawText(maTextRect.TopLeft(), maHelpText);
     380             :     }
     381             :     else // HELPWINSTYLE_BALLOON
     382             :     {
     383             :         DrawTextFlags nDrawFlags = DrawTextFlags::MultiLine|DrawTextFlags::WordBreak|
     384           0 :                                 DrawTextFlags::Left|DrawTextFlags::Top;
     385           0 :         if (mnStyle & QuickHelpFlags::CtrlText)
     386           0 :             nDrawFlags |= DrawTextFlags::Mnemonic;
     387           0 :         rRenderContext.DrawText(maTextRect, maHelpText, nDrawFlags);
     388             :     }
     389             : 
     390             :     // border
     391           0 :     if (!bNativeOK)
     392             :     {
     393           0 :         Size aSz = GetOutputSizePixel();
     394           0 :         rRenderContext.DrawRect(Rectangle(Point(), aSz));
     395           0 :         if (mnHelpWinStyle == HELPWINSTYLE_BALLOON)
     396             :         {
     397           0 :             aSz.Width() -= 2;
     398           0 :             aSz.Height() -= 2;
     399           0 :             Color aColor(rRenderContext.GetLineColor());
     400           0 :             rRenderContext.SetLineColor(COL_GRAY);
     401           0 :             rRenderContext.DrawRect(Rectangle(Point(1, 1), aSz));
     402           0 :             rRenderContext.SetLineColor(aColor);
     403             :         }
     404             :     }
     405           0 : }
     406             : 
     407           0 : void HelpTextWindow::ShowHelp( sal_uInt16 nDelayMode )
     408             : {
     409           0 :     sal_uLong nTimeout = 0;
     410           0 :     if ( nDelayMode != HELPDELAY_NONE )
     411             :     {
     412             :         // In case of ExtendedHelp display help sooner
     413           0 :         if ( ImplGetSVData()->maHelpData.mbExtHelpMode )
     414           0 :             nTimeout = 15;
     415             :         else
     416             :         {
     417           0 :             const HelpSettings& rHelpSettings = GetSettings().GetHelpSettings();
     418           0 :             if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
     419           0 :                 nTimeout = rHelpSettings.GetTipDelay();
     420             :             else
     421           0 :                 nTimeout = rHelpSettings.GetBalloonDelay();
     422             :         }
     423             : 
     424           0 :         if ( nDelayMode == HELPDELAY_SHORT )
     425           0 :             nTimeout /= 3;
     426             :     }
     427             : 
     428           0 :     maShowTimer.SetTimeout( nTimeout );
     429           0 :     maShowTimer.Start();
     430           0 : }
     431             : 
     432           0 : IMPL_LINK_TYPED( HelpTextWindow, TimerHdl, Timer*, pTimer, void)
     433             : {
     434           0 :     if ( pTimer == &maShowTimer )
     435             :     {
     436           0 :         if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
     437             :         {
     438             :             // start auto-hide-timer for non-ShowTip windows
     439           0 :             ImplSVData* pSVData = ImplGetSVData();
     440           0 :             if ( this == pSVData->maHelpData.mpHelpWin )
     441           0 :                 maHideTimer.Start();
     442             :         }
     443           0 :         ImplShow();
     444             :     }
     445             :     else
     446             :     {
     447             :         DBG_ASSERT( pTimer == &maHideTimer, "HelpTextWindow::TimerHdl with bad Timer" );
     448           0 :           ImplDestroyHelpWindow( true );
     449             :     }
     450           0 : }
     451             : 
     452           0 : Size HelpTextWindow::CalcOutSize() const
     453             : {
     454           0 :     Size aSz = maTextRect.GetSize();
     455           0 :     aSz.Width() += 2*maTextRect.Left();
     456           0 :     aSz.Height() += 2*maTextRect.Top();
     457           0 :     return aSz;
     458             : }
     459             : 
     460           0 : void HelpTextWindow::RequestHelp( const HelpEvent& /*rHEvt*/ )
     461             : {
     462             :     // Just to assure that Window::RequestHelp() is not called by
     463             :     // ShowQuickHelp/ShowBalloonHelp in the HelpTextWindow.
     464           0 : }
     465             : 
     466           0 : OUString HelpTextWindow::GetText() const
     467             : {
     468           0 :     return maHelpText;
     469             : }
     470             : 
     471           0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HelpTextWindow::CreateAccessible()
     472             : {
     473           0 :     return FloatingWindow::CreateAccessible();
     474             : }
     475             : 
     476           0 : void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle,
     477             :                          const OUString& rHelpText, const OUString& rStatusText,
     478             :                          const Point& rScreenPos, const Rectangle* pHelpArea )
     479             : {
     480           0 :     ImplSVData* pSVData = ImplGetSVData();
     481             : 
     482           0 :     if (rHelpText.isEmpty() && !pSVData->maHelpData.mbRequestingHelp)
     483           0 :         return;
     484             : 
     485           0 :     HelpTextWindow* pHelpWin = pSVData->maHelpData.mpHelpWin;
     486           0 :     sal_uInt16 nDelayMode = HELPDELAY_NORMAL;
     487           0 :     if ( pHelpWin )
     488             :     {
     489             :         DBG_ASSERT( pHelpWin != pParent, "HelpInHelp ?!" );
     490             : 
     491           0 :         if  (   (   ( pHelpWin->GetHelpText() != rHelpText )
     492           0 :                 ||  ( pHelpWin->GetWinStyle() != nHelpWinStyle )
     493           0 :                 ||  (   pHelpArea
     494           0 :                     &&  ( pHelpWin->GetHelpArea() != *pHelpArea )
     495             :                     )
     496             :                 )
     497           0 :             &&  pSVData->maHelpData.mbRequestingHelp
     498             :             )
     499             :         {
     500             :             // remove help window if no HelpText or other HelpText or
     501             :             // other help mode. but keep it if we are scrolling, ie not requesting help
     502           0 :             bool bWasVisible = pHelpWin->IsVisible();
     503           0 :             if ( bWasVisible )
     504           0 :                 nDelayMode = HELPDELAY_NONE; // display it quickly if we were already in quick help mode
     505           0 :             pHelpWin = NULL;
     506           0 :             ImplDestroyHelpWindow( bWasVisible );
     507             :         }
     508             :         else
     509             :         {
     510           0 :             bool const bTextChanged = rHelpText != pHelpWin->GetHelpText();
     511           0 :             if ( bTextChanged || ( nStyle & QuickHelpFlags::ForceReposition ) )
     512             :             {
     513           0 :                 vcl::Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
     514           0 :                 Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
     515           0 :                 if( pHelpWin->IsVisible() )
     516           0 :                     pWindow->Invalidate( aInvRect );
     517             : 
     518           0 :                 pHelpWin->SetHelpText( rHelpText );
     519             :                 // approach mouse position
     520           0 :                 ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea );
     521           0 :                 if( pHelpWin->IsVisible() )
     522           0 :                     pHelpWin->Invalidate();
     523             :             }
     524             :         }
     525             :     }
     526             : 
     527           0 :     if (!pHelpWin && !rHelpText.isEmpty())
     528             :     {
     529           0 :         sal_uInt64 nCurTime = tools::Time::GetSystemTicks();
     530           0 :         if  (   ( ( nCurTime - pSVData->maHelpData.mnLastHelpHideTime ) < pParent->GetSettings().GetHelpSettings().GetTipDelay() )
     531           0 :             ||  ( nStyle & QuickHelpFlags::NoDelay )
     532             :             )
     533           0 :             nDelayMode = HELPDELAY_NONE;
     534             : 
     535             :         DBG_ASSERT( !pHelpWin, "Noch ein HelpWin ?!" );
     536           0 :         pHelpWin = VclPtr<HelpTextWindow>::Create( pParent, rHelpText, nHelpWinStyle, nStyle );
     537           0 :         pSVData->maHelpData.mpHelpWin = pHelpWin;
     538           0 :         pHelpWin->SetStatusText( rStatusText );
     539           0 :         if ( pHelpArea )
     540           0 :             pHelpWin->SetHelpArea( *pHelpArea );
     541             : 
     542             :         //  positioning
     543           0 :         Size aSz = pHelpWin->CalcOutSize();
     544           0 :         pHelpWin->SetOutputSizePixel( aSz );
     545           0 :         ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea );
     546             :         // if not called from Window::RequestHelp, then without delay...
     547           0 :         if ( !pSVData->maHelpData.mbRequestingHelp )
     548           0 :             nDelayMode = HELPDELAY_NONE;
     549           0 :         pHelpWin->ShowHelp( nDelayMode );
     550             :     }
     551             : }
     552             : 
     553        6249 : void ImplDestroyHelpWindow( bool bUpdateHideTime )
     554             : {
     555        6249 :     ImplSVData* pSVData = ImplGetSVData();
     556        6249 :     VclPtr<HelpTextWindow> pHelpWin = pSVData->maHelpData.mpHelpWin;
     557        6249 :     if ( pHelpWin )
     558             :     {
     559           0 :         vcl::Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
     560             :         // find out screen area covered by system help window
     561           0 :         Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
     562           0 :         if( pHelpWin->IsVisible() )
     563           0 :             pWindow->Invalidate( aInvRect );
     564           0 :         pSVData->maHelpData.mpHelpWin = NULL;
     565           0 :         pSVData->maHelpData.mbKeyboardHelp = false;
     566           0 :         pHelpWin->Hide();
     567           0 :         pHelpWin.disposeAndClear();
     568           0 :         if( bUpdateHideTime )
     569           0 :             pSVData->maHelpData.mnLastHelpHideTime = tools::Time::GetSystemTicks();
     570        6249 :     }
     571        6249 : }
     572             : 
     573           0 : void ImplSetHelpWindowPos( vcl::Window* pHelpWin, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle,
     574             :                            const Point& rPos, const Rectangle* pHelpArea )
     575             : {
     576           0 :     Point       aPos = rPos;
     577           0 :     Size        aSz = pHelpWin->GetSizePixel();
     578           0 :     Rectangle   aScreenRect = pHelpWin->ImplGetFrameWindow()->GetDesktopRectPixel();
     579           0 :     aPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aPos );
     580             :     // get mouse screen coords
     581           0 :     Point mPos( pHelpWin->GetParent()->ImplGetFrameWindow()->GetPointerPosPixel() );
     582           0 :     mPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( mPos );
     583             : 
     584           0 :     if ( nHelpWinStyle == HELPWINSTYLE_QUICK )
     585             :     {
     586           0 :         if ( !(nStyle & QuickHelpFlags::NoAutoPos) )
     587             :         {
     588           0 :             long nScreenHeight = aScreenRect.GetHeight();
     589           0 :             aPos.X() -= 4;
     590           0 :             if ( aPos.Y() > aScreenRect.Top()+nScreenHeight-(nScreenHeight/4) )
     591           0 :                 aPos.Y() -= aSz.Height()+4;
     592             :             else
     593           0 :                 aPos.Y() += 21;
     594             :         }
     595             :     }
     596             :     else
     597             :     {
     598             :         // If it's the mouse position, move the window slightly
     599             :         // so the mouse pointer does not cover it
     600           0 :         if ( aPos == mPos )
     601             :         {
     602           0 :             aPos.X() += 12;
     603           0 :             aPos.Y() += 16;
     604             :         }
     605             :     }
     606             : 
     607           0 :     if ( nStyle & QuickHelpFlags::NoAutoPos )
     608             :     {
     609           0 :         if ( pHelpArea )
     610             :         {
     611             :             // convert help area to screen coords
     612             :             Rectangle devHelpArea(
     613           0 :                 pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->TopLeft() ),
     614           0 :                 pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->BottomRight() ) );
     615             : 
     616             :             // Welche Position vom Rechteck?
     617           0 :             aPos = devHelpArea.Center();
     618             : 
     619           0 :             if ( nStyle & QuickHelpFlags::Left )
     620           0 :                 aPos.X() = devHelpArea.Left();
     621           0 :             else if ( nStyle & QuickHelpFlags::Right )
     622           0 :                 aPos.X() = devHelpArea.Right();
     623             : 
     624           0 :             if ( nStyle & QuickHelpFlags::Top )
     625           0 :                 aPos.Y() = devHelpArea.Top();
     626           0 :             else if ( nStyle & QuickHelpFlags::Bottom )
     627           0 :                 aPos.Y() = devHelpArea.Bottom();
     628             :         }
     629             : 
     630             :         // which direction?
     631           0 :         if ( nStyle & QuickHelpFlags::Left )
     632             :             ;
     633           0 :         else if ( nStyle & QuickHelpFlags::Right )
     634           0 :             aPos.X() -= aSz.Width();
     635             :         else
     636           0 :             aPos.X() -= aSz.Width()/2;
     637             : 
     638           0 :         if ( nStyle & QuickHelpFlags::Top )
     639             :             ;
     640           0 :         else if ( nStyle & QuickHelpFlags::Bottom )
     641           0 :             aPos.Y() -= aSz.Height();
     642             :         else
     643           0 :             aPos.Y() -= aSz.Height()/2;
     644             :     }
     645             : 
     646           0 :     if ( aPos.X() < aScreenRect.Left() )
     647           0 :         aPos.X() = aScreenRect.Left();
     648           0 :     else if ( ( aPos.X() + aSz.Width() ) > aScreenRect.Right() )
     649           0 :         aPos.X() = aScreenRect.Right() - aSz.Width();
     650           0 :     if ( aPos.Y() < aScreenRect.Top() )
     651           0 :         aPos.Y() = aScreenRect.Top();
     652           0 :     else if ( ( aPos.Y() + aSz.Height() ) > aScreenRect.Bottom() )
     653           0 :         aPos.Y() = aScreenRect.Bottom() - aSz.Height();
     654             : 
     655           0 :     if( ! (nStyle & QuickHelpFlags::NoEvadePointer) )
     656             :     {
     657             :         /* the remark below should be obsolete by now as the helpwindow should
     658             :         not be focusable, leaving it as a hint. However it is sensible in most
     659             :         conditions to evade the mouse pointer so the content window is fully visible.
     660             : 
     661             :         // the popup must not appear under the mouse
     662             :         // otherwise it would directly be closed due to a focus change...
     663             :         */
     664           0 :         Rectangle aHelpRect( aPos, aSz );
     665           0 :         if( aHelpRect.IsInside( mPos ) )
     666             :         {
     667           0 :             Point delta(2,2);
     668           0 :             Point pSize( aSz.Width(), aSz.Height() );
     669           0 :             Point pTest( mPos - pSize - delta );
     670           0 :             if( pTest.X() > aScreenRect.Left() &&  pTest.Y() > aScreenRect.Top() )
     671           0 :                 aPos = pTest;
     672             :             else
     673           0 :                 aPos = mPos + delta;
     674             :         }
     675             :     }
     676             : 
     677           0 :     vcl::Window* pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
     678           0 :     aPos = pWindow->AbsoluteScreenToOutputPixel( aPos );
     679           0 :     pHelpWin->SetPosPixel( aPos );
     680           0 : }
     681             : 
     682             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11