1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <comphelper/string.hxx>
21 #include <sal/log.hxx>
23 #include <comphelper/diagnose_ex.hxx>
24 #include <tools/time.hxx>
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>
33 #include <helpwin.hxx>
34 #include <salframe.hxx>
37 #define HELPWINSTYLE_QUICK 0
38 #define HELPWINSTYLE_BALLOON 1
40 #define HELPTEXTMARGIN_QUICK 3
41 #define HELPTEXTMARGIN_BALLOON 6
43 #define HELPTEXTMAXLEN 150
53 bool Help::Start( const OUString
&, const vcl::Window
* )
58 bool Help::Start(const OUString
&, weld::Widget
*)
63 void Help::SearchKeyword( const OUString
& )
67 OUString
Help::GetHelpText( const OUString
& )
72 void Help::EnableContextHelp()
74 ImplGetSVHelpData().mbContextHelp
= true;
77 void Help::DisableContextHelp()
79 ImplGetSVHelpData().mbContextHelp
= false;
82 void Help::EnableExtHelp()
84 ImplGetSVHelpData().mbExtHelp
= true;
87 void Help::DisableExtHelp()
89 ImplGetSVHelpData().mbExtHelp
= false;
92 bool Help::IsExtHelpEnabled()
94 return ImplGetSVHelpData().mbExtHelp
;
97 bool Help::StartExtHelp()
99 ImplSVData
* pSVData
= ImplGetSVData();
100 ImplSVHelpData
& aHelpData
= ImplGetSVHelpData();
102 if ( aHelpData
.mbExtHelp
&& !aHelpData
.mbExtHelpMode
)
104 aHelpData
.mbExtHelpMode
= true;
105 aHelpData
.mbOldBalloonMode
= aHelpData
.mbBalloonHelp
;
106 aHelpData
.mbBalloonHelp
= true;
107 if (pSVData
->maFrameData
.mpAppWin
)
108 pSVData
->maFrameData
.mpAppWin
->ImplGenerateMouseMove();
115 bool Help::EndExtHelp()
117 ImplSVData
* pSVData
= ImplGetSVData();
118 ImplSVHelpData
& aHelpData
= ImplGetSVHelpData();
120 if ( aHelpData
.mbExtHelp
&& aHelpData
.mbExtHelpMode
)
122 aHelpData
.mbExtHelpMode
= false;
123 aHelpData
.mbBalloonHelp
= aHelpData
.mbOldBalloonMode
;
124 if (pSVData
->maFrameData
.mpAppWin
)
125 pSVData
->maFrameData
.mpAppWin
->ImplGenerateMouseMove();
132 void Help::EnableBalloonHelp()
134 ImplGetSVHelpData().mbBalloonHelp
= true;
137 void Help::DisableBalloonHelp()
139 ImplGetSVHelpData().mbBalloonHelp
= false;
142 bool Help::IsBalloonHelpEnabled()
144 return ImplGetSVHelpData().mbBalloonHelp
;
147 void Help::ShowBalloon( vcl::Window
* pParent
,
148 const Point
& rScreenPos
, const tools::Rectangle
& rRect
,
149 const OUString
& rHelpText
)
151 ImplShowHelpWindow( pParent
, HELPWINSTYLE_BALLOON
, QuickHelpFlags::NONE
,
152 rHelpText
, rScreenPos
, rRect
);
155 void Help::EnableQuickHelp()
157 ImplGetSVHelpData().mbQuickHelp
= true;
160 void Help::DisableQuickHelp()
162 ImplGetSVHelpData().mbQuickHelp
= false;
165 bool Help::IsQuickHelpEnabled()
167 return ImplGetSVHelpData().mbQuickHelp
;
170 void Help::ShowQuickHelp( vcl::Window
* pParent
,
171 const tools::Rectangle
& rScreenRect
,
172 const OUString
& rHelpText
,
173 QuickHelpFlags nStyle
)
175 sal_uInt16 nHelpWinStyle
= ( nStyle
& QuickHelpFlags::TipStyleBalloon
) ? HELPWINSTYLE_BALLOON
: HELPWINSTYLE_QUICK
;
176 Point aScreenPos
= nStyle
& QuickHelpFlags::NoAutoPos
178 : pParent
->OutputToScreenPixel(pParent
->GetPointerPosPixel());
179 ImplShowHelpWindow( pParent
, nHelpWinStyle
, nStyle
,
180 rHelpText
, aScreenPos
, rScreenRect
);
183 void Help::HideBalloonAndQuickHelp()
185 HelpTextWindow
const * pHelpWin
= ImplGetSVHelpData().mpHelpWin
;
186 bool const bIsVisible
= ( pHelpWin
!= nullptr ) && pHelpWin
->IsVisible();
187 ImplDestroyHelpWindow( bIsVisible
);
190 void* Help::ShowPopover(vcl::Window
* pParent
, const tools::Rectangle
& rScreenRect
,
191 const OUString
& rText
, QuickHelpFlags nStyle
)
193 void* nId
= pParent
->ImplGetFrame()->ShowPopover(rText
, pParent
, rScreenRect
, nStyle
);
196 //popovers are handled natively, return early
200 sal_uInt16 nHelpWinStyle
= ( nStyle
& QuickHelpFlags::TipStyleBalloon
) ? HELPWINSTYLE_BALLOON
: HELPWINSTYLE_QUICK
;
201 VclPtrInstance
<HelpTextWindow
> pHelpWin( pParent
, rText
, nHelpWinStyle
, nStyle
);
203 nId
= pHelpWin
.get();
204 UpdatePopover(nId
, pParent
, rScreenRect
, rText
);
206 pHelpWin
->ShowHelp(true);
210 void Help::UpdatePopover(void* nId
, vcl::Window
* pParent
, const tools::Rectangle
& rScreenRect
,
211 const OUString
& rText
)
213 if (pParent
->ImplGetFrame()->UpdatePopover(nId
, rText
, pParent
, rScreenRect
))
215 //popovers are handled natively, return early
219 HelpTextWindow
* pHelpWin
= static_cast< HelpTextWindow
* >( nId
);
220 ENSURE_OR_RETURN_VOID( pHelpWin
!= nullptr, "Help::UpdatePopover: invalid ID!" );
222 Size aSz
= pHelpWin
->CalcOutSize();
223 pHelpWin
->SetOutputSizePixel( aSz
);
224 ImplSetHelpWindowPos( pHelpWin
, pHelpWin
->GetWinStyle(), pHelpWin
->GetStyle(),
225 pParent
->OutputToScreenPixel( pParent
->GetPointerPosPixel() ), rScreenRect
);
227 pHelpWin
->SetHelpText( rText
);
228 pHelpWin
->Invalidate();
231 void Help::HidePopover(vcl::Window
const * pParent
, void* nId
)
233 if (pParent
->ImplGetFrame()->HidePopover(nId
))
235 //popovers are handled natively, return early
239 VclPtr
<HelpTextWindow
> pHelpWin
= static_cast<HelpTextWindow
*>(nId
);
240 vcl::Window
* pFrameWindow
= pHelpWin
->ImplGetFrameWindow();
242 // trigger update, so that a Paint is instantly triggered since we do not save the background
243 pFrameWindow
->ImplUpdateAll();
244 pHelpWin
.disposeAndClear();
245 ImplGetSVHelpData().mnLastHelpHideTime
= tools::Time::GetSystemTicks();
248 HelpTextWindow::HelpTextWindow( vcl::Window
* pParent
, const OUString
& rText
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
) :
249 FloatingWindow( pParent
, WB_SYSTEMWINDOW
|WB_TOOLTIPWIN
), // #105827# if we change the parent, mirroring will not work correctly when positioning this window
251 maShowTimer( "vcl::HelpTextWindow maShowTimer" ),
252 maHideTimer( "vcl::HelpTextWindow maHideTimer" )
254 SetType( WindowType::HELPTEXTWINDOW
);
255 ImplSetMouseTransparent( true );
256 mnHelpWinStyle
= nHelpWinStyle
;
259 if( mnStyle
& QuickHelpFlags::BiDiRtl
)
261 vcl::text::ComplexTextLayoutFlags nLayoutMode
= GetOutDev()->GetLayoutMode();
262 nLayoutMode
|= vcl::text::ComplexTextLayoutFlags::BiDiRtl
| vcl::text::ComplexTextLayoutFlags::TextOriginLeft
;
263 GetOutDev()->SetLayoutMode( nLayoutMode
);
265 SetHelpText( rText
);
266 Window::SetHelpText( rText
);
268 if ( ImplGetSVHelpData().mbSetKeyboardHelp
)
269 ImplGetSVHelpData().mbKeyboardHelp
= true;
272 maShowTimer
.SetInvokeHandler( LINK( this, HelpTextWindow
, TimerHdl
) );
274 const HelpSettings
& rHelpSettings
= pParent
->GetSettings().GetHelpSettings();
275 maHideTimer
.SetTimeout( rHelpSettings
.GetTipTimeout() );
276 maHideTimer
.SetInvokeHandler( LINK( this, HelpTextWindow
, TimerHdl
) );
279 void HelpTextWindow::ApplySettings(vcl::RenderContext
& rRenderContext
)
281 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
282 SetPointFont(rRenderContext
, rStyleSettings
.GetHelpFont());
283 rRenderContext
.SetTextColor(rStyleSettings
.GetHelpTextColor());
284 rRenderContext
.SetTextAlign(ALIGN_TOP
);
286 if (rRenderContext
.IsNativeControlSupported(ControlType::Tooltip
, ControlPart::Entire
))
288 EnableChildTransparentMode();
289 SetParentClipMode(ParentClipMode::NoClip
);
290 SetPaintTransparent(true);
291 rRenderContext
.SetBackground();
294 rRenderContext
.SetBackground(Wallpaper(rStyleSettings
.GetHelpColor()));
296 if (rStyleSettings
.GetHelpColor().IsDark())
297 rRenderContext
.SetLineColor(COL_WHITE
);
299 rRenderContext
.SetLineColor(COL_BLACK
);
300 rRenderContext
.SetFillColor();
303 HelpTextWindow::~HelpTextWindow()
308 void HelpTextWindow::dispose()
313 if( this == ImplGetSVHelpData().mpHelpWin
)
314 ImplGetSVHelpData().mpHelpWin
= nullptr;
315 FloatingWindow::dispose();
318 void HelpTextWindow::SetHelpText( const OUString
& rHelpText
)
320 maHelpText
= rHelpText
;
321 ApplySettings(*GetOutDev());
322 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
&& maHelpText
.getLength() < HELPTEXTMAXLEN
&& maHelpText
.indexOf('\n') < 0)
325 aSize
.setHeight( GetTextHeight() );
326 if ( mnStyle
& QuickHelpFlags::CtrlText
)
327 aSize
.setWidth( GetOutDev()->GetCtrlTextWidth( maHelpText
) );
329 aSize
.setWidth( GetTextWidth( maHelpText
) );
330 maTextRect
= tools::Rectangle( Point( HELPTEXTMARGIN_QUICK
, HELPTEXTMARGIN_QUICK
), aSize
);
332 else // HELPWINSTYLE_BALLOON
334 sal_Int32 nCharsInLine
;
335 if (mnHelpWinStyle
== HELPWINSTYLE_QUICK
)
336 nCharsInLine
= maHelpText
.getLength();
338 nCharsInLine
= 35 + ((maHelpText
.getLength() / 100) * 5);
339 // average width to have all windows consistent
340 OUStringBuffer
aBuf(nCharsInLine
);
341 comphelper::string::padToLength(aBuf
, nCharsInLine
, 'x');
342 tools::Long nWidth
= GetTextWidth( OUString::unacquired(aBuf
) );
343 Size
aTmpSize( nWidth
, 0x7FFFFFFF );
344 tools::Rectangle
aTry1( Point(), aTmpSize
);
345 DrawTextFlags nDrawFlags
= DrawTextFlags::MultiLine
| DrawTextFlags::WordBreak
|
346 DrawTextFlags::Left
| DrawTextFlags::Top
;
347 if ( mnStyle
& QuickHelpFlags::CtrlText
)
348 nDrawFlags
|= DrawTextFlags::Mnemonic
;
349 tools::Rectangle aTextRect
= GetTextRect( aTry1
, maHelpText
, nDrawFlags
);
351 // get a better width later...
352 maTextRect
= aTextRect
;
354 // safety distance...
355 maTextRect
.SetPos( Point( HELPTEXTMARGIN_BALLOON
, HELPTEXTMARGIN_BALLOON
) );
358 Size
aSize( CalcOutSize() );
359 SetOutputSizePixel( aSize
);
364 void HelpTextWindow::ImplShow()
366 VclPtr
<HelpTextWindow
> xWindow( this );
367 Show( true, ShowFlags::NoActivate
);
368 if( !xWindow
->isDisposed() )
372 void HelpTextWindow::Paint( vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& )
374 // paint native background
375 bool bNativeOK
= false;
376 if (rRenderContext
.IsNativeControlSupported(ControlType::Tooltip
, ControlPart::Entire
))
378 tools::Rectangle
aCtrlRegion(Point(0, 0), GetOutputSizePixel());
379 ImplControlValue aControlValue
;
380 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Tooltip
, ControlPart::Entire
, aCtrlRegion
,
381 ControlState::NONE
, aControlValue
, OUString());
385 if (mnHelpWinStyle
== HELPWINSTYLE_QUICK
&& maHelpText
.getLength() < HELPTEXTMAXLEN
&& maHelpText
.indexOf('\n') < 0)
387 if ( mnStyle
& QuickHelpFlags::CtrlText
)
388 rRenderContext
.DrawCtrlText(maTextRect
.TopLeft(), maHelpText
);
390 rRenderContext
.DrawText(maTextRect
.TopLeft(), maHelpText
);
392 else // HELPWINSTYLE_BALLOON
394 DrawTextFlags nDrawFlags
= DrawTextFlags::MultiLine
|DrawTextFlags::WordBreak
|
395 DrawTextFlags::Left
|DrawTextFlags::Top
;
396 if (mnStyle
& QuickHelpFlags::CtrlText
)
397 nDrawFlags
|= DrawTextFlags::Mnemonic
;
398 rRenderContext
.DrawText(maTextRect
, maHelpText
, nDrawFlags
);
405 Size aSz
= GetOutputSizePixel();
406 rRenderContext
.DrawRect(tools::Rectangle(Point(), aSz
));
407 if (mnHelpWinStyle
== HELPWINSTYLE_BALLOON
)
409 aSz
.AdjustWidth( -2 );
410 aSz
.AdjustHeight( -2 );
411 Color
aColor(rRenderContext
.GetLineColor());
412 rRenderContext
.SetLineColor(COL_GRAY
);
413 rRenderContext
.DrawRect(tools::Rectangle(Point(1, 1), aSz
));
414 rRenderContext
.SetLineColor(aColor
);
418 void HelpTextWindow::ShowHelp(bool bNoDelay
)
420 sal_uLong nTimeout
= 0;
423 // In case of ExtendedHelp display help sooner
424 if ( ImplGetSVHelpData().mbExtHelpMode
)
428 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
)
429 nTimeout
= HelpSettings::GetTipDelay();
431 nTimeout
= HelpSettings::GetBalloonDelay();
435 maShowTimer
.SetTimeout( nTimeout
);
439 IMPL_LINK( HelpTextWindow
, TimerHdl
, Timer
*, pTimer
, void)
441 if ( pTimer
== &maShowTimer
)
448 SAL_WARN_IF( pTimer
!= &maHideTimer
, "vcl", "HelpTextWindow::TimerHdl with bad Timer" );
449 ImplDestroyHelpWindow( true );
453 Size
HelpTextWindow::CalcOutSize() const
455 Size aSz
= maTextRect
.GetSize();
456 aSz
.AdjustWidth(2*maTextRect
.Left() );
457 aSz
.AdjustHeight(2*maTextRect
.Top() );
461 void HelpTextWindow::RequestHelp( const HelpEvent
& /*rHEvt*/ )
463 // Just to assure that Window::RequestHelp() is not called by
464 // ShowQuickHelp/ShowBalloonHelp in the HelpTextWindow.
467 OUString
HelpTextWindow::GetText() const
472 void HelpTextWindow::ResetHideTimer()
474 if (mnHelpWinStyle
== HELPWINSTYLE_QUICK
)
476 // start auto-hide-timer for non-ShowTip windows
477 if (this == ImplGetSVHelpData().mpHelpWin
)
482 void ImplShowHelpWindow( vcl::Window
* pParent
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
,
483 const OUString
& rHelpText
,
484 const Point
& rScreenPos
, const tools::Rectangle
& rHelpArea
)
486 if (pParent
->ImplGetFrame()->ShowTooltip(rHelpText
, rHelpArea
))
488 //tooltips are handled natively, return early
492 ImplSVHelpData
& aHelpData
= ImplGetSVHelpData();
494 if (rHelpText
.isEmpty() && !aHelpData
.mbRequestingHelp
)
497 bool bNoDelay
= false;
498 if (VclPtr
<HelpTextWindow
> pHelpWin
= aHelpData
.mpHelpWin
)
500 SAL_WARN_IF( pHelpWin
== pParent
, "vcl", "HelpInHelp ?!" );
502 bool bRemoveHelp
= (rHelpText
.isEmpty() || (pHelpWin
->GetWinStyle() != nHelpWinStyle
))
503 && aHelpData
.mbRequestingHelp
;
505 if (!bRemoveHelp
&& pHelpWin
->GetParent() == pParent
)
507 bool const bUpdate
= (pHelpWin
->GetHelpText() != rHelpText
) ||
508 ((pHelpWin
->GetHelpArea() != rHelpArea
) && aHelpData
.mbRequestingHelp
);
511 pHelpWin
->SetHelpText( rHelpText
);
512 // approach mouse position
513 ImplSetHelpWindowPos( pHelpWin
, nHelpWinStyle
, nStyle
, rScreenPos
, rHelpArea
);
514 if( pHelpWin
->IsVisible() )
515 pHelpWin
->Invalidate();
517 pHelpWin
->ResetHideTimer(); // It is shown anew, so prolongate the hide timeout
521 // remove help window if no HelpText or
522 // other help mode. but keep it if we are scrolling, ie not requesting help
523 bool bWasVisible
= pHelpWin
->IsVisible();
525 bNoDelay
= true; // display it quickly if we were already in quick help mode
526 ImplDestroyHelpWindow( bWasVisible
);
529 if (rHelpText
.isEmpty())
532 VclPtr
<HelpTextWindow
> pHelpWin
= VclPtr
<HelpTextWindow
>::Create( pParent
, rHelpText
, nHelpWinStyle
, nStyle
);
533 aHelpData
.mpHelpWin
= pHelpWin
;
534 pHelpWin
->SetHelpArea( rHelpArea
);
537 Size aSz
= pHelpWin
->CalcOutSize();
538 pHelpWin
->SetOutputSizePixel( aSz
);
539 ImplSetHelpWindowPos( pHelpWin
, nHelpWinStyle
, nStyle
, rScreenPos
, rHelpArea
);
540 // if not called from Window::RequestHelp, then without delay...
543 if ( !aHelpData
.mbRequestingHelp
)
549 sal_uInt64 nCurTime
= tools::Time::GetSystemTicks();
550 if ( ( nCurTime
- aHelpData
.mnLastHelpHideTime
) < o3tl::make_unsigned(HelpSettings::GetTipDelay()) )
554 pHelpWin
->ShowHelp(bNoDelay
);
557 void ImplDestroyHelpWindow( bool bUpdateHideTime
)
559 ImplDestroyHelpWindow(ImplGetSVHelpData(), bUpdateHideTime
);
562 void ImplDestroyHelpWindow(ImplSVHelpData
& rHelpData
, bool bUpdateHideTime
)
564 VclPtr
<HelpTextWindow
> pHelpWin
= rHelpData
.mpHelpWin
;
567 rHelpData
.mpHelpWin
= nullptr;
568 rHelpData
.mbKeyboardHelp
= false;
570 pHelpWin
.disposeAndClear();
571 if( bUpdateHideTime
)
572 rHelpData
.mnLastHelpHideTime
= tools::Time::GetSystemTicks();
576 void ImplSetHelpWindowPos( vcl::Window
* pHelpWin
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
,
577 const Point
& rPos
, const tools::Rectangle
& rHelpArea
)
579 AbsoluteScreenPixelPoint aPos
;
580 AbsoluteScreenPixelSize
aSz( pHelpWin
->GetSizePixel() );
581 AbsoluteScreenPixelRectangle aScreenRect
= pHelpWin
->ImplGetFrameWindow()->GetDesktopRectPixel();
582 vcl::Window
* pWindow
= pHelpWin
->GetParent()->ImplGetFrameWindow();
583 // get mouse screen coords
584 AbsoluteScreenPixelPoint
aMousePos(pWindow
->OutputToAbsoluteScreenPixel(pWindow
->GetPointerPosPixel()));
586 if ( nStyle
& QuickHelpFlags::NoAutoPos
)
588 // convert help area to screen coords
589 AbsoluteScreenPixelRectangle
devHelpArea(
590 pWindow
->OutputToAbsoluteScreenPixel( rHelpArea
.TopLeft() ),
591 pWindow
->OutputToAbsoluteScreenPixel( rHelpArea
.BottomRight() ) );
593 // which position of the rectangle?
594 aPos
= devHelpArea
.Center();
596 if ( nStyle
& QuickHelpFlags::Left
)
597 aPos
.setX( devHelpArea
.Left() );
598 else if ( nStyle
& QuickHelpFlags::Right
)
599 aPos
.setX( devHelpArea
.Right() );
601 if ( nStyle
& QuickHelpFlags::Top
)
602 aPos
.setY( devHelpArea
.Top() );
603 else if ( nStyle
& QuickHelpFlags::Bottom
)
604 aPos
.setY( devHelpArea
.Bottom() );
607 if ( nStyle
& QuickHelpFlags::Left
)
609 else if ( nStyle
& QuickHelpFlags::Right
)
610 aPos
.AdjustX( -(aSz
.Width()) );
612 aPos
.AdjustX( -(aSz
.Width()/2) );
614 if ( nStyle
& QuickHelpFlags::Top
)
616 else if ( nStyle
& QuickHelpFlags::Bottom
)
617 aPos
.AdjustY( -(aSz
.Height()) );
619 aPos
.AdjustY( -(aSz
.Height()/2) );
623 aPos
= pWindow
->OutputToAbsoluteScreenPixel(rPos
);
624 if ( nHelpWinStyle
== HELPWINSTYLE_QUICK
)
626 tools::Long nScreenHeight
= aScreenRect
.GetHeight();
628 if ( aPos
.Y() > aScreenRect
.Top()+nScreenHeight
-(nScreenHeight
/4) )
629 aPos
.AdjustY( -(aSz
.Height()+4) );
635 // If it's the mouse position, move the window slightly
636 // so the mouse pointer does not cover it
637 if ( aPos
== aMousePos
)
645 if ( aPos
.X() < aScreenRect
.Left() )
646 aPos
.setX( aScreenRect
.Left() );
647 else if ( ( aPos
.X() + aSz
.Width() ) > aScreenRect
.Right() )
648 aPos
.setX( aScreenRect
.Right() - aSz
.Width() );
649 if ( aPos
.Y() < aScreenRect
.Top() )
650 aPos
.setY( aScreenRect
.Top() );
651 else if ( ( aPos
.Y() + aSz
.Height() ) > aScreenRect
.Bottom() )
652 aPos
.setY( aScreenRect
.Bottom() - aSz
.Height() );
654 if( ! (nStyle
& QuickHelpFlags::NoEvadePointer
) )
656 /* the remark below should be obsolete by now as the helpwindow should
657 not be focusable, leaving it as a hint. However it is sensible in most
658 conditions to evade the mouse pointer so the content window is fully visible.
660 // the popup must not appear under the mouse
661 // otherwise it would directly be closed due to a focus change...
663 AbsoluteScreenPixelRectangle
aHelpRect( aPos
, aSz
);
664 if( aHelpRect
.Contains( aMousePos
) )
666 AbsoluteScreenPixelPoint
delta(2,2);
667 AbsoluteScreenPixelPoint
aSize( aSz
.Width(), aSz
.Height() );
668 AbsoluteScreenPixelPoint
aTest( aMousePos
- aSize
- delta
);
669 if( aTest
.X() > aScreenRect
.Left() && aTest
.Y() > aScreenRect
.Top() )
672 aPos
= aMousePos
+ delta
;
676 Point aPosOut
= pWindow
->AbsoluteScreenToOutputPixel( aPos
);
677 pHelpWin
->SetPosPixel( aPosOut
);
680 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */