⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmenubar.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qmenubar.h>#include <qstyle.h>#include <qlayout.h>#include <qapplication.h>#include <qdesktopwidget.h>#ifndef QT_NO_ACCESSIBILITY# include <qaccessible.h>#endif#include <qpainter.h>#include <qevent.h>#include <qmainwindow.h>#include <qtoolbar.h>#include <qtoolbutton.h>#include <qwhatsthis.h>#ifndef QT_NO_MENUBAR#ifdef QT3_SUPPORT#include <private/qaction_p.h>#include <qmenudata.h>#endif#include "qmenu_p.h"#include "qmenubar_p.h"#include "qdebug.h"class QMenuBarExtension : public QToolButton{public:    explicit QMenuBarExtension(QWidget *parent);    QSize sizeHint() const;};QMenuBarExtension::QMenuBarExtension(QWidget *parent)    : QToolButton(parent){    setObjectName(QLatin1String("qt_menubar_ext_button"));    setAutoRaise(true);#ifndef QT_NO_MENU    setPopupMode(QToolButton::InstantPopup);#endif    setIcon(style()->standardPixmap(QStyle::SP_ToolBarHorizontalExtensionButton));}QSize QMenuBarExtension::sizeHint() const{    int ext = style()->pixelMetric(QStyle::PM_ToolBarExtensionExtent);    return QSize(ext, ext);}QAction *QMenuBarPrivate::actionAt(QPoint p) const{    Q_Q(const QMenuBar);    QList<QAction*> items = q->actions();    for(int i = 0; i < items.size(); ++i) {        if(actionRect(items.at(i)).contains(p))            return items.at(i);    }    return 0;}bool QMenuBarPrivate::isVisible(QAction *action){    Q_Q(QMenuBar);    if (!extension->isHidden()) {        int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);        QRect menuRect = q->rect();        if (QApplication::layoutDirection() == Qt::RightToLeft)            menuRect.setLeft(menuRect.left() + extension->width() + hmargin);        else            menuRect.setWidth(menuRect.width() - extension->width() - hmargin);        if (menuRect.contains(actionRect(action)))            return true;        else            return false;     }     return true;}void QMenuBarPrivate::updateGeometries(){    Q_Q(QMenuBar);    if(!itemsDirty)        return;    int q_width = q->width()-(q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q)*2);    int q_start = -1;    if(leftWidget || rightWidget) {        int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q)                      + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);        int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q)                      + q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);        if(leftWidget && leftWidget->isVisible()) {            QSize sz = leftWidget->sizeHint();            q_width -= sz.width();            q_start = sz.width();            leftWidget->setGeometry(QRect(QPoint(hmargin, vmargin), sz));        }        if(rightWidget && rightWidget->isVisible()) {            QSize sz = rightWidget->sizeHint();            q_width -= sz.width();            rightWidget->setGeometry(QRect(QPoint(q->width() - sz.width() - hmargin, vmargin), sz));        }    }#ifdef Q_WS_MAC    if(mac_menubar) {//nothing to see here folks, move along..        itemsDirty = false;        return;    }#endif    calcActionRects(q_width, q_start, actionRects, actionList);    itemsWidth = q_width;    itemsStart = q_start;    currentAction = 0;#ifndef QT_NO_SHORTCUT    if(itemsDirty) {        for(int j = 0; j < shortcutIndexMap.size(); ++j)            q->releaseShortcut(shortcutIndexMap.value(j));        shortcutIndexMap.resize(0); // faster than clear        for(int i = 0; i < actionList.count(); i++)            shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actionList.at(i)->text())));    }#endif    itemsDirty = false;    QList<QAction *> hiddenActions;    int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);    QRect menuRect = q->rect();    if (!extension->isHidden() && (menuRect.width() < q->sizeHint().width())) {        if (QApplication::layoutDirection() == Qt::RightToLeft)            menuRect.setLeft(menuRect.left() + extension->width() + hmargin);        else            menuRect.setWidth(menuRect.width() - extension->width() - hmargin);    }    for (int i = 0; i < actionList.count(); ++i) {        if (!menuRect.contains(actionRect(actionList.at(i))))            hiddenActions.append(actionList.at(i));    }    if (hiddenActions.count() > 0) {        QMenu *pop = extension->menu();        if (!pop) {            pop = new QMenu(q);            extension->setMenu(pop);        }        pop->clear();        pop->addActions(hiddenActions);        int vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q);        int x = QApplication::layoutDirection() == Qt::RightToLeft                ? hmargin                : q->width() - extension->sizeHint().width() - hmargin;        extension->setGeometry(x, vmargin, extension->sizeHint().width(), menuRect.height() - vmargin*2);        extension->show();    } else {        extension->hide();    }    q->updateGeometry();#ifdef QT3_SUPPORT    if (q->parentWidget() != 0) {        QMenubarUpdatedEvent menubarUpdated(q);        QApplication::sendEvent(q->parentWidget(), &menubarUpdated);    }#endif}QRect QMenuBarPrivate::actionRect(QAction *act) const{    Q_Q(const QMenuBar);    QRect ret = actionRects.value(act);    const int fw = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);    ret.translate(fw, fw);    return QStyle::visualRect(q->layoutDirection(), q->rect(), ret);}void QMenuBarPrivate::setKeyboardMode(bool b){    Q_Q(QMenuBar);    if (b && !q->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation, 0, q)) {        setCurrentAction(0);        return;    }    keyboardState = b;    if(b) {        QWidget *fw = qApp->focusWidget();        if (fw != q)            keyboardFocusWidget = qApp->focusWidget();        if(!currentAction && !actionList.isEmpty())            setCurrentAction(actionList.first());        q->setFocus();    } else {        if(!popupState)            setCurrentAction(0);        if(keyboardFocusWidget) {            keyboardFocusWidget->setFocus();            keyboardFocusWidget = 0;        }    }    q->update();}void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst){    Q_Q(QMenuBar);    if(!action || !action->menu())        return;    popupState = true;    if (action->isEnabled() && action->menu()->isEnabled()) {        closePopupMode = 0;        activeMenu = action->menu();        activeMenu->d_func()->causedPopup.widget = q;        activeMenu->d_func()->causedPopup.action = action;        QRect adjustedActionRect = actionRect(action);        QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));        QSize popup_size = activeMenu->sizeHint();        if(q->isRightToLeft())            pos.setX(pos.x()-(popup_size.width()-adjustedActionRect.width()));        QRect screenRect = QApplication::desktop()->screenGeometry(pos);        if(pos.x() < screenRect.x()) {            pos.setX(screenRect.x());        } else {            const int off = pos.x()+popup_size.width() - screenRect.right();            if(off > 0)                pos.setX(qMax(screenRect.x(), pos.x()-off));        }        if(!defaultPopDown || (pos.y() + popup_size.height() > screenRect.bottom()))            pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));        activeMenu->popup(pos);        if(activateFirst)            activeMenu->d_func()->setFirstActionActive();    }    q->update(actionRect(action));}void QMenuBarPrivate::setCurrentAction(QAction *action, bool popup, bool activateFirst){    if(currentAction == action && popup == popupState)        return;    doChildEffects = (popup && !activeMenu);    Q_Q(QMenuBar);    QWidget *fw = 0;    if(activeMenu) {        QMenu *menu = activeMenu;        activeMenu = NULL;        if (popup) {            fw = q->window()->focusWidget();            q->setFocus(Qt::NoFocusReason);        }        menu->hide();    }    if(currentAction)        q->update(actionRect(currentAction));    popupState = popup;    QAction *previousAction = currentAction;    currentAction = action;    if(action) {        activateAction(action, QAction::Hover);        if(popup)            popupAction(action, activateFirst);        q->update(actionRect(action));    }  else if (previousAction) {        QString empty;        QStatusTipEvent tip(empty);        QApplication::sendEvent(q, &tip);    }    if (fw)        fw->setFocus(Qt::NoFocusReason);}void QMenuBarPrivate::calcActionRects(int max_width, int start, QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const{    Q_Q(const QMenuBar);    if(!itemsDirty && itemsWidth == max_width && itemsStart == start) {        actionRects = actionRects;        actionList = actionList;        return;    }    actionRects.clear();    actionList.clear();    const int itemSpacing = q->style()->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0, q);    int max_item_height = 0, separator = -1, separator_start = 0, separator_len = 0;    QList<QAction*> items = q->actions();    //calculate size    const QFontMetrics fm = q->fontMetrics();    const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0, q),              vmargin = q->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0, q),                icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);    for(int i = 0; i < items.count(); i++) {        QAction *action = items.at(i);        if(!action->isVisible())            continue;        QSize sz;        //calc what I think the size is..        if(action->isSeparator()) {            if (q->style()->styleHint(QStyle::SH_DrawMenuBarSeparator, 0, q))                separator = actionRects.count();            continue; //we don't really position these!        } else {            QString s = action->text();            if(!s.isEmpty()) {                int w = fm.width(s);                w -= s.count('&') * fm.width('&');                w += s.count("&&") * fm.width('&');                sz = QSize(w, fm.height());            }            QIcon is = action->icon();            if (!is.isNull()) {                QSize is_sz = QSize(icone, icone);                if (is_sz.height() > sz.height())                    sz.setHeight(is_sz.height());                if (is_sz.width() > sz.width())                    sz.setWidth(is_sz.width());            }        }        //let the style modify the above size..        QStyleOptionMenuItem opt = getStyleOption(action);        sz = q->style()->sizeFromContents(QStyle::CT_MenuBarItem, &opt, sz, q);        if(!sz.isEmpty()) {            { //update the separator state                int iWidth = sz.width();                iWidth += itemSpacing;                if(separator == -1)                    separator_start += iWidth;                else                    separator_len += iWidth;            }            //maximum height            max_item_height = qMax(max_item_height, sz.height());            //append            actionRects.insert(action, QRect(0, 0, sz.width(), sz.height()));            actionList.append(action);        }    }    //calculate position    int x = ((start == -1) ? hmargin : start) + itemSpacing;    int y = vmargin;    for(int i = 0; i < actionList.count(); i++) {        QAction *action = actionList.at(i);        QRect &rect = actionRects[action];        //resize        rect.setHeight(max_item_height);        //move        if(separator != -1 && i >= separator) { //after the separator            int left = (max_width - separator_len - hmargin - itemSpacing) + (x - separator_start - hmargin);            if(left < separator_start) { //wrap                separator_start = x = hmargin;                y += max_item_height;            }            rect.moveLeft(left);        } else {            rect.moveLeft(x);        }        rect.moveTop(y);        //keep moving along..        x += rect.width() + itemSpacing;    }}void QMenuBarPrivate::activateAction(QAction *action, QAction::ActionEvent action_e){    Q_Q(QMenuBar);    if (!action || !action->isEnabled())        return;    action->activate(action_e);    if (action_e == QAction::Hover)        action->showStatusText(q);//     if(action_e == QAction::Trigger)//         emit q->activated(action);//     else if(action_e == QAction::Hover)//         emit q->highlighted(action);}void QMenuBarPrivate::_q_actionTriggered(){    Q_Q(QMenuBar);    if (QAction *action = qobject_cast<QAction *>(q->sender())) {        emit q->triggered(action);#ifdef QT3_SUPPORT        emit q->activated(q->findIdForAction(action));#endif    }}void QMenuBarPrivate::_q_actionHovered(){    Q_Q(QMenuBar);    if (QAction *action = qobject_cast<QAction *>(q->sender())) {        emit q->hovered(action);#ifdef QT3_SUPPORT        emit q->highlighted(q->findIdForAction(action));#endif    }}QStyleOptionMenuItem QMenuBarPrivate::getStyleOption(const QAction *action) const{    Q_Q(const QMenuBar);    QStyleOptionMenuItem opt;    opt.palette = q->palette();    opt.state = QStyle::State_None;    if (q->isEnabled() && action->isEnabled())        opt.state |= QStyle::State_Enabled;    else        opt.palette.setCurrentColorGroup(QPalette::Disabled);    opt.fontMetrics = q->fontMetrics();    if (currentAction && currentAction == action) {        opt.state |= QStyle::State_Selected;        if (popupState && !closePopupMode)            opt.state |= QStyle::State_Sunken;    }    if (q->hasFocus() || currentAction)        opt.state |= QStyle::State_HasFocus;    opt.menuRect = q->rect();    opt.menuItemType = QStyleOptionMenuItem::Normal;    opt.checkType = QStyleOptionMenuItem::NotCheckable;    opt.text = action->text();    opt.icon = action->icon();    return opt;}/*!    \class QMenuBar    \brief The QMenuBar class provides a horizontal menu bar.    \ingroup application    \mainclass    A menu bar consists of a list of pull-down menu items. You add    menu items with addMenu(). For example, asuming that \c menubar    is a pointer to a QMenuBar and \c fileMenu is a pointer to a    QMenu, the following statement inserts the menu into the menu bar:    \code      menubar->addMenu(fileMenu);    \endcode

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -