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