📄 qdesigner_menu.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://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 "qdesigner_menu_p.h"#include "qdesigner_menubar_p.h"#include "qdesigner_toolbar_p.h"#include "qdesigner_command_p.h"#include "actionrepository_p.h"#include "actionprovider_p.h"#include "actioneditor_p.h"#include "qdesigner_utils_p.h"#include <QtDesigner/QtDesigner>#include <QtCore/QTimer>#include <QtCore/qdebug.h>#include <QtGui/QAction>#include <QtGui/QApplication>#include <QtGui/QLineEdit>#include <QtGui/QPainter>#include <QtGui/QRubberBand>#include <QtGui/QToolTip>#include <QtGui/qevent.h>Q_DECLARE_METATYPE(QAction*)Q_DECLARE_METATYPE(QListWidgetItem*)using namespace qdesigner_internal;QDesignerMenu::QDesignerMenu(QWidget *parent) : QMenu(parent){ m_interactive = true; m_dragging = false; m_currentIndex = 0; m_lastSubMenuIndex = -1; setContextMenuPolicy(Qt::DefaultContextMenu); setAcceptDrops(true); // ### fake m_adjustSizeTimer = new QTimer(this); connect(m_adjustSizeTimer, SIGNAL(timeout()), this, SLOT(slotAdjustSizeNow())); m_addItem = new SpecialMenuAction(this); m_addItem->setText(tr("Type Here")); addAction(m_addItem); m_addSeparator = new SpecialMenuAction(this); m_addSeparator->setText(tr("Add Separator")); addAction(m_addSeparator); m_showSubMenuTimer = new QTimer(this); connect(m_showSubMenuTimer, SIGNAL(timeout()), this, SLOT(slotShowSubMenuNow())); m_deactivateWindowTimer = new QTimer(this); connect(m_deactivateWindowTimer, SIGNAL(timeout()), this, SLOT(slotDeactivateNow())); m_editor = new QLineEdit(this); m_editor->setObjectName("__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){ int index = findAction(pos); if (index >= realActionCount()) return; QAction *action = safeActionAt(index); RemoveActionFromCommand *cmd = new RemoveActionFromCommand(formWindow()); cmd->init(this, action, actions().at(index + 1)); formWindow()->commandHistory()->push(cmd); QDrag *drag = new QDrag(this); drag->setPixmap(action->icon().pixmap(QSize(22, 22))); ActionRepositoryMimeData *data = new ActionRepositoryMimeData(); data->items.append(action); drag->setMimeData(data); int old_index = m_currentIndex; m_currentIndex = -1; if (drag->start() == Qt::IgnoreAction) { QAction *previous = safeActionAt(index); InsertActionIntoCommand *cmd = new InsertActionIntoCommand(formWindow()); cmd->init(this, action, previous); formWindow()->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: if (!currentAction() || currentAction()->isSeparator() || currentAction() == 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;}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) { QPoint pt = target->mapFromGlobal(event->globalPos()); QAction *action = mb == 0 ? menu->actionAt(pt) : mb->actionAt(pt); if (action) { QMouseEvent e(event->type(), pt, event->globalPos(), event->button(), event->buttons(), event->modifiers()); QApplication::sendEvent(target, &e); } } 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())) { if (QMenuBar *mb = qobject_cast<QMenuBar*>(QApplication::widgetAt(event->globalPos()))) { 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) QMouseEvent e(event->type(), pt, event->globalPos(), event->button(), event->buttons(), event->modifiers()); QApplication::sendEvent(mb, &e); return true; } } // hide the popup Qt will replay the event slotDeactivateNow(); return true; } m_showSubMenuTimer->stop(); m_startPosition = QPoint(); event->accept(); if (event->button() != Qt::LeftButton) return true; m_startPosition = mapFromGlobal(event->globalPos()); 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 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 slotShowSubMenuNow(); } else { hideSubMenu(); } } updateCurrentAction(); 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()))) { 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) QMouseEvent e(event->type(), pt, event->globalPos(), event->button(), event->buttons(), event->modifiers()); QApplication::sendEvent(mb, &e); return true; } // hide the popup Qt will replay the event slotDeactivateNow(); } return true; } if (m_startPosition.isNull()) return true; event->accept(); QPoint pos = mapFromGlobal(event->globalPos()); if ((pos - m_startPosition).manhattanLength() < qApp->startDragDistance()) return true; startDrag(m_startPosition); m_startPosition = QPoint(); return true;}bool QDesignerMenu::handleContextMenuEvent(QWidget *, QContextMenuEvent *event)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -