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 "menubarwindow.hxx"
21 : #include "menuitemlist.hxx"
22 : #include "menufloatingwindow.hxx"
23 :
24 : #include <vcl/dockingarea.hxx>
25 : #include <vcl/settings.hxx>
26 : #include <vcl/taskpanelist.hxx>
27 :
28 : #include <salframe.hxx>
29 : #include <salmenu.hxx>
30 : #include <svdata.hxx>
31 : #include <svids.hrc>
32 : #include <window.h>
33 :
34 : // document closing button
35 : #define IID_DOCUMENTCLOSE 1
36 :
37 3199 : DecoToolBox::DecoToolBox( vcl::Window* pParent, WinBits nStyle ) :
38 3199 : ToolBox( pParent, nStyle )
39 : {
40 3199 : ImplInit();
41 3199 : }
42 :
43 3199 : void DecoToolBox::ImplInit()
44 : {
45 3199 : lastSize = -1;
46 3199 : calcMinSize();
47 3199 : }
48 :
49 3 : void DecoToolBox::DataChanged( const DataChangedEvent& rDCEvt )
50 : {
51 3 : Window::DataChanged( rDCEvt );
52 :
53 3 : if ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE )
54 : {
55 0 : calcMinSize();
56 0 : SetBackground();
57 0 : SetImages( 0, true);
58 : }
59 3 : }
60 :
61 3199 : void DecoToolBox::calcMinSize()
62 : {
63 3199 : ScopedVclPtrInstance<ToolBox> aTbx( GetParent() );
64 3199 : if( GetItemCount() == 0 )
65 : {
66 3199 : ResMgr* pResMgr = ImplGetResMgr();
67 :
68 3199 : Bitmap aBitmap;
69 3199 : if( pResMgr )
70 3199 : aBitmap = Bitmap( ResId( SV_RESID_BITMAP_CLOSEDOC, *pResMgr ) );
71 3199 : aTbx->InsertItem( IID_DOCUMENTCLOSE, Image( aBitmap ) );
72 : }
73 : else
74 : {
75 0 : sal_uInt16 nItems = GetItemCount();
76 0 : for( sal_uInt16 i = 0; i < nItems; i++ )
77 : {
78 0 : sal_uInt16 nId = GetItemId( i );
79 0 : aTbx->InsertItem( nId, GetItemImage( nId ) );
80 : }
81 : }
82 3199 : aTbx->SetOutStyle( TOOLBOX_STYLE_FLAT );
83 3199 : maMinSize = aTbx->CalcWindowSizePixel();
84 :
85 3199 : aTbx.disposeAndClear();
86 3199 : }
87 :
88 3184 : void DecoToolBox::SetImages( long nMaxHeight, bool bForce )
89 : {
90 3184 : long border = getMinSize().Height() - maImage.GetSizePixel().Height();
91 :
92 3184 : if( !nMaxHeight && lastSize != -1 )
93 0 : nMaxHeight = lastSize + border; // don't change anything if called with 0
94 :
95 3184 : if( nMaxHeight < getMinSize().Height() )
96 1 : nMaxHeight = getMinSize().Height();
97 :
98 3184 : if( (lastSize != nMaxHeight - border) || bForce )
99 : {
100 3131 : lastSize = nMaxHeight - border;
101 :
102 3131 : Color aEraseColor( 255, 255, 255, 255 );
103 3131 : BitmapEx aBmpExDst( maImage.GetBitmapEx() );
104 6262 : BitmapEx aBmpExSrc( aBmpExDst );
105 :
106 3131 : aEraseColor.SetTransparency( 255 );
107 3131 : aBmpExDst.Erase( aEraseColor );
108 3131 : aBmpExDst.SetSizePixel( Size( lastSize, lastSize ) );
109 :
110 3131 : Rectangle aSrcRect( Point(0,0), maImage.GetSizePixel() );
111 6262 : Rectangle aDestRect( Point((lastSize - maImage.GetSizePixel().Width())/2,
112 6262 : (lastSize - maImage.GetSizePixel().Height())/2 ),
113 12524 : maImage.GetSizePixel() );
114 :
115 3131 : aBmpExDst.CopyPixel( aDestRect, aSrcRect, &aBmpExSrc );
116 6262 : SetItemImage( IID_DOCUMENTCLOSE, Image( aBmpExDst ) );
117 : }
118 3184 : }
119 :
120 3199 : MenuBarWindow::MenuBarWindow( vcl::Window* pParent ) :
121 : Window( pParent, 0 ),
122 : aCloseBtn(VclPtr<DecoToolBox>::Create(this)),
123 : aFloatBtn(VclPtr<PushButton>::Create(this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE)),
124 3199 : aHideBtn(VclPtr<PushButton>::Create(this, WB_NOPOINTERFOCUS | WB_SMALLSTYLE | WB_RECTSTYLE))
125 : {
126 3199 : SetType(WINDOW_MENUBARWINDOW);
127 3199 : pMenu = NULL;
128 3199 : pActivePopup = NULL;
129 3199 : nSaveFocusId = 0;
130 3199 : nHighlightedItem = ITEMPOS_INVALID;
131 3199 : nRolloveredItem = ITEMPOS_INVALID;
132 3199 : mbAutoPopup = true;
133 3199 : nSaveFocusId = 0;
134 3199 : bIgnoreFirstMove = true;
135 3199 : bStayActive = false;
136 :
137 3199 : ResMgr* pResMgr = ImplGetResMgr();
138 :
139 3199 : if(pResMgr)
140 : {
141 3199 : BitmapEx aBitmap(ResId(SV_RESID_BITMAP_CLOSEDOC, *pResMgr));
142 3199 : aCloseBtn->maImage = Image(aBitmap);
143 :
144 3199 : aCloseBtn->SetOutStyle(TOOLBOX_STYLE_FLAT);
145 3199 : aCloseBtn->SetBackground();
146 3199 : aCloseBtn->SetPaintTransparent(true);
147 3199 : aCloseBtn->SetParentClipMode(ParentClipMode::NoClip);
148 :
149 3199 : aCloseBtn->InsertItem(IID_DOCUMENTCLOSE, aCloseBtn->maImage, ToolBoxItemBits::NONE);
150 3199 : aCloseBtn->SetSelectHdl(LINK(this, MenuBarWindow, CloseHdl));
151 3199 : aCloseBtn->AddEventListener(LINK(this, MenuBarWindow, ToolboxEventHdl));
152 3199 : aCloseBtn->SetQuickHelpText(IID_DOCUMENTCLOSE, ResId(SV_HELPTEXT_CLOSEDOCUMENT, *pResMgr).toString());
153 :
154 3199 : aFloatBtn->SetClickHdl( LINK( this, MenuBarWindow, FloatHdl ) );
155 3199 : aFloatBtn->SetSymbol( SymbolType::FLOAT );
156 3199 : aFloatBtn->SetQuickHelpText( ResId(SV_HELPTEXT_RESTORE, *pResMgr).toString() );
157 :
158 3199 : aHideBtn->SetClickHdl( LINK( this, MenuBarWindow, HideHdl ) );
159 3199 : aHideBtn->SetSymbol( SymbolType::HIDE );
160 3199 : aHideBtn->SetQuickHelpText( ResId(SV_HELPTEXT_MINIMIZE, *pResMgr).toString() );
161 : }
162 :
163 3199 : ImplInitStyleSettings();
164 :
165 3199 : AddEventListener(LINK(this, MenuBarWindow, ShowHideListener));
166 3199 : }
167 :
168 9579 : MenuBarWindow::~MenuBarWindow()
169 : {
170 3193 : disposeOnce();
171 6386 : }
172 :
173 3193 : void MenuBarWindow::dispose()
174 : {
175 3193 : aCloseBtn->RemoveEventListener(LINK(this, MenuBarWindow, ToolboxEventHdl));
176 3193 : RemoveEventListener(LINK(this, MenuBarWindow, ShowHideListener));
177 :
178 3193 : aHideBtn.disposeAndClear();
179 3193 : aFloatBtn.disposeAndClear();
180 3193 : aCloseBtn.disposeAndClear();
181 :
182 3193 : Window::dispose();
183 3193 : }
184 :
185 3200 : void MenuBarWindow::SetMenu( MenuBar* pMen )
186 : {
187 3200 : pMenu = pMen;
188 3200 : KillActivePopup();
189 3200 : nHighlightedItem = ITEMPOS_INVALID;
190 3200 : if (pMen)
191 : {
192 3200 : aCloseBtn->ShowItem(IID_DOCUMENTCLOSE, pMen->HasCloseButton());
193 3200 : aCloseBtn->Show(pMen->HasCloseButton() || !m_aAddButtons.empty());
194 3200 : aFloatBtn->Show(pMen->HasFloatButton());
195 3200 : aHideBtn->Show(pMen->HasHideButton());
196 : }
197 3200 : Invalidate();
198 :
199 : // show and connect native menubar
200 3200 : if( pMenu && pMenu->ImplGetSalMenu() )
201 : {
202 2 : if( pMenu->ImplGetSalMenu()->VisibleMenuBar() )
203 0 : ImplGetFrame()->SetMenu( pMenu->ImplGetSalMenu() );
204 :
205 2 : pMenu->ImplGetSalMenu()->SetFrame( ImplGetFrame() );
206 : }
207 3200 : }
208 :
209 3200 : void MenuBarWindow::SetHeight(long nHeight)
210 : {
211 3200 : setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
212 3200 : }
213 :
214 3211 : void MenuBarWindow::ShowButtons( bool bClose, bool bFloat, bool bHide )
215 : {
216 3211 : aCloseBtn->ShowItem(IID_DOCUMENTCLOSE, bClose);
217 3211 : aCloseBtn->Show(bClose || !m_aAddButtons.empty());
218 3211 : aFloatBtn->Show( bFloat );
219 3211 : aHideBtn->Show( bHide );
220 3211 : Resize();
221 3211 : }
222 :
223 3368 : Size MenuBarWindow::MinCloseButtonSize()
224 : {
225 3368 : return aCloseBtn->getMinSize();
226 : }
227 :
228 0 : IMPL_LINK_NOARG_TYPED(MenuBarWindow, CloseHdl, ToolBox *, void)
229 : {
230 0 : if( ! pMenu )
231 0 : return;
232 :
233 0 : if( aCloseBtn->GetCurItemId() == IID_DOCUMENTCLOSE )
234 : {
235 : // #i106052# call close hdl asynchronously to ease handler implementation
236 : // this avoids still being in the handler while the DecoToolBox already
237 : // gets destroyed
238 0 : Application::PostUserEvent(static_cast<MenuBar*>(pMenu)->GetCloseButtonClickHdl(), pMenu);
239 : }
240 : else
241 : {
242 0 : std::map<sal_uInt16,AddButtonEntry>::iterator it = m_aAddButtons.find(aCloseBtn->GetCurItemId());
243 0 : if( it != m_aAddButtons.end() )
244 : {
245 : MenuBar::MenuBarButtonCallbackArg aArg;
246 0 : aArg.nId = it->first;
247 0 : aArg.bHighlight = (aCloseBtn->GetHighlightItemId() == it->first);
248 0 : aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
249 0 : it->second.m_aSelectLink.Call( &aArg );
250 : }
251 : }
252 : }
253 :
254 59794 : IMPL_LINK( MenuBarWindow, ToolboxEventHdl, VclWindowEvent*, pEvent )
255 : {
256 29897 : if( ! pMenu )
257 0 : return 0;
258 :
259 : MenuBar::MenuBarButtonCallbackArg aArg;
260 29897 : aArg.nId = 0xffff;
261 29897 : aArg.bHighlight = (pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT);
262 29897 : aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
263 29897 : if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHT )
264 0 : aArg.nId = aCloseBtn->GetHighlightItemId();
265 29897 : else if( pEvent->GetId() == VCLEVENT_TOOLBOX_HIGHLIGHTOFF )
266 : {
267 0 : sal_uInt16 nPos = static_cast< sal_uInt16 >(reinterpret_cast<sal_IntPtr>(pEvent->GetData()));
268 0 : aArg.nId = aCloseBtn->GetItemId(nPos);
269 : }
270 29897 : std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( aArg.nId );
271 29897 : if( it != m_aAddButtons.end() )
272 : {
273 0 : it->second.m_aHighlightLink.Call( &aArg );
274 : }
275 29897 : return 0;
276 : }
277 :
278 23678 : IMPL_LINK( MenuBarWindow, ShowHideListener, VclWindowEvent*, pEvent )
279 : {
280 11839 : if( ! pMenu )
281 0 : return 0;
282 :
283 11839 : if( pEvent->GetId() == VCLEVENT_WINDOW_SHOW )
284 4010 : pMenu->ImplCallEventListeners( VCLEVENT_MENU_SHOW, ITEMPOS_INVALID );
285 7829 : else if( pEvent->GetId() == VCLEVENT_WINDOW_HIDE )
286 0 : pMenu->ImplCallEventListeners( VCLEVENT_MENU_HIDE, ITEMPOS_INVALID );
287 11839 : return 0;
288 : }
289 :
290 0 : IMPL_LINK_NOARG(MenuBarWindow, FloatHdl)
291 : {
292 0 : return pMenu ? static_cast<MenuBar*>(pMenu)->GetFloatButtonClickHdl().Call( pMenu ) : 0;
293 : }
294 :
295 0 : IMPL_LINK_NOARG(MenuBarWindow, HideHdl)
296 : {
297 0 : return pMenu ? static_cast<MenuBar*>(pMenu)->GetHideButtonClickHdl().Call( pMenu ) : 0;
298 : }
299 :
300 24 : void MenuBarWindow::ImplCreatePopup( bool bPreSelectFirst )
301 : {
302 24 : MenuItemData* pItemData = pMenu ? pMenu->GetItemList()->GetDataFromPos( nHighlightedItem ) : NULL;
303 24 : if ( pItemData )
304 : {
305 8 : bIgnoreFirstMove = true;
306 8 : if ( pActivePopup && ( pActivePopup != pItemData->pSubMenu ) )
307 : {
308 0 : KillActivePopup();
309 : }
310 16 : if ( pItemData->bEnabled && pItemData->pSubMenu && ( nHighlightedItem != ITEMPOS_INVALID ) &&
311 8 : ( pItemData->pSubMenu != pActivePopup ) )
312 : {
313 8 : pActivePopup = static_cast<PopupMenu*>(pItemData->pSubMenu);
314 8 : long nX = 0;
315 8 : MenuItemData* pData = 0;
316 19 : for ( sal_uLong n = 0; n < nHighlightedItem; n++ )
317 : {
318 11 : pData = pMenu->GetItemList()->GetDataFromPos( n );
319 11 : nX += pData->aSz.Width();
320 : }
321 8 : pData = pMenu->pItemList->GetDataFromPos( nHighlightedItem );
322 8 : Point aItemTopLeft( nX, 0 );
323 8 : Point aItemBottomRight( aItemTopLeft );
324 8 : aItemBottomRight.X() += pData->aSz.Width();
325 :
326 : // the menu bar could have height 0 in fullscreen mode:
327 : // so do not use always WindowHeight, as ItemHeight < WindowHeight.
328 8 : if ( GetSizePixel().Height() )
329 : {
330 : // #107747# give menuitems the height of the menubar
331 8 : aItemBottomRight.Y() += GetOutputSizePixel().Height()-1;
332 : }
333 :
334 : // ImplExecute is not modal...
335 : // #99071# do not grab the focus, otherwise it will be restored to the menubar
336 : // when the frame is reactivated later
337 : //GrabFocus();
338 8 : pActivePopup->ImplExecute( this, Rectangle( aItemTopLeft, aItemBottomRight ), FloatWinPopupFlags::Down | FloatWinPopupFlags::NoHorzPlacement, pMenu, bPreSelectFirst );
339 : // does not have a window, if aborted before or if there are no entries
340 8 : if ( pActivePopup->ImplGetFloatingWindow() )
341 8 : pActivePopup->ImplGetFloatingWindow()->AddPopupModeWindow( this );
342 : else
343 0 : pActivePopup = nullptr;
344 : }
345 : }
346 24 : }
347 :
348 6401 : void MenuBarWindow::KillActivePopup()
349 : {
350 6401 : if ( pActivePopup )
351 : {
352 8 : if( pActivePopup->pWindow )
353 8 : if( static_cast<FloatingWindow *>(pActivePopup->pWindow.get())->IsInCleanUp() )
354 6401 : return; // kill it later
355 :
356 8 : if ( pActivePopup->bInCallback )
357 0 : pActivePopup->bCanceled = true;
358 :
359 8 : pActivePopup->bInCallback = true;
360 8 : pActivePopup->Deactivate();
361 8 : pActivePopup->bInCallback = false;
362 : // check for pActivePopup, if stopped by deactivate...
363 8 : if ( pActivePopup->ImplGetWindow() )
364 : {
365 8 : pActivePopup->ImplGetFloatingWindow()->StopExecute();
366 8 : pActivePopup->ImplGetFloatingWindow()->doShutdown();
367 8 : pActivePopup->pWindow->doLazyDelete();
368 8 : pActivePopup->pWindow = NULL;
369 : }
370 8 : pActivePopup = 0;
371 : }
372 : }
373 :
374 0 : void MenuBarWindow::PopupClosed( Menu* pPopup )
375 : {
376 0 : if ( pPopup == pActivePopup )
377 : {
378 0 : KillActivePopup();
379 0 : ChangeHighlightItem( ITEMPOS_INVALID, false, ImplGetFrameWindow()->ImplGetFrameData()->mbHasFocus, false );
380 : }
381 0 : }
382 :
383 0 : void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt )
384 : {
385 0 : mbAutoPopup = true;
386 0 : sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
387 0 : if ( ( nEntry != ITEMPOS_INVALID ) && !pActivePopup )
388 : {
389 0 : ChangeHighlightItem( nEntry, false );
390 : }
391 : else
392 : {
393 0 : KillActivePopup();
394 0 : ChangeHighlightItem( ITEMPOS_INVALID, false );
395 : }
396 0 : }
397 :
398 0 : void MenuBarWindow::MouseButtonUp( const MouseEvent& )
399 : {
400 0 : }
401 :
402 0 : void MenuBarWindow::MouseMove( const MouseEvent& rMEvt )
403 : {
404 0 : if ( rMEvt.IsSynthetic() || rMEvt.IsEnterWindow() )
405 0 : return;
406 :
407 0 : if ( rMEvt.IsLeaveWindow() )
408 : {
409 0 : if ( nRolloveredItem != ITEMPOS_INVALID && nRolloveredItem != nHighlightedItem )
410 0 : Invalidate(); //HighlightItem( nRolloveredItem, false );
411 :
412 0 : nRolloveredItem = ITEMPOS_INVALID;
413 0 : return;
414 : }
415 :
416 0 : sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
417 0 : if ( nHighlightedItem == ITEMPOS_INVALID )
418 : {
419 0 : if ( nRolloveredItem != nEntry )
420 : {
421 0 : if ( nRolloveredItem != ITEMPOS_INVALID )
422 0 : Invalidate(); //HighlightItem( nRolloveredItem, false );
423 :
424 0 : nRolloveredItem = nEntry;
425 0 : Invalidate(); //HighlightItem( nRolloveredItem, true );
426 : }
427 0 : return;
428 : }
429 0 : nRolloveredItem = nEntry;
430 :
431 0 : if( bIgnoreFirstMove )
432 : {
433 0 : bIgnoreFirstMove = false;
434 0 : return;
435 : }
436 :
437 0 : if ( ( nEntry != ITEMPOS_INVALID )
438 0 : && ( nEntry != nHighlightedItem ) )
439 0 : ChangeHighlightItem( nEntry, false );
440 : }
441 :
442 26 : void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, bool bSelectEntry, bool bAllowRestoreFocus, bool bDefaultToDocument)
443 : {
444 26 : if( ! pMenu )
445 26 : return;
446 :
447 : // #57934# close active popup if applicable, as TH's background storage works.
448 26 : MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
449 26 : if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) )
450 0 : KillActivePopup(); // pActivePopup when applicable without pWin, if Rescheduled in Activate()
451 :
452 : // activate menubar only ones per cycle...
453 26 : bool bJustActivated = false;
454 26 : if ( ( nHighlightedItem == ITEMPOS_INVALID ) && ( n != ITEMPOS_INVALID ) )
455 : {
456 10 : ImplGetSVData()->maWinData.mbNoDeactivate = true;
457 10 : if( !bStayActive )
458 : {
459 : // #105406# avoid saving the focus when we already have the focus
460 10 : bool bNoSaveFocus = (this == ImplGetSVData()->maWinData.mpFocusWin.get() );
461 :
462 10 : if( nSaveFocusId )
463 : {
464 0 : if( !ImplGetSVData()->maWinData.mbNoSaveFocus )
465 : {
466 : // we didn't clean up last time
467 0 : Window::EndSaveFocus( nSaveFocusId, false ); // clean up
468 0 : nSaveFocusId = 0;
469 0 : if( !bNoSaveFocus )
470 0 : nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated
471 : }
472 : else {
473 : ; // do nothing: we 're activated again from taskpanelist, focus was already saved
474 : }
475 : }
476 : else
477 : {
478 10 : if( !bNoSaveFocus )
479 8 : nSaveFocusId = Window::SaveFocus(); // only save focus when initially activated
480 : }
481 : }
482 : else
483 0 : bStayActive = false;
484 10 : pMenu->bInCallback = true; // set here if Activate overridden
485 10 : pMenu->Activate();
486 10 : pMenu->bInCallback = false;
487 10 : bJustActivated = true;
488 : }
489 16 : else if ( ( nHighlightedItem != ITEMPOS_INVALID ) && ( n == ITEMPOS_INVALID ) )
490 : {
491 16 : pMenu->bInCallback = true;
492 16 : pMenu->Deactivate();
493 16 : pMenu->bInCallback = false;
494 16 : ImplGetSVData()->maWinData.mbNoDeactivate = false;
495 16 : if( !ImplGetSVData()->maWinData.mbNoSaveFocus )
496 : {
497 16 : sal_uLong nTempFocusId = nSaveFocusId;
498 16 : nSaveFocusId = 0;
499 16 : Window::EndSaveFocus( nTempFocusId, bAllowRestoreFocus );
500 : // #105406# restore focus to document if we could not save focus before
501 16 : if( bDefaultToDocument && !nTempFocusId && bAllowRestoreFocus )
502 2 : GrabFocusToDocument();
503 : }
504 : }
505 :
506 26 : if ( nHighlightedItem != ITEMPOS_INVALID )
507 : {
508 8 : if ( nHighlightedItem != nRolloveredItem )
509 8 : Invalidate(); //HighlightItem( nHighlightedItem, false );
510 :
511 8 : pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem );
512 : }
513 :
514 26 : nHighlightedItem = (sal_uInt16)n;
515 : DBG_ASSERT( ( nHighlightedItem == ITEMPOS_INVALID ) || pMenu->ImplIsVisible( nHighlightedItem ), "ChangeHighlightItem: Not visible!" );
516 26 : if ( nHighlightedItem != ITEMPOS_INVALID )
517 10 : Invalidate(); //HighlightItem( nHighlightedItem, true );
518 16 : else if ( nRolloveredItem != ITEMPOS_INVALID )
519 0 : Invalidate(); //HighlightItem( nRolloveredItem, true );
520 26 : pMenu->ImplCallHighlight(nHighlightedItem);
521 :
522 26 : if( mbAutoPopup )
523 24 : ImplCreatePopup( bSelectEntry );
524 :
525 : // #58935# #73659# Focus, if no popup underneath...
526 26 : if ( bJustActivated && !pActivePopup )
527 2 : GrabFocus();
528 : }
529 :
530 0 : static int ImplGetTopDockingAreaHeight( vcl::Window *pWindow )
531 : {
532 : // find docking area that is top aligned and return its height
533 : // note: dockingareas are direct children of the SystemWindow
534 0 : if( pWindow->ImplGetFrameWindow() )
535 : {
536 0 : vcl::Window *pWin = pWindow->ImplGetFrameWindow()->GetWindow( GetWindowType::FirstChild ); //mpWindowImpl->mpFirstChild;
537 0 : while( pWin )
538 : {
539 0 : if( pWin->IsSystemWindow() )
540 : {
541 0 : vcl::Window *pChildWin = pWin->GetWindow( GetWindowType::FirstChild ); //mpWindowImpl->mpFirstChild;
542 0 : while( pChildWin )
543 : {
544 0 : DockingAreaWindow *pDockingArea = NULL;
545 0 : if ( pChildWin->GetType() == WINDOW_DOCKINGAREA )
546 0 : pDockingArea = static_cast< DockingAreaWindow* >( pChildWin );
547 :
548 0 : if( pDockingArea && pDockingArea->GetAlign() == WINDOWALIGN_TOP &&
549 0 : pDockingArea->IsVisible() && pDockingArea->GetOutputSizePixel().Height() != 0 )
550 : {
551 0 : return pDockingArea->GetOutputSizePixel().Height();
552 : }
553 :
554 0 : pChildWin = pChildWin->GetWindow( GetWindowType::Next ); //mpWindowImpl->mpNext;
555 : }
556 :
557 : }
558 :
559 0 : pWin = pWin->GetWindow( GetWindowType::Next ); //mpWindowImpl->mpNext;
560 : }
561 : }
562 0 : return 0;
563 : }
564 :
565 0 : static void ImplAddNWFSeparator( vcl::RenderContext& rRenderContext, const MenubarValue& rMenubarValue )
566 : {
567 : // add a separator if
568 : // - we have an adjacent docking area
569 : // - and if toolbars would draw them as well (mbDockingAreaSeparateTB must not be set, see dockingarea.cxx)
570 0 : if (rMenubarValue.maTopDockingAreaHeight
571 0 : && !ImplGetSVData()->maNWFData.mbDockingAreaSeparateTB
572 0 : && !ImplGetSVData()->maNWFData.mbDockingAreaAvoidTBFrames)
573 : {
574 : // note: the menubar only provides the upper (dark) half of it, the rest (bright part) is drawn by the docking area
575 :
576 0 : rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetSeparatorColor());
577 0 : Point aPt;
578 0 : Rectangle aRect(aPt, rRenderContext.GetOutputSizePixel());
579 0 : rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
580 : }
581 0 : }
582 :
583 8 : void MenuBarWindow::HighlightItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHighlight)
584 : {
585 8 : if (!pMenu)
586 0 : return;
587 :
588 8 : long nX = 0;
589 8 : size_t nCount = pMenu->pItemList->size();
590 19 : for (size_t n = 0; n < nCount; n++)
591 : {
592 19 : MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
593 19 : if (n == nPos)
594 : {
595 8 : if (pData->eType != MenuItemType::SEPARATOR)
596 : {
597 : // #107747# give menuitems the height of the menubar
598 8 : Rectangle aRect = Rectangle(Point(nX, 1), Size(pData->aSz.Width(), GetOutputSizePixel().Height() - 2));
599 8 : rRenderContext.Push(PushFlags::CLIPREGION);
600 8 : rRenderContext.IntersectClipRegion(aRect);
601 8 : bool bRollover = bHighlight && nPos != nHighlightedItem;
602 8 : if (bHighlight)
603 : {
604 8 : if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_MENU_ITEM) &&
605 0 : rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
606 : {
607 : // draw background (transparency)
608 0 : MenubarValue aControlValue;
609 0 : aControlValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this );
610 :
611 0 : if (!Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty() )
612 0 : Erase(rRenderContext);
613 : else
614 : {
615 0 : Rectangle aBgRegion(Point(), rRenderContext.GetOutputSizePixel());
616 : rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_ENTIRE_CONTROL, aBgRegion,
617 0 : ControlState::ENABLED, aControlValue, OUString());
618 : }
619 :
620 0 : ImplAddNWFSeparator(rRenderContext, aControlValue);
621 :
622 : // draw selected item
623 0 : ControlState nState = ControlState::ENABLED;
624 0 : if (bRollover)
625 0 : nState |= ControlState::ROLLOVER;
626 : else
627 0 : nState |= ControlState::SELECTED;
628 : rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_MENU_ITEM,
629 0 : aRect, nState, aControlValue, OUString() );
630 : }
631 : else
632 : {
633 8 : if (bRollover)
634 0 : rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuBarRolloverColor());
635 : else
636 8 : rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuHighlightColor());
637 8 : rRenderContext.SetLineColor();
638 8 : rRenderContext.DrawRect(aRect);
639 : }
640 : }
641 : else
642 : {
643 0 : if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
644 : {
645 0 : MenubarValue aMenubarValue;
646 0 : aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight( this );
647 :
648 0 : if (!Application::GetSettings().GetStyleSettings().GetPersonaHeader().IsEmpty())
649 0 : rRenderContext.Erase(aRect);
650 : else
651 : {
652 : // use full window size to get proper gradient
653 : // but clip accordingly
654 0 : Point aPt;
655 0 : Rectangle aCtrlRect(aPt, rRenderContext.GetOutputSizePixel());
656 :
657 : rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_ENTIRE_CONTROL,
658 0 : aCtrlRect, ControlState::ENABLED, aMenubarValue, OUString());
659 : }
660 :
661 0 : ImplAddNWFSeparator(rRenderContext, aMenubarValue);
662 : }
663 : else
664 0 : rRenderContext.Erase(aRect);
665 : }
666 8 : rRenderContext.Pop();
667 8 : pMenu->ImplPaint(rRenderContext, 0, 0, pData, bHighlight, false, bRollover);
668 : }
669 8 : return;
670 : }
671 :
672 11 : nX += pData->aSz.Width();
673 : }
674 : }
675 :
676 0 : Rectangle MenuBarWindow::ImplGetItemRect( sal_uInt16 nPos )
677 : {
678 0 : Rectangle aRect;
679 0 : if( pMenu )
680 : {
681 0 : long nX = 0;
682 0 : size_t nCount = pMenu->pItemList->size();
683 0 : for ( size_t n = 0; n < nCount; n++ )
684 : {
685 0 : MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
686 0 : if ( n == nPos )
687 : {
688 0 : if ( pData->eType != MenuItemType::SEPARATOR )
689 : // #107747# give menuitems the height of the menubar
690 0 : aRect = Rectangle( Point( nX, 1 ), Size( pData->aSz.Width(), GetOutputSizePixel().Height()-2 ) );
691 0 : break;
692 : }
693 :
694 0 : nX += pData->aSz.Width();
695 : }
696 : }
697 0 : return aRect;
698 : }
699 :
700 0 : void MenuBarWindow::KeyInput( const KeyEvent& rKEvent )
701 : {
702 0 : if ( !HandleKeyEvent( rKEvent ) )
703 0 : Window::KeyInput( rKEvent );
704 0 : }
705 :
706 0 : bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
707 : {
708 0 : if( ! pMenu )
709 0 : return false;
710 :
711 0 : if ( pMenu->bInCallback )
712 0 : return true; // swallow
713 :
714 0 : bool bDone = false;
715 0 : sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
716 :
717 0 : if( GetParent() )
718 : {
719 0 : if( GetParent()->GetWindow( GetWindowType::Client )->IsSystemWindow() )
720 : {
721 0 : SystemWindow *pSysWin = static_cast<SystemWindow*>(GetParent()->GetWindow( GetWindowType::Client ));
722 0 : if( pSysWin->GetTaskPaneList() )
723 0 : if( pSysWin->GetTaskPaneList()->HandleKeyEvent( rKEvent ) )
724 0 : return true;
725 : }
726 : }
727 :
728 0 : if ( nCode == KEY_MENU && !rKEvent.GetKeyCode().IsShift() ) // only F10, not Shift-F10
729 : {
730 0 : mbAutoPopup = ImplGetSVData()->maNWFData.mbOpenMenuOnF10;
731 0 : if ( nHighlightedItem == ITEMPOS_INVALID )
732 : {
733 0 : ChangeHighlightItem( 0, false );
734 0 : GrabFocus();
735 : }
736 : else
737 : {
738 0 : ChangeHighlightItem( ITEMPOS_INVALID, false );
739 0 : nSaveFocusId = 0;
740 : }
741 0 : bDone = true;
742 : }
743 0 : else if ( bFromMenu )
744 : {
745 0 : if ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ||
746 0 : ( nCode == KEY_HOME ) || ( nCode == KEY_END ) )
747 : {
748 0 : sal_uInt16 n = nHighlightedItem;
749 0 : if ( n == ITEMPOS_INVALID )
750 : {
751 0 : if ( nCode == KEY_LEFT)
752 0 : n = 0;
753 : else
754 0 : n = pMenu->GetItemCount()-1;
755 : }
756 :
757 : // handling gtk like (aka mbOpenMenuOnF10)
758 : // do not highlight an item when opening a sub menu
759 : // unless there already was a higlighted sub menu item
760 0 : bool bWasHighlight = false;
761 0 : if( pActivePopup )
762 : {
763 0 : MenuFloatingWindow* pSubWindow = dynamic_cast<MenuFloatingWindow*>(pActivePopup->ImplGetWindow());
764 0 : if( pSubWindow )
765 0 : bWasHighlight = (pSubWindow->GetHighlightedItem() != ITEMPOS_INVALID);
766 : }
767 :
768 0 : sal_uInt16 nLoop = n;
769 :
770 0 : if( nCode == KEY_HOME )
771 0 : { n = (sal_uInt16)-1; nLoop = n+1; }
772 0 : if( nCode == KEY_END )
773 0 : { n = pMenu->GetItemCount(); nLoop = n-1; }
774 :
775 0 : do
776 : {
777 0 : if ( nCode == KEY_LEFT || nCode == KEY_END )
778 : {
779 0 : if ( n )
780 0 : n--;
781 : else
782 0 : n = pMenu->GetItemCount()-1;
783 : }
784 0 : if ( nCode == KEY_RIGHT || nCode == KEY_HOME )
785 : {
786 0 : n++;
787 0 : if ( n >= pMenu->GetItemCount() )
788 0 : n = 0;
789 : }
790 :
791 0 : MenuItemData* pData = pMenu->GetItemList()->GetDataFromPos( n );
792 0 : if ( ( pData->eType != MenuItemType::SEPARATOR ) && pMenu->ImplIsVisible( n ) )
793 : {
794 0 : bool bDoSelect = true;
795 0 : if( ImplGetSVData()->maNWFData.mbOpenMenuOnF10 )
796 0 : bDoSelect = bWasHighlight;
797 0 : ChangeHighlightItem( n, bDoSelect );
798 0 : break;
799 : }
800 : } while ( n != nLoop );
801 0 : bDone = true;
802 : }
803 0 : else if ( nCode == KEY_RETURN )
804 : {
805 0 : if( pActivePopup ) KillActivePopup();
806 : else
807 0 : if ( !mbAutoPopup )
808 : {
809 0 : ImplCreatePopup( true );
810 0 : mbAutoPopup = true;
811 : }
812 0 : bDone = true;
813 : }
814 0 : else if ( ( nCode == KEY_UP ) || ( nCode == KEY_DOWN ) )
815 : {
816 0 : if ( !mbAutoPopup )
817 : {
818 0 : ImplCreatePopup( true );
819 0 : mbAutoPopup = true;
820 : }
821 0 : bDone = true;
822 : }
823 0 : else if ( nCode == KEY_ESCAPE || ( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() ) )
824 : {
825 0 : if( pActivePopup )
826 : {
827 : // bring focus to menu bar without any open popup
828 0 : mbAutoPopup = false;
829 0 : sal_uInt16 n = nHighlightedItem;
830 0 : nHighlightedItem = ITEMPOS_INVALID;
831 0 : bStayActive = true;
832 0 : ChangeHighlightItem( n, false );
833 0 : bStayActive = false;
834 0 : KillActivePopup();
835 0 : GrabFocus();
836 : }
837 : else
838 0 : ChangeHighlightItem( ITEMPOS_INVALID, false );
839 :
840 0 : if( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() )
841 : {
842 : // put focus into document
843 0 : GrabFocusToDocument();
844 : }
845 :
846 0 : bDone = true;
847 : }
848 : }
849 :
850 0 : if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsMod2() ) )
851 : {
852 0 : sal_Unicode nCharCode = rKEvent.GetCharCode();
853 0 : if ( nCharCode )
854 : {
855 : sal_uInt16 nEntry, nDuplicates;
856 0 : MenuItemData* pData = pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nEntry, nDuplicates, nHighlightedItem );
857 0 : if ( pData && (nEntry != ITEMPOS_INVALID) )
858 : {
859 0 : mbAutoPopup = true;
860 0 : ChangeHighlightItem( nEntry, true );
861 0 : bDone = true;
862 : }
863 : }
864 : }
865 0 : return bDone;
866 : }
867 :
868 1207 : void MenuBarWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
869 : {
870 1207 : if (!pMenu)
871 0 : return;
872 :
873 1207 : const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
874 :
875 : // no VCL paint if native menus
876 1207 : if (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar())
877 : {
878 0 : ImplGetFrame()->DrawMenuBar();
879 0 : return;
880 : }
881 :
882 1207 : if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
883 : {
884 0 : MenubarValue aMenubarValue;
885 0 : aMenubarValue.maTopDockingAreaHeight = ImplGetTopDockingAreaHeight(this);
886 :
887 0 : if (!rStyleSettings.GetPersonaHeader().IsEmpty())
888 0 : Erase(rRenderContext);
889 : else
890 : {
891 0 : Point aPt;
892 0 : Rectangle aCtrlRegion( aPt, GetOutputSizePixel() );
893 :
894 : rRenderContext.DrawNativeControl(CTRL_MENUBAR, PART_ENTIRE_CONTROL, aCtrlRegion,
895 0 : ControlState::ENABLED, aMenubarValue, OUString());
896 : }
897 :
898 0 : ImplAddNWFSeparator(rRenderContext, aMenubarValue);
899 : }
900 1207 : rRenderContext.SetFillColor(rStyleSettings.GetMenuColor());
901 :
902 1207 : pMenu->ImplPaint(rRenderContext, 0);
903 1207 : if (nHighlightedItem != ITEMPOS_INVALID)
904 8 : HighlightItem(rRenderContext, nHighlightedItem, true);
905 :
906 : // in high contrast mode draw a separating line on the lower edge
907 2414 : if (!rRenderContext.IsNativeControlSupported( CTRL_MENUBAR, PART_ENTIRE_CONTROL) &&
908 1207 : rStyleSettings.GetHighContrastMode())
909 : {
910 0 : rRenderContext.Push(PushFlags::LINECOLOR | PushFlags::MAPMODE);
911 0 : rRenderContext.SetLineColor(Color(COL_WHITE));
912 0 : rRenderContext.SetMapMode(MapMode(MAP_PIXEL));
913 0 : Size aSize = GetSizePixel();
914 0 : rRenderContext.DrawLine(Point(0, aSize.Height() - 1),
915 0 : Point(aSize.Width() - 1, aSize.Height() - 1));
916 0 : rRenderContext.Pop();
917 : }
918 : }
919 :
920 6436 : void MenuBarWindow::Resize()
921 : {
922 6436 : Size aOutSz = GetOutputSizePixel();
923 6436 : long n = aOutSz.Height()-4;
924 6436 : long nX = aOutSz.Width()-3;
925 6436 : long nY = 2;
926 :
927 6436 : if ( aCloseBtn->IsVisible() )
928 : {
929 3184 : aCloseBtn->Hide();
930 3184 : aCloseBtn->SetImages(n);
931 3184 : Size aTbxSize( aCloseBtn->CalcWindowSizePixel() );
932 3184 : nX -= aTbxSize.Width();
933 3184 : long nTbxY = (aOutSz.Height() - aTbxSize.Height())/2;
934 3184 : aCloseBtn->setPosSizePixel(nX, nTbxY, aTbxSize.Width(), aTbxSize.Height());
935 3184 : nX -= 3;
936 3184 : aCloseBtn->Show();
937 : }
938 6436 : if ( aFloatBtn->IsVisible() )
939 : {
940 0 : nX -= n;
941 0 : aFloatBtn->setPosSizePixel( nX, nY, n, n );
942 : }
943 6436 : if ( aHideBtn->IsVisible() )
944 : {
945 0 : nX -= n;
946 0 : aHideBtn->setPosSizePixel( nX, nY, n, n );
947 : }
948 :
949 6436 : aFloatBtn->SetSymbol( SymbolType::FLOAT );
950 6436 : aHideBtn->SetSymbol( SymbolType::HIDE );
951 :
952 6436 : Invalidate();
953 6436 : }
954 :
955 0 : sal_uInt16 MenuBarWindow::ImplFindEntry( const Point& rMousePos ) const
956 : {
957 0 : if( pMenu )
958 : {
959 0 : long nX = 0;
960 0 : size_t nCount = pMenu->pItemList->size();
961 0 : for ( size_t n = 0; n < nCount; n++ )
962 : {
963 0 : MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n );
964 0 : if ( pMenu->ImplIsVisible( n ) )
965 : {
966 0 : nX += pData->aSz.Width();
967 0 : if ( nX > rMousePos.X() )
968 0 : return (sal_uInt16)n;
969 : }
970 : }
971 : }
972 0 : return ITEMPOS_INVALID;
973 : }
974 :
975 0 : void MenuBarWindow::RequestHelp( const HelpEvent& rHEvt )
976 : {
977 0 : sal_uInt16 nId = nHighlightedItem;
978 0 : if ( rHEvt.GetMode() & (HelpEventMode::CONTEXT | HelpEventMode::EXTENDED) )
979 0 : ChangeHighlightItem( ITEMPOS_INVALID, true );
980 :
981 0 : Rectangle aHighlightRect( ImplGetItemRect( nHighlightedItem ) );
982 0 : if( !ImplHandleHelpEvent( this, pMenu, nId, rHEvt, aHighlightRect ) )
983 0 : Window::RequestHelp( rHEvt );
984 0 : }
985 :
986 7721 : void MenuBarWindow::StateChanged( StateChangedType nType )
987 : {
988 7721 : Window::StateChanged( nType );
989 :
990 7721 : if (nType == StateChangedType::ControlForeground ||
991 : nType == StateChangedType::ControlBackground)
992 : {
993 0 : ApplySettings(*this);
994 0 : Invalidate();
995 : }
996 7721 : else if(pMenu)
997 : {
998 7721 : pMenu->ImplKillLayoutData();
999 : }
1000 7721 : }
1001 :
1002 0 : void MenuBarWindow::LayoutChanged()
1003 : {
1004 0 : if (!pMenu)
1005 0 : return;
1006 :
1007 0 : ApplySettings(*this);
1008 :
1009 : // if the font was changed.
1010 0 : long nHeight = pMenu->ImplCalcSize(this).Height();
1011 :
1012 : // depending on the native implementation or the displayable flag
1013 : // the menubar windows is suppressed (ie, height=0)
1014 0 : if (!static_cast<MenuBar*>(pMenu)->IsDisplayable() ||
1015 0 : (pMenu->ImplGetSalMenu() && pMenu->ImplGetSalMenu()->VisibleMenuBar()))
1016 : {
1017 0 : nHeight = 0;
1018 : }
1019 0 : setPosSizePixel(0, 0, 0, nHeight, PosSizeFlags::Height);
1020 0 : GetParent()->Resize();
1021 0 : Invalidate();
1022 0 : Resize();
1023 :
1024 0 : pMenu->ImplKillLayoutData();
1025 : }
1026 :
1027 1207 : void MenuBarWindow::ApplySettings(vcl::RenderContext& rRenderContext)
1028 : {
1029 1207 : Window::ApplySettings(rRenderContext);
1030 1207 : const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1031 :
1032 1207 : SetPointFont(rRenderContext, rStyleSettings.GetMenuFont());
1033 :
1034 1207 : const BitmapEx& rPersonaBitmap = Application::GetSettings().GetStyleSettings().GetPersonaHeader();
1035 1207 : if (!rPersonaBitmap.IsEmpty())
1036 : {
1037 0 : Wallpaper aWallpaper(rPersonaBitmap);
1038 0 : aWallpaper.SetStyle(WALLPAPER_TOPRIGHT);
1039 0 : aWallpaper.SetColor(Application::GetSettings().GetStyleSettings().GetWorkspaceColor());
1040 :
1041 0 : rRenderContext.SetBackground(aWallpaper);
1042 0 : SetPaintTransparent(false);
1043 0 : SetParentClipMode(ParentClipMode::NONE);
1044 : }
1045 1207 : else if (rRenderContext.IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
1046 : {
1047 0 : rRenderContext.SetBackground(); // background will be drawn by NWF
1048 : }
1049 : else
1050 : {
1051 1207 : Wallpaper aWallpaper;
1052 1207 : aWallpaper.SetStyle(WALLPAPER_APPLICATIONGRADIENT);
1053 1207 : rRenderContext.SetBackground(aWallpaper);
1054 1207 : SetPaintTransparent(false);
1055 1207 : SetParentClipMode(ParentClipMode::NONE);
1056 : }
1057 :
1058 1207 : rRenderContext.SetTextColor(rStyleSettings.GetMenuBarTextColor());
1059 1207 : rRenderContext.SetTextFillColor();
1060 1207 : rRenderContext.SetLineColor();
1061 1207 : }
1062 :
1063 3199 : void MenuBarWindow::ImplInitStyleSettings()
1064 : {
1065 3201 : if (IsNativeControlSupported(CTRL_MENUBAR, PART_MENU_ITEM) &&
1066 2 : IsNativeControlSupported(CTRL_MENUBAR, PART_ENTIRE_CONTROL))
1067 : {
1068 2 : AllSettings aSettings(GetSettings());
1069 2 : ImplGetFrame()->UpdateSettings(aSettings); // to update persona
1070 4 : StyleSettings aStyle(aSettings.GetStyleSettings());
1071 2 : Color aHighlightTextColor = ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor;
1072 2 : if (aHighlightTextColor != Color(COL_TRANSPARENT))
1073 : {
1074 0 : aStyle.SetMenuHighlightTextColor(aHighlightTextColor);
1075 : }
1076 2 : aSettings.SetStyleSettings(aStyle);
1077 4 : OutputDevice::SetSettings(aSettings);
1078 : }
1079 3199 : }
1080 :
1081 3 : void MenuBarWindow::DataChanged( const DataChangedEvent& rDCEvt )
1082 : {
1083 3 : Window::DataChanged( rDCEvt );
1084 :
1085 12 : if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1086 9 : (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
1087 9 : ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1088 12 : (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1089 : {
1090 0 : ApplySettings(*this);
1091 0 : ImplInitStyleSettings();
1092 0 : LayoutChanged();
1093 : }
1094 3 : }
1095 :
1096 8 : void MenuBarWindow::LoseFocus()
1097 : {
1098 8 : if ( !HasChildPathFocus( true ) )
1099 8 : ChangeHighlightItem( ITEMPOS_INVALID, false, false );
1100 8 : }
1101 :
1102 8 : void MenuBarWindow::GetFocus()
1103 : {
1104 8 : if ( nHighlightedItem == ITEMPOS_INVALID )
1105 : {
1106 2 : mbAutoPopup = false; // do not open menu when activated by focus handling like taskpane cycling
1107 2 : ChangeHighlightItem( 0, false );
1108 : }
1109 8 : }
1110 :
1111 10 : css::uno::Reference<css::accessibility::XAccessible> MenuBarWindow::CreateAccessible()
1112 : {
1113 10 : css::uno::Reference<css::accessibility::XAccessible> xAcc;
1114 :
1115 10 : if (pMenu)
1116 10 : xAcc = pMenu->GetAccessible();
1117 :
1118 10 : return xAcc;
1119 : }
1120 :
1121 0 : sal_uInt16 MenuBarWindow::AddMenuBarButton( const Image& i_rImage, const Link<>& i_rLink, const OUString& i_rToolTip, sal_uInt16 i_nPos )
1122 : {
1123 : // find first free button id
1124 0 : sal_uInt16 nId = IID_DOCUMENTCLOSE;
1125 0 : std::map< sal_uInt16, AddButtonEntry >::const_iterator it;
1126 0 : if( i_nPos > m_aAddButtons.size() )
1127 0 : i_nPos = static_cast<sal_uInt16>(m_aAddButtons.size());
1128 0 : do
1129 : {
1130 0 : nId++;
1131 0 : it = m_aAddButtons.find( nId );
1132 0 : } while( it != m_aAddButtons.end() && nId < 128 );
1133 : DBG_ASSERT( nId < 128, "too many addbuttons in menubar" );
1134 0 : AddButtonEntry& rNewEntry = m_aAddButtons[nId];
1135 0 : rNewEntry.m_nId = nId;
1136 0 : rNewEntry.m_aSelectLink = i_rLink;
1137 0 : aCloseBtn->InsertItem(nId, i_rImage, ToolBoxItemBits::NONE, 0);
1138 0 : aCloseBtn->calcMinSize();
1139 0 : ShowButtons(aCloseBtn->IsItemVisible(IID_DOCUMENTCLOSE), aFloatBtn->IsVisible(), aHideBtn->IsVisible());
1140 0 : LayoutChanged();
1141 :
1142 0 : if( pMenu->mpSalMenu )
1143 0 : pMenu->mpSalMenu->AddMenuBarButton( SalMenuButtonItem( nId, i_rImage, i_rToolTip ) );
1144 :
1145 0 : return nId;
1146 : }
1147 :
1148 0 : void MenuBarWindow::SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link<>& rLink )
1149 : {
1150 0 : std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( nId );
1151 0 : if( it != m_aAddButtons.end() )
1152 0 : it->second.m_aHighlightLink = rLink;
1153 0 : }
1154 :
1155 0 : Rectangle MenuBarWindow::GetMenuBarButtonRectPixel( sal_uInt16 nId )
1156 : {
1157 0 : Rectangle aRect;
1158 0 : if( m_aAddButtons.find( nId ) != m_aAddButtons.end() )
1159 : {
1160 0 : if( pMenu->mpSalMenu )
1161 : {
1162 0 : aRect = pMenu->mpSalMenu->GetMenuBarButtonRectPixel( nId, ImplGetWindowImpl()->mpFrame );
1163 0 : if( aRect == Rectangle( Point( -1, -1 ), Size( 1, 1 ) ) )
1164 : {
1165 : // system menu button is somewhere but location cannot be determined
1166 0 : return Rectangle();
1167 : }
1168 : }
1169 :
1170 0 : if( aRect.IsEmpty() )
1171 : {
1172 0 : aRect = aCloseBtn->GetItemRect(nId);
1173 0 : Point aOffset = aCloseBtn->OutputToScreenPixel(Point());
1174 0 : aRect.Move( aOffset.X(), aOffset.Y() );
1175 : }
1176 : }
1177 0 : return aRect;
1178 : }
1179 :
1180 0 : void MenuBarWindow::RemoveMenuBarButton( sal_uInt16 nId )
1181 : {
1182 0 : sal_uInt16 nPos = aCloseBtn->GetItemPos(nId);
1183 0 : aCloseBtn->RemoveItem(nPos);
1184 0 : m_aAddButtons.erase( nId );
1185 0 : aCloseBtn->calcMinSize();
1186 0 : LayoutChanged();
1187 :
1188 0 : if( pMenu->mpSalMenu )
1189 0 : pMenu->mpSalMenu->RemoveMenuBarButton( nId );
1190 0 : }
1191 :
1192 0 : bool MenuBarWindow::HandleMenuButtonEvent( sal_uInt16 i_nButtonId )
1193 : {
1194 0 : std::map< sal_uInt16, AddButtonEntry >::iterator it = m_aAddButtons.find( i_nButtonId );
1195 0 : if( it != m_aAddButtons.end() )
1196 : {
1197 : MenuBar::MenuBarButtonCallbackArg aArg;
1198 0 : aArg.nId = it->first;
1199 0 : aArg.bHighlight = true;
1200 0 : aArg.pMenuBar = dynamic_cast<MenuBar*>(pMenu);
1201 0 : return it->second.m_aSelectLink.Call( &aArg );
1202 : }
1203 0 : return false;
1204 : }
1205 :
1206 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|