Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / source / app / help.cxx
blob29221658c2e23be745999d399bcbf69638deabe4
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>
22 #include "tools/diagnose_ex.h"
23 #include "tools/time.hxx"
25 #include <vcl/window.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/wrkwin.hxx>
29 #include <vcl/help.hxx>
30 #include <vcl/settings.hxx>
32 #include "helpwin.hxx"
33 #include "salframe.hxx"
34 #include "svdata.hxx"
36 #define HELPWINSTYLE_QUICK 0
37 #define HELPWINSTYLE_BALLOON 1
39 #define HELPTEXTMARGIN_QUICK 3
40 #define HELPTEXTMARGIN_BALLOON 6
42 #define HELPDELAY_NORMAL 1
43 #define HELPDELAY_SHORT 2
44 #define HELPDELAY_NONE 3
46 #define HELPTEXTMAXLEN 150
48 Help::Help()
52 Help::~Help()
56 bool Help::Start( const OUString&, const vcl::Window* )
58 return false;
61 bool Help::SearchKeyword( const OUString& )
63 return false;
66 OUString Help::GetHelpText( const OUString&, const vcl::Window* )
68 return OUString();
71 void Help::EnableContextHelp()
73 ImplGetSVData()->maHelpData.mbContextHelp = true;
76 void Help::DisableContextHelp()
78 ImplGetSVData()->maHelpData.mbContextHelp = false;
81 bool Help::IsContextHelpEnabled()
83 return ImplGetSVData()->maHelpData.mbContextHelp;
86 void Help::EnableExtHelp()
88 ImplGetSVData()->maHelpData.mbExtHelp = true;
91 void Help::DisableExtHelp()
93 ImplGetSVData()->maHelpData.mbExtHelp = false;
96 bool Help::IsExtHelpEnabled()
98 return ImplGetSVData()->maHelpData.mbExtHelp;
101 bool Help::StartExtHelp()
103 ImplSVData* pSVData = ImplGetSVData();
105 if ( pSVData->maHelpData.mbExtHelp && !pSVData->maHelpData.mbExtHelpMode )
107 pSVData->maHelpData.mbExtHelpMode = true;
108 pSVData->maHelpData.mbOldBalloonMode = pSVData->maHelpData.mbBalloonHelp;
109 pSVData->maHelpData.mbBalloonHelp = true;
110 if ( pSVData->maWinData.mpAppWin )
111 pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
112 return true;
115 return false;
118 bool Help::EndExtHelp()
120 ImplSVData* pSVData = ImplGetSVData();
122 if ( pSVData->maHelpData.mbExtHelp && pSVData->maHelpData.mbExtHelpMode )
124 pSVData->maHelpData.mbExtHelpMode = false;
125 pSVData->maHelpData.mbBalloonHelp = pSVData->maHelpData.mbOldBalloonMode;
126 if ( pSVData->maWinData.mpAppWin )
127 pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
128 return true;
131 return false;
134 void Help::EnableBalloonHelp()
136 ImplGetSVData()->maHelpData.mbBalloonHelp = true;
139 void Help::DisableBalloonHelp()
141 ImplGetSVData()->maHelpData.mbBalloonHelp = false;
144 bool Help::IsBalloonHelpEnabled()
146 return ImplGetSVData()->maHelpData.mbBalloonHelp;
149 bool Help::ShowBalloon( vcl::Window* pParent,
150 const Point& rScreenPos, const tools::Rectangle& rRect,
151 const OUString& rHelpText )
153 ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, QuickHelpFlags::NONE,
154 rHelpText, OUString(), rScreenPos, rRect );
156 return true;
159 void Help::EnableQuickHelp()
161 ImplGetSVData()->maHelpData.mbQuickHelp = true;
164 void Help::DisableQuickHelp()
166 ImplGetSVData()->maHelpData.mbQuickHelp = false;
169 bool Help::IsQuickHelpEnabled()
171 return ImplGetSVData()->maHelpData.mbQuickHelp;
174 bool Help::ShowQuickHelp( vcl::Window* pParent,
175 const tools::Rectangle& rScreenRect,
176 const OUString& rHelpText,
177 const OUString& rLongHelpText,
178 QuickHelpFlags nStyle )
180 sal_uInt16 nHelpWinStyle = ( nStyle & QuickHelpFlags::TipStyleBalloon ) ? HELPWINSTYLE_BALLOON : HELPWINSTYLE_QUICK;
181 ImplShowHelpWindow( pParent, nHelpWinStyle, nStyle,
182 rHelpText, rLongHelpText,
183 pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), rScreenRect );
184 return true;
187 void Help::HideBalloonAndQuickHelp()
189 HelpTextWindow const * pHelpWin = ImplGetSVData()->maHelpData.mpHelpWin;
190 bool const bIsVisible = ( pHelpWin != nullptr ) && pHelpWin->IsVisible();
191 ImplDestroyHelpWindow( bIsVisible );
194 sal_uIntPtr Help::ShowPopover(vcl::Window* pParent, const tools::Rectangle& rScreenRect,
195 const OUString& rText, QuickHelpFlags nStyle)
197 sal_uIntPtr nId = pParent->ImplGetFrame()->ShowPopover(rText, rScreenRect, nStyle);
198 if (nId)
200 //popovers are handled natively, return early
201 return nId;
204 sal_uInt16 nHelpWinStyle = ( nStyle & QuickHelpFlags::TipStyleBalloon ) ? HELPWINSTYLE_BALLOON : HELPWINSTYLE_QUICK;
205 VclPtrInstance<HelpTextWindow> pHelpWin( pParent, rText, nHelpWinStyle, nStyle );
207 nId = reinterpret_cast< sal_uIntPtr >( pHelpWin.get() );
208 UpdatePopover(nId, pParent, rScreenRect, rText);
210 pHelpWin->ShowHelp( HELPDELAY_NONE );
211 return nId;
214 void Help::UpdatePopover(sal_uIntPtr nId, vcl::Window* pParent, const tools::Rectangle& rScreenRect,
215 const OUString& rText)
217 if (pParent->ImplGetFrame()->UpdatePopover(nId, rText, rScreenRect))
219 //popovers are handled natively, return early
220 return;
223 HelpTextWindow* pHelpWin = reinterpret_cast< HelpTextWindow* >( nId );
224 ENSURE_OR_RETURN_VOID( pHelpWin != nullptr, "Help::UpdatePopover: invalid ID!" );
226 Size aSz = pHelpWin->CalcOutSize();
227 pHelpWin->SetOutputSizePixel( aSz );
228 ImplSetHelpWindowPos( pHelpWin, pHelpWin->GetWinStyle(), pHelpWin->GetStyle(),
229 pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), rScreenRect );
231 pHelpWin->SetHelpText( rText );
232 pHelpWin->Invalidate();
235 void Help::HidePopover(vcl::Window* pParent, sal_uLong nId)
237 if (pParent->ImplGetFrame()->HidePopover(nId))
239 //popovers are handled natively, return early
240 return;
243 VclPtr<HelpTextWindow> pHelpWin = reinterpret_cast<HelpTextWindow*>(nId);
244 vcl::Window* pFrameWindow = pHelpWin->ImplGetFrameWindow();
245 pHelpWin->Hide();
246 // trigger update, so that a Paint is instantly triggered since we do not save the background
247 pFrameWindow->ImplUpdateAll();
248 pHelpWin.disposeAndClear();
249 ImplGetSVData()->maHelpData.mnLastHelpHideTime = tools::Time::GetSystemTicks();
252 HelpTextWindow::HelpTextWindow( vcl::Window* pParent, const OUString& rText, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle ) :
253 FloatingWindow( pParent, WB_SYSTEMWINDOW|WB_TOOLTIPWIN ), // #105827# if we change the parent, mirroring will not work correctly when positioning this window
254 maHelpText( rText )
256 SetType( WindowType::HELPTEXTWINDOW );
257 ImplSetMouseTransparent( true );
258 mnHelpWinStyle = nHelpWinStyle;
259 mnStyle = nStyle;
261 if( mnStyle & QuickHelpFlags::BiDiRtl )
263 ComplexTextLayoutFlags nLayoutMode = GetLayoutMode();
264 nLayoutMode |= ComplexTextLayoutFlags::BiDiRtl | ComplexTextLayoutFlags::TextOriginLeft;
265 SetLayoutMode( nLayoutMode );
267 SetHelpText( rText );
268 Window::SetHelpText( rText );
270 ImplSVData* pSVData = ImplGetSVData();
271 if ( pSVData->maHelpData.mbSetKeyboardHelp )
272 pSVData->maHelpData.mbKeyboardHelp = true;
275 maShowTimer.SetInvokeHandler( LINK( this, HelpTextWindow, TimerHdl ) );
276 maShowTimer.SetDebugName( "vcl::HelpTextWindow maShowTimer" );
278 const HelpSettings& rHelpSettings = pParent->GetSettings().GetHelpSettings();
279 maHideTimer.SetTimeout( rHelpSettings.GetTipTimeout() );
280 maHideTimer.SetInvokeHandler( LINK( this, HelpTextWindow, TimerHdl ) );
281 maHideTimer.SetDebugName( "vcl::HelpTextWindow maHideTimer" );
284 void HelpTextWindow::StateChanged(StateChangedType nType)
286 FloatingWindow::StateChanged(nType);
287 if (nType == StateChangedType::InitShow)
289 ApplySettings(*this);
290 SetHelpText(maHelpText);
291 Invalidate();
295 void HelpTextWindow::ApplySettings(vcl::RenderContext& rRenderContext)
297 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
298 SetPointFont(rRenderContext, rStyleSettings.GetHelpFont());
299 rRenderContext.SetTextColor(rStyleSettings.GetHelpTextColor());
300 rRenderContext.SetTextAlign(ALIGN_TOP);
302 if (rRenderContext.IsNativeControlSupported(ControlType::Tooltip, ControlPart::Entire))
304 EnableChildTransparentMode();
305 SetParentClipMode(ParentClipMode::NoClip);
306 SetPaintTransparent(true);
307 rRenderContext.SetBackground();
309 else
310 rRenderContext.SetBackground(Wallpaper(rStyleSettings.GetHelpColor()));
312 if (rStyleSettings.GetHelpColor().IsDark())
313 rRenderContext.SetLineColor(COL_WHITE);
314 else
315 rRenderContext.SetLineColor(COL_BLACK);
316 rRenderContext.SetFillColor();
319 HelpTextWindow::~HelpTextWindow()
321 disposeOnce();
324 void HelpTextWindow::dispose()
326 maShowTimer.Stop();
327 maHideTimer.Stop();
329 if( this == ImplGetSVData()->maHelpData.mpHelpWin )
330 ImplGetSVData()->maHelpData.mpHelpWin = nullptr;
331 FloatingWindow::dispose();
334 void HelpTextWindow::SetHelpText( const OUString& rHelpText )
336 maHelpText = rHelpText;
337 if ( mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN)
339 Size aSize;
340 aSize.Height() = GetTextHeight();
341 if ( mnStyle & QuickHelpFlags::CtrlText )
342 aSize.Width() = GetCtrlTextWidth( maHelpText );
343 else
344 aSize.Width() = GetTextWidth( maHelpText );
345 maTextRect = tools::Rectangle( Point( HELPTEXTMARGIN_QUICK, HELPTEXTMARGIN_QUICK ), aSize );
347 else // HELPWINSTYLE_BALLOON
349 Point aTmpPoint;
350 sal_Int32 nCharsInLine = 35 + ((maHelpText.getLength()/100)*5);
351 // average width to have all windows consistent
352 OUStringBuffer aBuf;
353 comphelper::string::padToLength(aBuf, nCharsInLine, 'x');
354 OUString aXXX = aBuf.makeStringAndClear();
355 long nWidth = GetTextWidth( aXXX );
356 Size aTmpSize( nWidth, 0x7FFFFFFF );
357 tools::Rectangle aTry1( aTmpPoint, aTmpSize );
358 DrawTextFlags nDrawFlags = DrawTextFlags::MultiLine | DrawTextFlags::WordBreak |
359 DrawTextFlags::Left | DrawTextFlags::Top;
360 if ( mnStyle & QuickHelpFlags::CtrlText )
361 nDrawFlags |= DrawTextFlags::Mnemonic;
362 tools::Rectangle aTextRect = GetTextRect( aTry1, maHelpText, nDrawFlags );
364 // get a better width later...
365 maTextRect = aTextRect;
367 // safety distance...
368 maTextRect.SetPos( Point( HELPTEXTMARGIN_BALLOON, HELPTEXTMARGIN_BALLOON ) );
371 Size aSize( CalcOutSize() );
372 SetOutputSizePixel( aSize );
375 void HelpTextWindow::ImplShow()
377 VclPtr<HelpTextWindow> xWindow( this );
378 Show( true, ShowFlags::NoActivate );
379 if( !xWindow->IsDisposed() )
380 Update();
383 void HelpTextWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
385 // paint native background
386 bool bNativeOK = false;
387 if (rRenderContext.IsNativeControlSupported(ControlType::Tooltip, ControlPart::Entire))
389 tools::Rectangle aCtrlRegion(Point(0, 0), GetOutputSizePixel());
390 ImplControlValue aControlValue;
391 bNativeOK = rRenderContext.DrawNativeControl(ControlType::Tooltip, ControlPart::Entire, aCtrlRegion,
392 ControlState::NONE, aControlValue, OUString());
395 // paint text
396 if (mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN)
398 if ( mnStyle & QuickHelpFlags::CtrlText )
399 rRenderContext.DrawCtrlText(maTextRect.TopLeft(), maHelpText);
400 else
401 rRenderContext.DrawText(maTextRect.TopLeft(), maHelpText);
403 else // HELPWINSTYLE_BALLOON
405 DrawTextFlags nDrawFlags = DrawTextFlags::MultiLine|DrawTextFlags::WordBreak|
406 DrawTextFlags::Left|DrawTextFlags::Top;
407 if (mnStyle & QuickHelpFlags::CtrlText)
408 nDrawFlags |= DrawTextFlags::Mnemonic;
409 rRenderContext.DrawText(maTextRect, maHelpText, nDrawFlags);
412 // border
413 if (!bNativeOK)
415 Size aSz = GetOutputSizePixel();
416 rRenderContext.DrawRect(tools::Rectangle(Point(), aSz));
417 if (mnHelpWinStyle == HELPWINSTYLE_BALLOON)
419 aSz.Width() -= 2;
420 aSz.Height() -= 2;
421 Color aColor(rRenderContext.GetLineColor());
422 rRenderContext.SetLineColor(COL_GRAY);
423 rRenderContext.DrawRect(tools::Rectangle(Point(1, 1), aSz));
424 rRenderContext.SetLineColor(aColor);
429 void HelpTextWindow::ShowHelp( sal_uInt16 nDelayMode )
431 sal_uLong nTimeout = 0;
432 if ( nDelayMode != HELPDELAY_NONE )
434 // In case of ExtendedHelp display help sooner
435 if ( ImplGetSVData()->maHelpData.mbExtHelpMode )
436 nTimeout = 15;
437 else
439 const HelpSettings& rHelpSettings = GetSettings().GetHelpSettings();
440 if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
441 nTimeout = rHelpSettings.GetTipDelay();
442 else
443 nTimeout = rHelpSettings.GetBalloonDelay();
446 if ( nDelayMode == HELPDELAY_SHORT )
447 nTimeout /= 3;
450 maShowTimer.SetTimeout( nTimeout );
451 maShowTimer.Start();
454 IMPL_LINK( HelpTextWindow, TimerHdl, Timer*, pTimer, void)
456 if ( pTimer == &maShowTimer )
458 if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
460 // start auto-hide-timer for non-ShowTip windows
461 ImplSVData* pSVData = ImplGetSVData();
462 if ( this == pSVData->maHelpData.mpHelpWin )
463 maHideTimer.Start();
465 ImplShow();
467 else
469 SAL_WARN_IF( pTimer != &maHideTimer, "vcl", "HelpTextWindow::TimerHdl with bad Timer" );
470 ImplDestroyHelpWindow( true );
474 Size HelpTextWindow::CalcOutSize() const
476 Size aSz = maTextRect.GetSize();
477 aSz.Width() += 2*maTextRect.Left();
478 aSz.Height() += 2*maTextRect.Top();
479 return aSz;
482 void HelpTextWindow::RequestHelp( const HelpEvent& /*rHEvt*/ )
484 // Just to assure that Window::RequestHelp() is not called by
485 // ShowQuickHelp/ShowBalloonHelp in the HelpTextWindow.
488 OUString HelpTextWindow::GetText() const
490 return maHelpText;
493 void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle,
494 const OUString& rHelpText, const OUString& rStatusText,
495 const Point& rScreenPos, const tools::Rectangle& rHelpArea )
497 if (pParent->ImplGetFrame()->ShowTooltip(rHelpText, rHelpArea))
499 //tooltips are handled natively, return early
500 return;
503 ImplSVData* pSVData = ImplGetSVData();
505 if (rHelpText.isEmpty() && !pSVData->maHelpData.mbRequestingHelp)
506 return;
508 VclPtr<HelpTextWindow> pHelpWin = pSVData->maHelpData.mpHelpWin;
509 sal_uInt16 nDelayMode = HELPDELAY_NORMAL;
510 if ( pHelpWin )
512 SAL_WARN_IF( pHelpWin == pParent, "vcl", "HelpInHelp ?!" );
514 if ( ( ( pHelpWin->GetHelpText() != rHelpText )
515 || ( pHelpWin->GetWinStyle() != nHelpWinStyle )
516 || ( pHelpWin->GetHelpArea() != rHelpArea )
518 && pSVData->maHelpData.mbRequestingHelp
521 // remove help window if no HelpText or other 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 nDelayMode = HELPDELAY_NONE; // display it quickly if we were already in quick help mode
526 pHelpWin = nullptr;
527 ImplDestroyHelpWindow( bWasVisible );
529 else
531 bool const bTextChanged = rHelpText != pHelpWin->GetHelpText();
532 if (bTextChanged)
534 vcl::Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
535 tools::Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
536 if( pHelpWin->IsVisible() )
537 pWindow->Invalidate( aInvRect );
539 pHelpWin->SetHelpText( rHelpText );
540 // approach mouse position
541 ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, rHelpArea );
542 if( pHelpWin->IsVisible() )
543 pHelpWin->Invalidate();
548 if (!pHelpWin && !rHelpText.isEmpty())
550 sal_uInt64 nCurTime = tools::Time::GetSystemTicks();
551 if ( ( ( nCurTime - pSVData->maHelpData.mnLastHelpHideTime ) < pParent->GetSettings().GetHelpSettings().GetTipDelay() )
552 || ( nStyle & QuickHelpFlags::NoDelay )
554 nDelayMode = HELPDELAY_NONE;
556 pHelpWin = VclPtr<HelpTextWindow>::Create( pParent, rHelpText, nHelpWinStyle, nStyle );
557 pSVData->maHelpData.mpHelpWin = pHelpWin;
558 pHelpWin->SetStatusText( rStatusText );
559 pHelpWin->SetHelpArea( rHelpArea );
561 // positioning
562 Size aSz = pHelpWin->CalcOutSize();
563 pHelpWin->SetOutputSizePixel( aSz );
564 ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, rHelpArea );
565 // if not called from Window::RequestHelp, then without delay...
566 if ( !pSVData->maHelpData.mbRequestingHelp )
567 nDelayMode = HELPDELAY_NONE;
568 pHelpWin->ShowHelp( nDelayMode );
572 void ImplDestroyHelpWindow( bool bUpdateHideTime )
574 ImplSVData* pSVData = ImplGetSVData();
575 VclPtr<HelpTextWindow> pHelpWin = pSVData->maHelpData.mpHelpWin;
576 if ( pHelpWin )
578 vcl::Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
579 // find out screen area covered by system help window
580 tools::Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
581 if( pHelpWin->IsVisible() )
582 pWindow->Invalidate( aInvRect );
583 pSVData->maHelpData.mpHelpWin = nullptr;
584 pSVData->maHelpData.mbKeyboardHelp = false;
585 pHelpWin->Hide();
586 pHelpWin.disposeAndClear();
587 if( bUpdateHideTime )
588 pSVData->maHelpData.mnLastHelpHideTime = tools::Time::GetSystemTicks();
592 void ImplSetHelpWindowPos( vcl::Window* pHelpWin, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle,
593 const Point& rPos, const tools::Rectangle& rHelpArea )
595 Point aPos = rPos;
596 Size aSz = pHelpWin->GetSizePixel();
597 tools::Rectangle aScreenRect = pHelpWin->ImplGetFrameWindow()->GetDesktopRectPixel();
598 aPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aPos );
599 // get mouse screen coords
600 Point aMousePos( pHelpWin->GetParent()->ImplGetFrameWindow()->GetPointerPosPixel() );
601 aMousePos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aMousePos );
603 if ( nHelpWinStyle == HELPWINSTYLE_QUICK )
605 if ( !(nStyle & QuickHelpFlags::NoAutoPos) )
607 long nScreenHeight = aScreenRect.GetHeight();
608 aPos.X() -= 4;
609 if ( aPos.Y() > aScreenRect.Top()+nScreenHeight-(nScreenHeight/4) )
610 aPos.Y() -= aSz.Height()+4;
611 else
612 aPos.Y() += 21;
615 else
617 // If it's the mouse position, move the window slightly
618 // so the mouse pointer does not cover it
619 if ( aPos == aMousePos )
621 aPos.X() += 12;
622 aPos.Y() += 16;
626 if ( nStyle & QuickHelpFlags::NoAutoPos )
628 // convert help area to screen coords
629 tools::Rectangle devHelpArea(
630 pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea.TopLeft() ),
631 pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea.BottomRight() ) );
633 // Welche Position vom Rechteck?
634 aPos = devHelpArea.Center();
636 if ( nStyle & QuickHelpFlags::Left )
637 aPos.X() = devHelpArea.Left();
638 else if ( nStyle & QuickHelpFlags::Right )
639 aPos.X() = devHelpArea.Right();
641 if ( nStyle & QuickHelpFlags::Top )
642 aPos.Y() = devHelpArea.Top();
643 else if ( nStyle & QuickHelpFlags::Bottom )
644 aPos.Y() = devHelpArea.Bottom();
646 // which direction?
647 if ( nStyle & QuickHelpFlags::Left )
649 else if ( nStyle & QuickHelpFlags::Right )
650 aPos.X() -= aSz.Width();
651 else
652 aPos.X() -= aSz.Width()/2;
654 if ( nStyle & QuickHelpFlags::Top )
656 else if ( nStyle & QuickHelpFlags::Bottom )
657 aPos.Y() -= aSz.Height();
658 else
659 aPos.Y() -= aSz.Height()/2;
662 if ( aPos.X() < aScreenRect.Left() )
663 aPos.X() = aScreenRect.Left();
664 else if ( ( aPos.X() + aSz.Width() ) > aScreenRect.Right() )
665 aPos.X() = aScreenRect.Right() - aSz.Width();
666 if ( aPos.Y() < aScreenRect.Top() )
667 aPos.Y() = aScreenRect.Top();
668 else if ( ( aPos.Y() + aSz.Height() ) > aScreenRect.Bottom() )
669 aPos.Y() = aScreenRect.Bottom() - aSz.Height();
671 if( ! (nStyle & QuickHelpFlags::NoEvadePointer) )
673 /* the remark below should be obsolete by now as the helpwindow should
674 not be focusable, leaving it as a hint. However it is sensible in most
675 conditions to evade the mouse pointer so the content window is fully visible.
677 // the popup must not appear under the mouse
678 // otherwise it would directly be closed due to a focus change...
680 tools::Rectangle aHelpRect( aPos, aSz );
681 if( aHelpRect.IsInside( aMousePos ) )
683 Point delta(2,2);
684 Point aSize( aSz.Width(), aSz.Height() );
685 Point aTest( aMousePos - aSize - delta );
686 if( aTest.X() > aScreenRect.Left() && aTest.Y() > aScreenRect.Top() )
687 aPos = aTest;
688 else
689 aPos = aMousePos + delta;
693 vcl::Window* pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
694 aPos = pWindow->AbsoluteScreenToOutputPixel( aPos );
695 pHelpWin->SetPosPixel( aPos );
698 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */