Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "menufloatingwindow.hxx"
21 : #include "menuitemlist.hxx"
22 :
23 : #include <svdata.hxx>
24 : #include <vcl/decoview.hxx>
25 : #include <vcl/settings.hxx>
26 : #include <window.h>
27 :
28 16 : MenuFloatingWindow::MenuFloatingWindow( Menu* pMen, vcl::Window* pParent, WinBits nStyle ) :
29 16 : FloatingWindow( pParent, nStyle )
30 : {
31 16 : mpWindowImpl->mbMenuFloatingWindow= true;
32 16 : pMenu = pMen;
33 16 : pActivePopup = 0;
34 16 : nSaveFocusId = 0;
35 16 : bInExecute = false;
36 16 : bScrollMenu = false;
37 16 : nHighlightedItem = ITEMPOS_INVALID;
38 16 : nMBDownPos = ITEMPOS_INVALID;
39 16 : nPosInParent = ITEMPOS_INVALID;
40 16 : nScrollerHeight = 0;
41 16 : nBorder = EXTRASPACEY;
42 16 : nFirstEntry = 0;
43 16 : bScrollUp = false;
44 16 : bScrollDown = false;
45 16 : bIgnoreFirstMove = true;
46 16 : bKeyInput = false;
47 :
48 16 : EnableSaveBackground();
49 16 : ImplInitMenuWindow( this, true, false );
50 :
51 16 : SetPopupModeEndHdl( LINK( this, MenuFloatingWindow, PopupEnd ) );
52 :
53 16 : aHighlightChangedTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, HighlightChanged ) );
54 16 : aHighlightChangedTimer.SetTimeout( GetSettings().GetMouseSettings().GetMenuDelay() );
55 16 : aSubmenuCloseTimer.SetTimeout( GetSettings().GetMouseSettings().GetMenuDelay() );
56 16 : aSubmenuCloseTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, SubmenuClose ) );
57 16 : aScrollTimer.SetTimeoutHdl( LINK( this, MenuFloatingWindow, AutoScroll ) );
58 :
59 16 : AddEventListener( LINK( this, MenuFloatingWindow, ShowHideListener ) );
60 16 : }
61 :
62 32 : void MenuFloatingWindow::doShutdown()
63 : {
64 32 : if( pMenu )
65 : {
66 : // #105373# notify toolkit that highlight was removed
67 : // otherwise the entry will not be read when the menu is opened again
68 16 : if( nHighlightedItem != ITEMPOS_INVALID )
69 0 : pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
70 16 : if (!bKeyInput && pMenu && pMenu->pStartedFrom && !pMenu->pStartedFrom->IsMenuBar())
71 : {
72 : // #102461# remove highlight in parent
73 : MenuItemData* pData;
74 0 : size_t i, nCount = pMenu->pStartedFrom->pItemList->size();
75 0 : for(i = 0; i < nCount; i++)
76 : {
77 0 : pData = pMenu->pStartedFrom->pItemList->GetDataFromPos( i );
78 0 : if( pData && ( pData->pSubMenu == pMenu ) )
79 0 : break;
80 : }
81 0 : if( i < nCount )
82 : {
83 0 : MenuFloatingWindow* pPWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->ImplGetWindow());
84 0 : if( pPWin )
85 0 : pPWin->HighlightItem( i, false );
86 : }
87 : }
88 :
89 : // free the reference to the accessible component
90 16 : SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >() );
91 :
92 16 : aHighlightChangedTimer.Stop();
93 :
94 : // #95056# invalidate screen area covered by system window
95 : // so this can be taken into account if the commandhandler performs a scroll operation
96 16 : if( GetParent() )
97 : {
98 16 : Rectangle aInvRect( GetWindowExtentsRelative( GetParent() ) );
99 16 : GetParent()->Invalidate( aInvRect );
100 : }
101 16 : pMenu = NULL;
102 16 : RemoveEventListener( LINK( this, MenuFloatingWindow, ShowHideListener ) );
103 : }
104 32 : }
105 :
106 48 : MenuFloatingWindow::~MenuFloatingWindow()
107 : {
108 16 : doShutdown();
109 32 : }
110 :
111 16 : void MenuFloatingWindow::Resize()
112 : {
113 16 : InitMenuClipRegion();
114 16 : }
115 :
116 16 : long MenuFloatingWindow::ImplGetStartY() const
117 : {
118 16 : long nY = 0;
119 16 : if( pMenu )
120 : {
121 16 : for ( sal_uInt16 n = 0; n < nFirstEntry; n++ )
122 0 : nY += pMenu->GetItemList()->GetDataFromPos( n )->aSz.Height();
123 : }
124 16 : return -nY;
125 : }
126 :
127 0 : vcl::Region MenuFloatingWindow::ImplCalcClipRegion( bool bIncludeLogo ) const
128 : {
129 0 : Size aOutSz = GetOutputSizePixel();
130 0 : Point aPos;
131 0 : Rectangle aRect( aPos, aOutSz );
132 0 : aRect.Top() += nScrollerHeight;
133 0 : aRect.Bottom() -= nScrollerHeight;
134 :
135 0 : if ( pMenu && pMenu->pLogo && !bIncludeLogo )
136 0 : aRect.Left() += pMenu->pLogo->aBitmap.GetSizePixel().Width();
137 :
138 0 : vcl::Region aRegion(aRect);
139 0 : if ( pMenu && pMenu->pLogo && bIncludeLogo && nScrollerHeight )
140 0 : aRegion.Union( Rectangle( Point(), Size( pMenu->pLogo->aBitmap.GetSizePixel().Width(), aOutSz.Height() ) ) );
141 :
142 0 : return aRegion;
143 : }
144 :
145 16 : void MenuFloatingWindow::InitMenuClipRegion()
146 : {
147 16 : if ( IsScrollMenu() )
148 : {
149 0 : SetClipRegion( ImplCalcClipRegion() );
150 : }
151 : else
152 : {
153 16 : SetClipRegion();
154 : }
155 16 : }
156 :
157 0 : void MenuFloatingWindow::ImplHighlightItem( const MouseEvent& rMEvt, bool bMBDown )
158 : {
159 0 : if( ! pMenu )
160 0 : return;
161 :
162 0 : long nY = nScrollerHeight + ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
163 0 : long nMouseY = rMEvt.GetPosPixel().Y();
164 0 : Size aOutSz = GetOutputSizePixel();
165 0 : if ( ( nMouseY >= nY ) && ( nMouseY < ( aOutSz.Height() - nY ) ) )
166 : {
167 0 : bool bHighlighted = false;
168 0 : size_t nCount = pMenu->pItemList->size();
169 0 : nY += ImplGetStartY(); // ggf. gescrollt.
170 0 : for ( size_t n = 0; !bHighlighted && ( n < nCount ); n++ )
171 : {
172 0 : if ( pMenu->ImplIsVisible( n ) )
173 : {
174 0 : MenuItemData* pItemData = pMenu->pItemList->GetDataFromPos( n );
175 0 : long nOldY = nY;
176 0 : nY += pItemData->aSz.Height();
177 0 : if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) && pMenu->ImplIsSelectable( n ) )
178 : {
179 0 : bool bPopupArea = true;
180 0 : if ( pItemData->nBits & MenuItemBits::POPUPSELECT )
181 : {
182 : // only when clicked over the arrow...
183 0 : Size aSz = GetOutputSizePixel();
184 0 : long nFontHeight = GetTextHeight();
185 0 : bPopupArea = ( rMEvt.GetPosPixel().X() >= ( aSz.Width() - nFontHeight - nFontHeight/4 ) );
186 : }
187 :
188 0 : if ( bMBDown )
189 : {
190 0 : if ( n != nHighlightedItem )
191 : {
192 0 : ChangeHighlightItem( (sal_uInt16)n, false );
193 : }
194 :
195 0 : bool bAllowNewPopup = true;
196 0 : if ( pActivePopup )
197 : {
198 0 : MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
199 0 : bAllowNewPopup = pData && ( pData->pSubMenu != pActivePopup );
200 0 : if ( bAllowNewPopup )
201 0 : KillActivePopup();
202 : }
203 :
204 0 : if ( bPopupArea && bAllowNewPopup )
205 : {
206 0 : HighlightChanged( NULL );
207 : }
208 : }
209 : else
210 : {
211 0 : if ( n != nHighlightedItem )
212 : {
213 0 : ChangeHighlightItem( (sal_uInt16)n, true );
214 : }
215 0 : else if ( pItemData->nBits & MenuItemBits::POPUPSELECT )
216 : {
217 0 : if ( bPopupArea && ( pActivePopup != pItemData->pSubMenu ) )
218 0 : HighlightChanged( NULL );
219 : }
220 : }
221 0 : bHighlighted = true;
222 : }
223 : }
224 : }
225 0 : if ( !bHighlighted )
226 0 : ChangeHighlightItem( ITEMPOS_INVALID, true );
227 : }
228 : else
229 : {
230 0 : ImplScroll( rMEvt.GetPosPixel() );
231 0 : ChangeHighlightItem( ITEMPOS_INVALID, true );
232 : }
233 : }
234 :
235 0 : IMPL_LINK_NOARG(MenuFloatingWindow, PopupEnd)
236 : {
237 : // "this" will be deleted before the end of this method!
238 0 : Menu* pM = pMenu;
239 0 : if ( bInExecute )
240 : {
241 0 : if ( pActivePopup )
242 : {
243 : //DBG_ASSERT( !pActivePopup->ImplGetWindow(), "PopupEnd, obwohl pActivePopup MIT Window!" );
244 0 : KillActivePopup(); // should be ok to just remove it
245 : //pActivePopup->bCanceled = true;
246 : }
247 0 : bInExecute = false;
248 0 : pMenu->bInCallback = true;
249 0 : pMenu->Deactivate();
250 0 : pMenu->bInCallback = false;
251 : }
252 : else
253 : {
254 0 : if (pMenu && pMenu->pStartedFrom)
255 0 : pMenu->pStartedFrom->ClosePopup(pMenu);
256 : }
257 :
258 0 : if ( pM )
259 0 : pM->pStartedFrom = 0;
260 :
261 0 : return 0;
262 : }
263 :
264 0 : IMPL_LINK_NOARG(MenuFloatingWindow, AutoScroll)
265 : {
266 0 : ImplScroll( GetPointerPosPixel() );
267 0 : return 1;
268 : }
269 :
270 0 : IMPL_LINK( MenuFloatingWindow, HighlightChanged, Timer*, pTimer )
271 : {
272 0 : if( ! pMenu )
273 0 : return 0;
274 :
275 0 : MenuItemData* pItemData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
276 0 : if ( pItemData )
277 : {
278 0 : if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) )
279 : {
280 0 : sal_uLong nOldFlags = GetPopupModeFlags();
281 0 : SetPopupModeFlags( GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE );
282 0 : KillActivePopup();
283 0 : SetPopupModeFlags( nOldFlags );
284 : }
285 0 : if ( pItemData->bEnabled && pItemData->pSubMenu && pItemData->pSubMenu->GetItemCount() && ( pItemData->pSubMenu != pActivePopup ) )
286 : {
287 0 : pActivePopup = static_cast<PopupMenu*>(pItemData->pSubMenu);
288 0 : long nY = nScrollerHeight+ImplGetStartY();
289 0 : MenuItemData* pData = 0;
290 0 : for ( sal_uLong n = 0; n < nHighlightedItem; n++ )
291 : {
292 0 : pData = pMenu->pItemList->GetDataFromPos( n );
293 0 : nY += pData->aSz.Height();
294 : }
295 0 : pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
296 0 : Size MySize = GetOutputSizePixel();
297 0 : Point aItemTopLeft( 0, nY );
298 0 : Point aItemBottomRight( aItemTopLeft );
299 0 : aItemBottomRight.X() += MySize.Width();
300 0 : aItemBottomRight.Y() += pData->aSz.Height();
301 :
302 : // shift the popups a little
303 0 : aItemTopLeft.X() += 2;
304 0 : aItemBottomRight.X() -= 2;
305 0 : if ( nHighlightedItem )
306 0 : aItemTopLeft.Y() -= 2;
307 : else
308 : {
309 : sal_Int32 nL, nT, nR, nB;
310 0 : GetBorder( nL, nT, nR, nB );
311 0 : aItemTopLeft.Y() -= nT;
312 : }
313 :
314 : // pTest: crash due to Reschedule() in call of Activate()
315 : // Also it is prevented that submenus are displayed which
316 : // were for long in Activate Rescheduled and which should not be
317 : // displayed now.
318 0 : Menu* pTest = pActivePopup;
319 0 : sal_uLong nOldFlags = GetPopupModeFlags();
320 0 : SetPopupModeFlags( GetPopupModeFlags() | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE );
321 0 : sal_uInt16 nRet = pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FLOATWIN_POPUPMODE_RIGHT, pMenu, pTimer ? false : true );
322 0 : SetPopupModeFlags( nOldFlags );
323 :
324 : // nRet != 0, wenn es waerend Activate() abgeschossen wurde...
325 0 : if ( !nRet && ( pActivePopup == pTest ) && pActivePopup->ImplGetWindow() )
326 0 : pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
327 : }
328 : }
329 :
330 0 : return 0;
331 : }
332 :
333 0 : IMPL_LINK_NOARG(MenuFloatingWindow, SubmenuClose)
334 : {
335 0 : if( pMenu && pMenu->pStartedFrom )
336 : {
337 0 : MenuFloatingWindow* pWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->GetWindow());
338 0 : if( pWin )
339 0 : pWin->KillActivePopup();
340 : }
341 0 : return 0;
342 : }
343 :
344 192 : IMPL_LINK( MenuFloatingWindow, ShowHideListener, VclWindowEvent*, pEvent )
345 : {
346 96 : if( ! pMenu )
347 0 : return 0;
348 :
349 96 : if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW )
350 32 : pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID );
351 64 : else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
352 32 : pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID );
353 96 : return 0;
354 : }
355 :
356 0 : void MenuFloatingWindow::EnableScrollMenu( bool b )
357 : {
358 0 : bScrollMenu = b;
359 0 : nScrollerHeight = b ? (sal_uInt16) GetSettings().GetStyleSettings().GetScrollBarSize() /2 : 0;
360 0 : bScrollDown = true;
361 0 : InitMenuClipRegion();
362 0 : }
363 :
364 0 : void MenuFloatingWindow::Execute()
365 : {
366 0 : ImplSVData* pSVData = ImplGetSVData();
367 :
368 0 : pSVData->maAppData.mpActivePopupMenu = static_cast<PopupMenu*>(pMenu);
369 :
370 0 : bInExecute = true;
371 : // bCallingSelect = false;
372 :
373 0 : while ( bInExecute )
374 0 : Application::Yield();
375 :
376 0 : pSVData->maAppData.mpActivePopupMenu = NULL;
377 0 : }
378 :
379 16 : void MenuFloatingWindow::StopExecute( sal_uLong nFocusId )
380 : {
381 : // restore focus
382 : // (could have been restored in Select)
383 16 : if ( nSaveFocusId )
384 : {
385 0 : Window::EndSaveFocus( nFocusId, false );
386 0 : nFocusId = nSaveFocusId;
387 0 : if ( nFocusId )
388 : {
389 0 : nSaveFocusId = 0;
390 0 : ImplGetSVData()->maWinData.mbNoDeactivate = false;
391 : }
392 : }
393 16 : ImplEndPopupMode( 0, nFocusId );
394 :
395 16 : aHighlightChangedTimer.Stop();
396 16 : bInExecute = false;
397 16 : if ( pActivePopup )
398 : {
399 0 : KillActivePopup();
400 : }
401 : // notify parent, needed for accessibility
402 16 : if( pMenu && pMenu->pStartedFrom )
403 16 : pMenu->pStartedFrom->ImplCallEventListeners( VCLEVENT_MENU_SUBMENUDEACTIVATE, nPosInParent );
404 16 : }
405 :
406 0 : void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly )
407 : {
408 0 : if ( pActivePopup && ( !pThisOnly || ( pThisOnly == pActivePopup ) ) )
409 : {
410 0 : if( pActivePopup->pWindow != NULL )
411 0 : if( static_cast<FloatingWindow *>(pActivePopup->pWindow)->IsInCleanUp() )
412 0 : return; // kill it later
413 0 : if ( pActivePopup->bInCallback )
414 0 : pActivePopup->bCanceled = true;
415 :
416 : // For all actions pActivePopup = 0, if e.g.
417 : // PopupModeEndHdl the popups to destroy were called synchronous
418 0 : PopupMenu* pPopup = pActivePopup;
419 0 : pActivePopup = NULL;
420 0 : pPopup->bInCallback = true;
421 0 : pPopup->Deactivate();
422 0 : pPopup->bInCallback = false;
423 0 : if ( pPopup->ImplGetWindow() )
424 : {
425 0 : pPopup->ImplGetFloatingWindow()->StopExecute();
426 0 : pPopup->ImplGetFloatingWindow()->doShutdown();
427 0 : pPopup->pWindow->doLazyDelete();
428 0 : pPopup->pWindow = NULL;
429 :
430 0 : Update();
431 : }
432 : }
433 : }
434 :
435 0 : void MenuFloatingWindow::EndExecute()
436 : {
437 0 : Menu* pStart = pMenu ? pMenu->ImplGetStartMenu() : NULL;
438 0 : sal_uLong nFocusId = 0;
439 0 : if (pStart)
440 0 : nFocusId = pStart->DeactivateMenuBar(nFocusId);
441 :
442 : // if started elsewhere, cleanup there as well
443 0 : MenuFloatingWindow* pCleanUpFrom = this;
444 0 : MenuFloatingWindow* pWin = this;
445 0 : while (pWin && !pWin->bInExecute &&
446 0 : pWin->pMenu->pStartedFrom && !pWin->pMenu->pStartedFrom->IsMenuBar())
447 : {
448 0 : pWin = static_cast<PopupMenu*>(pWin->pMenu->pStartedFrom)->ImplGetFloatingWindow();
449 : }
450 0 : if ( pWin )
451 0 : pCleanUpFrom = pWin;
452 :
453 : // this window will be destroyed => store date locally...
454 0 : Menu* pM = pMenu;
455 0 : sal_uInt16 nItem = nHighlightedItem;
456 :
457 0 : pCleanUpFrom->StopExecute( nFocusId );
458 :
459 0 : if ( nItem != ITEMPOS_INVALID && pM )
460 : {
461 0 : MenuItemData* pItemData = pM->GetItemList()->GetDataFromPos( nItem );
462 0 : if ( pItemData && !pItemData->bIsTemporary )
463 : {
464 0 : pM->nSelectedId = pItemData->nId;
465 0 : if ( pStart )
466 0 : pStart->nSelectedId = pItemData->nId;
467 :
468 0 : pM->ImplSelect();
469 : }
470 : }
471 0 : }
472 :
473 0 : void MenuFloatingWindow::EndExecute( sal_uInt16 nId )
474 : {
475 : size_t nPos;
476 0 : if ( pMenu && pMenu->GetItemList()->GetData( nId, nPos ) )
477 0 : nHighlightedItem = nPos;
478 : else
479 0 : nHighlightedItem = ITEMPOS_INVALID;
480 :
481 0 : EndExecute();
482 0 : }
483 :
484 0 : void MenuFloatingWindow::MouseButtonDown( const MouseEvent& rMEvt )
485 : {
486 : // TH creates a ToTop on this window, but the active popup
487 : // should stay on top...
488 : // due to focus change this would close all menus -> don't do it (#94123)
489 : //if ( pActivePopup && pActivePopup->ImplGetWindow() && !pActivePopup->ImplGetFloatingWindow()->pActivePopup )
490 : // pActivePopup->ImplGetFloatingWindow()->ToTop( TOTOP_NOGRABFOCUS );
491 :
492 0 : ImplHighlightItem( rMEvt, true );
493 :
494 0 : nMBDownPos = nHighlightedItem;
495 0 : }
496 :
497 0 : void MenuFloatingWindow::MouseButtonUp( const MouseEvent& rMEvt )
498 : {
499 0 : MenuItemData* pData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL;
500 : // nMBDownPos store in local variable and reset immediately,
501 : // as it will be too late after EndExecute
502 0 : sal_uInt16 _nMBDownPos = nMBDownPos;
503 0 : nMBDownPos = ITEMPOS_INVALID;
504 0 : if ( pData && pData->bEnabled && ( pData->eType != MenuItemType::SEPARATOR ) )
505 : {
506 0 : if ( !pData->pSubMenu )
507 : {
508 0 : EndExecute();
509 : }
510 0 : else if ( ( pData->nBits & MenuItemBits::POPUPSELECT ) && ( nHighlightedItem == _nMBDownPos ) && ( rMEvt.GetClicks() == 2 ) )
511 : {
512 : // not when clicked over the arrow...
513 0 : Size aSz = GetOutputSizePixel();
514 0 : long nFontHeight = GetTextHeight();
515 0 : if ( rMEvt.GetPosPixel().X() < ( aSz.Width() - nFontHeight - nFontHeight/4 ) )
516 0 : EndExecute();
517 : }
518 : }
519 :
520 0 : }
521 :
522 0 : void MenuFloatingWindow::MouseMove( const MouseEvent& rMEvt )
523 : {
524 0 : if ( !IsVisible() || rMEvt.IsSynthetic() || rMEvt.IsEnterWindow() )
525 0 : return;
526 :
527 0 : if ( rMEvt.IsLeaveWindow() )
528 : {
529 : // #102461# do not remove highlight if a popup menu is open at this position
530 0 : MenuItemData* pData = pMenu ? pMenu->pItemList->GetDataFromPos( nHighlightedItem ) : NULL;
531 : // close popup with some delayed if we leave somewhere else
532 0 : if( pActivePopup && pData && pData->pSubMenu != pActivePopup )
533 0 : pActivePopup->ImplGetFloatingWindow()->aSubmenuCloseTimer.Start();
534 :
535 0 : if( !pActivePopup || (pData && pData->pSubMenu != pActivePopup ) )
536 0 : ChangeHighlightItem( ITEMPOS_INVALID, false );
537 :
538 0 : if ( IsScrollMenu() )
539 0 : ImplScroll( rMEvt.GetPosPixel() );
540 : }
541 : else
542 : {
543 0 : aSubmenuCloseTimer.Stop();
544 0 : if( bIgnoreFirstMove )
545 0 : bIgnoreFirstMove = false;
546 : else
547 0 : ImplHighlightItem( rMEvt, false );
548 : }
549 : }
550 :
551 0 : void MenuFloatingWindow::ImplScroll( bool bUp )
552 : {
553 0 : KillActivePopup();
554 0 : Update();
555 :
556 0 : if( ! pMenu )
557 0 : return;
558 :
559 0 : HighlightItem( nHighlightedItem, false );
560 :
561 0 : pMenu->ImplKillLayoutData();
562 :
563 0 : if ( bScrollUp && bUp )
564 : {
565 0 : nFirstEntry = pMenu->ImplGetPrevVisible( nFirstEntry );
566 : DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" );
567 :
568 0 : long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height();
569 :
570 0 : if ( !bScrollDown )
571 : {
572 0 : bScrollDown = true;
573 0 : ImplDrawScroller( false );
574 : }
575 :
576 0 : if ( pMenu->ImplGetPrevVisible( nFirstEntry ) == ITEMPOS_INVALID )
577 : {
578 0 : bScrollUp = false;
579 0 : ImplDrawScroller( true );
580 : }
581 :
582 0 : Scroll( 0, nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), SCROLL_CLIP );
583 : }
584 0 : else if ( bScrollDown && !bUp )
585 : {
586 0 : long nScrollEntryHeight = pMenu->GetItemList()->GetDataFromPos( nFirstEntry )->aSz.Height();
587 :
588 0 : nFirstEntry = pMenu->ImplGetNextVisible( nFirstEntry );
589 : DBG_ASSERT( nFirstEntry != ITEMPOS_INVALID, "Scroll?!" );
590 :
591 0 : if ( !bScrollUp )
592 : {
593 0 : bScrollUp = true;
594 0 : ImplDrawScroller( true );
595 : }
596 :
597 0 : long nHeight = GetOutputSizePixel().Height();
598 : sal_uInt16 nLastVisible;
599 0 : static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( nHeight, nFirstEntry, &nLastVisible );
600 0 : if ( pMenu->ImplGetNextVisible( nLastVisible ) == ITEMPOS_INVALID )
601 : {
602 0 : bScrollDown = false;
603 0 : ImplDrawScroller( false );
604 : }
605 :
606 0 : Scroll( 0, -nScrollEntryHeight, ImplCalcClipRegion( false ).GetBoundRect(), SCROLL_CLIP );
607 : }
608 :
609 0 : HighlightItem( nHighlightedItem, true );
610 : }
611 :
612 0 : void MenuFloatingWindow::ImplScroll( const Point& rMousePos )
613 : {
614 0 : Size aOutSz = GetOutputSizePixel();
615 :
616 0 : long nY = nScrollerHeight;
617 0 : long nMouseY = rMousePos.Y();
618 0 : long nDelta = 0;
619 :
620 0 : if ( bScrollUp && ( nMouseY < nY ) )
621 : {
622 0 : ImplScroll( true );
623 0 : nDelta = nY - nMouseY;
624 : }
625 0 : else if ( bScrollDown && ( nMouseY > ( aOutSz.Height() - nY ) ) )
626 : {
627 0 : ImplScroll( false );
628 0 : nDelta = nMouseY - ( aOutSz.Height() - nY );
629 : }
630 :
631 0 : if ( nDelta )
632 : {
633 0 : aScrollTimer.Stop(); // if scrolled through MouseMove.
634 : long nTimeout;
635 0 : if ( nDelta < 3 )
636 0 : nTimeout = 200;
637 0 : else if ( nDelta < 5 )
638 0 : nTimeout = 100;
639 0 : else if ( nDelta < 8 )
640 0 : nTimeout = 70;
641 0 : else if ( nDelta < 12 )
642 0 : nTimeout = 40;
643 : else
644 0 : nTimeout = 20;
645 0 : aScrollTimer.SetTimeout( nTimeout );
646 0 : aScrollTimer.Start();
647 : }
648 0 : }
649 0 : void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, bool bStartPopupTimer )
650 : {
651 : // #57934# ggf. immediately close the active, as TH's backgroundstorage works.
652 : // #65750# we prefer to refrain from the background storage of small lines.
653 : // otherwise the menus are difficult to operate.
654 : // MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
655 : // if ( pActivePopup && pNextData && ( pActivePopup != pNextData->pSubMenu ) )
656 : // KillActivePopup();
657 :
658 0 : aSubmenuCloseTimer.Stop();
659 0 : if( ! pMenu )
660 0 : return;
661 :
662 0 : if ( nHighlightedItem != ITEMPOS_INVALID )
663 : {
664 0 : HighlightItem( nHighlightedItem, false );
665 0 : pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
666 : }
667 :
668 0 : nHighlightedItem = (sal_uInt16)n;
669 : DBG_ASSERT( pMenu->ImplIsVisible( nHighlightedItem ) || nHighlightedItem == ITEMPOS_INVALID, "ChangeHighlightItem: Not visible!" );
670 0 : if( nHighlightedItem != ITEMPOS_INVALID )
671 : {
672 0 : if (pMenu->pStartedFrom && !pMenu->pStartedFrom->IsMenuBar())
673 : {
674 : // #102461# make sure parent entry is highlighted as well
675 : MenuItemData* pData;
676 0 : size_t i, nCount = pMenu->pStartedFrom->pItemList->size();
677 0 : for(i = 0; i < nCount; i++)
678 : {
679 0 : pData = pMenu->pStartedFrom->pItemList->GetDataFromPos( i );
680 0 : if( pData && ( pData->pSubMenu == pMenu ) )
681 0 : break;
682 : }
683 0 : if( i < nCount )
684 : {
685 0 : MenuFloatingWindow* pPWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->ImplGetWindow());
686 0 : if( pPWin && pPWin->nHighlightedItem != i )
687 : {
688 0 : pPWin->HighlightItem( i, true );
689 0 : pPWin->nHighlightedItem = i;
690 : }
691 : }
692 : }
693 0 : HighlightItem( nHighlightedItem, true );
694 0 : pMenu->ImplCallHighlight( nHighlightedItem );
695 : }
696 : else
697 0 : pMenu->nSelectedId = 0;
698 :
699 0 : if ( bStartPopupTimer )
700 : {
701 : // #102438# Menu items are not selectable
702 : // If a menu item is selected by an AT-tool via the XAccessibleAction, XAccessibleValue
703 : // or XAccessibleSelection interface, and the parent popup menus are not executed yet,
704 : // the parent popup menus must be executed SYNCHRONOUSLY, before the menu item is selected.
705 0 : if ( GetSettings().GetMouseSettings().GetMenuDelay() )
706 0 : aHighlightChangedTimer.Start();
707 : else
708 0 : HighlightChanged( &aHighlightChangedTimer );
709 : }
710 : }
711 :
712 0 : void MenuFloatingWindow::HighlightItem( sal_uInt16 nPos, bool bHighlight )
713 : {
714 0 : if( ! pMenu )
715 0 : return;
716 :
717 0 : Size aSz = GetOutputSizePixel();
718 0 : long nStartY = ImplGetStartY();
719 0 : long nY = nScrollerHeight + nStartY + ImplGetSVData()->maNWFData.mnMenuFormatBorderY;
720 0 : long nX = 0;
721 :
722 0 : if ( pMenu->pLogo )
723 0 : nX = pMenu->pLogo->aBitmap.GetSizePixel().Width();
724 :
725 0 : int nOuterSpaceX = ImplGetSVData()->maNWFData.mnMenuFormatBorderX;
726 :
727 0 : size_t nCount = pMenu->pItemList->size();
728 0 : for ( size_t n = 0; n < nCount; n++ )
729 : {
730 0 : MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
731 0 : if ( n == nPos )
732 : {
733 : DBG_ASSERT( pMenu->ImplIsVisible( n ), "Highlight: Item not visible!" );
734 0 : if ( pData->eType != MenuItemType::SEPARATOR )
735 : {
736 0 : bool bRestoreLineColor = false;
737 0 : Color oldLineColor;
738 0 : bool bDrawItemRect = true;
739 :
740 0 : Rectangle aItemRect( Point( nX+nOuterSpaceX, nY ), Size( aSz.Width()-2*nOuterSpaceX, pData->aSz.Height() ) );
741 0 : if ( pData->nBits & MenuItemBits::POPUPSELECT )
742 : {
743 0 : long nFontHeight = GetTextHeight();
744 0 : aItemRect.Right() -= nFontHeight + nFontHeight/4;
745 : }
746 :
747 0 : if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
748 : {
749 0 : Size aPxSize( GetOutputSizePixel() );
750 0 : Push( PushFlags::CLIPREGION );
751 0 : IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) ) );
752 0 : Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) );
753 0 : MenupopupValue aVal( pMenu->nTextPos-GUTTERBORDER, aItemRect );
754 : DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
755 : aCtrlRect,
756 : CTRL_STATE_ENABLED,
757 : aVal,
758 0 : OUString() );
759 0 : if( bHighlight &&
760 0 : IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) )
761 : {
762 0 : bDrawItemRect = false;
763 0 : if( !DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM,
764 : aItemRect,
765 : CTRL_STATE_SELECTED | ( pData->bEnabled? CTRL_STATE_ENABLED: 0 ),
766 : aVal,
767 0 : OUString() ) )
768 : {
769 0 : bDrawItemRect = bHighlight;
770 : }
771 : }
772 : else
773 0 : bDrawItemRect = bHighlight;
774 0 : Pop();
775 : }
776 0 : if( bDrawItemRect )
777 : {
778 0 : if ( bHighlight )
779 : {
780 0 : if( pData->bEnabled )
781 0 : SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
782 : else
783 : {
784 0 : SetFillColor();
785 0 : oldLineColor = GetLineColor();
786 0 : SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
787 0 : bRestoreLineColor = true;
788 : }
789 : }
790 : else
791 0 : SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
792 :
793 0 : DrawRect( aItemRect );
794 : }
795 0 : pMenu->ImplPaint( this, nScrollerHeight, nStartY, pData, bHighlight );
796 0 : if( bRestoreLineColor )
797 0 : SetLineColor( oldLineColor );
798 : }
799 0 : return;
800 : }
801 :
802 0 : nY += pData->aSz.Height();
803 : }
804 : }
805 :
806 0 : Rectangle MenuFloatingWindow::ImplGetItemRect( sal_uInt16 nPos )
807 : {
808 0 : if( ! pMenu )
809 0 : return Rectangle();
810 :
811 0 : Rectangle aRect;
812 0 : Size aSz = GetOutputSizePixel();
813 0 : long nStartY = ImplGetStartY();
814 0 : long nY = nScrollerHeight+nStartY;
815 0 : long nX = 0;
816 :
817 0 : if ( pMenu->pLogo )
818 0 : nX = pMenu->pLogo->aBitmap.GetSizePixel().Width();
819 :
820 0 : size_t nCount = pMenu->pItemList->size();
821 0 : for ( size_t n = 0; n < nCount; n++ )
822 : {
823 0 : MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
824 0 : if ( n == nPos )
825 : {
826 : DBG_ASSERT( pMenu->ImplIsVisible( n ), "ImplGetItemRect: Item not visible!" );
827 0 : if ( pData->eType != MenuItemType::SEPARATOR )
828 : {
829 0 : aRect = Rectangle( Point( nX, nY ), Size( aSz.Width(), pData->aSz.Height() ) );
830 0 : if ( pData->nBits & MenuItemBits::POPUPSELECT )
831 : {
832 0 : long nFontHeight = GetTextHeight();
833 0 : aRect.Right() -= nFontHeight + nFontHeight/4;
834 : }
835 : }
836 0 : break;
837 : }
838 0 : nY += pData->aSz.Height();
839 : }
840 0 : return aRect;
841 : }
842 :
843 0 : void MenuFloatingWindow::ImplCursorUpDown( bool bUp, bool bHomeEnd )
844 : {
845 0 : if( ! pMenu )
846 0 : return;
847 :
848 0 : const StyleSettings& rSettings = GetSettings().GetStyleSettings();
849 :
850 0 : sal_uInt16 n = nHighlightedItem;
851 0 : if ( n == ITEMPOS_INVALID )
852 : {
853 0 : if ( bUp )
854 0 : n = 0;
855 : else
856 0 : n = pMenu->GetItemCount()-1;
857 : }
858 :
859 0 : sal_uInt16 nLoop = n;
860 :
861 0 : if( bHomeEnd )
862 : {
863 : // absolute positioning
864 0 : if( bUp )
865 : {
866 0 : n = pMenu->GetItemCount();
867 0 : nLoop = n-1;
868 : }
869 : else
870 : {
871 0 : n = (sal_uInt16)-1;
872 0 : nLoop = n+1;
873 : }
874 : }
875 :
876 0 : do
877 : {
878 0 : if ( bUp )
879 : {
880 0 : if ( n )
881 0 : n--;
882 : else
883 0 : if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
884 0 : n = pMenu->GetItemCount()-1;
885 : else
886 0 : break;
887 : }
888 : else
889 : {
890 0 : n++;
891 0 : if ( n >= pMenu->GetItemCount() )
892 : {
893 0 : if ( !IsScrollMenu() || ( nHighlightedItem == ITEMPOS_INVALID ) )
894 0 : n = 0;
895 : else
896 0 : break;
897 : }
898 : }
899 :
900 0 : MenuItemData* pData = (MenuItemData*)pMenu->GetItemList()->GetDataFromPos( n );
901 0 : if ( ( pData->bEnabled || !rSettings.GetSkipDisabledInMenus() )
902 0 : && ( pData->eType != MenuItemType::SEPARATOR ) && pMenu->ImplIsVisible( n ) && pMenu->ImplIsSelectable( n ) )
903 : {
904 : // Is selection in visible area?
905 0 : if ( IsScrollMenu() )
906 : {
907 0 : ChangeHighlightItem( ITEMPOS_INVALID, false );
908 :
909 0 : while ( n < nFirstEntry )
910 0 : ImplScroll( true );
911 :
912 0 : Size aOutSz = GetOutputSizePixel();
913 : sal_uInt16 nLastVisible;
914 0 : static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry, &nLastVisible );
915 0 : while ( n > nLastVisible )
916 : {
917 0 : ImplScroll( false );
918 0 : static_cast<PopupMenu*>(pMenu)->ImplCalcVisEntries( aOutSz.Height(), nFirstEntry, &nLastVisible );
919 : }
920 : }
921 0 : ChangeHighlightItem( n, false );
922 0 : break;
923 : }
924 : } while ( n != nLoop );
925 : }
926 :
927 0 : void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent )
928 : {
929 0 : ImplDelData aDelData;
930 0 : ImplAddDel( &aDelData );
931 :
932 0 : sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
933 0 : bKeyInput = true;
934 0 : switch ( nCode )
935 : {
936 : case KEY_UP:
937 : case KEY_DOWN:
938 : {
939 0 : ImplCursorUpDown( nCode == KEY_UP );
940 : }
941 0 : break;
942 : case KEY_END:
943 : case KEY_HOME:
944 : {
945 0 : ImplCursorUpDown( nCode == KEY_END, true );
946 : }
947 0 : break;
948 : case KEY_F6:
949 : case KEY_ESCAPE:
950 : {
951 : // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
952 0 : if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
953 0 : break;
954 0 : if( pMenu )
955 : {
956 0 : if ( !pMenu->pStartedFrom )
957 : {
958 0 : StopExecute();
959 0 : KillActivePopup();
960 : }
961 0 : else if (pMenu->pStartedFrom->IsMenuBar())
962 : {
963 0 : pMenu->pStartedFrom->MenuBarKeyInput(rKEvent);
964 : }
965 : else
966 : {
967 0 : StopExecute();
968 0 : PopupMenu* pPopupMenu = static_cast<PopupMenu*>(pMenu->pStartedFrom);
969 0 : MenuFloatingWindow* pFloat = pPopupMenu->ImplGetFloatingWindow();
970 0 : pFloat->GrabFocus();
971 0 : pFloat->KillActivePopup();
972 0 : pPopupMenu->ImplCallHighlight(pFloat->nHighlightedItem);
973 : }
974 : }
975 : }
976 0 : break;
977 : case KEY_LEFT:
978 : {
979 0 : if ( pMenu && pMenu->pStartedFrom )
980 : {
981 0 : StopExecute();
982 0 : if (pMenu->pStartedFrom->IsMenuBar())
983 : {
984 0 : pMenu->pStartedFrom->MenuBarKeyInput(rKEvent);
985 : }
986 : else
987 : {
988 0 : MenuFloatingWindow* pFloat = static_cast<PopupMenu*>(pMenu->pStartedFrom)->ImplGetFloatingWindow();
989 0 : pFloat->GrabFocus();
990 0 : pFloat->KillActivePopup();
991 0 : sal_uInt16 highlightItem = pFloat->GetHighlightedItem();
992 0 : pFloat->ChangeHighlightItem(highlightItem, false);
993 : }
994 : }
995 : }
996 0 : break;
997 : case KEY_RIGHT:
998 : {
999 0 : if( pMenu )
1000 : {
1001 0 : bool bDone = false;
1002 0 : if ( nHighlightedItem != ITEMPOS_INVALID )
1003 : {
1004 0 : MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
1005 0 : if ( pData && pData->pSubMenu )
1006 : {
1007 0 : HighlightChanged( 0 );
1008 0 : bDone = true;
1009 : }
1010 : }
1011 0 : if ( !bDone )
1012 : {
1013 0 : Menu* pStart = pMenu->ImplGetStartMenu();
1014 0 : if (pStart && pStart->IsMenuBar())
1015 : {
1016 : // Forward...
1017 0 : pStart->ImplGetWindow()->KeyInput( rKEvent );
1018 : }
1019 : }
1020 : }
1021 : }
1022 0 : break;
1023 : case KEY_RETURN:
1024 : {
1025 0 : if( pMenu )
1026 : {
1027 0 : MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( nHighlightedItem );
1028 0 : if ( pData && pData->bEnabled )
1029 : {
1030 0 : if ( pData->pSubMenu )
1031 0 : HighlightChanged( 0 );
1032 : else
1033 0 : EndExecute();
1034 : }
1035 : else
1036 0 : StopExecute();
1037 : }
1038 : }
1039 0 : break;
1040 : case KEY_MENU:
1041 : {
1042 0 : if( pMenu )
1043 : {
1044 0 : Menu* pStart = pMenu->ImplGetStartMenu();
1045 0 : if (pStart && pStart->IsMenuBar())
1046 : {
1047 : // Forward...
1048 0 : pStart->ImplGetWindow()->KeyInput( rKEvent );
1049 : }
1050 : }
1051 : }
1052 0 : break;
1053 : default:
1054 : {
1055 0 : sal_Unicode nCharCode = rKEvent.GetCharCode();
1056 0 : sal_uInt16 nPos = 0;
1057 0 : sal_uInt16 nDuplicates = 0;
1058 0 : MenuItemData* pData = (nCharCode && pMenu) ? pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nPos, nDuplicates, nHighlightedItem ) : NULL;
1059 0 : if ( pData )
1060 : {
1061 0 : if ( pData->pSubMenu || nDuplicates > 1 )
1062 : {
1063 0 : ChangeHighlightItem( nPos, false );
1064 0 : HighlightChanged( 0 );
1065 : }
1066 : else
1067 : {
1068 0 : nHighlightedItem = nPos;
1069 0 : EndExecute();
1070 : }
1071 : }
1072 : else
1073 0 : FloatingWindow::KeyInput( rKEvent );
1074 : }
1075 : }
1076 : // #105474# check if menu window was not destroyed
1077 0 : if ( !aDelData.IsDead() )
1078 : {
1079 0 : ImplRemoveDel( &aDelData );
1080 0 : bKeyInput = false;
1081 0 : }
1082 0 : }
1083 :
1084 14 : void MenuFloatingWindow::Paint( const Rectangle& )
1085 : {
1086 14 : if( ! pMenu )
1087 14 : return;
1088 :
1089 14 : if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
1090 : {
1091 0 : SetClipRegion();
1092 0 : long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0;
1093 0 : Size aPxSize( GetOutputSizePixel() );
1094 0 : aPxSize.Width() -= nX;
1095 0 : ImplControlValue aVal( pMenu->nTextPos-GUTTERBORDER );
1096 : DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
1097 : Rectangle( Point( nX, 0 ), aPxSize ),
1098 : CTRL_STATE_ENABLED,
1099 : aVal,
1100 0 : OUString() );
1101 0 : InitMenuClipRegion();
1102 : }
1103 14 : if ( IsScrollMenu() )
1104 : {
1105 0 : ImplDrawScroller( true );
1106 0 : ImplDrawScroller( false );
1107 : }
1108 14 : SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
1109 14 : pMenu->ImplPaint( this, nScrollerHeight, ImplGetStartY() );
1110 14 : if ( nHighlightedItem != ITEMPOS_INVALID )
1111 0 : HighlightItem( nHighlightedItem, true );
1112 : }
1113 :
1114 0 : void MenuFloatingWindow::ImplDrawScroller( bool bUp )
1115 : {
1116 0 : if( ! pMenu )
1117 0 : return;
1118 :
1119 0 : SetClipRegion();
1120 :
1121 0 : Size aOutSz = GetOutputSizePixel();
1122 0 : long nY = bUp ? 0 : ( aOutSz.Height() - nScrollerHeight );
1123 0 : long nX = pMenu->pLogo ? pMenu->pLogo->aBitmap.GetSizePixel().Width() : 0;
1124 0 : Rectangle aRect( Point( nX, nY ), Size( aOutSz.Width()-nX, nScrollerHeight ) );
1125 :
1126 0 : DecorationView aDecoView( this );
1127 0 : SymbolType eSymbol = bUp ? SymbolType::SPIN_UP : SymbolType::SPIN_DOWN;
1128 :
1129 0 : sal_uInt16 nStyle = 0;
1130 0 : if ( ( bUp && !bScrollUp ) || ( !bUp && !bScrollDown ) )
1131 0 : nStyle |= SYMBOL_DRAW_DISABLE;
1132 :
1133 0 : aDecoView.DrawSymbol( aRect, eSymbol, GetSettings().GetStyleSettings().GetButtonTextColor(), nStyle );
1134 :
1135 0 : InitMenuClipRegion();
1136 : }
1137 :
1138 0 : void MenuFloatingWindow::RequestHelp( const HelpEvent& rHEvt )
1139 : {
1140 0 : sal_uInt16 nId = nHighlightedItem;
1141 0 : Menu* pM = pMenu;
1142 0 : vcl::Window* pW = this;
1143 :
1144 : // #102618# Get item rect before destroying the window in EndExecute() call
1145 0 : Rectangle aHighlightRect( ImplGetItemRect( nHighlightedItem ) );
1146 :
1147 0 : if ( rHEvt.GetMode() & (HELPMODE_CONTEXT | HELPMODE_EXTENDED) )
1148 : {
1149 0 : nHighlightedItem = ITEMPOS_INVALID;
1150 0 : EndExecute();
1151 0 : pW = NULL;
1152 : }
1153 :
1154 0 : if( !ImplHandleHelpEvent( pW, pM, nId, rHEvt, aHighlightRect ) )
1155 0 : Window::RequestHelp( rHEvt );
1156 0 : }
1157 :
1158 48 : void MenuFloatingWindow::StateChanged( StateChangedType nType )
1159 : {
1160 48 : FloatingWindow::StateChanged( nType );
1161 :
1162 48 : if ( ( nType == StateChangedType::CONTROLFOREGROUND ) || ( nType == StateChangedType::CONTROLBACKGROUND ) )
1163 : {
1164 0 : ImplInitMenuWindow( this, false, false );
1165 0 : Invalidate();
1166 : }
1167 48 : }
1168 :
1169 0 : void MenuFloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
1170 : {
1171 0 : FloatingWindow::DataChanged( rDCEvt );
1172 :
1173 0 : if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1174 0 : (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1175 0 : ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1176 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1177 : {
1178 0 : ImplInitMenuWindow( this, false, false );
1179 0 : Invalidate();
1180 : }
1181 0 : }
1182 :
1183 0 : void MenuFloatingWindow::Command( const CommandEvent& rCEvt )
1184 : {
1185 0 : if ( rCEvt.GetCommand() == COMMAND_WHEEL )
1186 : {
1187 0 : const CommandWheelData* pData = rCEvt.GetWheelData();
1188 0 : if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
1189 : {
1190 : // ImplCursorUpDown( pData->GetDelta() > 0L );
1191 0 : ImplScroll( pData->GetDelta() > 0L );
1192 0 : MouseMove( MouseEvent( GetPointerPosPixel(), 0 ) );
1193 : }
1194 : }
1195 0 : }
1196 :
1197 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > MenuFloatingWindow::CreateAccessible()
1198 : {
1199 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc;
1200 :
1201 0 : if ( pMenu && !pMenu->pStartedFrom )
1202 0 : xAcc = pMenu->GetAccessible();
1203 :
1204 0 : return xAcc;
1205 1233 : }
1206 :
1207 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|