crashtesting: assert on reimport of docx export of ooo102874-2.doc
[LibreOffice.git] / vcl / source / app / help.cxx
blobde54818d05a0dbb2170362b73750a2ec3595ba8a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
35 #include <svdata.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
45 Help::Help()
49 Help::~Help()
53 bool Help::Start( const OUString&, const vcl::Window* )
55 return false;
58 bool Help::Start(const OUString&, weld::Widget*)
60 return false;
63 void Help::SearchKeyword( const OUString& )
67 OUString Help::GetHelpText( const OUString& )
69 return 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();
109 return true;
112 return false;
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();
126 return true;
129 return false;
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
177 ? Point()
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);
194 if (nId)
196 //popovers are handled natively, return early
197 return nId;
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);
207 return nId;
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
216 return;
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
236 return;
239 VclPtr<HelpTextWindow> pHelpWin = static_cast<HelpTextWindow*>(nId);
240 vcl::Window* pFrameWindow = pHelpWin->ImplGetFrameWindow();
241 pHelpWin->Hide();
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
250 maHelpText( rText ),
251 maShowTimer( "vcl::HelpTextWindow maShowTimer" ),
252 maHideTimer( "vcl::HelpTextWindow maHideTimer" )
254 SetType( WindowType::HELPTEXTWINDOW );
255 ImplSetMouseTransparent( true );
256 mnHelpWinStyle = nHelpWinStyle;
257 mnStyle = nStyle;
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();
293 else
294 rRenderContext.SetBackground(Wallpaper(rStyleSettings.GetHelpColor()));
296 if (rStyleSettings.GetHelpColor().IsDark())
297 rRenderContext.SetLineColor(COL_WHITE);
298 else
299 rRenderContext.SetLineColor(COL_BLACK);
300 rRenderContext.SetFillColor();
303 HelpTextWindow::~HelpTextWindow()
305 disposeOnce();
308 void HelpTextWindow::dispose()
310 maShowTimer.Stop();
311 maHideTimer.Stop();
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)
324 Size aSize;
325 aSize.setHeight( GetTextHeight() );
326 if ( mnStyle & QuickHelpFlags::CtrlText )
327 aSize.setWidth( GetOutDev()->GetCtrlTextWidth( maHelpText ) );
328 else
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();
337 else
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 );
360 if (IsVisible())
361 PaintImmediately();
364 void HelpTextWindow::ImplShow()
366 VclPtr<HelpTextWindow> xWindow( this );
367 Show( true, ShowFlags::NoActivate );
368 if( !xWindow->isDisposed() )
369 PaintImmediately();
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());
384 // paint text
385 if (mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN && maHelpText.indexOf('\n') < 0)
387 if ( mnStyle & QuickHelpFlags::CtrlText )
388 rRenderContext.DrawCtrlText(maTextRect.TopLeft(), maHelpText);
389 else
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);
401 // border
402 if (bNativeOK)
403 return;
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;
421 if (!bNoDelay)
423 // In case of ExtendedHelp display help sooner
424 if ( ImplGetSVHelpData().mbExtHelpMode )
425 nTimeout = 15;
426 else
428 if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
429 nTimeout = HelpSettings::GetTipDelay();
430 else
431 nTimeout = HelpSettings::GetBalloonDelay();
435 maShowTimer.SetTimeout( nTimeout );
436 maShowTimer.Start();
439 IMPL_LINK( HelpTextWindow, TimerHdl, Timer*, pTimer, void)
441 if ( pTimer == &maShowTimer )
443 ResetHideTimer();
444 ImplShow();
446 else
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() );
458 return aSz;
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
469 return maHelpText;
472 void HelpTextWindow::ResetHideTimer()
474 if (mnHelpWinStyle == HELPWINSTYLE_QUICK)
476 // start auto-hide-timer for non-ShowTip windows
477 if (this == ImplGetSVHelpData().mpHelpWin)
478 maHideTimer.Start();
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
489 return;
492 ImplSVHelpData& aHelpData = ImplGetSVHelpData();
494 if (rHelpText.isEmpty() && !aHelpData.mbRequestingHelp)
495 return;
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);
509 if (bUpdate)
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
518 return;
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();
524 if ( bWasVisible )
525 bNoDelay = true; // display it quickly if we were already in quick help mode
526 ImplDestroyHelpWindow( bWasVisible );
529 if (rHelpText.isEmpty())
530 return;
532 VclPtr<HelpTextWindow> pHelpWin = VclPtr<HelpTextWindow>::Create( pParent, rHelpText, nHelpWinStyle, nStyle );
533 aHelpData.mpHelpWin = pHelpWin;
534 pHelpWin->SetHelpArea( rHelpArea );
536 // positioning
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...
541 if (!bNoDelay)
543 if ( !aHelpData.mbRequestingHelp )
545 bNoDelay = true;
547 else
549 sal_uInt64 nCurTime = tools::Time::GetSystemTicks();
550 if ( ( nCurTime - aHelpData.mnLastHelpHideTime ) < o3tl::make_unsigned(HelpSettings::GetTipDelay()) )
551 bNoDelay = true;
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;
565 if( pHelpWin )
567 rHelpData.mpHelpWin = nullptr;
568 rHelpData.mbKeyboardHelp = false;
569 pHelpWin->Hide();
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() );
606 // which direction?
607 if ( nStyle & QuickHelpFlags::Left )
609 else if ( nStyle & QuickHelpFlags::Right )
610 aPos.AdjustX( -(aSz.Width()) );
611 else
612 aPos.AdjustX( -(aSz.Width()/2) );
614 if ( nStyle & QuickHelpFlags::Top )
616 else if ( nStyle & QuickHelpFlags::Bottom )
617 aPos.AdjustY( -(aSz.Height()) );
618 else
619 aPos.AdjustY( -(aSz.Height()/2) );
621 else
623 aPos = pWindow->OutputToAbsoluteScreenPixel(rPos);
624 if ( nHelpWinStyle == HELPWINSTYLE_QUICK )
626 tools::Long nScreenHeight = aScreenRect.GetHeight();
627 aPos.AdjustX( -4 );
628 if ( aPos.Y() > aScreenRect.Top()+nScreenHeight-(nScreenHeight/4) )
629 aPos.AdjustY( -(aSz.Height()+4) );
630 else
631 aPos.AdjustY(21 );
633 else
635 // If it's the mouse position, move the window slightly
636 // so the mouse pointer does not cover it
637 if ( aPos == aMousePos )
639 aPos.AdjustX(12 );
640 aPos.AdjustY(16 );
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() )
670 aPos = aTest;
671 else
672 aPos = aMousePos + delta;
676 Point aPosOut = pWindow->AbsoluteScreenToOutputPixel( aPos );
677 pHelpWin->SetPosPixel( aPosOut );
680 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */