diff options
Diffstat (limited to 'tools/designer/src/lib/shared/qdesigner_menubar.cpp')
-rw-r--r-- | tools/designer/src/lib/shared/qdesigner_menubar.cpp | 955 |
1 files changed, 955 insertions, 0 deletions
diff --git a/tools/designer/src/lib/shared/qdesigner_menubar.cpp b/tools/designer/src/lib/shared/qdesigner_menubar.cpp new file mode 100644 index 0000000..97f1734 --- /dev/null +++ b/tools/designer/src/lib/shared/qdesigner_menubar.cpp @@ -0,0 +1,955 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdesigner_menubar_p.h" +#include "qdesigner_menu_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 "promotiontaskmenu_p.h" +#include "qdesigner_objectinspector_p.h" + +#include <QtDesigner/QDesignerFormWindowInterface> +#include <QtDesigner/QDesignerFormEditorInterface> +#include <QtDesigner/QDesignerWidgetFactoryInterface> +#include <QtDesigner/QExtensionManager> + +#include <QtCore/QMimeData> + +#include <QtCore/qdebug.h> + +#include <QtGui/QApplication> +#include <QtGui/QDrag> +#include <QtGui/QLineEdit> +#include <QtGui/QPainter> +#include <QtGui/qevent.h> + +Q_DECLARE_METATYPE(QAction*) + +QT_BEGIN_NAMESPACE + +typedef QList<QAction *> ActionList; + +using namespace qdesigner_internal; + +namespace qdesigner_internal +{ + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +SpecialMenuAction::SpecialMenuAction(QObject *parent) + : QAction(parent) +{ +} + +SpecialMenuAction::~SpecialMenuAction() +{ +} + + +} // namespace qdesigner_internal + + +///////////////////////////////////////////////////////////////////////////////////////////////////////// +QDesignerMenuBar::QDesignerMenuBar(QWidget *parent) : + QMenuBar(parent), + m_addMenu(new SpecialMenuAction(this)), + m_currentIndex(0), + m_interactive(true), + m_editor(new QLineEdit(this)), + m_dragging(false), + m_lastMenuActionIndex( -1), + m_promotionTaskMenu(new PromotionTaskMenu(this, PromotionTaskMenu::ModeSingleWidget, this)) +{ + setContextMenuPolicy(Qt::DefaultContextMenu); + + setAcceptDrops(true); // ### fake + + m_addMenu->setText(tr("Type Here")); + addAction(m_addMenu); + + QFont italic; + italic.setItalic(true); + m_addMenu->setFont(italic); + + m_editor->setObjectName(QLatin1String("__qt__passive_editor")); + m_editor->hide(); + m_editor->installEventFilter(this); + installEventFilter(this); +} + +QDesignerMenuBar::~QDesignerMenuBar() +{ +} + +void QDesignerMenuBar::paintEvent(QPaintEvent *event) +{ + QMenuBar::paintEvent(event); + + QPainter p(this); + + foreach (QAction *a, actions()) { + if (qobject_cast<SpecialMenuAction*>(a)) { + const QRect g = actionGeometry(a); + QLinearGradient lg(g.left(), g.top(), g.left(), g.bottom()); + lg.setColorAt(0.0, Qt::transparent); + lg.setColorAt(0.7, QColor(0, 0, 0, 32)); + lg.setColorAt(1.0, Qt::transparent); + + p.fillRect(g, lg); + } + } + + QAction *action = currentAction(); + + if (m_dragging || !action) + return; + + if (hasFocus()) { + const QRect g = actionGeometry(action); + QDesignerMenu::drawSelection(&p, g.adjusted(1, 1, -1, -1)); + } else if (action->menu() && action->menu()->isVisible()) { + const QRect g = actionGeometry(action); + p.drawRect(g.adjusted(1, 1, -1, -1)); + } +} + +bool QDesignerMenuBar::handleEvent(QWidget *widget, QEvent *event) +{ + if (!formWindow()) + return false; + + if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) + update(); + + switch (event->type()) { + default: break; + + case QEvent::MouseButtonDblClick: + return handleMouseDoubleClickEvent(widget, static_cast<QMouseEvent*>(event)); + case QEvent::MouseButtonPress: + return handleMousePressEvent(widget, static_cast<QMouseEvent*>(event)); + case QEvent::MouseButtonRelease: + return handleMouseReleaseEvent(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)); + case QEvent::FocusIn: + case QEvent::FocusOut: + return widget != m_editor; + } + + return true; +} + +bool QDesignerMenuBar::handleMouseDoubleClickEvent(QWidget *, QMouseEvent *event) +{ + if (!rect().contains(event->pos())) + return true; + + if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton) + return true; + + event->accept(); + + m_startPosition = QPoint(); + + m_currentIndex = actionIndexAt(this, event->pos(), Qt::Horizontal); + if (m_currentIndex != -1) { + showLineEdit(); + } + + return true; +} + +bool QDesignerMenuBar::handleKeyPressEvent(QWidget *, QKeyEvent *e) +{ + if (m_editor->isHidden()) { // In navigation mode + switch (e->key()) { + + case Qt::Key_Delete: + if (m_currentIndex == -1 || m_currentIndex >= realActionCount()) + break; + hideMenu(); + deleteMenu(); + break; + + case Qt::Key_Left: + e->accept(); + if (QApplication::layoutDirection() == Qt::LeftToRight) + moveLeft(e->modifiers() & Qt::ControlModifier); + else + moveRight(e->modifiers() & Qt::ControlModifier); + return true; + + case Qt::Key_Right: + e->accept(); + if (QApplication::layoutDirection() == Qt::LeftToRight) + moveRight(e->modifiers() & Qt::ControlModifier); + else + moveLeft(e->modifiers() & Qt::ControlModifier); + return true; // no update + + case Qt::Key_Up: + e->accept(); + moveUp(); + return true; + + case Qt::Key_Down: + e->accept(); + moveDown(); + 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: + e->accept(); + enterEditMode(); + return true; // no update + + case Qt::Key_Alt: + case Qt::Key_Shift: + case Qt::Key_Control: + case Qt::Key_Escape: + e->ignore(); + setFocus(); // FIXME: this is because some other widget get the focus when CTRL is pressed + return true; // no update + + default: + if (!e->text().isEmpty() && e->text().at(0).toLatin1() >= 32) { + showLineEdit(); + QApplication::sendEvent(m_editor, e); + e->accept(); + } else { + e->ignore(); + } + return true; + } + } else { // In edit mode + switch (e->key()) { + default: + return false; + + case Qt::Key_Control: + e->ignore(); + return true; + + case Qt::Key_Enter: + case Qt::Key_Return: + if (!m_editor->text().isEmpty()) { + leaveEditMode(ForceAccept); + if (m_lastFocusWidget) + m_lastFocusWidget->setFocus(); + + m_editor->hide(); + showMenu(); + break; + } + // fall through + + case Qt::Key_Escape: + update(); + setFocus(); + break; + } + } + + e->accept(); + update(); + + return true; +} + +void QDesignerMenuBar::startDrag(const QPoint &pos) +{ + const int index = findAction(pos); + if (m_currentIndex == -1 || index >= realActionCount()) + return; + + QAction *action = safeActionAt(index); + + QDesignerFormWindowInterface *fw = formWindow(); + RemoveActionFromCommand *cmd = new RemoveActionFromCommand(fw); + cmd->init(this, action, actions().at(index + 1)); + fw->commandHistory()->push(cmd); + + adjustSize(); + + hideMenu(index); + + QDrag *drag = new QDrag(this); + drag->setPixmap(ActionRepositoryMimeData::actionDragPixmap(action)); + drag->setMimeData(new ActionRepositoryMimeData(action, Qt::MoveAction)); + + const int old_index = m_currentIndex; + m_currentIndex = -1; + + if (drag->start(Qt::MoveAction) == Qt::IgnoreAction) { + InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw); + cmd->init(this, action, safeActionAt(index)); + fw->commandHistory()->push(cmd); + + m_currentIndex = old_index; + adjustSize(); + } +} + +bool QDesignerMenuBar::handleMousePressEvent(QWidget *, QMouseEvent *event) +{ + m_startPosition = QPoint(); + event->accept(); + + if (event->button() != Qt::LeftButton) + return true; + + m_startPosition = event->pos(); + const int newIndex = actionIndexAt(this, m_startPosition, Qt::Horizontal); + const bool changed = newIndex != m_currentIndex; + m_currentIndex = newIndex; + updateCurrentAction(changed); + + return true; +} + +bool QDesignerMenuBar::handleMouseReleaseEvent(QWidget *, QMouseEvent *event) +{ + m_startPosition = QPoint(); + + if (event->button() != Qt::LeftButton) + return true; + + event->accept(); + m_currentIndex = actionIndexAt(this, event->pos(), Qt::Horizontal); + if (!m_editor->isVisible() && m_currentIndex != -1 && m_currentIndex < realActionCount()) + showMenu(); + + return true; +} + +bool QDesignerMenuBar::handleMouseMoveEvent(QWidget *, QMouseEvent *event) +{ + if ((event->buttons() & Qt::LeftButton) != Qt::LeftButton) + return true; + + if (m_startPosition.isNull()) + return true; + + const QPoint pos = mapFromGlobal(event->globalPos()); + + if ((pos - m_startPosition).manhattanLength() < qApp->startDragDistance()) + return true; + + const int index = actionIndexAt(this, m_startPosition, Qt::Horizontal); + if (index < actions().count()) { + hideMenu(index); + update(); + } + + startDrag(m_startPosition); + m_startPosition = QPoint(); + + return true; +} + +ActionList QDesignerMenuBar::contextMenuActions() +{ + ActionList rc; + if (QAction *action = safeActionAt(m_currentIndex)) { + if (!qobject_cast<SpecialMenuAction*>(action)) { + QVariant itemData; + qVariantSetValue(itemData, action); + + QAction *remove_action = new QAction(tr("Remove Menu '%1'").arg(action->menu()->objectName()), 0); + remove_action->setData(itemData); + connect(remove_action, SIGNAL(triggered()), this, SLOT(deleteMenu())); + rc.push_back(remove_action); + QAction *sep = new QAction(0); + sep->setSeparator(true); + rc.push_back(sep); + } + } + + m_promotionTaskMenu->addActions(formWindow(), PromotionTaskMenu::TrailingSeparator, rc); + + QAction *remove_menubar = new QAction(tr("Remove Menu Bar"), 0); + connect(remove_menubar, SIGNAL(triggered()), this, SLOT(slotRemoveMenuBar())); + rc.push_back(remove_menubar); + return rc; +} + +bool QDesignerMenuBar::handleContextMenuEvent(QWidget *, QContextMenuEvent *event) +{ + event->accept(); + + m_currentIndex = actionIndexAt(this, mapFromGlobal(event->globalPos()), Qt::Horizontal); + + update(); + + QMenu menu; + const ActionList al = contextMenuActions(); + const ActionList::const_iterator acend = al.constEnd(); + for (ActionList::const_iterator it = al.constBegin(); it != acend; ++it) + menu.addAction(*it); + menu.exec(event->globalPos()); + return true; +} + +void QDesignerMenuBar::slotRemoveMenuBar() +{ + Q_ASSERT(formWindow() != 0); + + QDesignerFormWindowInterface *fw = formWindow(); + + DeleteMenuBarCommand *cmd = new DeleteMenuBarCommand(fw); + cmd->init(this); + fw->commandHistory()->push(cmd); +} + +void QDesignerMenuBar::focusOutEvent(QFocusEvent *event) +{ + QMenuBar::focusOutEvent(event); +} + +void QDesignerMenuBar::enterEditMode() +{ + if (m_currentIndex >= 0 && m_currentIndex <= realActionCount()) { + showLineEdit(); + } +} + +void QDesignerMenuBar::leaveEditMode(LeaveEditMode mode) +{ + m_editor->releaseKeyboard(); + + if (mode == Default) + return; + + if (m_editor->text().isEmpty()) + return; + + QAction *action = 0; + + QDesignerFormWindowInterface *fw = formWindow(); + Q_ASSERT(fw); + + if (m_currentIndex >= 0 && m_currentIndex < realActionCount()) { + action = safeActionAt(m_currentIndex); + fw->beginCommand(QApplication::translate("Command", "Change Title")); + } else { + fw->beginCommand(QApplication::translate("Command", "Insert Menu")); + const QString niceObjectName = ActionEditor::actionTextToName(m_editor->text(), QLatin1String("menu")); + QMenu *menu = qobject_cast<QMenu*>(fw->core()->widgetFactory()->createWidget(QLatin1String("QMenu"), this)); + fw->core()->widgetFactory()->initialize(menu); + menu->setObjectName(niceObjectName); + menu->setTitle(tr("Menu")); + fw->ensureUniqueObjectName(menu); + action = menu->menuAction(); + AddMenuActionCommand *cmd = new AddMenuActionCommand(fw); + cmd->init(action, m_addMenu, this, this); + fw->commandHistory()->push(cmd); + } + + SetPropertyCommand *cmd = new SetPropertyCommand(fw); + cmd->init(action, QLatin1String("text"), m_editor->text()); + fw->commandHistory()->push(cmd); + fw->endCommand(); +} + +void QDesignerMenuBar::showLineEdit() +{ + QAction *action = 0; + + if (m_currentIndex >= 0 && m_currentIndex < realActionCount()) + action = safeActionAt(m_currentIndex); + else + action = m_addMenu; + + if (action->isSeparator()) + return; + + // hideMenu(); + + m_lastFocusWidget = qApp->focusWidget(); + + // open edit field for item name + const QString text = action != m_addMenu ? action->text() : QString(); + + m_editor->setText(text); + m_editor->selectAll(); + m_editor->setGeometry(actionGeometry(action)); + m_editor->show(); + qApp->setActiveWindow(m_editor); + m_editor->setFocus(); + m_editor->grabKeyboard(); +} + +bool QDesignerMenuBar::eventFilter(QObject *object, QEvent *event) +{ + if (object != this && object != m_editor) + return false; + + if (!m_editor->isHidden() && object == m_editor && event->type() == QEvent::FocusOut) { + leaveEditMode(Default); + m_editor->hide(); + update(); + return true; + } + + bool dispatch = true; + + switch (event->type()) { + default: break; + + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::ContextMenu: + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + dispatch = (object != m_editor); + // no break + + case QEvent::Enter: + case QEvent::Leave: + case QEvent::FocusIn: + case QEvent::FocusOut: + { + QWidget *widget = qobject_cast<QWidget*>(object); + + if (dispatch && widget && (widget == this || isAncestorOf(widget))) + return handleEvent(widget, event); + } break; + + case QEvent::Shortcut: + event->accept(); + return true; + } + + return false; +}; + +int QDesignerMenuBar::findAction(const QPoint &pos) const +{ + const int index = actionIndexAt(this, pos, Qt::Horizontal); + if (index == -1) + return realActionCount(); + + return index; +} + +void QDesignerMenuBar::adjustIndicator(const QPoint &pos) +{ + const int index = findAction(pos); + QAction *action = safeActionAt(index); + Q_ASSERT(action != 0); + + if (pos != QPoint(-1, -1)) { + QDesignerMenu *m = qobject_cast<QDesignerMenu*>(action->menu()); + if (!m || m->parentMenu()) { + m_currentIndex = index; + showMenu(index); + } + } + + if (QDesignerActionProviderExtension *a = actionProvider()) { + a->adjustIndicator(pos); + } +} + +QDesignerMenuBar::ActionDragCheck QDesignerMenuBar::checkAction(QAction *action) const +{ + // action belongs to another form + if (!action || !Utils::isObjectAncestorOf(formWindow()->mainContainer(), action)) + return NoActionDrag; + + if (!action->menu()) + return ActionDragOnSubMenu; // simple action only on sub menus + + QDesignerMenu *m = qobject_cast<QDesignerMenu*>(action->menu()); + if (m && m->parentMenu()) + return ActionDragOnSubMenu; // it looks like a submenu + + if (actions().contains(action)) + return ActionDragOnSubMenu; // we already have the action in the menubar + + return AcceptActionDrag; +} + +void QDesignerMenuBar::dragEnterEvent(QDragEnterEvent *event) +{ + const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData()); + if (!d || d->actionList().empty()) { + event->ignore(); + return; + } + + QAction *action = d->actionList().first(); + switch (checkAction(action)) { + case NoActionDrag: + event->ignore(); + break; + case ActionDragOnSubMenu: + m_dragging = true; + d->accept(event); + break; + case AcceptActionDrag: + m_dragging = true; + d->accept(event); + adjustIndicator(event->pos()); + break; + } +} + +void QDesignerMenuBar::dragMoveEvent(QDragMoveEvent *event) +{ + const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData()); + if (!d || d->actionList().empty()) { + event->ignore(); + return; + } + QAction *action = d->actionList().first(); + + switch (checkAction(action)) { + case NoActionDrag: + event->ignore(); + break; + case ActionDragOnSubMenu: + event->ignore(); + showMenu(findAction(event->pos())); + break; + case AcceptActionDrag: + d->accept(event); + adjustIndicator(event->pos()); + break; + } +} + +void QDesignerMenuBar::dragLeaveEvent(QDragLeaveEvent *) +{ + m_dragging = false; + + adjustIndicator(QPoint(-1, -1)); +} + +void QDesignerMenuBar::dropEvent(QDropEvent *event) +{ + m_dragging = false; + + if (const ActionRepositoryMimeData *d = qobject_cast<const ActionRepositoryMimeData*>(event->mimeData())) { + + QAction *action = d->actionList().first(); + if (checkAction(action) == AcceptActionDrag) { + event->acceptProposedAction(); + int index = findAction(event->pos()); + index = qMin(index, actions().count() - 1); + + QDesignerFormWindowInterface *fw = formWindow(); + InsertActionIntoCommand *cmd = new InsertActionIntoCommand(fw); + cmd->init(this, action, safeActionAt(index)); + fw->commandHistory()->push(cmd); + + m_currentIndex = index; + update(); + adjustIndicator(QPoint(-1, -1)); + return; + } + } + event->ignore(); +} + +void QDesignerMenuBar::actionEvent(QActionEvent *event) +{ + QMenuBar::actionEvent(event); +} + +QDesignerFormWindowInterface *QDesignerMenuBar::formWindow() const +{ + return QDesignerFormWindowInterface::findFormWindow(const_cast<QDesignerMenuBar*>(this)); +} + +QDesignerActionProviderExtension *QDesignerMenuBar::actionProvider() +{ + if (QDesignerFormWindowInterface *fw = formWindow()) { + QDesignerFormEditorInterface *core = fw->core(); + return qt_extension<QDesignerActionProviderExtension*>(core->extensionManager(), this); + } + + return 0; +} + +QAction *QDesignerMenuBar::currentAction() const +{ + if (m_currentIndex < 0 || m_currentIndex >= actions().count()) + return 0; + + return safeActionAt(m_currentIndex); +} + +int QDesignerMenuBar::realActionCount() const +{ + return actions().count() - 1; // 1 fake actions +} + +void QDesignerMenuBar::moveLeft(bool ctrl) +{ + if (ctrl) + (void) swap(m_currentIndex, m_currentIndex - 1); + + m_currentIndex = qMax(0, --m_currentIndex); + // Always re-select, swapping destroys order + updateCurrentAction(true); +} + +bool QDesignerMenuBar::dragging() const +{ + return m_dragging; +} + +void QDesignerMenuBar::moveRight(bool ctrl) +{ + if (ctrl) + (void) swap(m_currentIndex + 1, m_currentIndex); + + m_currentIndex = qMin(actions().count() - 1, ++m_currentIndex); + updateCurrentAction(!ctrl); +} + +void QDesignerMenuBar::moveUp() +{ + update(); +} + +void QDesignerMenuBar::moveDown() +{ + showMenu(); +} + +void QDesignerMenuBar::adjustSpecialActions() +{ + removeAction(m_addMenu); + addAction(m_addMenu); +} + +bool QDesignerMenuBar::interactive(bool i) +{ + const bool old = m_interactive; + m_interactive = i; + return old; +} + +void QDesignerMenuBar::hideMenu(int index) +{ + if (index < 0 && m_currentIndex >= 0) + index = m_currentIndex; + + if (index < 0 || index >= realActionCount()) + return; + + QAction *action = safeActionAt(index); + + if (action && action->menu()) { + action->menu()->hide(); + + if (QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(action->menu())) { + menu->closeMenuChain(); + } + } +} + +void QDesignerMenuBar::deleteMenu() +{ + deleteMenuAction(currentAction()); +} + +void QDesignerMenuBar::deleteMenuAction(QAction *action) +{ + if (action && !qobject_cast<SpecialMenuAction*>(action)) { + const int pos = actions().indexOf(action); + QAction *action_before = 0; + if (pos != -1) + action_before = safeActionAt(pos + 1); + + QDesignerFormWindowInterface *fw = formWindow(); + RemoveMenuActionCommand *cmd = new RemoveMenuActionCommand(fw); + cmd->init(action, action_before, this, this); + fw->commandHistory()->push(cmd); + } +} + +void QDesignerMenuBar::showMenu(int index) +{ + if (index < 0 && m_currentIndex >= 0) + index = m_currentIndex; + + if (index < 0 || index >= realActionCount()) + return; + + m_currentIndex = index; + QAction *action = currentAction(); + + if (action && action->menu()) { + if (m_lastMenuActionIndex != -1 && m_lastMenuActionIndex != index) { + hideMenu(m_lastMenuActionIndex); + } + + m_lastMenuActionIndex = index; + QMenu *menu = action->menu(); + const QRect g = actionGeometry(action); + + if (!menu->isVisible()) { + if ((menu->windowFlags() & Qt::Popup) != Qt::Popup) + menu->setWindowFlags(Qt::Popup); + menu->adjustSize(); + menu->move(mapToGlobal(g.bottomLeft())); + menu->setFocus(Qt::MouseFocusReason); + menu->raise(); + menu->show(); + } else { + menu->raise(); + } + } +} + +QAction *QDesignerMenuBar::safeActionAt(int index) const +{ + if (index < 0 || index >= actions().count()) + return 0; + + return actions().at(index); +} + +bool QDesignerMenuBar::swap(int a, int b) +{ + const int left = qMin(a, b); + int right = qMax(a, b); + + QAction *action_a = safeActionAt(left); + QAction *action_b = safeActionAt(right); + + if (action_a == action_b + || !action_a + || !action_b + || qobject_cast<SpecialMenuAction*>(action_a) + || qobject_cast<SpecialMenuAction*>(action_b)) + return false; // nothing to do + + right = qMin(right, realActionCount()); + if (right < 0) + return false; // nothing to do + + formWindow()->beginCommand(QApplication::translate("Command", "Move action")); + + QAction *action_b_before = safeActionAt(right + 1); + + QDesignerFormWindowInterface *fw = formWindow(); + RemoveActionFromCommand *cmd1 = new RemoveActionFromCommand(fw); + cmd1->init(this, action_b, action_b_before, false); + fw->commandHistory()->push(cmd1); + + QAction *action_a_before = safeActionAt(left + 1); + + InsertActionIntoCommand *cmd2 = new InsertActionIntoCommand(fw); + cmd2->init(this, action_b, action_a_before, false); + fw->commandHistory()->push(cmd2); + + RemoveActionFromCommand *cmd3 = new RemoveActionFromCommand(fw); + cmd3->init(this, action_a, action_b, false); + fw->commandHistory()->push(cmd3); + + InsertActionIntoCommand *cmd4 = new InsertActionIntoCommand(fw); + cmd4->init(this, action_a, action_b_before, true); + fw->commandHistory()->push(cmd4); + + fw->endCommand(); + + return true; +} + +void QDesignerMenuBar::keyPressEvent(QKeyEvent *event) +{ + event->ignore(); +} + +void QDesignerMenuBar::keyReleaseEvent(QKeyEvent *event) +{ + event->ignore(); +} + +void QDesignerMenuBar::updateCurrentAction(bool selectAction) +{ + update(); + + if (!selectAction) + return; + + QAction *action = currentAction(); + if (!action || action == m_addMenu) + return; + + QMenu *menu = action->menu(); + if (!menu) + return; + + QDesignerObjectInspector *oi = 0; + if (QDesignerFormWindowInterface *fw = formWindow()) + oi = qobject_cast<QDesignerObjectInspector *>(fw->core()->objectInspector()); + + if (!oi) + return; + + oi->clearSelection(); + oi->selectObject(menu); +} + +QT_END_NAMESPACE |