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 <tools/diagnose_ex.h>
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
&, const vcl::Window
* )
72 OUString
Help::GetHelpText( const OUString
&, const weld::Widget
* )
77 void Help::EnableContextHelp()
79 ImplGetSVHelpData().mbContextHelp
= true;
82 void Help::DisableContextHelp()
84 ImplGetSVHelpData().mbContextHelp
= false;
87 bool Help::IsContextHelpEnabled()
89 return ImplGetSVHelpData().mbContextHelp
;
92 void Help::EnableExtHelp()
94 ImplGetSVHelpData().mbExtHelp
= true;
97 void Help::DisableExtHelp()
99 ImplGetSVHelpData().mbExtHelp
= false;
102 bool Help::IsExtHelpEnabled()
104 return ImplGetSVHelpData().mbExtHelp
;
107 bool Help::StartExtHelp()
109 ImplSVData
* pSVData
= ImplGetSVData();
110 ImplSVHelpData
& aHelpData
= ImplGetSVHelpData();
112 if ( aHelpData
.mbExtHelp
&& !aHelpData
.mbExtHelpMode
)
114 aHelpData
.mbExtHelpMode
= true;
115 aHelpData
.mbOldBalloonMode
= aHelpData
.mbBalloonHelp
;
116 aHelpData
.mbBalloonHelp
= true;
117 if (pSVData
->maFrameData
.mpAppWin
)
118 pSVData
->maFrameData
.mpAppWin
->ImplGenerateMouseMove();
125 bool Help::EndExtHelp()
127 ImplSVData
* pSVData
= ImplGetSVData();
128 ImplSVHelpData
& aHelpData
= ImplGetSVHelpData();
130 if ( aHelpData
.mbExtHelp
&& aHelpData
.mbExtHelpMode
)
132 aHelpData
.mbExtHelpMode
= false;
133 aHelpData
.mbBalloonHelp
= aHelpData
.mbOldBalloonMode
;
134 if (pSVData
->maFrameData
.mpAppWin
)
135 pSVData
->maFrameData
.mpAppWin
->ImplGenerateMouseMove();
142 void Help::EnableBalloonHelp()
144 ImplGetSVHelpData().mbBalloonHelp
= true;
147 void Help::DisableBalloonHelp()
149 ImplGetSVHelpData().mbBalloonHelp
= false;
152 bool Help::IsBalloonHelpEnabled()
154 return ImplGetSVHelpData().mbBalloonHelp
;
157 void Help::ShowBalloon( vcl::Window
* pParent
,
158 const Point
& rScreenPos
, const tools::Rectangle
& rRect
,
159 const OUString
& rHelpText
)
161 ImplShowHelpWindow( pParent
, HELPWINSTYLE_BALLOON
, QuickHelpFlags::NONE
,
162 rHelpText
, rScreenPos
, rRect
);
165 void Help::EnableQuickHelp()
167 ImplGetSVHelpData().mbQuickHelp
= true;
170 void Help::DisableQuickHelp()
172 ImplGetSVHelpData().mbQuickHelp
= false;
175 bool Help::IsQuickHelpEnabled()
177 return ImplGetSVHelpData().mbQuickHelp
;
180 void Help::ShowQuickHelp( vcl::Window
* pParent
,
181 const tools::Rectangle
& rScreenRect
,
182 const OUString
& rHelpText
,
183 QuickHelpFlags nStyle
)
185 sal_uInt16 nHelpWinStyle
= ( nStyle
& QuickHelpFlags::TipStyleBalloon
) ? HELPWINSTYLE_BALLOON
: HELPWINSTYLE_QUICK
;
186 ImplShowHelpWindow( pParent
, nHelpWinStyle
, nStyle
,
188 pParent
->OutputToScreenPixel( pParent
->GetPointerPosPixel() ), rScreenRect
);
191 void Help::HideBalloonAndQuickHelp()
193 HelpTextWindow
const * pHelpWin
= ImplGetSVHelpData().mpHelpWin
;
194 bool const bIsVisible
= ( pHelpWin
!= nullptr ) && pHelpWin
->IsVisible();
195 ImplDestroyHelpWindow( bIsVisible
);
198 void* Help::ShowPopover(vcl::Window
* pParent
, const tools::Rectangle
& rScreenRect
,
199 const OUString
& rText
, QuickHelpFlags nStyle
)
201 void* nId
= pParent
->ImplGetFrame()->ShowPopover(rText
, pParent
, rScreenRect
, nStyle
);
204 //popovers are handled natively, return early
208 sal_uInt16 nHelpWinStyle
= ( nStyle
& QuickHelpFlags::TipStyleBalloon
) ? HELPWINSTYLE_BALLOON
: HELPWINSTYLE_QUICK
;
209 VclPtrInstance
<HelpTextWindow
> pHelpWin( pParent
, rText
, nHelpWinStyle
, nStyle
);
211 nId
= pHelpWin
.get();
212 UpdatePopover(nId
, pParent
, rScreenRect
, rText
);
214 pHelpWin
->ShowHelp(true);
218 void Help::UpdatePopover(void* nId
, vcl::Window
* pParent
, const tools::Rectangle
& rScreenRect
,
219 const OUString
& rText
)
221 if (pParent
->ImplGetFrame()->UpdatePopover(nId
, rText
, pParent
, rScreenRect
))
223 //popovers are handled natively, return early
227 HelpTextWindow
* pHelpWin
= static_cast< HelpTextWindow
* >( nId
);
228 ENSURE_OR_RETURN_VOID( pHelpWin
!= nullptr, "Help::UpdatePopover: invalid ID!" );
230 Size aSz
= pHelpWin
->CalcOutSize();
231 pHelpWin
->SetOutputSizePixel( aSz
);
232 ImplSetHelpWindowPos( pHelpWin
, pHelpWin
->GetWinStyle(), pHelpWin
->GetStyle(),
233 pParent
->OutputToScreenPixel( pParent
->GetPointerPosPixel() ), rScreenRect
);
235 pHelpWin
->SetHelpText( rText
);
236 pHelpWin
->Invalidate();
239 void Help::HidePopover(vcl::Window
const * pParent
, void* nId
)
241 if (pParent
->ImplGetFrame()->HidePopover(nId
))
243 //popovers are handled natively, return early
247 VclPtr
<HelpTextWindow
> pHelpWin
= static_cast<HelpTextWindow
*>(nId
);
248 vcl::Window
* pFrameWindow
= pHelpWin
->ImplGetFrameWindow();
250 // trigger update, so that a Paint is instantly triggered since we do not save the background
251 pFrameWindow
->ImplUpdateAll();
252 pHelpWin
.disposeAndClear();
253 ImplGetSVHelpData().mnLastHelpHideTime
= tools::Time::GetSystemTicks();
256 HelpTextWindow::HelpTextWindow( vcl::Window
* pParent
, const OUString
& rText
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
) :
257 FloatingWindow( pParent
, WB_SYSTEMWINDOW
|WB_TOOLTIPWIN
), // #105827# if we change the parent, mirroring will not work correctly when positioning this window
260 SetType( WindowType::HELPTEXTWINDOW
);
261 ImplSetMouseTransparent( true );
262 mnHelpWinStyle
= nHelpWinStyle
;
265 if( mnStyle
& QuickHelpFlags::BiDiRtl
)
267 ComplexTextLayoutFlags nLayoutMode
= GetLayoutMode();
268 nLayoutMode
|= ComplexTextLayoutFlags::BiDiRtl
| ComplexTextLayoutFlags::TextOriginLeft
;
269 SetLayoutMode( nLayoutMode
);
271 SetHelpText( rText
);
272 Window::SetHelpText( rText
);
274 if ( ImplGetSVHelpData().mbSetKeyboardHelp
)
275 ImplGetSVHelpData().mbKeyboardHelp
= true;
278 maShowTimer
.SetInvokeHandler( LINK( this, HelpTextWindow
, TimerHdl
) );
279 maShowTimer
.SetDebugName( "vcl::HelpTextWindow maShowTimer" );
281 const HelpSettings
& rHelpSettings
= pParent
->GetSettings().GetHelpSettings();
282 maHideTimer
.SetTimeout( rHelpSettings
.GetTipTimeout() );
283 maHideTimer
.SetInvokeHandler( LINK( this, HelpTextWindow
, TimerHdl
) );
284 maHideTimer
.SetDebugName( "vcl::HelpTextWindow maHideTimer" );
287 void HelpTextWindow::ApplySettings(vcl::RenderContext
& rRenderContext
)
289 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
290 SetPointFont(rRenderContext
, rStyleSettings
.GetHelpFont());
291 rRenderContext
.SetTextColor(rStyleSettings
.GetHelpTextColor());
292 rRenderContext
.SetTextAlign(ALIGN_TOP
);
294 if (rRenderContext
.IsNativeControlSupported(ControlType::Tooltip
, ControlPart::Entire
))
296 EnableChildTransparentMode();
297 SetParentClipMode(ParentClipMode::NoClip
);
298 SetPaintTransparent(true);
299 rRenderContext
.SetBackground();
302 rRenderContext
.SetBackground(Wallpaper(rStyleSettings
.GetHelpColor()));
304 if (rStyleSettings
.GetHelpColor().IsDark())
305 rRenderContext
.SetLineColor(COL_WHITE
);
307 rRenderContext
.SetLineColor(COL_BLACK
);
308 rRenderContext
.SetFillColor();
311 HelpTextWindow::~HelpTextWindow()
316 void HelpTextWindow::dispose()
321 if( this == ImplGetSVHelpData().mpHelpWin
)
322 ImplGetSVHelpData().mpHelpWin
= nullptr;
323 FloatingWindow::dispose();
326 void HelpTextWindow::SetHelpText( const OUString
& rHelpText
)
328 maHelpText
= rHelpText
;
329 ApplySettings(*this);
330 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
&& maHelpText
.getLength() < HELPTEXTMAXLEN
&& maHelpText
.indexOf('\n') < 0)
333 aSize
.setHeight( GetTextHeight() );
334 if ( mnStyle
& QuickHelpFlags::CtrlText
)
335 aSize
.setWidth( GetCtrlTextWidth( maHelpText
) );
337 aSize
.setWidth( GetTextWidth( maHelpText
) );
338 maTextRect
= tools::Rectangle( Point( HELPTEXTMARGIN_QUICK
, HELPTEXTMARGIN_QUICK
), aSize
);
340 else // HELPWINSTYLE_BALLOON
342 sal_Int32 nCharsInLine
= 35 + ((maHelpText
.getLength()/100)*5);
343 // average width to have all windows consistent
345 comphelper::string::padToLength(aBuf
, nCharsInLine
, 'x');
346 OUString aXXX
= aBuf
.makeStringAndClear();
347 tools::Long nWidth
= GetTextWidth( aXXX
);
348 Size
aTmpSize( nWidth
, 0x7FFFFFFF );
349 tools::Rectangle
aTry1( Point(), aTmpSize
);
350 DrawTextFlags nDrawFlags
= DrawTextFlags::MultiLine
| DrawTextFlags::WordBreak
|
351 DrawTextFlags::Left
| DrawTextFlags::Top
;
352 if ( mnStyle
& QuickHelpFlags::CtrlText
)
353 nDrawFlags
|= DrawTextFlags::Mnemonic
;
354 tools::Rectangle aTextRect
= GetTextRect( aTry1
, maHelpText
, nDrawFlags
);
356 // get a better width later...
357 maTextRect
= aTextRect
;
359 // safety distance...
360 maTextRect
.SetPos( Point( HELPTEXTMARGIN_BALLOON
, HELPTEXTMARGIN_BALLOON
) );
363 Size
aSize( CalcOutSize() );
364 SetOutputSizePixel( aSize
);
367 void HelpTextWindow::ImplShow()
369 VclPtr
<HelpTextWindow
> xWindow( this );
370 Show( true, ShowFlags::NoActivate
);
371 if( !xWindow
->IsDisposed() )
375 void HelpTextWindow::Paint( vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& )
377 // paint native background
378 bool bNativeOK
= false;
379 if (rRenderContext
.IsNativeControlSupported(ControlType::Tooltip
, ControlPart::Entire
))
381 tools::Rectangle
aCtrlRegion(Point(0, 0), GetOutputSizePixel());
382 ImplControlValue aControlValue
;
383 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Tooltip
, ControlPart::Entire
, aCtrlRegion
,
384 ControlState::NONE
, aControlValue
, OUString());
388 if (mnHelpWinStyle
== HELPWINSTYLE_QUICK
&& maHelpText
.getLength() < HELPTEXTMAXLEN
&& maHelpText
.indexOf('\n') < 0)
390 if ( mnStyle
& QuickHelpFlags::CtrlText
)
391 rRenderContext
.DrawCtrlText(maTextRect
.TopLeft(), maHelpText
);
393 rRenderContext
.DrawText(maTextRect
.TopLeft(), maHelpText
);
395 else // HELPWINSTYLE_BALLOON
397 DrawTextFlags nDrawFlags
= DrawTextFlags::MultiLine
|DrawTextFlags::WordBreak
|
398 DrawTextFlags::Left
|DrawTextFlags::Top
;
399 if (mnStyle
& QuickHelpFlags::CtrlText
)
400 nDrawFlags
|= DrawTextFlags::Mnemonic
;
401 rRenderContext
.DrawText(maTextRect
, maHelpText
, nDrawFlags
);
408 Size aSz
= GetOutputSizePixel();
409 rRenderContext
.DrawRect(tools::Rectangle(Point(), aSz
));
410 if (mnHelpWinStyle
== HELPWINSTYLE_BALLOON
)
412 aSz
.AdjustWidth( -2 );
413 aSz
.AdjustHeight( -2 );
414 Color
aColor(rRenderContext
.GetLineColor());
415 rRenderContext
.SetLineColor(COL_GRAY
);
416 rRenderContext
.DrawRect(tools::Rectangle(Point(1, 1), aSz
));
417 rRenderContext
.SetLineColor(aColor
);
421 void HelpTextWindow::ShowHelp(bool bNoDelay
)
423 sal_uLong nTimeout
= 0;
426 // In case of ExtendedHelp display help sooner
427 if ( ImplGetSVHelpData().mbExtHelpMode
)
431 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
)
432 nTimeout
= HelpSettings::GetTipDelay();
434 nTimeout
= HelpSettings::GetBalloonDelay();
438 maShowTimer
.SetTimeout( nTimeout
);
442 IMPL_LINK( HelpTextWindow
, TimerHdl
, Timer
*, pTimer
, void)
444 if ( pTimer
== &maShowTimer
)
446 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
)
448 // start auto-hide-timer for non-ShowTip windows
449 if ( this == ImplGetSVHelpData().mpHelpWin
)
456 SAL_WARN_IF( pTimer
!= &maHideTimer
, "vcl", "HelpTextWindow::TimerHdl with bad Timer" );
457 ImplDestroyHelpWindow( true );
461 Size
HelpTextWindow::CalcOutSize() const
463 Size aSz
= maTextRect
.GetSize();
464 aSz
.AdjustWidth(2*maTextRect
.Left() );
465 aSz
.AdjustHeight(2*maTextRect
.Top() );
469 void HelpTextWindow::RequestHelp( const HelpEvent
& /*rHEvt*/ )
471 // Just to assure that Window::RequestHelp() is not called by
472 // ShowQuickHelp/ShowBalloonHelp in the HelpTextWindow.
475 OUString
HelpTextWindow::GetText() const
480 void ImplShowHelpWindow( vcl::Window
* pParent
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
,
481 const OUString
& rHelpText
,
482 const Point
& rScreenPos
, const tools::Rectangle
& rHelpArea
)
484 if (pParent
->ImplGetFrame()->ShowTooltip(rHelpText
, rHelpArea
))
486 //tooltips are handled natively, return early
490 ImplSVHelpData
& aHelpData
= ImplGetSVHelpData();
492 if (rHelpText
.isEmpty() && !aHelpData
.mbRequestingHelp
)
495 VclPtr
<HelpTextWindow
> pHelpWin
= aHelpData
.mpHelpWin
;
496 bool bNoDelay
= false;
499 SAL_WARN_IF( pHelpWin
== pParent
, "vcl", "HelpInHelp ?!" );
501 bool bRemoveHelp
= (rHelpText
.isEmpty() || (pHelpWin
->GetWinStyle() != nHelpWinStyle
))
502 && aHelpData
.mbRequestingHelp
;
504 if (!bRemoveHelp
&& pHelpWin
->GetParent() == pParent
)
506 bool const bUpdate
= (pHelpWin
->GetHelpText() != rHelpText
) ||
507 ((pHelpWin
->GetHelpArea() != rHelpArea
) && aHelpData
.mbRequestingHelp
);
510 pHelpWin
->SetHelpText( rHelpText
);
511 // approach mouse position
512 ImplSetHelpWindowPos( pHelpWin
, nHelpWinStyle
, nStyle
, rScreenPos
, rHelpArea
);
513 if( pHelpWin
->IsVisible() )
514 pHelpWin
->Invalidate();
519 // remove help window if no HelpText or
520 // other help mode. but keep it if we are scrolling, ie not requesting help
521 bool bWasVisible
= pHelpWin
->IsVisible();
523 bNoDelay
= true; // display it quickly if we were already in quick help mode
525 ImplDestroyHelpWindow( bWasVisible
);
529 if (pHelpWin
|| rHelpText
.isEmpty())
532 sal_uInt64 nCurTime
= tools::Time::GetSystemTicks();
533 if ( ( nCurTime
- aHelpData
.mnLastHelpHideTime
) < HelpSettings::GetTipDelay() )
536 pHelpWin
= VclPtr
<HelpTextWindow
>::Create( pParent
, rHelpText
, nHelpWinStyle
, nStyle
);
537 aHelpData
.mpHelpWin
= pHelpWin
;
538 pHelpWin
->SetHelpArea( rHelpArea
);
541 Size aSz
= pHelpWin
->CalcOutSize();
542 pHelpWin
->SetOutputSizePixel( aSz
);
543 ImplSetHelpWindowPos( pHelpWin
, nHelpWinStyle
, nStyle
, rScreenPos
, rHelpArea
);
544 // if not called from Window::RequestHelp, then without delay...
545 if ( !aHelpData
.mbRequestingHelp
)
547 pHelpWin
->ShowHelp(bNoDelay
);
551 void ImplDestroyHelpWindow( bool bUpdateHideTime
)
553 ImplDestroyHelpWindow(ImplGetSVHelpData(), bUpdateHideTime
);
556 void ImplDestroyHelpWindow(ImplSVHelpData
& rHelpData
, bool bUpdateHideTime
)
558 VclPtr
<HelpTextWindow
> pHelpWin
= rHelpData
.mpHelpWin
;
561 rHelpData
.mpHelpWin
= nullptr;
562 rHelpData
.mbKeyboardHelp
= false;
564 pHelpWin
.disposeAndClear();
565 if( bUpdateHideTime
)
566 rHelpData
.mnLastHelpHideTime
= tools::Time::GetSystemTicks();
570 void ImplSetHelpWindowPos( vcl::Window
* pHelpWin
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
,
571 const Point
& rPos
, const tools::Rectangle
& rHelpArea
)
574 Size aSz
= pHelpWin
->GetSizePixel();
575 tools::Rectangle aScreenRect
= pHelpWin
->ImplGetFrameWindow()->GetDesktopRectPixel();
576 aPos
= pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aPos
);
577 // get mouse screen coords
578 Point
aMousePos( pHelpWin
->GetParent()->ImplGetFrameWindow()->GetPointerPosPixel() );
579 aMousePos
= pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aMousePos
);
581 if ( nHelpWinStyle
== HELPWINSTYLE_QUICK
)
583 if ( !(nStyle
& QuickHelpFlags::NoAutoPos
) )
585 tools::Long nScreenHeight
= aScreenRect
.GetHeight();
587 if ( aPos
.Y() > aScreenRect
.Top()+nScreenHeight
-(nScreenHeight
/4) )
588 aPos
.AdjustY( -(aSz
.Height()+4) );
595 // If it's the mouse position, move the window slightly
596 // so the mouse pointer does not cover it
597 if ( aPos
== aMousePos
)
604 if ( nStyle
& QuickHelpFlags::NoAutoPos
)
606 // convert help area to screen coords
607 tools::Rectangle
devHelpArea(
608 pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea
.TopLeft() ),
609 pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea
.BottomRight() ) );
611 // which position of the rectangle?
612 aPos
= devHelpArea
.Center();
614 if ( nStyle
& QuickHelpFlags::Left
)
615 aPos
.setX( devHelpArea
.Left() );
616 else if ( nStyle
& QuickHelpFlags::Right
)
617 aPos
.setX( devHelpArea
.Right() );
619 if ( nStyle
& QuickHelpFlags::Top
)
620 aPos
.setY( devHelpArea
.Top() );
621 else if ( nStyle
& QuickHelpFlags::Bottom
)
622 aPos
.setY( devHelpArea
.Bottom() );
625 if ( nStyle
& QuickHelpFlags::Left
)
627 else if ( nStyle
& QuickHelpFlags::Right
)
628 aPos
.AdjustX( -(aSz
.Width()) );
630 aPos
.AdjustX( -(aSz
.Width()/2) );
632 if ( nStyle
& QuickHelpFlags::Top
)
634 else if ( nStyle
& QuickHelpFlags::Bottom
)
635 aPos
.AdjustY( -(aSz
.Height()) );
637 aPos
.AdjustY( -(aSz
.Height()/2) );
640 if ( aPos
.X() < aScreenRect
.Left() )
641 aPos
.setX( aScreenRect
.Left() );
642 else if ( ( aPos
.X() + aSz
.Width() ) > aScreenRect
.Right() )
643 aPos
.setX( aScreenRect
.Right() - aSz
.Width() );
644 if ( aPos
.Y() < aScreenRect
.Top() )
645 aPos
.setY( aScreenRect
.Top() );
646 else if ( ( aPos
.Y() + aSz
.Height() ) > aScreenRect
.Bottom() )
647 aPos
.setY( aScreenRect
.Bottom() - aSz
.Height() );
649 if( ! (nStyle
& QuickHelpFlags::NoEvadePointer
) )
651 /* the remark below should be obsolete by now as the helpwindow should
652 not be focusable, leaving it as a hint. However it is sensible in most
653 conditions to evade the mouse pointer so the content window is fully visible.
655 // the popup must not appear under the mouse
656 // otherwise it would directly be closed due to a focus change...
658 tools::Rectangle
aHelpRect( aPos
, aSz
);
659 if( aHelpRect
.IsInside( aMousePos
) )
662 Point
aSize( aSz
.Width(), aSz
.Height() );
663 Point
aTest( aMousePos
- aSize
- delta
);
664 if( aTest
.X() > aScreenRect
.Left() && aTest
.Y() > aScreenRect
.Top() )
667 aPos
= aMousePos
+ delta
;
671 vcl::Window
* pWindow
= pHelpWin
->GetParent()->ImplGetFrameWindow();
672 aPos
= pWindow
->AbsoluteScreenToOutputPixel( aPos
);
673 pHelpWin
->SetPosPixel( aPos
);
676 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */