?? qmenubar.cpp
字號:
/****************************************************************************** $Id: qt/src/widgets/qmenubar.cpp 2.3.12 edited 2005-10-27 $**** Implementation of QMenuBar class**** Created : 941209**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the widgets module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/// qmainwindow.h before qmenubar.h because of GCC-2.7.* compatibility// ### could be reorganised by discarding INCLUDE_MENUITEM_DEF and put// the relevant declarations in a private header?#include "qmainwindow.h"#ifndef QT_NO_MENUBAR#define INCLUDE_MENUITEM_DEF#include "qmenubar.h"#include "qaccel.h"#include "qpainter.h"#include "qdrawutil.h"#include "qapplication.h"#include "qguardedptr.h"#include "qlayout.h"#include "qdatetime.h"#include <ctype.h>class QMenuDataData { // attention: also defined in qmenudata.cpppublic: QMenuDataData(); QGuardedPtr<QWidget> aWidget; int aInt;};static QTime moveActiveTime;// NOT REVISED/*! \class QMenuBar qmenubar.h \brief The QMenuBar class provides a horizontal menu bar. \ingroup application A menu bar consists of a list of submenu items, so-called pulldown menus. You add submenu items with insertItem(). Assuming that \c menubar is a pointer to a QMenuBar and \c filemenu a pointer to a QPopupMenu, \code menubar->insertItem( "&File", filemenu ); \endcode inserts the menu into the menu bar. The ampersand in the item text declares Alt-f as shortcut for this menu. Use "&&" to get a real ampsend in the menubar. Items are either enabled or disabled. You toggle their state with setItemEnabled(). Note that there is no need to layout a menu bar. It automatically sets its own geometry to the top of the parent widget and changes it appropriately whenever the parent is resized. \important insertItem removeItem clear insertSeparator setItemEnabled isItemEnabled menu/menu.cpp is a typical example of QMenuBar and QPopupMenu use. <img src=qmenubar-m.png> <img src=qmenubar-w.png> \sa QPopupMenu <a href="guibooks.html#fowler">GUI Design Handbook: Menu Bar</a>*//*! \enum QMenuBar::Separator This enum type is used to decide whether QMenuBar should draw a separator line at its bottom. The possible values are: <ul> <li> \c Never - in many applications, there already is a separator, and two looks stupid. <li> \c InWindowsStyle - in some other applications, a separator looks good in Windows style but not else. </ul> *//*! \fn void QMenuBar::activated( int id ) This signal is emitted when a menu item is selected; \a id is the id of the selected item. Normally, you will connect each menu item to a single slot using QMenuData::insertItem(), but sometimes you will want to connect several items to a single slot (most often if the user selects from an array). This signal is handy in such cases. \sa highlighted(), QMenuData::insertItem()*//*! \fn void QMenuBar::highlighted( int id ) This signal is emitted when a menu item is highlighted; \a id is the id of the highlighted item. Normally, you will connect each menu item to a single slot using QMenuData::insertItem(), but sometimes you will want to connect several items to a single slot (most often if the user selects from an array). This signal is handy in such cases. \sa activated(), QMenuData::insertItem()*/// Motif style parametersstatic const int motifBarHMargin = 2; // menu bar hor margin to itemstatic const int motifBarVMargin = 1; // menu bar ver margin to itemstatic const int motifItemFrame = 2; // menu item frame widthstatic const int motifItemHMargin = 5; // menu item hor text marginstatic const int motifItemVMargin = 4; // menu item ver text margin/*+-----------------------------| BarFrame| +-------------------------| | V BarMargin| | +---------------------| | H | ItemFrame| | | +-----------------| | | | \| | | | ^ T E X T ^ | ItemVMargin| | | | | | /| | | ItemHMargin| ||*//***************************************************************************** QMenuBar member functions *****************************************************************************//*! Constructs a menu bar with a \e parent and a \e name.*/QMenuBar::QMenuBar( QWidget *parent, const char *name ) : QFrame( parent, name, 0, FALSE ){ isMenuBar = TRUE;#ifndef QT_NO_ACCEL autoaccel = 0;#endif irects = 0; rightSide = 0; // Right of here is rigth-aligned content mseparator = 0; waitforalt = 0; popupvisible = 0; hasmouse = 0; defaultup = 0; toggleclose = 0; if ( parent ) { // filter parent events for resizing parent->installEventFilter( this ); // filter top-level-widget events for accelerators QWidget *tlw = topLevelWidget(); if ( tlw != parent ) tlw->installEventFilter( this ); } QFontMetrics fm = fontMetrics(); int gs = style(); int h; if ( gs == WindowsStyle ) { h = 2 + fm.height() + motifItemVMargin + 2*style().defaultFrameWidth(); } else { h = style().defaultFrameWidth() + motifBarVMargin + fm.height() + motifItemVMargin + 2*style().defaultFrameWidth() + 2*motifItemFrame; } move( 0, 0 ); resize( width(), h ); switch ( gs ) { case WindowsStyle: setFrameStyle( QFrame::NoFrame ); setMouseTracking( TRUE ); break; case MotifStyle: setFrameStyle( QFrame::Panel | QFrame::Raised ); setLineWidth( style().defaultFrameWidth() ); break; default: break; } setBackgroundMode( PaletteButton );}/*! \reimp */void QMenuBar::styleChange( QStyle& old ){ switch ( style().guiStyle() ) { case WindowsStyle: setFrameStyle( QFrame::NoFrame ); setMouseTracking( TRUE ); break; case MotifStyle: setFrameStyle( QFrame::Panel | QFrame::Raised ); setLineWidth( style().defaultFrameWidth() ); setMouseTracking( FALSE ); break; default: break; } updateGeometry(); QFrame::styleChange( old );}/*! Destroys the menu bar.*/QMenuBar::~QMenuBar(){#ifndef QT_NO_ACCEL delete autoaccel;#endif if ( irects ) // Avoid purify complaint. delete [] irects;}/*! \internal Needs documentation.*/void QMenuBar::updateItem( int id ){ int i = indexOf( id ); if ( i >= 0 && irects ) repaint( irects[i], FALSE );}/*! Recomputes the menu bar's display data according to the new contents. You should never need to call this, it is called automatically by QMenuData whenever it needs to be called.*/void QMenuBar::menuContentsChanged(){#ifndef QT_NO_ACCEL setupAccelerators();#endif badSize = TRUE; // might change the size if ( isVisible() ) { calculateRects(); update();#ifndef QT_NO_MAINWINDOW if ( parent() && parent()->inherits( "QMainWindow" ) ) { ( (QMainWindow*)parent() )->triggerLayout(); ( (QMainWindow*)parent() )->update(); }#endif#ifndef QT_NO_LAYOUT if ( parentWidget() && parentWidget()->layout() ) parentWidget()->layout()->activate();#endif }}/*! Recomputes the menu bar's display data according to the new state. You should never need to call this, it is called automatically by QMenuData whenever it needs to be called.*/void QMenuBar::menuStateChanged(){#ifndef QT_NO_ACCEL setupAccelerators(); // ### when we have a good solution for the accel vs. focus widget problem, remove that. That is only a workaround#endif update();}void QMenuBar::menuInsPopup( QPopupMenu *popup ){#ifndef QT_NO_POPUPMENU popup->parentMenu = this; // set parent menu connect( popup, SIGNAL(activatedRedirect(int)), SLOT(subActivated(int)) ); connect( popup, SIGNAL(highlightedRedirect(int)), SLOT(subHighlighted(int)) );#endif}void QMenuBar::menuDelPopup( QPopupMenu *popup ){#ifndef QT_NO_POPUPMENU popup->parentMenu = 0; popup->disconnect( SIGNAL(activatedRedirect(int)), this, SLOT(subActivated(int)) ); popup->disconnect( SIGNAL(highlightedRedirect(int)), this, SLOT(subHighlighted(int)) );#endif}void QMenuBar::frameChanged(){ menuContentsChanged();}/*! This function is used to adjust the menu bar's geometry to the parent widget's. Note that this is \e not part of the public interface - the function is \c public only because QObject::eventFilter() is. \internal Resizes the menu bar to fit in the parent widget when the parent receives a resize event.*/bool QMenuBar::eventFilter( QObject *object, QEvent *event ){ if ( object == parent() && object && !object->inherits( "QToolBar" ) && event->type() == QEvent::Resize ) { QResizeEvent *e = (QResizeEvent *)event; int w = e->size().width(); setGeometry( 0, y(), w, heightForWidth(w) ); return FALSE; } if ( waitforalt && event->type() == QEvent::FocusOut ) { // some window systems/managers use alt/meta as accelerator keys // for switching between windows/desktops/etc. If the focus // widget gets unfocused, then we need to stop waiting for alt // NOTE: this event came from the real focus widget, so we don't // need to touch the event filters waitforalt = 0; return FALSE; } else if ( style() != WindowsStyle || !isVisible() || !object->isWidgetType() || !( event->type() == QEvent::Accel || event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease ) ) return FALSE;#ifndef QT_NO_ACCEL // look for Alt press and Alt-anything press if ( event->type() == QEvent::Accel ) { QWidget * f = ((QWidget *)object)->focusWidget(); QKeyEvent * ke = (QKeyEvent *) event; if ( f ) { // ### this thinks alt and meta are the same if ( ke->key() == Key_Alt || ke->key() == Key_Meta ) { if ( waitforalt ) { waitforalt = 0; if ( object->parent() ) object->removeEventFilter( this ); ke->accept(); return TRUE; } else if ( hasFocus() ) { setAltMode( FALSE ); ke->accept(); return TRUE; } else { waitforalt = 1; if ( f != object ) f->installEventFilter( this ); } } else if ( ke->key() == Key_Control || ke->key() == Key_Shift) setAltMode( FALSE ); } // ### ! block all accelerator events when the menu bar is active if ( qApp && qApp->focusWidget() == this ) { return TRUE; } return FALSE; }#endif // look for Alt release if ( ((QWidget*)object)->focusWidget() == object || (object->parent() == 0 && ((QWidget*)object)->focusWidget() == 0) ) { if ( waitforalt && event->type() == QEvent::KeyRelease && (((QKeyEvent *)event)->key() == Key_Alt || ((QKeyEvent *)event)->key() == Key_Meta) ) { setAltMode( TRUE ); if ( object->parent() ) object->removeEventFilter( this ); QWidget * tlw = ((QWidget *)object)->topLevelWidget(); if ( tlw ) { // ### ! // make sure to be the first event filter, so we can kill // accelerator events before the accelerators get to them. tlw->removeEventFilter( this ); tlw->installEventFilter( this ); } return TRUE; } else if ( (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) && !(((QKeyEvent *)event)->key() == Key_Alt || ((QKeyEvent *)event)->key() == Key_Meta) ) { if ( object->parent() ) object->removeEventFilter( this );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -