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

📄 qmenubar.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 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://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** 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()->standardIcon(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;}QRect QMenuBarPrivate::menuRect(bool extVisible) const{    Q_Q(const QMenuBar);    int hmargin = q->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0, q);    QRect result = q->rect();    result.adjust(hmargin, 0, -hmargin, 0);    if (extVisible) {        if (q->layoutDirection() == Qt::RightToLeft)            result.setLeft(result.left() + extension->sizeHint().width());        else            result.setWidth(result.width() - extension->sizeHint().width());    }    if (leftWidget && leftWidget->isVisible()) {        QSize sz = leftWidget->sizeHint();        if (q->layoutDirection() == Qt::RightToLeft)            result.setRight(result.right() - sz.width());        else            result.setLeft(result.left() + sz.width());    }    if (rightWidget && rightWidget->isVisible()) {        QSize sz = rightWidget->sizeHint();        if (q->layoutDirection() == Qt::RightToLeft)            result.setLeft(result.left() + sz.width());        else            result.setRight(result.right() - sz.width());    }    return result;}bool QMenuBarPrivate::isVisible(QAction *action){    return !hiddenActions.contains(action);}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();            QPoint pos(hmargin, (q->height() - leftWidget->height()) / 2);            QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));            leftWidget->setGeometry(vRect);        }        if (rightWidget && rightWidget->isVisible()) {            QSize sz = rightWidget->sizeHint();            q_width -= sz.width();            QPoint pos(q->width() - sz.width() - hmargin, vmargin);            QRect vRect = QStyle::visualRect(q->layoutDirection(), q->rect(), QRect(pos, sz));            rightWidget->setGeometry(vRect);        }    }#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;    hiddenActions.clear();    //this is the menu rectangle without any extension    QRect menuRect = this->menuRect(false);    //we try to see if the actions will fit there    bool hasHiddenActions = false;    foreach(QAction *action, actionList) {        if (!menuRect.contains(actionRect(action))) {            hasHiddenActions = true;            break;        }    }    //...and if not, determine the ones that fit on the menu with the extension visible    if (hasHiddenActions) {        menuRect = this->menuRect(true);        foreach(QAction *action, actionList) {            if (!menuRect.contains(actionRect(action))) {                hiddenActions.append(action);            }        }    }    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 = q->layoutDirection() == Qt::RightToLeft                ? menuRect.left() - extension->sizeHint().width() + 1                : menuRect.right();        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() || closePopupMode)        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();        QRect screenRect = QApplication::desktop()->screenGeometry(pos);        const bool fitUp = (q->mapToGlobal(adjustedActionRect.topLeft()).y() >= popup_size.height());        const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());        const int actionWidth = adjustedActionRect.width();        if (!fitUp && !fitDown) { //we should shift the menu            bool shouldShiftToRight = !q->isRightToLeft();            if (q->isRightToLeft() && popup_size.width() > pos.x())                shouldShiftToRight = true;            else if (actionWidth + popup_size.width() + pos.x() > screenRect.right())                shouldShiftToRight = false;            if (shouldShiftToRight)                pos.rx() += actionWidth;            else                pos.rx() -= popup_size.width();        } else if (q->isRightToLeft()) {            pos.setX(pos.x()-(popup_size.width() - actionWidth));        }        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 || (fitUp && !fitDown))            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));}bool QMenuBarPrivate::closeActiveMenu(){    if(activeMenu) {        QMenu *menu = activeMenu;        activeMenu = 0;        menu->hide();        return true;    }    return false;}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(closeActiveMenu() && popup) {        fw = q->window()->focusWidget();        q->setFocus(Qt::NoFocusReason);    }    if(currentAction)        q->update(actionRect(currentAction));    popupState = popup;#ifndef QT_NO_STATUSTIP    QAction *previousAction = currentAction;#endif    currentAction = action;    if (fw)        fw->setFocus(Qt::NoFocusReason);    if (action) {        activateAction(action, QAction::Hover);        if(popup)            popupAction(action, activateFirst);        q->update(actionRect(action));#ifndef QT_NO_STATUSTIP    }  else if (previousAction) {        QString empty;        QStatusTipEvent tip(empty);        QApplication::sendEvent(q, &tip);#endif    }}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(QLatin1Char('&')) * fm.width(QLatin1Char('&'));                w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&'));                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;        q->initStyleOption(&opt, 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

⌨️ 快捷键说明

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