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 + -
显示快捷键?