qdesigner_menu.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 1,357 行 · 第 1/3 页

CPP
1,357
字号
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer 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 "qdesigner_menu_p.h"#include "qdesigner_menubar_p.h"#include "qdesigner_toolbar_p.h"#include "qdesigner_command_p.h"#include "qdesigner_propertycommand_p.h"#include "actionrepository_p.h"#include "actionprovider_p.h"#include "actioneditor_p.h"#include "qdesigner_utils_p.h"#include "qdesigner_objectinspector_p.h"#include <QtCore/QTimer>#include <QtCore/qdebug.h>#include <QtDesigner/QDesignerFormEditorInterface>#include <QtDesigner/QDesignerWidgetFactoryInterface>#include <QtDesigner/QDesignerMetaDataBaseInterface>#include <QtDesigner/QExtensionManager>#include <QtGui/QAction>#include <QtGui/QApplication>#include <QtGui/QLineEdit>#include <QtGui/QPainter>#include <QtGui/QRubberBand>#include <QtGui/QToolTip>#include <QtGui/QToolBar>#include <QtGui/qevent.h>Q_DECLARE_METATYPE(QAction*)Q_DECLARE_METATYPE(QListWidgetItem*)using namespace qdesigner_internal;QDesignerMenu::QDesignerMenu(QWidget *parent) :    QMenu(parent),    m_currentIndex(0),    m_addItem(new SpecialMenuAction(this)),    m_addSeparator(new SpecialMenuAction(this)),    m_showSubMenuTimer(new QTimer(this)),    m_deactivateWindowTimer(new QTimer(this)),    m_adjustSizeTimer(new QTimer(this)),    m_editor(new QLineEdit(this)),    m_dragging(false),    m_lastSubMenuIndex(-1){    setContextMenuPolicy(Qt::DefaultContextMenu);    setAcceptDrops(true); // ### fake    setSeparatorsCollapsible(false);    connect(m_adjustSizeTimer, SIGNAL(timeout()), this, SLOT(slotAdjustSizeNow()));    m_addItem->setText(tr("Type Here"));    addAction(m_addItem);    m_addSeparator->setText(tr("Add Separator"));    addAction(m_addSeparator);    connect(m_showSubMenuTimer, SIGNAL(timeout()), this, SLOT(slotShowSubMenuNow()));    connect(m_deactivateWindowTimer, SIGNAL(timeout()), this, SLOT(slotDeactivateNow()));    m_editor->setObjectName(QLatin1String("__qt__passive_editor"));    m_editor->hide();    m_editor->installEventFilter(this);    installEventFilter(this);}QDesignerMenu::~QDesignerMenu(){}void QDesignerMenu::slotAdjustSizeNow(){    // Not using a single-shot, since we want to compress the timers if many items are being    // adjusted    m_adjustSizeTimer->stop();    adjustSize();}bool QDesignerMenu::handleEvent(QWidget *widget, QEvent *event){    if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) {        update();        if (widget == m_editor)            return false;    }    switch (event->type()) {        default: break;        case QEvent::MouseButtonPress:            return handleMousePressEvent(widget, static_cast<QMouseEvent*>(event));        case QEvent::MouseButtonRelease:            return handleMouseReleaseEvent(widget, static_cast<QMouseEvent*>(event));        case QEvent::MouseButtonDblClick:            return handleMouseDoubleClickEvent(widget, static_cast<QMouseEvent*>(event));        case QEvent::MouseMove:            return handleMouseMoveEvent(widget, static_cast<QMouseEvent*>(event));        case QEvent::ContextMenu:            return handleContextMenuEvent(widget, static_cast<QContextMenuEvent*>(event));        case QEvent::KeyPress:            return handleKeyPressEvent(widget, static_cast<QKeyEvent*>(event));    }    return true;}void QDesignerMenu::startDrag(const QPoint &pos, Qt::KeyboardModifiers modifiers){    const int index = findAction(pos);    if (index >= realActionCount())        return;    QAction *action = safeActionAt(index);    QDesignerFormWindowInterface *fw = formWindow();    const Qt::DropAction dropAction = (modifiers & Qt::ControlModifier) ? Qt::CopyAction : Qt::MoveAction;    if (dropAction == Qt::MoveAction) {        RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw);        cmd->init(this, action, actions().at(index + 1));        fw->commandHistory()->push(cmd);    }    QDrag *drag = new QDrag(this);    drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(action));    drag->setMimeData(new ActionRepositoryMimeData(action, dropAction));    const int old_index = m_currentIndex;    m_currentIndex = -1;    if (drag->start(dropAction) == Qt::IgnoreAction) {        if (dropAction == Qt::MoveAction) {            QAction *previous = safeActionAt(index);            InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw);            cmd->init(this, action, previous);            fw->commandHistory()->push(cmd);        }        m_currentIndex = old_index;    }}bool QDesignerMenu::handleKeyPressEvent(QWidget * /*widget*/, QKeyEvent *e){    m_showSubMenuTimer->stop();    if (m_editor->isHidden() && hasFocus()) { // In navigation mode        switch (e->key()) {        case Qt::Key_Delete:            if (m_currentIndex == -1 || m_currentIndex >= realActionCount())                break;            hideSubMenu();            deleteAction();            break;        case Qt::Key_Left:            e->accept();            moveLeft();            return true;        case Qt::Key_Right:            e->accept();            moveRight();            return true; // no update        case Qt::Key_Up:            e->accept();            moveUp(e->modifiers() & Qt::ControlModifier);            return true;        case Qt::Key_Down:            e->accept();            moveDown(e->modifiers() & Qt::ControlModifier);            return true;        case Qt::Key_PageUp:            m_currentIndex = 0;            break;        case Qt::Key_PageDown:            m_currentIndex = actions().count() - 1;            break;        case Qt::Key_Enter:        case Qt::Key_Return:        case Qt::Key_F2:            e->accept();            enterEditMode();            return true; // no update        case Qt::Key_Escape:            e->ignore();            setFocus();            hide();            closeMenuChain();            return true;        case Qt::Key_Alt:        case Qt::Key_Shift:        case Qt::Key_Control:            e->ignore();            setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed            return true; // no update        default: {            QAction *action = currentAction();            if (!action || action->isSeparator() || action == m_addSeparator) {                e->ignore();                return true;            } else if (!e->text().isEmpty() && e->text().at(0).toLatin1() >= 32) {                showLineEdit();                QApplication::sendEvent(m_editor, e);                e->accept();            } else {                e->ignore();            }        }            return true;        }    } else if (m_editor->hasFocus()) { // In edit mode        switch (e->key()) {        default:            e->ignore();            return false;        case Qt::Key_Enter:        case Qt::Key_Return:            if (!m_editor->text().isEmpty()) {                leaveEditMode(ForceAccept);                m_editor->hide();                setFocus();                moveDown(false);                break;            }            // fall through        case Qt::Key_Escape:            m_editor->hide();            setFocus();            break;        }    }    e->accept();    update();    return true;}static void sendMouseEventTo(QWidget *target, const QPoint &targetPoint, const QMouseEvent *event){    QMouseEvent e(event->type(), targetPoint, event->globalPos(), event->button(), event->buttons(), event->modifiers());    QApplication::sendEvent(target, &e);}bool QDesignerMenu::handleMouseDoubleClickEvent(QWidget *, QMouseEvent *event){    event->accept();    m_startPosition = QPoint();    if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)        return true;    if (!rect().contains(event->pos())) {        // special case for menubar        QWidget *target = QApplication::widgetAt(event->globalPos());        QMenuBar *mb = qobject_cast<QMenuBar*>(target);        QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(target);        if (mb != 0 || menu != 0) {            const QPoint pt = target->mapFromGlobal(event->globalPos());            QAction *action = mb == 0 ? menu->actionAt(pt) : mb->actionAt(pt);            if (action)                 sendMouseEventTo(target, pt, event);        }        return true;    }    m_currentIndex = findAction(event->pos());    QAction *action = safeActionAt(m_currentIndex);    QRect pm_rect;    if (action->menu() || hasSubMenuPixmap(action)) {        pm_rect = subMenuPixmapRect(action);        pm_rect.setLeft(pm_rect.left() - 20); // give the user a little more                                              // space to click    }    if (!pm_rect.contains(event->pos()) && m_currentIndex != -1)        enterEditMode();    return true;}bool QDesignerMenu::handleMousePressEvent(QWidget * /*widget*/, QMouseEvent *event){    if (!rect().contains(event->pos())) {        QWidget *clickedWidget = QApplication::widgetAt(event->globalPos());        if (QMenuBar *mb = qobject_cast<QMenuBar*>(clickedWidget)) {            const QPoint pt = mb->mapFromGlobal(event->globalPos());            if (QAction *action = mb->actionAt(pt)) {                QMenu * menu = action->menu();                if (menu == findRootMenu()) {                    // propagate the mouse press event (but don't close the popup)                    sendMouseEventTo(mb, pt, event);                    return true;                }            }        }        // hide the popup Qt will replay the event. Try to focus the clicked window.        slotDeactivateNow();        if (clickedWidget) {            if (QWidget *focusProxy = clickedWidget->focusProxy())                clickedWidget = focusProxy;            if (clickedWidget->focusPolicy() != Qt::NoFocus)                clickedWidget->setFocus(Qt::OtherFocusReason);        }        return true;    }    m_showSubMenuTimer->stop();    m_startPosition = QPoint();    event->accept();    if (event->button() != Qt::LeftButton)        return true;    m_startPosition = mapFromGlobal(event->globalPos());    const int index = findAction(m_startPosition);    QAction *action = safeActionAt(index);    QRect pm_rect = subMenuPixmapRect(action);    pm_rect.setLeft(pm_rect.left() - 20); // give the user a little more space to click    const int old_index = m_currentIndex;    m_currentIndex = index;    if ((hasSubMenuPixmap(action) || action->menu() != 0)        && pm_rect.contains(m_startPosition)) {        if (m_currentIndex == m_lastSubMenuIndex) {            hideSubMenu();        } else            slotShowSubMenuNow();    } else {        if (index == old_index) {            if (m_currentIndex == m_lastSubMenuIndex)                hideSubMenu();        } else {            hideSubMenu();        }    }    update();    if (index != old_index)        selectCurrentAction();    return true;}bool QDesignerMenu::handleMouseReleaseEvent(QWidget *, QMouseEvent *event){    event->accept();    m_startPosition = QPoint();    return true;}bool QDesignerMenu::handleMouseMoveEvent(QWidget *, QMouseEvent *event){    if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton)        return true;    if (!rect().contains(event->pos())) {        if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::widgetAt(event->globalPos()))) {            const QPoint pt = mb->mapFromGlobal(event->globalPos());            QAction *action = mb->actionAt(pt);            if (action && action->menu() == findRootMenu()) {                // propagate the mouse press event (but don't close the popup)                sendMouseEventTo(mb, pt, event);                return true;            }            // hide the popup Qt will replay the event            slotDeactivateNow();        }        return true;    }    if (m_startPosition.isNull())        return true;    event->accept();    const QPoint pos = mapFromGlobal(event->globalPos());    if ((pos - m_startPosition).manhattanLength() < qApp->startDragDistance())        return true;    startDrag(m_startPosition, event->modifiers());    m_startPosition = QPoint();    return true;}bool QDesignerMenu::handleContextMenuEvent(QWidget *, QContextMenuEvent *event){    event->accept();    const int index = findAction(mapFromGlobal(event->globalPos()));    QAction *action = safeActionAt(index);    if (qobject_cast<SpecialMenuAction*>(action))        return true;    QMenu menu(this);    QVariant itemData;

⌨️ 快捷键说明

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