Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "tools/debug.hxx"
31 : : #include "tools/diagnose_ex.h"
32 : : #include "tools/time.hxx"
33 : :
34 : : #include "vcl/window.hxx"
35 : : #include "vcl/event.hxx"
36 : : #include "vcl/svapp.hxx"
37 : : #include "vcl/wrkwin.hxx"
38 : : #include "vcl/help.hxx"
39 : :
40 : : #include "helpwin.hxx"
41 : : #include "svdata.hxx"
42 : :
43 : : // =======================================================================
44 : :
45 : : #define HELPWINSTYLE_QUICK 0
46 : : #define HELPWINSTYLE_BALLOON 1
47 : :
48 : : #define HELPTEXTMARGIN_QUICK 3
49 : : #define HELPTEXTMARGIN_BALLOON 6
50 : :
51 : : #define HELPDELAY_NORMAL 1
52 : : #define HELPDELAY_SHORT 2
53 : : #define HELPDELAY_NONE 3
54 : :
55 : : // =======================================================================
56 : :
57 : 233 : Help::Help()
58 : : {
59 : 233 : }
60 : :
61 : 158 : Help::~Help()
62 : : {
63 [ - + ]: 158 : }
64 : :
65 : : // -----------------------------------------------------------------------
66 : :
67 : 0 : void Help::OpenHelpAgent( const rtl::OString& )
68 : : {
69 : 0 : }
70 : :
71 : : // -----------------------------------------------------------------------
72 : :
73 : 0 : sal_Bool Help::Start( const XubString&, const Window* )
74 : : {
75 : 0 : return sal_False;
76 : : }
77 : :
78 : 0 : sal_Bool Help::SearchKeyword( const XubString& )
79 : : {
80 : 0 : return sal_False;
81 : : }
82 : :
83 : : // -----------------------------------------------------------------------
84 : :
85 : 0 : XubString Help::GetHelpText( const String&, const Window* )
86 : : {
87 : 0 : return ImplGetSVEmptyStr();
88 : : }
89 : :
90 : : // -----------------------------------------------------------------------
91 : :
92 : 233 : void Help::EnableContextHelp()
93 : : {
94 : 233 : ImplGetSVData()->maHelpData.mbContextHelp = sal_True;
95 : 233 : }
96 : :
97 : : // -----------------------------------------------------------------------
98 : :
99 : 0 : void Help::DisableContextHelp()
100 : : {
101 : 0 : ImplGetSVData()->maHelpData.mbContextHelp = sal_False;
102 : 0 : }
103 : :
104 : : // -----------------------------------------------------------------------
105 : :
106 : 0 : sal_Bool Help::IsContextHelpEnabled()
107 : : {
108 : 0 : return ImplGetSVData()->maHelpData.mbContextHelp;
109 : : }
110 : :
111 : : // -----------------------------------------------------------------------
112 : :
113 : 233 : void Help::EnableExtHelp()
114 : : {
115 : 233 : ImplGetSVData()->maHelpData.mbExtHelp = sal_True;
116 : 233 : }
117 : :
118 : : // -----------------------------------------------------------------------
119 : :
120 : 0 : void Help::DisableExtHelp()
121 : : {
122 : 0 : ImplGetSVData()->maHelpData.mbExtHelp = sal_False;
123 : 0 : }
124 : :
125 : : // -----------------------------------------------------------------------
126 : :
127 : 0 : sal_Bool Help::IsExtHelpEnabled()
128 : : {
129 : 0 : return ImplGetSVData()->maHelpData.mbExtHelp;
130 : : }
131 : :
132 : : // -----------------------------------------------------------------------
133 : :
134 : 0 : sal_Bool Help::StartExtHelp()
135 : : {
136 : 0 : ImplSVData* pSVData = ImplGetSVData();
137 : :
138 [ # # ][ # # ]: 0 : if ( pSVData->maHelpData.mbExtHelp && !pSVData->maHelpData.mbExtHelpMode )
139 : : {
140 : 0 : pSVData->maHelpData.mbExtHelpMode = sal_True;
141 : 0 : pSVData->maHelpData.mbOldBalloonMode = pSVData->maHelpData.mbBalloonHelp;
142 : 0 : pSVData->maHelpData.mbBalloonHelp = sal_True;
143 [ # # ]: 0 : if ( pSVData->maWinData.mpAppWin )
144 : 0 : pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
145 : 0 : return sal_True;
146 : : }
147 : :
148 : 0 : return sal_False;
149 : : }
150 : :
151 : : // -----------------------------------------------------------------------
152 : :
153 : 0 : sal_Bool Help::EndExtHelp()
154 : : {
155 : 0 : ImplSVData* pSVData = ImplGetSVData();
156 : :
157 [ # # ][ # # ]: 0 : if ( pSVData->maHelpData.mbExtHelp && pSVData->maHelpData.mbExtHelpMode )
158 : : {
159 : 0 : pSVData->maHelpData.mbExtHelpMode = sal_False;
160 : 0 : pSVData->maHelpData.mbBalloonHelp = pSVData->maHelpData.mbOldBalloonMode;
161 [ # # ]: 0 : if ( pSVData->maWinData.mpAppWin )
162 : 0 : pSVData->maWinData.mpAppWin->ImplGenerateMouseMove();
163 : 0 : return sal_True;
164 : : }
165 : :
166 : 0 : return sal_False;
167 : : }
168 : :
169 : : // -----------------------------------------------------------------------
170 : :
171 : 0 : void Help::EnableBalloonHelp()
172 : : {
173 : 0 : ImplGetSVData()->maHelpData.mbBalloonHelp = sal_True;
174 : 0 : }
175 : :
176 : : // -----------------------------------------------------------------------
177 : :
178 : 233 : void Help::DisableBalloonHelp()
179 : : {
180 : 233 : ImplGetSVData()->maHelpData.mbBalloonHelp = sal_False;
181 : 233 : }
182 : :
183 : : // -----------------------------------------------------------------------
184 : :
185 : 233 : sal_Bool Help::IsBalloonHelpEnabled()
186 : : {
187 : 233 : return ImplGetSVData()->maHelpData.mbBalloonHelp;
188 : : }
189 : :
190 : : // -----------------------------------------------------------------------
191 : :
192 : 0 : sal_Bool Help::ShowBalloon( Window* pParent,
193 : : const Point& rScreenPos,
194 : : const XubString& rHelpText )
195 : : {
196 : : ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, 0,
197 : 0 : rHelpText, ImplGetSVEmptyStr(), rScreenPos );
198 : :
199 : 0 : return sal_True;
200 : : }
201 : :
202 : : // -----------------------------------------------------------------------
203 : :
204 : 0 : sal_Bool Help::ShowBalloon( Window* pParent,
205 : : const Point& rScreenPos, const Rectangle& rRect,
206 : : const XubString& rHelpText )
207 : : {
208 : : ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, 0,
209 : 0 : rHelpText, ImplGetSVEmptyStr(), rScreenPos, &rRect );
210 : :
211 : 0 : return sal_True;
212 : : }
213 : :
214 : : // -----------------------------------------------------------------------
215 : :
216 : 466 : void Help::EnableQuickHelp()
217 : : {
218 : 466 : ImplGetSVData()->maHelpData.mbQuickHelp = sal_True;
219 : 466 : }
220 : :
221 : : // -----------------------------------------------------------------------
222 : :
223 : 0 : void Help::DisableQuickHelp()
224 : : {
225 : 0 : ImplGetSVData()->maHelpData.mbQuickHelp = sal_False;
226 : 0 : }
227 : :
228 : : // -----------------------------------------------------------------------
229 : :
230 : 233 : sal_Bool Help::IsQuickHelpEnabled()
231 : : {
232 : 233 : return ImplGetSVData()->maHelpData.mbQuickHelp;
233 : : }
234 : :
235 : : // -----------------------------------------------------------------------
236 : :
237 : 0 : sal_Bool Help::ShowQuickHelp( Window* pParent,
238 : : const Rectangle& rScreenRect,
239 : : const XubString& rHelpText,
240 : : const XubString& rLongHelpText,
241 : : sal_uInt16 nStyle )
242 : : {
243 : : ImplShowHelpWindow( pParent, HELPWINSTYLE_QUICK, nStyle,
244 : : rHelpText, rLongHelpText,
245 [ # # ][ # # ]: 0 : pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect );
246 : 0 : return sal_True;
247 : : }
248 : :
249 : : // -----------------------------------------------------------------------
250 : :
251 : 0 : sal_uIntPtr Help::ShowTip( Window* pParent, const Rectangle& rScreenRect,
252 : : const XubString& rText, sal_uInt16 nStyle )
253 : : {
254 [ # # ]: 0 : sal_uInt16 nHelpWinStyle = ( ( nStyle & QUICKHELP_TIP_STYLE_BALLOON ) != 0 ) ? HELPWINSTYLE_BALLOON : HELPWINSTYLE_QUICK;
255 [ # # ]: 0 : HelpTextWindow* pHelpWin = new HelpTextWindow( pParent, rText, nHelpWinStyle, nStyle );
256 : :
257 : 0 : sal_uIntPtr nId = reinterpret_cast< sal_uIntPtr >( pHelpWin );
258 : 0 : UpdateTip( nId, pParent, rScreenRect, rText );
259 : :
260 : 0 : pHelpWin->ShowHelp( HELPDELAY_NONE );
261 : 0 : return nId;
262 : : }
263 : :
264 : : // -----------------------------------------------------------------------
265 : :
266 : 0 : void Help::UpdateTip( sal_uIntPtr nId, Window* pParent, const Rectangle& rScreenRect, const XubString& rText )
267 : : {
268 : 0 : HelpTextWindow* pHelpWin = reinterpret_cast< HelpTextWindow* >( nId );
269 [ # # ]: 0 : ENSURE_OR_RETURN_VOID( pHelpWin != NULL, "Help::UpdateTip: invalid ID!" );
270 : :
271 [ # # ]: 0 : Size aSz = pHelpWin->CalcOutSize();
272 [ # # ]: 0 : pHelpWin->SetOutputSizePixel( aSz );
273 : 0 : ImplSetHelpWindowPos( pHelpWin, pHelpWin->GetWinStyle(), pHelpWin->GetStyle(),
274 [ # # ]: 0 : pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect );
[ # # # # ]
275 : :
276 [ # # ]: 0 : pHelpWin->SetHelpText( rText );
277 : : }
278 : :
279 : : // -----------------------------------------------------------------------
280 : :
281 : 0 : void Help::HideTip( sal_uLong nId )
282 : : {
283 : 0 : HelpTextWindow* pHelpWin = (HelpTextWindow*)nId;
284 : 0 : Window* pFrameWindow = pHelpWin->ImplGetFrameWindow();
285 : 0 : pHelpWin->Hide();
286 : : // trigger update, so that a Paint is instantly triggered since we do not save the background
287 : 0 : pFrameWindow->ImplUpdateAll();
288 [ # # ]: 0 : delete pHelpWin;
289 : 0 : ImplGetSVData()->maHelpData.mnLastHelpHideTime = Time::GetSystemTicks();
290 : 0 : }
291 : :
292 : : // =======================================================================
293 : :
294 : 0 : HelpTextWindow::HelpTextWindow( Window* pParent, const XubString& rText, sal_uInt16 nHelpWinStyle, sal_uInt16 nStyle ) :
295 : : //FloatingWindow( pParent->ImplGetFrameWindow(), WB_SYSTEMWINDOW ),
296 : : FloatingWindow( pParent, WB_SYSTEMWINDOW|WB_TOOLTIPWIN ), // #105827# if we change the parent, mirroring will not work correctly when positioning this window
297 [ # # ][ # # ]: 0 : maHelpText( rText )
[ # # ][ # # ]
[ # # ][ # # ]
298 : : {
299 [ # # ]: 0 : SetType( WINDOW_HELPTEXTWINDOW );
300 [ # # ]: 0 : ImplSetMouseTransparent( sal_True );
301 : 0 : mnHelpWinStyle = nHelpWinStyle;
302 : 0 : mnStyle = nStyle;
303 : : // on windows this will raise the application window, because help windows are system windows now
304 : : // EnableAlwaysOnTop();
305 [ # # ]: 0 : EnableSaveBackground();
306 : :
307 : 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
308 [ # # ]: 0 : SetPointFont( rStyleSettings.GetHelpFont() );
309 [ # # ]: 0 : SetTextColor( rStyleSettings.GetHelpTextColor() );
310 [ # # ]: 0 : SetTextAlign( ALIGN_TOP );
311 [ # # ][ # # ]: 0 : if ( IsNativeControlSupported( CTRL_TOOLTIP, PART_ENTIRE_CONTROL ) )
312 : : {
313 [ # # ]: 0 : EnableChildTransparentMode( sal_True );
314 [ # # ]: 0 : SetParentClipMode( PARENTCLIPMODE_NOCLIP );
315 [ # # ]: 0 : SetPaintTransparent( sal_True );
316 [ # # ]: 0 : SetBackground();
317 : : }
318 : : else
319 [ # # ][ # # ]: 0 : SetBackground( Wallpaper( rStyleSettings.GetHelpColor() ) );
[ # # ]
320 [ # # ][ # # ]: 0 : if( rStyleSettings.GetHelpColor().IsDark() )
321 [ # # ]: 0 : SetLineColor( COL_WHITE );
322 : : else
323 [ # # ]: 0 : SetLineColor( COL_BLACK );
324 [ # # ]: 0 : SetFillColor();
325 : :
326 [ # # ]: 0 : if( mnStyle & QUICKHELP_BIDI_RTL )
327 : : {
328 : 0 : sal_uLong nLayoutMode = GetLayoutMode();
329 : 0 : nLayoutMode |= TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
330 [ # # ]: 0 : SetLayoutMode( nLayoutMode );
331 : : }
332 [ # # ]: 0 : SetHelpText( rText );
333 [ # # ]: 0 : Window::SetHelpText( rText );
334 : :
335 [ # # ]: 0 : ImplSVData* pSVData = ImplGetSVData();
336 [ # # ]: 0 : if ( pSVData->maHelpData.mbSetKeyboardHelp )
337 : 0 : pSVData->maHelpData.mbKeyboardHelp = sal_True;
338 : :
339 : 0 : const HelpSettings& rHelpSettings = pParent->GetSettings().GetHelpSettings();
340 [ # # ]: 0 : maShowTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
341 [ # # ]: 0 : maHideTimer.SetTimeoutHdl( LINK( this, HelpTextWindow, TimerHdl ) );
342 [ # # ]: 0 : maHideTimer.SetTimeout( rHelpSettings.GetTipTimeout() );
343 : 0 : }
344 : :
345 : : // -----------------------------------------------------------------------
346 : :
347 [ # # ][ # # ]: 0 : HelpTextWindow::~HelpTextWindow()
[ # # ][ # # ]
348 : : {
349 [ # # ]: 0 : maShowTimer.Stop();
350 [ # # ]: 0 : maHideTimer.Stop();
351 : :
352 [ # # ][ # # ]: 0 : if( this == ImplGetSVData()->maHelpData.mpHelpWin )
353 [ # # ]: 0 : ImplGetSVData()->maHelpData.mpHelpWin = NULL;
354 [ # # ]: 0 : }
355 : :
356 : : // -----------------------------------------------------------------------
357 : :
358 : 0 : void HelpTextWindow::SetHelpText( const String& rHelpText )
359 : : {
360 [ # # ]: 0 : maHelpText = rHelpText;
361 [ # # ]: 0 : if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
362 : : {
363 : 0 : Size aSize;
364 [ # # ]: 0 : aSize.Height() = GetTextHeight();
365 [ # # ]: 0 : if ( mnStyle & QUICKHELP_CTRLTEXT )
366 [ # # ]: 0 : aSize.Width() = GetCtrlTextWidth( maHelpText );
367 : : else
368 [ # # ]: 0 : aSize.Width() = GetTextWidth( maHelpText );
369 [ # # ]: 0 : maTextRect = Rectangle( Point( HELPTEXTMARGIN_QUICK, HELPTEXTMARGIN_QUICK ), aSize );
370 : : }
371 : : else // HELPWINSTYLE_BALLOON
372 : : {
373 : 0 : Point aTmpPoint;
374 : 0 : sal_uInt16 nCharsInLine = 35 + ((maHelpText.Len()/100)*5);
375 [ # # ]: 0 : XubString aXXX;
376 [ # # ]: 0 : aXXX.Fill( nCharsInLine, 'x' ); // average width to have all windows consistent
377 [ # # ]: 0 : long nWidth = GetTextWidth( aXXX );
378 : 0 : Size aTmpSize( nWidth, 0x7FFFFFFF );
379 [ # # ]: 0 : Rectangle aTry1( aTmpPoint, aTmpSize );
380 : : sal_uInt16 nDrawFlags = TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK |
381 : 0 : TEXT_DRAW_LEFT | TEXT_DRAW_TOP;
382 [ # # ]: 0 : if ( mnStyle & QUICKHELP_CTRLTEXT )
383 : 0 : nDrawFlags |= TEXT_DRAW_MNEMONIC;
384 [ # # ]: 0 : Rectangle aTextRect = GetTextRect( aTry1, maHelpText, nDrawFlags );
385 : :
386 : : // get a better width later...
387 : 0 : maTextRect = aTextRect;
388 : :
389 : : // safety distance...
390 [ # # ]: 0 : maTextRect.SetPos( Point( HELPTEXTMARGIN_BALLOON, HELPTEXTMARGIN_BALLOON ) );
391 : : }
392 : :
393 [ # # ]: 0 : Size aSize( CalcOutSize() );
394 [ # # ]: 0 : SetOutputSizePixel( aSize );
395 : 0 : }
396 : :
397 : : // -----------------------------------------------------------------------
398 : :
399 : 0 : void HelpTextWindow::ImplShow()
400 : : {
401 [ # # ]: 0 : ImplDelData aDogTag( this );
402 [ # # ]: 0 : Show( sal_True, SHOW_NOACTIVATE );
403 [ # # ]: 0 : if( !aDogTag.IsDead() )
404 [ # # ][ # # ]: 0 : Update();
405 : 0 : }
406 : :
407 : : // -----------------------------------------------------------------------
408 : :
409 : 0 : void HelpTextWindow::Paint( const Rectangle& )
410 : : {
411 : : // paint native background
412 : 0 : bool bNativeOK = false;
413 [ # # ]: 0 : if ( IsNativeControlSupported( CTRL_TOOLTIP, PART_ENTIRE_CONTROL ) )
414 : : {
415 : : // #i46472# workaround gcc3.3 temporary problem
416 [ # # ]: 0 : Rectangle aCtrlRegion( Point( 0, 0 ), GetOutputSizePixel() );
417 : 0 : ImplControlValue aControlValue;
418 : : bNativeOK = DrawNativeControl( CTRL_TOOLTIP, PART_ENTIRE_CONTROL, aCtrlRegion,
419 [ # # ][ # # ]: 0 : 0, aControlValue, rtl::OUString() );
420 : : }
421 : :
422 : : // paint text
423 [ # # ]: 0 : if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
424 : : {
425 [ # # ]: 0 : if ( mnStyle & QUICKHELP_CTRLTEXT )
426 [ # # ]: 0 : DrawCtrlText( maTextRect.TopLeft(), maHelpText );
427 : : else
428 [ # # ]: 0 : DrawText( maTextRect.TopLeft(), maHelpText );
429 : : }
430 : : else // HELPWINSTYLE_BALLOON
431 : : {
432 : : sal_uInt16 nDrawFlags = TEXT_DRAW_MULTILINE|TEXT_DRAW_WORDBREAK|
433 : 0 : TEXT_DRAW_LEFT|TEXT_DRAW_TOP;
434 [ # # ]: 0 : if ( mnStyle & QUICKHELP_CTRLTEXT )
435 : 0 : nDrawFlags |= TEXT_DRAW_MNEMONIC;
436 : 0 : DrawText( maTextRect, maHelpText, nDrawFlags );
437 : : }
438 : :
439 : : // border
440 [ # # ]: 0 : if( ! bNativeOK )
441 : : {
442 : 0 : Size aSz = GetOutputSizePixel();
443 [ # # ][ # # ]: 0 : DrawRect( Rectangle( Point(), aSz ) );
444 [ # # ]: 0 : if ( mnHelpWinStyle == HELPWINSTYLE_BALLOON )
445 : : {
446 : 0 : aSz.Width() -= 2;
447 : 0 : aSz.Height() -= 2;
448 : 0 : Color aColor( GetLineColor() );
449 [ # # ]: 0 : SetLineColor( ( COL_GRAY ) );
450 [ # # ][ # # ]: 0 : DrawRect( Rectangle( Point( 1, 1 ), aSz ) );
451 [ # # ]: 0 : SetLineColor( aColor );
452 : : }
453 : : }
454 : 0 : }
455 : :
456 : : // -----------------------------------------------------------------------
457 : :
458 : 0 : void HelpTextWindow::ShowHelp( sal_uInt16 nDelayMode )
459 : : {
460 : 0 : sal_uLong nTimeout = 0;
461 [ # # ]: 0 : if ( nDelayMode != HELPDELAY_NONE )
462 : : {
463 : : // In case of ExtendedHelp display help sooner
464 [ # # ]: 0 : if ( ImplGetSVData()->maHelpData.mbExtHelpMode )
465 : 0 : nTimeout = 15;
466 : : else
467 : : {
468 : 0 : const HelpSettings& rHelpSettings = GetSettings().GetHelpSettings();
469 [ # # ]: 0 : if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
470 : 0 : nTimeout = rHelpSettings.GetTipDelay();
471 : : else
472 : 0 : nTimeout = rHelpSettings.GetBalloonDelay();
473 : : }
474 : :
475 [ # # ]: 0 : if ( nDelayMode == HELPDELAY_SHORT )
476 : 0 : nTimeout /= 3;
477 : : }
478 : :
479 : 0 : maShowTimer.SetTimeout( nTimeout );
480 : 0 : maShowTimer.Start();
481 : 0 : }
482 : :
483 : : // -----------------------------------------------------------------------
484 : :
485 : 0 : IMPL_LINK( HelpTextWindow, TimerHdl, Timer*, pTimer)
486 : : {
487 [ # # ]: 0 : if ( pTimer == &maShowTimer )
488 : : {
489 [ # # ]: 0 : if ( mnHelpWinStyle == HELPWINSTYLE_QUICK )
490 : : {
491 : : // start auto-hide-timer for non-ShowTip windows
492 : 0 : ImplSVData* pSVData = ImplGetSVData();
493 [ # # ]: 0 : if ( this == pSVData->maHelpData.mpHelpWin )
494 : 0 : maHideTimer.Start();
495 : : }
496 : 0 : ImplShow();
497 : : }
498 : : else
499 : : {
500 : : DBG_ASSERT( pTimer == &maHideTimer, "HelpTextWindow::TimerHdl with bad Timer" );
501 : 0 : ImplDestroyHelpWindow( true );
502 : : }
503 : :
504 : 0 : return 1;
505 : : }
506 : :
507 : : // -----------------------------------------------------------------------
508 : :
509 : 0 : Size HelpTextWindow::CalcOutSize() const
510 : : {
511 : 0 : Size aSz = maTextRect.GetSize();
512 : 0 : aSz.Width() += 2*maTextRect.Left();
513 : 0 : aSz.Height() += 2*maTextRect.Top();
514 : 0 : return aSz;
515 : : }
516 : :
517 : : // -----------------------------------------------------------------------
518 : :
519 : 0 : void HelpTextWindow::RequestHelp( const HelpEvent& /*rHEvt*/ )
520 : : {
521 : : // Just to assure that Window::RequestHelp() is not called by
522 : : // ShowQuickHelp/ShowBalloonHelp in the HelpTextWindow.
523 : 0 : }
524 : :
525 : : // -----------------------------------------------------------------------
526 : :
527 : 0 : String HelpTextWindow::GetText() const
528 : : {
529 : 0 : return maHelpText;
530 : : }
531 : :
532 : : // -----------------------------------------------------------------------
533 : :
534 : 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HelpTextWindow::CreateAccessible()
535 : : {
536 : 0 : return FloatingWindow::CreateAccessible();
537 : : }
538 : :
539 : :
540 : : // =======================================================================
541 : :
542 : 0 : void ImplShowHelpWindow( Window* pParent, sal_uInt16 nHelpWinStyle, sal_uInt16 nStyle,
543 : : const XubString& rHelpText, const XubString& rStatusText,
544 : : const Point& rScreenPos, const Rectangle* pHelpArea )
545 : : {
546 : 0 : ImplSVData* pSVData = ImplGetSVData();
547 : :
548 [ # # ][ # # ]: 0 : if( !rHelpText.Len() && !pSVData->maHelpData.mbRequestingHelp )
[ # # ]
549 : 0 : return;
550 : :
551 : 0 : HelpTextWindow* pHelpWin = pSVData->maHelpData.mpHelpWin;
552 : 0 : sal_uInt16 nDelayMode = HELPDELAY_NORMAL;
553 [ # # ]: 0 : if ( pHelpWin )
554 : : {
555 : : DBG_ASSERT( pHelpWin != pParent, "HelpInHelp ?!" );
556 : :
557 [ # # # # ]: 0 : if ( ( ( pHelpWin->GetHelpText() != rHelpText )
[ # # # # ]
[ # # ][ # # ]
558 : 0 : || ( pHelpWin->GetWinStyle() != nHelpWinStyle )
559 : : || ( pHelpArea
560 : 0 : && ( pHelpWin->GetHelpArea() != *pHelpArea )
561 : : )
562 : : )
563 : : && pSVData->maHelpData.mbRequestingHelp
564 : : )
565 : : {
566 : : // remove help window if no HelpText or other HelpText or
567 : : // other help mode. but keep it if we are scrolling, ie not requesting help
568 : 0 : bool bWasVisible = pHelpWin->IsVisible();
569 [ # # ]: 0 : if ( bWasVisible )
570 : 0 : nDelayMode = HELPDELAY_NONE; // display it quickly if we were already in quick help mode
571 : 0 : pHelpWin = NULL;
572 : 0 : ImplDestroyHelpWindow( bWasVisible );
573 : : }
574 : : else
575 : : {
576 : 0 : bool const bTextChanged = rHelpText != pHelpWin->GetHelpText();
577 [ # # ][ # # ]: 0 : if ( bTextChanged || ( ( nStyle & QUICKHELP_FORCE_REPOSITION ) != 0 ) )
578 : : {
579 [ # # ][ # # ]: 0 : Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
580 [ # # ]: 0 : Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
581 [ # # ][ # # ]: 0 : if( pHelpWin->IsVisible() )
582 [ # # ]: 0 : pWindow->Invalidate( aInvRect );
583 : :
584 [ # # ]: 0 : pHelpWin->SetHelpText( rHelpText );
585 : : // approach mouse position
586 [ # # ]: 0 : ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea );
587 [ # # ][ # # ]: 0 : if( pHelpWin->IsVisible() )
588 [ # # ]: 0 : pHelpWin->Invalidate();
589 : : }
590 : : }
591 : : }
592 : :
593 [ # # ][ # # ]: 0 : if ( !pHelpWin && rHelpText.Len() )
[ # # ]
594 : : {
595 [ # # ]: 0 : sal_uLong nCurTime = Time::GetSystemTicks();
596 [ # # ][ # # ]: 0 : if ( ( ( nCurTime - pSVData->maHelpData.mnLastHelpHideTime ) < pParent->GetSettings().GetHelpSettings().GetTipDelay() )
[ # # ]
597 : : || ( ( nStyle & QUICKHELP_NO_DELAY ) != 0 )
598 : : )
599 : 0 : nDelayMode = HELPDELAY_NONE;
600 : :
601 : : DBG_ASSERT( !pHelpWin, "Noch ein HelpWin ?!" );
602 [ # # ][ # # ]: 0 : pHelpWin = new HelpTextWindow( pParent, rHelpText, nHelpWinStyle, nStyle );
603 : 0 : pSVData->maHelpData.mpHelpWin = pHelpWin;
604 [ # # ]: 0 : pHelpWin->SetStatusText( rStatusText );
605 [ # # ]: 0 : if ( pHelpArea )
606 : 0 : pHelpWin->SetHelpArea( *pHelpArea );
607 : :
608 : : // positioning
609 [ # # ]: 0 : Size aSz = pHelpWin->CalcOutSize();
610 [ # # ]: 0 : pHelpWin->SetOutputSizePixel( aSz );
611 [ # # ]: 0 : ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea );
612 : : // if not called from Window::RequestHelp, then without delay...
613 [ # # ]: 0 : if ( !pSVData->maHelpData.mbRequestingHelp )
614 : 0 : nDelayMode = HELPDELAY_NONE;
615 [ # # ]: 0 : pHelpWin->ShowHelp( nDelayMode );
616 : : }
617 : : }
618 : :
619 : : // -----------------------------------------------------------------------
620 : :
621 : 3749 : void ImplDestroyHelpWindow( bool bUpdateHideTime )
622 : : {
623 : 3749 : ImplSVData* pSVData = ImplGetSVData();
624 : 3749 : HelpTextWindow* pHelpWin = pSVData->maHelpData.mpHelpWin;
625 [ - + ]: 3749 : if ( pHelpWin )
626 : : {
627 [ # # ][ # # ]: 0 : Window * pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
628 : : // find out screen area covered by system help window
629 [ # # ]: 0 : Rectangle aInvRect( pHelpWin->GetWindowExtentsRelative( pWindow ) );
630 [ # # ][ # # ]: 0 : if( pHelpWin->IsVisible() )
631 [ # # ]: 0 : pWindow->Invalidate( aInvRect );
632 : 0 : pSVData->maHelpData.mpHelpWin = NULL;
633 : 0 : pSVData->maHelpData.mbKeyboardHelp = sal_False;
634 [ # # ]: 0 : pHelpWin->Hide();
635 [ # # ][ # # ]: 0 : delete pHelpWin;
636 [ # # ]: 0 : if( bUpdateHideTime )
637 [ # # ]: 0 : pSVData->maHelpData.mnLastHelpHideTime = Time::GetSystemTicks();
638 : : }
639 : 3749 : }
640 : :
641 : : // -----------------------------------------------------------------------
642 : :
643 : 0 : void ImplSetHelpWindowPos( Window* pHelpWin, sal_uInt16 nHelpWinStyle, sal_uInt16 nStyle,
644 : : const Point& rPos, const Rectangle* pHelpArea )
645 : : {
646 : 0 : Point aPos = rPos;
647 [ # # ]: 0 : Size aSz = pHelpWin->GetSizePixel();
648 [ # # ][ # # ]: 0 : Rectangle aScreenRect = pHelpWin->ImplGetFrameWindow()->GetDesktopRectPixel();
649 [ # # ][ # # ]: 0 : aPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( aPos );
[ # # ]
650 : : // get mouse screen coords
651 [ # # ][ # # ]: 0 : Point mPos( pHelpWin->GetParent()->ImplGetFrameWindow()->GetPointerPosPixel() );
[ # # ]
652 [ # # ][ # # ]: 0 : mPos = pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( mPos );
[ # # ]
653 : :
654 [ # # ]: 0 : if ( nHelpWinStyle == HELPWINSTYLE_QUICK )
655 : : {
656 [ # # ]: 0 : if ( !(nStyle & QUICKHELP_NOAUTOPOS) )
657 : : {
658 [ # # ]: 0 : long nScreenHeight = aScreenRect.GetHeight();
659 : 0 : aPos.X() -= 4;
660 [ # # ]: 0 : if ( aPos.Y() > aScreenRect.Top()+nScreenHeight-(nScreenHeight/4) )
661 : 0 : aPos.Y() -= aSz.Height()+4;
662 : : else
663 : 0 : aPos.Y() += 21;
664 : : }
665 : : }
666 : : else
667 : : {
668 : : // If it's the mouse position, move the window slightly
669 : : // so the mouse pointer does not cover it
670 [ # # ]: 0 : if ( aPos == mPos )
671 : : {
672 : 0 : aPos.X() += 12;
673 : 0 : aPos.Y() += 16;
674 : : }
675 : : }
676 : :
677 [ # # ]: 0 : if ( nStyle & QUICKHELP_NOAUTOPOS )
678 : : {
679 [ # # ]: 0 : if ( pHelpArea )
680 : : {
681 : : // convert help area to screen coords
682 : : Rectangle devHelpArea(
683 [ # # ][ # # ]: 0 : pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->TopLeft() ),
684 [ # # ][ # # ]: 0 : pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->BottomRight() ) );
[ # # ][ # # ]
[ # # ][ # # ]
685 : :
686 : : // Welche Position vom Rechteck?
687 [ # # ]: 0 : aPos = devHelpArea.Center();
688 : :
689 [ # # ]: 0 : if ( nStyle & QUICKHELP_LEFT )
690 : 0 : aPos.X() = devHelpArea.Left();
691 [ # # ]: 0 : else if ( nStyle & QUICKHELP_RIGHT )
692 : 0 : aPos.X() = devHelpArea.Right();
693 : :
694 [ # # ]: 0 : if ( nStyle & QUICKHELP_TOP )
695 : 0 : aPos.Y() = devHelpArea.Top();
696 [ # # ]: 0 : else if ( nStyle & QUICKHELP_BOTTOM )
697 : 0 : aPos.Y() = devHelpArea.Bottom();
698 : : }
699 : :
700 : : // Welche Richtung?
701 [ # # ]: 0 : if ( nStyle & QUICKHELP_LEFT )
702 : : ;
703 [ # # ]: 0 : else if ( nStyle & QUICKHELP_RIGHT )
704 : 0 : aPos.X() -= aSz.Width();
705 : : else
706 : 0 : aPos.X() -= aSz.Width()/2;
707 : :
708 [ # # ]: 0 : if ( nStyle & QUICKHELP_TOP )
709 : : ;
710 [ # # ]: 0 : else if ( nStyle & QUICKHELP_BOTTOM )
711 : 0 : aPos.Y() -= aSz.Height();
712 : : else
713 : 0 : aPos.Y() -= aSz.Height()/2;
714 : : }
715 : :
716 [ # # ]: 0 : if ( aPos.X() < aScreenRect.Left() )
717 : 0 : aPos.X() = aScreenRect.Left();
718 [ # # ]: 0 : else if ( ( aPos.X() + aSz.Width() ) > aScreenRect.Right() )
719 : 0 : aPos.X() = aScreenRect.Right() - aSz.Width();
720 [ # # ]: 0 : if ( aPos.Y() < aScreenRect.Top() )
721 : 0 : aPos.Y() = aScreenRect.Top();
722 [ # # ]: 0 : else if ( ( aPos.Y() + aSz.Height() ) > aScreenRect.Bottom() )
723 : 0 : aPos.Y() = aScreenRect.Bottom() - aSz.Height();
724 : :
725 [ # # ]: 0 : if( ! (nStyle & QUICKHELP_NOEVADEPOINTER) )
726 : : {
727 : : /* the remark below should be obsolete by now as the helpwindow should
728 : : not be focusable, leaving it as a hint. However it is sensible in most
729 : : conditions to evade the mouse pointer so the content window is fully visible.
730 : :
731 : : // the popup must not appear under the mouse
732 : : // otherwise it would directly be closed due to a focus change...
733 : : */
734 [ # # ]: 0 : Rectangle aHelpRect( aPos, aSz );
735 [ # # ][ # # ]: 0 : if( aHelpRect.IsInside( mPos ) )
736 : : {
737 : 0 : Point delta(2,2);
738 : 0 : Point pSize( aSz.Width(), aSz.Height() );
739 : 0 : Point pTest( mPos - pSize - delta );
740 [ # # ][ # # ]: 0 : if( pTest.X() > aScreenRect.Left() && pTest.Y() > aScreenRect.Top() )
[ # # ]
741 : 0 : aPos = pTest;
742 : : else
743 : 0 : aPos = mPos + delta;
744 : : }
745 : : }
746 : :
747 [ # # ][ # # ]: 0 : Window* pWindow = pHelpWin->GetParent()->ImplGetFrameWindow();
748 [ # # ]: 0 : aPos = pWindow->AbsoluteScreenToOutputPixel( aPos );
749 [ # # ]: 0 : pHelpWin->SetPosPixel( aPos );
750 : 0 : }
751 : :
752 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|