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

📄 qmenu.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 "qmenu.h"#ifndef QT_NO_MENU#include "qdebug.h"#include "qstyle.h"#include "qevent.h"#include "qtimer.h"#include "qlayout.h"#include "qpainter.h"#include "qapplication.h"#include "qdesktopwidget.h"#ifndef QT_NO_ACCESSIBILITY# include "qaccessible.h"#endif#ifndef QT_NO_EFFECTS# include <private/qeffects_p.h>#endif#ifndef QT_NO_WHATSTHIS# include <qwhatsthis.h>#endif#include "qmenu_p.h"#include "qmenubar_p.h"#include "qwidgetaction.h"#include "qtoolbutton.h"#include <private/qaction_p.h>#ifdef QT3_SUPPORT#include <qmenudata.h>#endif // QT3_SUPPORT#ifdef Q_WS_X11#include <private/qt_x11_p.h>#endifQPointer<QMenu> QMenuPrivate::mouseDown;QBasicTimer QMenuPrivate::menuDelayTimer;QBasicTimer QMenuPrivate::sloppyDelayTimer;/* QMenu code */// internal class used for the torn off popupclass QTornOffMenu : public QMenu{    Q_OBJECT    class QTornOffMenuPrivate : public QMenuPrivate    {        Q_DECLARE_PUBLIC(QMenu)    public:        QTornOffMenuPrivate(QMenu *p) : causedMenu(p) {            tornoff = 1;            causedPopup.widget = 0;            causedPopup.action = ((QTornOffMenu*)p)->d_func()->causedPopup.action;            causedStack = ((QTornOffMenu*)p)->d_func()->calcCausedStack();        }        QList<QPointer<QWidget> > calcCausedStack() const { return causedStack; }        QPointer<QMenu> causedMenu;        QList<QPointer<QWidget> > causedStack;    };public:    QTornOffMenu(QMenu *p) : QMenu(*(new QTornOffMenuPrivate(p)))    {        setParent(p, Qt::Window | Qt::Tool);	setAttribute(Qt::WA_DeleteOnClose, true);        setWindowTitle(p->windowTitle());        setEnabled(p->isEnabled());        //QObject::connect(this, SIGNAL(triggered(QAction*)), this, SLOT(onTrigger(QAction*)));        //QObject::connect(this, SIGNAL(hovered(QAction*)), this, SLOT(onHovered(QAction*)));        QList<QAction*> items = p->actions();        for(int i = 0; i < items.count(); i++)            addAction(items.at(i));    }    void syncWithMenu(QMenu *menu, QActionEvent *act)    {        Q_D(QTornOffMenu);        if(menu != d->causedMenu)            return;        if (act->type() == QEvent::ActionAdded) {            insertAction(act->before(), act->action());        } else if (act->type() == QEvent::ActionRemoved)            removeAction(act->action());    }    void actionEvent(QActionEvent *e)    {        QMenu::actionEvent(e);        setFixedSize(sizeHint());    }public slots:    void onTrigger(QAction *action) { d_func()->activateAction(action, QAction::Trigger, false); }    void onHovered(QAction *action) { d_func()->activateAction(action, QAction::Hover, false); }private:    Q_DECLARE_PRIVATE(QTornOffMenu)    friend class QMenuPrivate;};#include "qmenu.moc"void QMenuPrivate::init(){    Q_Q(QMenu);#ifndef QT_NO_WHATSTHIS    q->setAttribute(Qt::WA_CustomWhatsThis);#endif    q->setMouseTracking(q->style()->styleHint(QStyle::SH_Menu_MouseTracking, 0, q));    if (q->style()->styleHint(QStyle::SH_Menu_Scrollable, 0, q)) {        scroll = new QMenuPrivate::QMenuScroller;        scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;    }    defaultMenuAction = menuAction = new QAction(q);    menuAction->d_func()->menu = q;}//Windows and KDE allows menus to cover the taskbar, while GNOME and Mac don'tQRect QMenuPrivate::popupGeometry(int screen) const{#ifdef Q_WS_WIN    return QApplication::desktop()->screenGeometry(screen);#elif defined Q_WS_X11    if (X11->desktopEnvironment == DE_KDE)        return QApplication::desktop()->screenGeometry(screen);    else        return QApplication::desktop()->availableGeometry(screen);#else        return QApplication::desktop()->availableGeometry(screen);#endif}QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const{    QList<QPointer<QWidget> > ret;    for(QWidget *widget = causedPopup.widget; widget; ) {        ret.append(widget);        if (QTornOffMenu *qtmenu = ::qobject_cast<QTornOffMenu*>(widget))            ret += qtmenu->d_func()->causedStack;        if (QMenu *qmenu = ::qobject_cast<QMenu*>(widget))            widget = qmenu->d_func()->causedPopup.widget;        else            break;    }    return ret;}void QMenuPrivate::calcActionRects(QMap<QAction*, QRect> &actionRects, QList<QAction*> &actionList) const{    Q_Q(const QMenu);    if (!itemsDirty) {        actionRects = this->actionRects;        actionList = this->actionList;        return;    }    actionRects.clear();    actionList.clear();    QList<QAction*> items = filterActions(q->actions());    int max_column_width = 0,        dh = popupGeometry(QApplication::desktop()->screenNumber(q)).height(),        ncols = 1,        y = 0;    const int hmargin = q->style()->pixelMetric(QStyle::PM_MenuHMargin, 0, q),              vmargin = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q),              icone = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q);    //for compatability now - will have to refactor this away..    tabWidth = 0;    maxIconWidth = 0;    hasCheckableItems = false;    for(int i = 0; i < items.count(); i++) {        QAction *action = items.at(i);        if (widgetItems.value(action))            continue;        hasCheckableItems |= action->isCheckable();        QIcon is = action->icon();        if (!is.isNull()) {            uint miw = maxIconWidth;            maxIconWidth = qMax<uint>(miw, icone + 4);        }    }    //calculate size    QFontMetrics qfm = q->fontMetrics();    for(int i = 0; i < items.count(); i++) {        QAction *action = items.at(i);        QFontMetrics fm(action->font().resolve(q->font()));        QSize sz;        //let the style modify the above size..        QStyleOptionMenuItem opt;        q->initStyleOption(&opt, action);        opt.rect = q->rect();        if (QWidget *w = widgetItems.value(action)) {          sz=w->sizeHint().expandedTo(w->minimumSize()).expandedTo(w->minimumSizeHint()).boundedTo(w->maximumSize());        } else {            //calc what I think the size is..            if (action->isSeparator()) {                sz = QSize(2, 2);            } else {                QString s = action->text();                int t = s.indexOf(QLatin1Char('\t'));                if (t != -1) {                    tabWidth = qMax(int(tabWidth), qfm.width(s.mid(t+1)));                    s = s.left(t);    #ifndef QT_NO_SHORTCUT                } else {                    QKeySequence seq = action->shortcut();                    if (!seq.isEmpty())                        tabWidth = qMax(int(tabWidth), qfm.width(seq));    #endif                }                int w = fm.width(s);                w -= s.count(QLatin1Char('&')) * fm.width(QLatin1Char('&'));                w += s.count(QLatin1String("&&")) * fm.width(QLatin1Char('&'));                sz.setWidth(w);                sz.setHeight(qMax(fm.height(), qfm.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());                }            }          sz = q->style()->sizeFromContents(QStyle::CT_MenuItem, &opt, sz, q);        }        if (!sz.isEmpty()) {            max_column_width = qMax(max_column_width, sz.width());            //wrapping            if (!scroll &&               y+sz.height()+vmargin > dh - (q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) {                ncols++;                y = vmargin;            }            y += sz.height();            //append item            actionRects.insert(action, QRect(0, 0, sz.width(), sz.height()));            actionList.append(action);        }    }    if (tabWidth)        max_column_width += tabWidth; //finally add in the tab width    //calculate position    int x = hmargin;    y = vmargin;    for(int i = 0; i < actionList.count(); i++) {        QAction *action = actionList.at(i);        QRect &rect = actionRects[action];        if (rect.isNull())            continue;        if (!scroll &&           y+rect.height() > dh - (q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, q) * 2)) {            ncols--;            if (ncols < 0)                qWarning("QMenu: Column calculation mismatch (%d)", ncols);            x += max_column_width + hmargin;            y = vmargin;        }        rect.translate(x, y);                        //move        rect.setWidth(max_column_width); //uniform width        y += rect.height();    }}void QMenuPrivate::updateActions(){    Q_Q(const QMenu);    if (!itemsDirty)        return;    sloppyAction = 0;    calcActionRects(actionRects, actionList);    for (QHash<QAction *, QWidget *>::ConstIterator item = widgetItems.constBegin(),         end = widgetItems.constEnd(); item != end; ++item) {        QAction *action = item.key();        QWidget *widget = item.value();        widget->setGeometry(actionRect(action));        widget->setVisible(action->isVisible());    }    ncols = 1;    int last_left = q->style()->pixelMetric(QStyle::PM_MenuVMargin, 0, q);    if (!scroll) {        for(int i = 0; i < actionList.count(); i++) {            int left = actionRects.value(actionList.at(i)).left();            if (left > last_left) {                last_left = left;                ncols++;            }        }    }    itemsDirty = 0;}QList<QAction *> QMenuPrivate::filterActions(const QList<QAction *> &actions) const{    QList<QAction *> visibleActions;    int i = 0;    while (i < actions.count()) {        QAction *action = actions.at(i);        if (!action->isVisible()) {            ++i;            continue;        }        if (!action->isSeparator() || !collapsibleSeparators) {            visibleActions.append(action);            ++i;            continue;        }        // no leading separators        if (!visibleActions.isEmpty())            visibleActions.append(action);        // skip double/tripple/etc. separators        while (i < actions.count()               && (!actions.at(i)->isVisible() || actions.at(i)->isSeparator()))            ++i;    }    if (collapsibleSeparators) {        // remove trailing separators        while (!visibleActions.isEmpty() && visibleActions.last()->isSeparator())            visibleActions.removeLast();    }    return visibleActions;}QRect QMenuPrivate::actionRect(QAction *act) const{    Q_Q(const QMenu);    QRect ret = actionRects.value(act);    if (ret.isNull())        return ret;    if (scroll)        ret.translate(0, scroll->scrollOffset);    if (tearoff)        ret.translate(0, q->style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, q));    const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q);    ret.translate(fw+leftmargin, fw+topmargin);    return ret;}void QMenuPrivate::hideUpToMenuBar(){    Q_Q(QMenu);    if (!tornoff) {        QWidget *caused = causedPopup.widget;        q->hide(); //hide after getting causedPopup        while(caused) {#ifndef QT_NO_MENUBAR            if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) {                mb->d_func()->setCurrentAction(0);                caused = 0;            } else#endif

⌨️ 快捷键说明

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