build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / app / help.cxx
bloba531c11bfde043000fdf8133890a170191e520fa
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/debug.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"
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 HELPDELAY_NORMAL 1
44 #define HELPDELAY_SHORT 2
45 #define HELPDELAY_NONE 3
47 #define HELPTEXTMAXLEN 150
49 Help::Help()
53 Help::~Help()
57 bool Help::Start( const OUString&, const vcl::Window* )
59 return false;
62 bool Help::SearchKeyword( const OUString& )
64 return false;
67 OUString Help::GetHelpText( const OUString&, const vcl::Window* )
69 return OUString();
72 void Help::EnableContextHelp()
74 ImplGetSVData()->maHelpData.mbContextHelp = true;
77 void Help::DisableContextHelp()
79 ImplGetSVData()->maHelpData.mbContextHelp = false;
82 bool Help::IsContextHelpEnabled()
84 return ImplGetSVData()->maHelpData.mbContextHelp;
87 void Help::EnableExtHelp()
89 ImplGetSVData()->maHelpData.mbExtHelp = true;
92 void Help::DisableExtHelp()
94 ImplGetSVData()->maHelpData.mbExtHelp = false;
97 bool Help::IsExtHelpEnabled()
99 return ImplGetSVData()->maHelpData.mbExtHelp;
102 bool Help::StartExtHelp()
104 ImplSVData* pSVData = ImplGetSVData();
106 if ( pSVData->maHelpData.mbExtHelp && !pSVData->maHelpData.mbExtHelpMode )
108 pSVData->maHelpData.mbExtHelpMode = true;
109 pSVData->maHelpData.mbOldBalloonMode = pSVData->maHelpData.mbBalloonHelp;
110 pSVData->maHelpData.mbBalloonHelp = true;
111 if ( pSVData->maWinData.mpAppWin )
112 pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
113 return true;
116 return false;
119 bool Help::EndExtHelp()
121 ImplSVData* pSVData = ImplGetSVData();
123 if ( pSVData->maHelpData.mbExtHelp && pSVData->maHelpData.mbExtHelpMode )
125 pSVData->maHelpData.mbExtHelpMode = false;
126 pSVData->maHelpData.mbBalloonHelp = pSVData->maHelpData.mbOldBalloonMode;
127 if ( pSVData->maWinData.mpAppWin )
128 pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
129 return true;
132 return false;
135 void Help::EnableBalloonHelp()
137 ImplGetSVData()->maHelpData.mbBalloonHelp = true;
140 void Help::DisableBalloonHelp()
142 ImplGetSVData()->maHelpData.mbBalloonHelp = false;
145 bool Help::IsBalloonHelpEnabled()
147 return ImplGetSVData()->maHelpData.mbBalloonHelp;
150 bool Help::ShowBalloon( vcl::Window* pParent,
151 const Point& rScreenPos, const Rectangle& rRect,
152 const OUString& rHelpText )
154 ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, QuickHelpFlags::NONE,
155 rHelpText, OUString(), rScreenPos, rRect );
157 return true;
160 void Help::EnableQuickHelp()
162 ImplGetSVData()->maHelpData.mbQuickHelp = true;
165 void Help::DisableQuickHelp()
167 ImplGetSVData()->maHelpData.mbQuickHelp = false;
170 bool Help::IsQuickHelpEnabled()
172 return ImplGetSVData()->maHelpData.mbQuickHelp;
175 bool Help::ShowQuickHelp( vcl::Window* pParent,
176 const Rectangle& rScreenRect,
177 const OUString& rHelpText,
178 const OUString& rLongHelpText,
179 QuickHelpFlags nStyle )
181 sal_uInt16 nHelpWinStyle = ( nStyle & QuickHelpFlags::TipStyleBalloon ) ? HELPWINSTYLE_BALLOON : HELPWINSTYLE_QUICK;
182 ImplShowHelpWindow( pParent, nHelpWinStyle, nStyle,
183 rHelpText, rLongHelpText,
184 pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), rScreenRect );
185 return true;
188 void Help::HideBalloonAndQuickHelp()
190 HelpTextWindow const * pHelpWin = ImplGetSVData()->maHelpData.mpHelpWin;
191 bool const bIsVisible = ( pHelpWin != nullptr ) && pHelpWin->IsVisible();
192 ImplDestroyHelpWindow( bIsVisible );
195 sal_uIntPtr Help::ShowPopover(vcl::Window* pParent, const Rectangle& rScreenRect,
196 const OUString& rText, QuickHelpFlags nStyle)
198 sal_uIntPtr nId = pParent->ImplGetFrame()->ShowPopover(rText, rScreenRect, nStyle);
199 if (nId)
201 //popovers are handled natively, return early
202 return nId;
205 sal_uInt16 nHelpWinStyle = ( nStyle & QuickHelpFlags::TipStyleBalloon ) ? HELPWINSTYLE_BALLOON : HELPWINSTYLE_QUICK;
206 VclPtrInstance<HelpTextWindow> pHelpWin( pParent, rText, nHelpWinStyle, nStyle );
208 nId = reinterpret_cast< sal_uIntPtr >( pHelpWin.get() );
209 UpdatePopover(nId, pParent, rScreenRect, rText);
211 pHelpWin->ShowHelp( HELPDELAY_NONE );
212 return nId;
215 void Help::UpdatePopover(sal_uIntPtr nId, vcl::Window* pParent, const Rectangle& rScreenRect,
216 const OUString& rText)
218 if (pParent->ImplGetFrame()->UpdatePopover(nId, rText, rScreenRect))
220 //popovers are handled natively, return early
221 return;
224 HelpTextWindow* pHelpWin = reinterpret_cast< HelpTextWindow* >( nId );
225 ENSURE_OR_RETURN_VOID( pHelpWin != nullptr, "Help::UpdatePopover: invalid ID!" );
227 Size aSz = pHelpWin->CalcOutSize();
228 pHelpWin->SetOutputSizePixel( aSz );
229 ImplSetHelpWindowPos( pHelpWin, pHelpWin->GetWinStyle(), pHelpWin->GetStyle(),
230 pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), rScreenRect );
232 pHelpWin->SetHelpText( rText );
233 pHelpWin->Invalidate();
236 void Help::HidePopover(vcl::Window* pParent, sal_uLong nId)
238 if (pParent->ImplGetFrame()->HidePopover(nId))
240 //popovers are handled natively, return early
241 return;
244 VclPtr<HelpTextWindow> pHelpWin = reinterpret_cast<HelpTextWindow*>(nId);
245 vcl::Window* pFrameWindow = pHelpWin->ImplGetFrameWindow();
246 pHelpWin->Hide();
247 // trigger update, so that a Paint is instantly triggered since we do not save the background
248 pFrameWindow->ImplUpdateAll();
249 pHelpWin.disposeAndClear();
250 ImplGetSVData()->maHelpData.mnLastHelpHideTime = tools::Time::GetSystemTicks();
253 HelpTextWindow::HelpTextWindow( vcl::Window* pParent, const OUString& rText, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle ) :
254 FloatingWindow( pParent, WB_SYSTEMWINDOW|WB_TOOLTIPWIN ), // #105827# if we change the parent, mirroring will not work correctly when positioning this window
255 maHelpText( rText )
257 SetType( WINDOW_HELPTEXTWINDOW );
258 ImplSetMouseTransparent( true );
259 mnHelpWinStyle = nHelpWinStyle;
260 mnStyle = nStyle;
262 if( mnStyle & QuickHelpFlags::BiDiRtl )
264 ComplexTextLayoutFlags nLayoutMode = GetLayoutMode();
265 nLayoutMode |= ComplexTextLayoutFlags::BiDiRtl | ComplexTextLayoutFlags::TextOriginLeft;
266 SetLayoutMode( nLayoutMode );
268 SetHelpText( rText );
269 Window::SetHelpText( rText );
271 ImplSVData* pSVData = ImplGetSVData();
272 if ( pSVData->maHelpData.mbSetKeyboardHelp )
273 pSVData->maHelpData.mbKeyboardHelp = true;
276 maShowTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
277 maShowTimer.SetDebugName( "vcl::HelpTextWindow maShowTimer" );
279 const HelpSettings& rHelpSettings = pParent->GetSettings().GetHelpSettings();
280 maHideTimer.SetTimeout( rHelpSettings.GetTipTimeout() );
281 maHideTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
282 maHideTimer.SetDebugName( "vcl::HelpTextWindow maHideTimer" );
285 void HelpTextWindow::StateChanged(StateChangedType nType)
287 FloatingWindow::StateChanged(nType);
288 if (nType == StateChangedType::InitShow)
290 ApplySettings(*this);
291 SetHelpText(maHelpText);
292 Invalidate();
296 void HelpTextWindow::ApplySettings(vcl::RenderContext& rRenderContext)
298 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
299 SetPointFont(rRenderContext, rStyleSettings.GetHelpFont());
300 rRenderContext.SetTextColor(rStyleSettings.GetHelpTextColor());
301 rRenderContext.SetTextAlign(ALIGN_TOP);
303 if (rRenderContext.IsNativeControlSupported(ControlType::Tooltip, ControlPart::Entire))
305 EnableChildTransparentMode();
306 SetParentClipMode(ParentClipMode::NoClip);
307 SetPaintTransparent(true);
308 rRenderContext.SetBackground();
310 else
311 rRenderContext.SetBackground(Wallpaper(rStyleSettings.GetHelpColor()));
313 if (rStyleSettings.GetHelpColor().IsDark())
314 rRenderContext.SetLineColor(COL_WHITE);
315 else
316 rRenderContext.SetLineColor(COL_BLACK);
317 rRenderContext.SetFillColor();
320 HelpTextWindow::~HelpTextWindow()
322 disposeOnce();
325 void HelpTextWindow::dispose()
327 maShowTimer.Stop();
328 maHideTimer.Stop();
330 if( this == ImplGetSVData()->maHelpData.mpHelpWin )
331 ImplGetSVData()->maHelpData.mpHelpWin = nullptr;
332 FloatingWindow::dispose();
335 void HelpTextWindow::SetHelpText( const OUString& rHelpText )
337 maHelpText = rHelpText;
338 if ( mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN)
340 Size aSize;
341 aSize.Height() = GetTextHeight();
342 if ( mnStyle & QuickHelpFlags::CtrlText )
343 aSize.Width() = GetCtrlTextWidth( maHelpText );
344 else
345 aSize.Width() = GetTextWidth( maHelpText );
346 maTextRect = Rectangle( Point( HELPTEXTMARGIN_QUICK, HELPTEXTMARGIN_QUICK ), aSize );
348 else // HELPWINSTYLE_BALLOON
350 Point aTmpPoint;
351 sal_Int32 nCharsInLine = 35 + ((maHelpText.getLength()/100)*5);
352 // average width to have all windows consistent
353 OUStringBuffer aBuf;
354 comphelper::string::padToLength(aBuf, nCharsInLine, 'x');
355 OUString aXXX = aBuf.makeStringAndClear();
356 long nWidth = GetTextWidth( aXXX );
357 Size aTmpSize( nWidth, 0x7FFFFFFF );
358 Rectangle aTry1( aTmpPoint, aTmpSize );
359 DrawTextFlags nDrawFlags = DrawTextFlags::MultiLine | DrawTextFlags::WordBreak |
360 DrawTextFlags::Left | DrawTextFlags::Top;
361 if ( mnStyle & QuickHelpFlags::CtrlText )
362 nDrawFlags |= DrawTextFlags::Mnemonic;
363 Rectangle aTextRect = GetTextRect( aTry1, maHelpText, nDrawFlags );
365 // get a better width later...
366 maTextRect = aTextRect;
368 // safety distance...
369 maTextRect.SetPos( Point( HELPTEXTMARGIN_BALLOON, HELPTEXTMARGIN_BALLOON ) );
372 Size aSize( CalcOutSize() );
373 SetOutputSizePixel( aSize );
376 void HelpTextWindow::ImplShow()
378 VclPtr<HelpTextWindow> xWindow( this );
379 Show( true, ShowFlags::NoActivate );
380 if( !xWindow->IsDisposed() )
381 Update();
384 void HelpTextWindow::Paint( vcl::RenderContext& rRenderContext, const Rectangle& )
386 // paint native background
387 bool bNativeOK = false;
388 if (rRenderContext.IsNativeControlSupported(ControlType::Tooltip, ControlPart::Entire))
390 Rectangle aCtrlRegion(Point(0, 0), GetOutputSizePixel());
391 ImplControlValue aControlValue;
392 bNativeOK = rRenderContext.DrawNativeControl(ControlType::Tooltip, ControlPart::Entire, aCtrlRegion,
393 ControlState::NONE, aControlValue, OUString());
396 // paint text
397 if (mnHelpWinStyle == HELPWINSTYLE_QUICK && maHelpText.getLength() < HELPTEXTMAXLEN)
399 if ( mnStyle & QuickHelpFlags::CtrlText )
400 rRenderContext.DrawCtrlText(maTextRect.TopLeft(), maHelpText);
401 else
402 rRenderContext.DrawText(maTextRect.TopLeft(), maHelpText);
404 else // HELPWINSTYLE_BALLOON
406 DrawTextFlags nDrawFlags = DrawTextFlags::MultiLine|DrawTextFlags::WordBreak|
407 DrawTextFlags::Left|DrawTextFlags::Top;
408 if (mnStyle & QuickHelpFlags::CtrlText)
409 nDrawFlags |= DrawTextFlags::Mnemonic;
410 rRenderContext.DrawText(maTextRect, maHelpText, nDrawFlags);
413 // border
414 if (!bNativeOK)
416 Size aSz = GetOutputSizePixel();
417 rRenderContext.DrawRect(Rectangle(Point(), aSz));
418 if (mnHelpWinStyle == HELPWINSTYLE_BALLOON)
420 aSz.Width() -= 2;
421 aSz.Height() -= 2;
422 Color aColor(rRenderContext.GetLineColor());
423 rRenderContext.SetLineColor(COL_GRAY);
424 rRenderContext.DrawRect(Rectangle(Point(1, 1), aSz));
425 rRenderContext.SetLineColor(aColor);
430 void HelpTextWindow::ShowHelp( sal_uInt16 nDelayMode )
432 sal_uLong nTimeout = 0;
433 if ( nDelayMode != HELPDELAY_NONE )
435 // In case of ExtendedHelp display help sooner
436 if ( ImplGetSVData()->maHelpData.mbExtHelpMode )
437 nTimeout = 15;
438 else
440 const HelpSettings& rHelpSettings = GetSettings().GetHelpSettings();
441 if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
442 nTimeout = rHelpSettings.GetTipDelay();
443 else
444 nTimeout = rHelpSettings.GetBalloonDelay();
447 if ( nDelayMode == HELPDELAY_SHORT )
448 nTimeout /= 3;
451 maShowTimer.SetTimeout( nTimeout );
452 maShowTimer.Start();
455 IMPL_LINK( HelpTextWindow, TimerHdl, Timer*, pTimer, void)
457 if ( pTimer == &maShowTimer )
459 if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
461 // start auto-hide-timer for non-ShowTip windows
462 ImplSVData* pSVData = ImplGetSVData();
463 if ( this == pSVData->maHelpData.mpHelpWin )
464 maHideTimer.Start();
466 ImplShow();
468 else
470 SAL_WARN_IF( pTimer != &maHideTimer, "vcl", "HelpTextWindow::TimerHdl with bad Timer" );
471 ImplDestroyHelpWindow( true );
475 Size HelpTextWindow::CalcOutSize() const
477 Size aSz = maTextRect.GetSize();
478 aSz.Width() += 2*maTextRect.Left();
479 aSz.Height() += 2*maTextRect.Top();
480 return aSz;
483 void HelpTextWindow::RequestHelp( const HelpEvent& /*rHEvt*/ )
485 // Just to assure that Window::RequestHelp() is not called by
486 // ShowQuickHelp/ShowBalloonHelp in the HelpTextWindow.
489 OUString HelpTextWindow::GetText() const
491 return maHelpText;
494 void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle,
495 const OUString& rHelpText, const OUString& rStatusText,
496 const Point& rScreenPos, const Rectangle& rHelpArea )
498 if (pParent->ImplGetFrame()->ShowTooltip(rHelpText, rHelpArea))
500 //tooltips are handled natively, return early
501 return;
504 ImplSVData* pSVData = ImplGetSVData();
506 if (rHelpText.isEmpty() && !pSVData->maHelpData.mbRequestingHelp)
507 return;
509 VclPtr<HelpTextWindow> pHelpWin = pSVData->maHelpData.mpHelpWin;
510 sal_uInt16 nDelayMode = HELPDELAY_NORMAL;
511 if ( pHelpWin )
513 SAL_WARN_IF( pHelpWin == pParent, "vcl", "HelpInHelp ?!" );
515 if ( ( ( pHelpWin->GetHelpText() != rHelpText )
516 || ( pHelpWin->GetWinStyle() != nHelpWinStyle )
517 || ( pHelpWin->GetHelpArea() != rHelpArea )
519 && pSVData->maHelpData.mbRequestingHelp
522 // remove help window if no HelpText or other HelpText or
523 // other help mode. but keep it if we are scrolling, ie not requesting help
524 bool bWasVisible = pHelpWin->IsVisible();
525 if ( bWasVisible )
526 nDelayMode = HELPDELAY_NONE; // display it quickly if we were already in quick help mode
527 pHelpWin = nullptr;
528 ImplDestroyHelpWindow( bWasVisible );
530 else
532 bool const bTextChanged = rHelpText != pHelpWin->GetHelpText();
533 if (bTextChanged)
535 vcl::Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
536 Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
537 if( pHelpWin->IsVisible() )
538 pWindow->Invalidate( aInvRect );
540 pHelpWin->SetHelpText( rHelpText );
541 // approach mouse position
542 ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, rHelpArea );
543 if( pHelpWin->IsVisible() )
544 pHelpWin->Invalidate();
549 if (!pHelpWin && !rHelpText.isEmpty())
551 sal_uInt64 nCurTime = tools::Time::GetSystemTicks();
552 if ( ( ( nCurTime - pSVData->maHelpData.mnLastHelpHideTime ) < pParent->GetSettings().GetHelpSettings().GetTipDelay() )
553 || ( nStyle & QuickHelpFlags::NoDelay )
555 nDelayMode = HELPDELAY_NONE;
557 pHelpWin = VclPtr<HelpTextWindow>::Create( pParent, rHelpText, nHelpWinStyle, nStyle );
558 pSVData->maHelpData.mpHelpWin = pHelpWin;
559 pHelpWin->SetStatusText( rStatusText );
560 pHelpWin->SetHelpArea( rHelpArea );
562 // positioning
563 Size aSz = pHelpWin->CalcOutSize();
564 pHelpWin->SetOutputSizePixel( aSz );
565 ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, rHelpArea );
566 // if not called from Window::RequestHelp, then without delay...
567 if ( !pSVData->maHelpData.mbRequestingHelp )
568 nDelayMode = HELPDELAY_NONE;
569 pHelpWin->ShowHelp( nDelayMode );
573 void ImplDestroyHelpWindow( bool bUpdateHideTime )
575 ImplSVData* pSVData = ImplGetSVData();
576 VclPtr<HelpTextWindow> pHelpWin = pSVData->maHelpData.mpHelpWin;
577 if ( pHelpWin )
579 vcl::Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
580 // find out screen area covered by system help window
581 Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
582 if( pHelpWin->IsVisible() )
583 pWindow->Invalidate( aInvRect );
584 pSVData->maHelpData.mpHelpWin = nullptr;
585 pSVData->maHelpData.mbKeyboardHelp = false;
586 pHelpWin->Hide();
587 pHelpWin.disposeAndClear();
588 if( bUpdateHideTime )
589 pSVData->maHelpData.mnLastHelpHideTime = tools::Time::GetSystemTicks();
593 void ImplSetHelpWindowPos( vcl::Window* pHelpWin, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle,
594 const Point& rPos, const Rectangle& rHelpArea )
596 Point aPos = rPos;
597 Size aSz = pHelpWin->GetSizePixel();
598 Rectangle aScreenRect = pHelpWin->ImplGetFrameWindow()->GetDesktopRectPixel();
599 aPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aPos );
600 // get mouse screen coords
601 Point aMousePos( pHelpWin->GetParent()->ImplGetFrameWindow()->GetPointerPosPixel() );
602 aMousePos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aMousePos );
604 if ( nHelpWinStyle == HELPWINSTYLE_QUICK )
606 if ( !(nStyle & QuickHelpFlags::NoAutoPos) )
608 long nScreenHeight = aScreenRect.GetHeight();
609 aPos.X() -= 4;
610 if ( aPos.Y() > aScreenRect.Top()+nScreenHeight-(nScreenHeight/4) )
611 aPos.Y() -= aSz.Height()+4;
612 else
613 aPos.Y() += 21;
616 else
618 // If it's the mouse position, move the window slightly
619 // so the mouse pointer does not cover it
620 if ( aPos == aMousePos )
622 aPos.X() += 12;
623 aPos.Y() += 16;
627 if ( nStyle & QuickHelpFlags::NoAutoPos )
629 // convert help area to screen coords
630 Rectangle devHelpArea(
631 pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea.TopLeft() ),
632 pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea.BottomRight() ) );
634 // which position of the rectangle?
635 aPos = devHelpArea.Center();
637 if ( nStyle & QuickHelpFlags::Left )
638 aPos.X() = devHelpArea.Left();
639 else if ( nStyle & QuickHelpFlags::Right )
640 aPos.X() = devHelpArea.Right();
642 if ( nStyle & QuickHelpFlags::Top )
643 aPos.Y() = devHelpArea.Top();
644 else if ( nStyle & QuickHelpFlags::Bottom )
645 aPos.Y() = devHelpArea.Bottom();
647 // which direction?
648 if ( nStyle & QuickHelpFlags::Left )
650 else if ( nStyle & QuickHelpFlags::Right )
651 aPos.X() -= aSz.Width();
652 else
653 aPos.X() -= aSz.Width()/2;
655 if ( nStyle & QuickHelpFlags::Top )
657 else if ( nStyle & QuickHelpFlags::Bottom )
658 aPos.Y() -= aSz.Height();
659 else
660 aPos.Y() -= aSz.Height()/2;
663 if ( aPos.X() < aScreenRect.Left() )
664 aPos.X() = aScreenRect.Left();
665 else if ( ( aPos.X() + aSz.Width() ) > aScreenRect.Right() )
666 aPos.X() = aScreenRect.Right() - aSz.Width();
667 if ( aPos.Y() < aScreenRect.Top() )
668 aPos.Y() = aScreenRect.Top();
669 else if ( ( aPos.Y() + aSz.Height() ) > aScreenRect.Bottom() )
670 aPos.Y() = aScreenRect.Bottom() - aSz.Height();
672 if( ! (nStyle & QuickHelpFlags::NoEvadePointer) )
674 /* the remark below should be obsolete by now as the helpwindow should
675 not be focusable, leaving it as a hint. However it is sensible in most
676 conditions to evade the mouse pointer so the content window is fully visible.
678 // the popup must not appear under the mouse
679 // otherwise it would directly be closed due to a focus change...
681 Rectangle aHelpRect( aPos, aSz );
682 if( aHelpRect.IsInside( aMousePos ) )
684 Point delta(2,2);
685 Point aSize( aSz.Width(), aSz.Height() );
686 Point aTest( aMousePos - aSize - delta );
687 if( aTest.X() > aScreenRect.Left() && aTest.Y() > aScreenRect.Top() )
688 aPos = aTest;
689 else
690 aPos = aMousePos + delta;
694 vcl::Window* pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
695 aPos = pWindow->AbsoluteScreenToOutputPixel( aPos );
696 pHelpWin->SetPosPixel( aPos );
699 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */