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 ImplGetSVData()->maHelpData
.mbContextHelp
= true;
82 void Help::DisableContextHelp()
84 ImplGetSVData()->maHelpData
.mbContextHelp
= false;
87 bool Help::IsContextHelpEnabled()
89 return ImplGetSVData()->maHelpData
.mbContextHelp
;
92 void Help::EnableExtHelp()
94 ImplGetSVData()->maHelpData
.mbExtHelp
= true;
97 void Help::DisableExtHelp()
99 ImplGetSVData()->maHelpData
.mbExtHelp
= false;
102 bool Help::IsExtHelpEnabled()
104 return ImplGetSVData()->maHelpData
.mbExtHelp
;
107 bool Help::StartExtHelp()
109 ImplSVData
* pSVData
= ImplGetSVData();
111 if ( pSVData
->maHelpData
.mbExtHelp
&& !pSVData
->maHelpData
.mbExtHelpMode
)
113 pSVData
->maHelpData
.mbExtHelpMode
= true;
114 pSVData
->maHelpData
.mbOldBalloonMode
= pSVData
->maHelpData
.mbBalloonHelp
;
115 pSVData
->maHelpData
.mbBalloonHelp
= true;
116 if ( pSVData
->maWinData
.mpAppWin
)
117 pSVData
->maWinData
.mpAppWin
->ImplGenerateMouseMove();
124 bool Help::EndExtHelp()
126 ImplSVData
* pSVData
= ImplGetSVData();
128 if ( pSVData
->maHelpData
.mbExtHelp
&& pSVData
->maHelpData
.mbExtHelpMode
)
130 pSVData
->maHelpData
.mbExtHelpMode
= false;
131 pSVData
->maHelpData
.mbBalloonHelp
= pSVData
->maHelpData
.mbOldBalloonMode
;
132 if ( pSVData
->maWinData
.mpAppWin
)
133 pSVData
->maWinData
.mpAppWin
->ImplGenerateMouseMove();
140 void Help::EnableBalloonHelp()
142 ImplGetSVData()->maHelpData
.mbBalloonHelp
= true;
145 void Help::DisableBalloonHelp()
147 ImplGetSVData()->maHelpData
.mbBalloonHelp
= false;
150 bool Help::IsBalloonHelpEnabled()
152 return ImplGetSVData()->maHelpData
.mbBalloonHelp
;
155 void Help::ShowBalloon( vcl::Window
* pParent
,
156 const Point
& rScreenPos
, const tools::Rectangle
& rRect
,
157 const OUString
& rHelpText
)
159 ImplShowHelpWindow( pParent
, HELPWINSTYLE_BALLOON
, QuickHelpFlags::NONE
,
160 rHelpText
, rScreenPos
, rRect
);
163 void Help::EnableQuickHelp()
165 ImplGetSVData()->maHelpData
.mbQuickHelp
= true;
168 void Help::DisableQuickHelp()
170 ImplGetSVData()->maHelpData
.mbQuickHelp
= false;
173 bool Help::IsQuickHelpEnabled()
175 return ImplGetSVData()->maHelpData
.mbQuickHelp
;
178 void Help::ShowQuickHelp( vcl::Window
* pParent
,
179 const tools::Rectangle
& rScreenRect
,
180 const OUString
& rHelpText
,
181 QuickHelpFlags nStyle
)
183 sal_uInt16 nHelpWinStyle
= ( nStyle
& QuickHelpFlags::TipStyleBalloon
) ? HELPWINSTYLE_BALLOON
: HELPWINSTYLE_QUICK
;
184 ImplShowHelpWindow( pParent
, nHelpWinStyle
, nStyle
,
186 pParent
->OutputToScreenPixel( pParent
->GetPointerPosPixel() ), rScreenRect
);
189 void Help::HideBalloonAndQuickHelp()
191 HelpTextWindow
const * pHelpWin
= ImplGetSVData()->maHelpData
.mpHelpWin
;
192 bool const bIsVisible
= ( pHelpWin
!= nullptr ) && pHelpWin
->IsVisible();
193 ImplDestroyHelpWindow( bIsVisible
);
196 void* Help::ShowPopover(vcl::Window
* pParent
, const tools::Rectangle
& rScreenRect
,
197 const OUString
& rText
, QuickHelpFlags nStyle
)
199 void* nId
= pParent
->ImplGetFrame()->ShowPopover(rText
, pParent
, rScreenRect
, nStyle
);
202 //popovers are handled natively, return early
206 sal_uInt16 nHelpWinStyle
= ( nStyle
& QuickHelpFlags::TipStyleBalloon
) ? HELPWINSTYLE_BALLOON
: HELPWINSTYLE_QUICK
;
207 VclPtrInstance
<HelpTextWindow
> pHelpWin( pParent
, rText
, nHelpWinStyle
, nStyle
);
209 nId
= pHelpWin
.get();
210 UpdatePopover(nId
, pParent
, rScreenRect
, rText
);
212 pHelpWin
->ShowHelp(true);
216 void Help::UpdatePopover(void* nId
, vcl::Window
* pParent
, const tools::Rectangle
& rScreenRect
,
217 const OUString
& rText
)
219 if (pParent
->ImplGetFrame()->UpdatePopover(nId
, rText
, pParent
, rScreenRect
))
221 //popovers are handled natively, return early
225 HelpTextWindow
* pHelpWin
= static_cast< HelpTextWindow
* >( nId
);
226 ENSURE_OR_RETURN_VOID( pHelpWin
!= nullptr, "Help::UpdatePopover: invalid ID!" );
228 Size aSz
= pHelpWin
->CalcOutSize();
229 pHelpWin
->SetOutputSizePixel( aSz
);
230 ImplSetHelpWindowPos( pHelpWin
, pHelpWin
->GetWinStyle(), pHelpWin
->GetStyle(),
231 pParent
->OutputToScreenPixel( pParent
->GetPointerPosPixel() ), rScreenRect
);
233 pHelpWin
->SetHelpText( rText
);
234 pHelpWin
->Invalidate();
237 void Help::HidePopover(vcl::Window
const * pParent
, void* nId
)
239 if (pParent
->ImplGetFrame()->HidePopover(nId
))
241 //popovers are handled natively, return early
245 VclPtr
<HelpTextWindow
> pHelpWin
= static_cast<HelpTextWindow
*>(nId
);
246 vcl::Window
* pFrameWindow
= pHelpWin
->ImplGetFrameWindow();
248 // trigger update, so that a Paint is instantly triggered since we do not save the background
249 pFrameWindow
->ImplUpdateAll();
250 pHelpWin
.disposeAndClear();
251 ImplGetSVData()->maHelpData
.mnLastHelpHideTime
= tools::Time::GetSystemTicks();
254 HelpTextWindow::HelpTextWindow( vcl::Window
* pParent
, const OUString
& rText
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
) :
255 FloatingWindow( pParent
, WB_SYSTEMWINDOW
|WB_TOOLTIPWIN
), // #105827# if we change the parent, mirroring will not work correctly when positioning this window
258 SetType( WindowType::HELPTEXTWINDOW
);
259 ImplSetMouseTransparent( true );
260 mnHelpWinStyle
= nHelpWinStyle
;
263 if( mnStyle
& QuickHelpFlags::BiDiRtl
)
265 ComplexTextLayoutFlags nLayoutMode
= GetLayoutMode();
266 nLayoutMode
|= ComplexTextLayoutFlags::BiDiRtl
| ComplexTextLayoutFlags::TextOriginLeft
;
267 SetLayoutMode( nLayoutMode
);
269 SetHelpText( rText
);
270 Window::SetHelpText( rText
);
272 ImplSVData
* pSVData
= ImplGetSVData();
273 if ( pSVData
->maHelpData
.mbSetKeyboardHelp
)
274 pSVData
->maHelpData
.mbKeyboardHelp
= true;
277 maShowTimer
.SetInvokeHandler( LINK( this, HelpTextWindow
, TimerHdl
) );
278 maShowTimer
.SetDebugName( "vcl::HelpTextWindow maShowTimer" );
280 const HelpSettings
& rHelpSettings
= pParent
->GetSettings().GetHelpSettings();
281 maHideTimer
.SetTimeout( rHelpSettings
.GetTipTimeout() );
282 maHideTimer
.SetInvokeHandler( LINK( this, HelpTextWindow
, TimerHdl
) );
283 maHideTimer
.SetDebugName( "vcl::HelpTextWindow maHideTimer" );
286 void HelpTextWindow::ApplySettings(vcl::RenderContext
& rRenderContext
)
288 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
289 SetPointFont(rRenderContext
, rStyleSettings
.GetHelpFont());
290 rRenderContext
.SetTextColor(rStyleSettings
.GetHelpTextColor());
291 rRenderContext
.SetTextAlign(ALIGN_TOP
);
293 if (rRenderContext
.IsNativeControlSupported(ControlType::Tooltip
, ControlPart::Entire
))
295 EnableChildTransparentMode();
296 SetParentClipMode(ParentClipMode::NoClip
);
297 SetPaintTransparent(true);
298 rRenderContext
.SetBackground();
301 rRenderContext
.SetBackground(Wallpaper(rStyleSettings
.GetHelpColor()));
303 if (rStyleSettings
.GetHelpColor().IsDark())
304 rRenderContext
.SetLineColor(COL_WHITE
);
306 rRenderContext
.SetLineColor(COL_BLACK
);
307 rRenderContext
.SetFillColor();
310 HelpTextWindow::~HelpTextWindow()
315 void HelpTextWindow::dispose()
320 if( this == ImplGetSVData()->maHelpData
.mpHelpWin
)
321 ImplGetSVData()->maHelpData
.mpHelpWin
= nullptr;
322 FloatingWindow::dispose();
325 void HelpTextWindow::SetHelpText( const OUString
& rHelpText
)
327 maHelpText
= rHelpText
;
328 ApplySettings(*this);
329 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
&& maHelpText
.getLength() < HELPTEXTMAXLEN
&& maHelpText
.indexOf('\n') < 0)
332 aSize
.setHeight( GetTextHeight() );
333 if ( mnStyle
& QuickHelpFlags::CtrlText
)
334 aSize
.setWidth( GetCtrlTextWidth( maHelpText
) );
336 aSize
.setWidth( GetTextWidth( maHelpText
) );
337 maTextRect
= tools::Rectangle( Point( HELPTEXTMARGIN_QUICK
, HELPTEXTMARGIN_QUICK
), aSize
);
339 else // HELPWINSTYLE_BALLOON
341 sal_Int32 nCharsInLine
= 35 + ((maHelpText
.getLength()/100)*5);
342 // average width to have all windows consistent
344 comphelper::string::padToLength(aBuf
, nCharsInLine
, 'x');
345 OUString aXXX
= aBuf
.makeStringAndClear();
346 long nWidth
= GetTextWidth( aXXX
);
347 Size
aTmpSize( nWidth
, 0x7FFFFFFF );
348 tools::Rectangle
aTry1( Point(), aTmpSize
);
349 DrawTextFlags nDrawFlags
= DrawTextFlags::MultiLine
| DrawTextFlags::WordBreak
|
350 DrawTextFlags::Left
| DrawTextFlags::Top
;
351 if ( mnStyle
& QuickHelpFlags::CtrlText
)
352 nDrawFlags
|= DrawTextFlags::Mnemonic
;
353 tools::Rectangle aTextRect
= GetTextRect( aTry1
, maHelpText
, nDrawFlags
);
355 // get a better width later...
356 maTextRect
= aTextRect
;
358 // safety distance...
359 maTextRect
.SetPos( Point( HELPTEXTMARGIN_BALLOON
, HELPTEXTMARGIN_BALLOON
) );
362 Size
aSize( CalcOutSize() );
363 SetOutputSizePixel( aSize
);
366 void HelpTextWindow::ImplShow()
368 VclPtr
<HelpTextWindow
> xWindow( this );
369 Show( true, ShowFlags::NoActivate
);
370 if( !xWindow
->IsDisposed() )
374 void HelpTextWindow::Paint( vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& )
376 // paint native background
377 bool bNativeOK
= false;
378 if (rRenderContext
.IsNativeControlSupported(ControlType::Tooltip
, ControlPart::Entire
))
380 tools::Rectangle
aCtrlRegion(Point(0, 0), GetOutputSizePixel());
381 ImplControlValue aControlValue
;
382 bNativeOK
= rRenderContext
.DrawNativeControl(ControlType::Tooltip
, ControlPart::Entire
, aCtrlRegion
,
383 ControlState::NONE
, aControlValue
, OUString());
387 if (mnHelpWinStyle
== HELPWINSTYLE_QUICK
&& maHelpText
.getLength() < HELPTEXTMAXLEN
&& maHelpText
.indexOf('\n') < 0)
389 if ( mnStyle
& QuickHelpFlags::CtrlText
)
390 rRenderContext
.DrawCtrlText(maTextRect
.TopLeft(), maHelpText
);
392 rRenderContext
.DrawText(maTextRect
.TopLeft(), maHelpText
);
394 else // HELPWINSTYLE_BALLOON
396 DrawTextFlags nDrawFlags
= DrawTextFlags::MultiLine
|DrawTextFlags::WordBreak
|
397 DrawTextFlags::Left
|DrawTextFlags::Top
;
398 if (mnStyle
& QuickHelpFlags::CtrlText
)
399 nDrawFlags
|= DrawTextFlags::Mnemonic
;
400 rRenderContext
.DrawText(maTextRect
, maHelpText
, nDrawFlags
);
406 Size aSz
= GetOutputSizePixel();
407 rRenderContext
.DrawRect(tools::Rectangle(Point(), aSz
));
408 if (mnHelpWinStyle
== HELPWINSTYLE_BALLOON
)
410 aSz
.AdjustWidth( -2 );
411 aSz
.AdjustHeight( -2 );
412 Color
aColor(rRenderContext
.GetLineColor());
413 rRenderContext
.SetLineColor(COL_GRAY
);
414 rRenderContext
.DrawRect(tools::Rectangle(Point(1, 1), aSz
));
415 rRenderContext
.SetLineColor(aColor
);
420 void HelpTextWindow::ShowHelp(bool bNoDelay
)
422 sal_uLong nTimeout
= 0;
425 // In case of ExtendedHelp display help sooner
426 if ( ImplGetSVData()->maHelpData
.mbExtHelpMode
)
430 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
)
431 nTimeout
= HelpSettings::GetTipDelay();
433 nTimeout
= HelpSettings::GetBalloonDelay();
437 maShowTimer
.SetTimeout( nTimeout
);
441 IMPL_LINK( HelpTextWindow
, TimerHdl
, Timer
*, pTimer
, void)
443 if ( pTimer
== &maShowTimer
)
445 if ( mnHelpWinStyle
== HELPWINSTYLE_QUICK
)
447 // start auto-hide-timer for non-ShowTip windows
448 ImplSVData
* pSVData
= ImplGetSVData();
449 if ( this == pSVData
->maHelpData
.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 ImplSVData
* pSVData
= ImplGetSVData();
492 if (rHelpText
.isEmpty() && !pSVData
->maHelpData
.mbRequestingHelp
)
495 VclPtr
<HelpTextWindow
> pHelpWin
= pSVData
->maHelpData
.mpHelpWin
;
496 bool bNoDelay
= false;
499 SAL_WARN_IF( pHelpWin
== pParent
, "vcl", "HelpInHelp ?!" );
501 if ( ( rHelpText
.isEmpty()
502 || ( pHelpWin
->GetWinStyle() != nHelpWinStyle
)
504 && pSVData
->maHelpData
.mbRequestingHelp
507 // remove help window if no HelpText or
508 // other help mode. but keep it if we are scrolling, ie not requesting help
509 bool bWasVisible
= pHelpWin
->IsVisible();
511 bNoDelay
= true; // display it quickly if we were already in quick help mode
513 ImplDestroyHelpWindow( bWasVisible
);
517 bool const bUpdate
= (pHelpWin
->GetHelpText() != rHelpText
) ||
518 ((pHelpWin
->GetHelpArea() != rHelpArea
) && pSVData
->maHelpData
.mbRequestingHelp
);
521 vcl::Window
* pWindow
= pHelpWin
->GetParent()->ImplGetFrameWindow();
522 tools::Rectangle
aInvRect( pHelpWin
->GetWindowExtentsRelative( pWindow
) );
523 if( pHelpWin
->IsVisible() )
524 pWindow
->Invalidate( aInvRect
);
526 pHelpWin
->SetHelpText( rHelpText
);
527 // approach mouse position
528 ImplSetHelpWindowPos( pHelpWin
, nHelpWinStyle
, nStyle
, rScreenPos
, rHelpArea
);
529 if( pHelpWin
->IsVisible() )
530 pHelpWin
->Invalidate();
535 if (pHelpWin
|| rHelpText
.isEmpty())
538 sal_uInt64 nCurTime
= tools::Time::GetSystemTicks();
539 if ( ( nCurTime
- pSVData
->maHelpData
.mnLastHelpHideTime
) < HelpSettings::GetTipDelay() )
542 pHelpWin
= VclPtr
<HelpTextWindow
>::Create( pParent
, rHelpText
, nHelpWinStyle
, nStyle
);
543 pSVData
->maHelpData
.mpHelpWin
= pHelpWin
;
544 pHelpWin
->SetHelpArea( rHelpArea
);
547 Size aSz
= pHelpWin
->CalcOutSize();
548 pHelpWin
->SetOutputSizePixel( aSz
);
549 ImplSetHelpWindowPos( pHelpWin
, nHelpWinStyle
, nStyle
, rScreenPos
, rHelpArea
);
550 // if not called from Window::RequestHelp, then without delay...
551 if ( !pSVData
->maHelpData
.mbRequestingHelp
)
553 pHelpWin
->ShowHelp(bNoDelay
);
557 void ImplDestroyHelpWindow( bool bUpdateHideTime
)
559 ImplSVData
* pSVData
= ImplGetSVData();
560 VclPtr
<HelpTextWindow
> pHelpWin
= pSVData
->maHelpData
.mpHelpWin
;
563 vcl::Window
* pWindow
= pHelpWin
->GetParent()->ImplGetFrameWindow();
564 // find out screen area covered by system help window
565 tools::Rectangle
aInvRect( pHelpWin
->GetWindowExtentsRelative( pWindow
) );
566 if( pHelpWin
->IsVisible() )
567 pWindow
->Invalidate( aInvRect
);
568 pSVData
->maHelpData
.mpHelpWin
= nullptr;
569 pSVData
->maHelpData
.mbKeyboardHelp
= false;
571 pHelpWin
.disposeAndClear();
572 if( bUpdateHideTime
)
573 pSVData
->maHelpData
.mnLastHelpHideTime
= tools::Time::GetSystemTicks();
577 void ImplSetHelpWindowPos( vcl::Window
* pHelpWin
, sal_uInt16 nHelpWinStyle
, QuickHelpFlags nStyle
,
578 const Point
& rPos
, const tools::Rectangle
& rHelpArea
)
581 Size aSz
= pHelpWin
->GetSizePixel();
582 tools::Rectangle aScreenRect
= pHelpWin
->ImplGetFrameWindow()->GetDesktopRectPixel();
583 aPos
= pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aPos
);
584 // get mouse screen coords
585 Point
aMousePos( pHelpWin
->GetParent()->ImplGetFrameWindow()->GetPointerPosPixel() );
586 aMousePos
= pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aMousePos
);
588 if ( nHelpWinStyle
== HELPWINSTYLE_QUICK
)
590 if ( !(nStyle
& QuickHelpFlags::NoAutoPos
) )
592 long nScreenHeight
= aScreenRect
.GetHeight();
594 if ( aPos
.Y() > aScreenRect
.Top()+nScreenHeight
-(nScreenHeight
/4) )
595 aPos
.AdjustY( -(aSz
.Height()+4) );
602 // If it's the mouse position, move the window slightly
603 // so the mouse pointer does not cover it
604 if ( aPos
== aMousePos
)
611 if ( nStyle
& QuickHelpFlags::NoAutoPos
)
613 // convert help area to screen coords
614 tools::Rectangle
devHelpArea(
615 pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea
.TopLeft() ),
616 pHelpWin
->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea
.BottomRight() ) );
618 // which position of the rectangle?
619 aPos
= devHelpArea
.Center();
621 if ( nStyle
& QuickHelpFlags::Left
)
622 aPos
.setX( devHelpArea
.Left() );
623 else if ( nStyle
& QuickHelpFlags::Right
)
624 aPos
.setX( devHelpArea
.Right() );
626 if ( nStyle
& QuickHelpFlags::Top
)
627 aPos
.setY( devHelpArea
.Top() );
628 else if ( nStyle
& QuickHelpFlags::Bottom
)
629 aPos
.setY( devHelpArea
.Bottom() );
632 if ( nStyle
& QuickHelpFlags::Left
)
634 else if ( nStyle
& QuickHelpFlags::Right
)
635 aPos
.AdjustX( -(aSz
.Width()) );
637 aPos
.AdjustX( -(aSz
.Width()/2) );
639 if ( nStyle
& QuickHelpFlags::Top
)
641 else if ( nStyle
& QuickHelpFlags::Bottom
)
642 aPos
.AdjustY( -(aSz
.Height()) );
644 aPos
.AdjustY( -(aSz
.Height()/2) );
647 if ( aPos
.X() < aScreenRect
.Left() )
648 aPos
.setX( aScreenRect
.Left() );
649 else if ( ( aPos
.X() + aSz
.Width() ) > aScreenRect
.Right() )
650 aPos
.setX( aScreenRect
.Right() - aSz
.Width() );
651 if ( aPos
.Y() < aScreenRect
.Top() )
652 aPos
.setY( aScreenRect
.Top() );
653 else if ( ( aPos
.Y() + aSz
.Height() ) > aScreenRect
.Bottom() )
654 aPos
.setY( aScreenRect
.Bottom() - aSz
.Height() );
656 if( ! (nStyle
& QuickHelpFlags::NoEvadePointer
) )
658 /* the remark below should be obsolete by now as the helpwindow should
659 not be focusable, leaving it as a hint. However it is sensible in most
660 conditions to evade the mouse pointer so the content window is fully visible.
662 // the popup must not appear under the mouse
663 // otherwise it would directly be closed due to a focus change...
665 tools::Rectangle
aHelpRect( aPos
, aSz
);
666 if( aHelpRect
.IsInside( aMousePos
) )
669 Point
aSize( aSz
.Width(), aSz
.Height() );
670 Point
aTest( aMousePos
- aSize
- delta
);
671 if( aTest
.X() > aScreenRect
.Left() && aTest
.Y() > aScreenRect
.Top() )
674 aPos
= aMousePos
+ delta
;
678 vcl::Window
* pWindow
= pHelpWin
->GetParent()->ImplGetFrameWindow();
679 aPos
= pWindow
->AbsoluteScreenToOutputPixel( aPos
);
680 pHelpWin
->SetPosPixel( aPos
);
683 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */