/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Designer of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage ** 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.1, 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. ** ** Other Usage ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qdesigner_taskmenu_p.h" #include "qdesigner_command_p.h" #include "qdesigner_command2_p.h" #include "richtexteditor_p.h" #include "plaintexteditor_p.h" #include "stylesheeteditor_p.h" #include "qlayout_widget_p.h" #include "layout_p.h" #include "spacer_widget_p.h" #include "textpropertyeditor_p.h" #include "promotiontaskmenu_p.h" #include "metadatabase_p.h" #include "scriptdialog_p.h" #include "scriptcommand_p.h" #include "signalslotdialog_p.h" #include "qdesigner_membersheet_p.h" #include "qdesigner_propertycommand_p.h" #include "qdesigner_utils_p.h" #include "qdesigner_objectinspector_p.h" #include "morphmenu_p.h" #include "qdesigner_integration_p.h" #include "formlayoutmenu_p.h" #include "ui_selectsignaldialog.h" #include "widgetfactory_p.h" #include "abstractintrospection_p.h" #include "widgetdatabase_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE static QMenuBar *findMenuBar(const QWidget *widget) { const QList children = widget->children(); foreach (QObject *obj, widget->children()) { if (QMenuBar *mb = qobject_cast(obj)) { return mb; } } return 0; } static QStatusBar *findStatusBar(const QWidget *widget) { const QList children = widget->children(); foreach (QObject *obj, widget->children()) { if (QStatusBar *sb = qobject_cast(obj)) { return sb; } } return 0; } static inline QAction *createSeparatorHelper(QObject *parent) { QAction *rc = new QAction(parent); rc->setSeparator(true); return rc; } static inline qdesigner_internal::QDesignerIntegration *integration(const QDesignerFormEditorInterface *core) { return qobject_cast(core->integration()); } static QString objName(const QDesignerFormEditorInterface *core, QObject *object) { QDesignerPropertySheetExtension *sheet = qt_extension(core->extensionManager(), object); Q_ASSERT(sheet != 0); const QString objectNameProperty = QLatin1String("objectName"); const int index = sheet->indexOf(objectNameProperty); const qdesigner_internal::PropertySheetStringValue objectNameValue = qvariant_cast(sheet->property(index)); return objectNameValue.value(); } enum { ApplyMinimumWidth = 0x1, ApplyMinimumHeight = 0x2, ApplyMaximumWidth = 0x4, ApplyMaximumHeight = 0x8 }; namespace { // --------------- ObjectNameDialog class ObjectNameDialog : public QDialog { public: ObjectNameDialog(QWidget *parent, const QString &oldName); QString newObjectName() const; private: qdesigner_internal::TextPropertyEditor *m_editor; }; ObjectNameDialog::ObjectNameDialog(QWidget *parent, const QString &oldName) : QDialog(parent), m_editor( new qdesigner_internal::TextPropertyEditor(this, qdesigner_internal::TextPropertyEditor::EmbeddingNone, qdesigner_internal::ValidationObjectName)) { setWindowTitle(QCoreApplication::translate("ObjectNameDialog", "Change Object Name")); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); QVBoxLayout *vboxLayout = new QVBoxLayout(this); vboxLayout->addWidget(new QLabel(QCoreApplication::translate("ObjectNameDialog", "Object Name"))); m_editor->setText(oldName); m_editor->selectAll(); m_editor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); vboxLayout->addWidget(m_editor); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); vboxLayout->addWidget(buttonBox); connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); } QString ObjectNameDialog::newObjectName() const { return m_editor->text(); } } // namespace namespace qdesigner_internal { // Sub menu displaying the alignment options of a widget in a managed // grid/box layout cell. class LayoutAlignmentMenu { public: explicit LayoutAlignmentMenu(QObject *parent); QAction *subMenuAction() const { return m_subMenuAction; } void connect(QObject *receiver, const char *aSlot); // Set up enabled state and checked actions according to widget (managed box/grid) bool setAlignment(const QDesignerFormEditorInterface *core, QWidget *w); // Return the currently checked alignment Qt::Alignment alignment() const; private: enum Actions { HorizNone, Left, HorizCenter, Right, VerticalNone, Top, VerticalCenter, Bottom }; static QAction *createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag); QAction *m_subMenuAction; QActionGroup *m_horizGroup; QActionGroup *m_verticalGroup; QAction *m_actions[Bottom + 1]; }; QAction *LayoutAlignmentMenu::createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag) { QAction * a = new QAction(text, 0); a->setCheckable(true); a->setData(QVariant(data)); menu->addAction(a); ag->addAction(a); return a; } LayoutAlignmentMenu::LayoutAlignmentMenu(QObject *parent) : m_subMenuAction(new QAction(QDesignerTaskMenu::tr("Layout Alignment"), parent)), m_horizGroup(new QActionGroup(parent)), m_verticalGroup(new QActionGroup(parent)) { m_horizGroup->setExclusive(true); m_verticalGroup->setExclusive(true); QMenu *menu = new QMenu; m_subMenuAction->setMenu(menu); m_actions[HorizNone] = createAction(QDesignerTaskMenu::tr("No Horizontal Alignment"), 0, menu, m_horizGroup); m_actions[Left] = createAction(QDesignerTaskMenu::tr("Left"), Qt::AlignLeft, menu, m_horizGroup); m_actions[HorizCenter] = createAction(QDesignerTaskMenu::tr("Center Horizontally"), Qt::AlignHCenter, menu, m_horizGroup); m_actions[Right] = createAction(QDesignerTaskMenu::tr("Right"), Qt::AlignRight, menu, m_horizGroup); menu->addSeparator(); m_actions[VerticalNone] = createAction(QDesignerTaskMenu::tr("No Vertical Alignment"), 0, menu, m_verticalGroup); m_actions[Top] = createAction(QDesignerTaskMenu::tr("Top"), Qt::AlignTop, menu, m_verticalGroup); m_actions[VerticalCenter] = createAction(QDesignerTaskMenu::tr("Center Vertically"), Qt::AlignVCenter, menu, m_verticalGroup); m_actions[Bottom] = createAction(QDesignerTaskMenu::tr("Bottom"), Qt::AlignBottom, menu, m_verticalGroup); } void LayoutAlignmentMenu::connect(QObject *receiver, const char *aSlot) { QObject::connect(m_horizGroup, SIGNAL(triggered(QAction*)), receiver, aSlot); QObject::connect(m_verticalGroup, SIGNAL(triggered(QAction*)), receiver, aSlot); } bool LayoutAlignmentMenu::setAlignment(const QDesignerFormEditorInterface *core, QWidget *w) { bool enabled; const Qt::Alignment alignment = LayoutAlignmentCommand::alignmentOf(core, w, &enabled); if (!enabled) { m_subMenuAction->setEnabled(false); m_actions[HorizNone]->setChecked(true); m_actions[VerticalNone]->setChecked(true); return false; } // Get alignment switch (alignment & Qt::AlignHorizontal_Mask) { case Qt::AlignLeft: m_actions[Left]->setChecked(true); break; case Qt::AlignHCenter: m_actions[HorizCenter]->setChecked(true); break; case Qt::AlignRight: m_actions[Right]->setChecked(true); break; default: m_actions[HorizNone]->setChecked(true); break; } switch (alignment & Qt::AlignVertical_Mask) { case Qt::AlignTop: m_actions[Top]->setChecked(true); break; case Qt::AlignVCenter: m_actions[VerticalCenter]->setChecked(true); break; case Qt::AlignBottom: m_actions[Bottom]->setChecked(true); break; default: m_actions[VerticalNone]->setChecked(true); break; } return true; } Qt::Alignment LayoutAlignmentMenu::alignment() const { Qt::Alignment alignment = 0; if (const QAction *horizAction = m_horizGroup->checkedAction()) if (const int horizAlign = horizAction->data().toInt()) alignment |= static_cast(horizAlign); if (const QAction *vertAction = m_verticalGroup->checkedAction()) if (const int vertAlign = vertAction->data().toInt()) alignment |= static_cast(vertAlign); return alignment; } // -------------- QDesignerTaskMenuPrivate class QDesignerTaskMenuPrivate { public: QDesignerTaskMenuPrivate(QWidget *widget, QObject *parent); QDesignerTaskMenu *m_q; QPointer m_widget; QAction *m_separator; QAction *m_separator2; QAction *m_separator3; QAction *m_separator4; QAction *m_separator5; QAction *m_separator6; QAction *m_separator7; QAction *m_changeObjectNameAction; QAction *m_changeToolTip; QAction *m_changeWhatsThis; QAction *m_changeStyleSheet; MorphMenu *m_morphMenu; FormLayoutMenu *m_formLayoutMenu; QAction *m_addMenuBar; QAction *m_addToolBar; QAction *m_addStatusBar; QAction *m_removeStatusBar; QAction *m_changeScript; QAction *m_containerFakeMethods; QAction *m_navigateToSlot; PromotionTaskMenu* m_promotionTaskMenu; QActionGroup *m_sizeActionGroup; LayoutAlignmentMenu m_layoutAlignmentMenu; QAction *m_sizeActionsSubMenu; }; QDesignerTaskMenuPrivate::QDesignerTaskMenuPrivate(QWidget *widget, QObject *parent) : m_q(0), m_widget(widget), m_separator(createSeparatorHelper(parent)), m_separator2(createSeparatorHelper(parent)), m_separator3(createSeparatorHelper(parent)), m_separator4(createSeparatorHelper(parent)), m_separator5(createSeparatorHelper(parent)), m_separator6(createSeparatorHelper(parent)), m_separator7(createSeparatorHelper(parent)), m_changeObjectNameAction(new QAction(QDesignerTaskMenu::tr("Change objectName..."), parent)), m_changeToolTip(new QAction(QDesignerTaskMenu::tr("Change toolTip..."), parent)), m_changeWhatsThis(new QAction(QDesignerTaskMenu::tr("Change whatsThis..."), parent)), m_changeStyleSheet(new QAction(QDesignerTaskMenu::tr("Change styleSheet..."), parent)), m_morphMenu(new MorphMenu(parent)), m_formLayoutMenu(new FormLayoutMenu(parent)), m_addMenuBar(new QAction(QDesignerTaskMenu::tr("Create Menu Bar"), parent)), m_addToolBar(new QAction(QDesignerTaskMenu::tr("Add Tool Bar"), parent)), m_addStatusBar(new QAction(QDesignerTaskMenu::tr("Create Status Bar"), parent)), m_removeStatusBar(new QAction(QDesignerTaskMenu::tr("Remove Status Bar"), parent)), m_changeScript(new QAction(QDesignerTaskMenu::tr("Change script..."), parent)), m_containerFakeMethods(new QAction(QDesignerTaskMenu::tr("Change signals/slots..."), parent)), m_navigateToSlot(new QAction(QDesignerTaskMenu::tr("Go to slot..."), parent)), m_promotionTaskMenu(new PromotionTaskMenu(widget, PromotionTaskMenu::ModeManagedMultiSelection, parent)), m_sizeActionGroup(new QActionGroup(parent)), m_layoutAlignmentMenu(parent), m_sizeActionsSubMenu(new QAction(QDesignerTaskMenu::tr("Size Constraints"), parent)) { QMenu *sizeMenu = new QMenu; m_sizeActionsSubMenu->setMenu(sizeMenu); QAction *sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Width")); sizeAction->setData(ApplyMinimumWidth); sizeMenu->addAction(sizeAction); sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Height")); sizeAction->setData(ApplyMinimumHeight); sizeMenu->addAction(sizeAction); sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Size")); sizeAction->setData(ApplyMinimumWidth|ApplyMinimumHeight); sizeMenu->addAction(sizeAction); sizeMenu->addSeparator(); sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Width")); sizeAction->setData(ApplyMaximumWidth); sizeMenu->addAction(sizeAction); sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Height")); sizeAction->setData(ApplyMaximumHeight); sizeMenu->addAction(sizeAction); sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Size")); sizeAction->setData(ApplyMaximumWidth|ApplyMaximumHeight); sizeMenu->addAction(sizeAction); } // --------- QDesignerTaskMenu QDesignerTaskMenu::QDesignerTaskMenu(QWidget *widget, QObject *parent) : QObject(parent), d(new QDesignerTaskMenuPrivate(widget, parent)) { d->m_q = this; Q_ASSERT(qobject_cast(widget) == 0); connect(d->m_changeObjectNameAction, SIGNAL(triggered()), this, SLOT(changeObjectName())); connect(d->m_changeToolTip, SIGNAL(triggered()), this, SLOT(changeToolTip())); connect(d->m_changeWhatsThis, SIGNAL(triggered()), this, SLOT(changeWhatsThis())); connect(d->m_changeStyleSheet, SIGNAL(triggered()), this, SLOT(changeStyleSheet())); connect(d->m_addMenuBar, SIGNAL(triggered()), this, SLOT(createMenuBar())); connect(d->m_addToolBar, SIGNAL(triggered()), this, SLOT(addToolBar())); connect(d->m_addStatusBar, SIGNAL(triggered()), this, SLOT(createStatusBar())); connect(d->m_removeStatusBar, SIGNAL(triggered()), this, SLOT(removeStatusBar())); connect(d->m_changeScript, SIGNAL(triggered()), this, SLOT(changeScript())); connect(d->m_containerFakeMethods, SIGNAL(triggered()), this, SLOT(containerFakeMethods())); connect(d->m_navigateToSlot, SIGNAL(triggered()), this, SLOT(slotNavigateToSlot())); connect(d->m_sizeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(applySize(QAction*))); d->m_layoutAlignmentMenu.connect(this, SLOT(slotLayoutAlignment())); } QDesignerTaskMenu::~QDesignerTaskMenu() { delete d; } QAction *QDesignerTaskMenu::createSeparator() { return createSeparatorHelper(this); } QWidget *QDesignerTaskMenu::widget() const { return d->m_widget; } QDesignerFormWindowInterface *QDesignerTaskMenu::formWindow() const { QDesignerFormWindowInterface *result = QDesignerFormWindowInterface::findFormWindow(widget()); Q_ASSERT(result != 0); return result; } void QDesignerTaskMenu::createMenuBar() { if (QDesignerFormWindowInterface *fw = formWindow()) { QMainWindow *mw = qobject_cast(fw->mainContainer()); if (!mw) { // ### warning message return; } CreateMenuBarCommand *cmd = new CreateMenuBarCommand(fw); cmd->init(mw); fw->commandHistory()->push(cmd); } } void QDesignerTaskMenu::addToolBar() { if (QDesignerFormWindowInterface *fw = formWindow()) { QMainWindow *mw = qobject_cast(fw->mainContainer()); if (!mw) { // ### warning message return; } AddToolBarCommand *cmd = new AddToolBarCommand(fw); cmd->init(mw); fw->commandHistory()->push(cmd); } } void QDesignerTaskMenu::createStatusBar() { if (QDesignerFormWindowInterface *fw = formWindow()) { QMainWindow *mw = qobject_cast(fw->mainContainer()); if (!mw) { // ### warning message return; } CreateStatusBarCommand *cmd = new CreateStatusBarCommand(fw); cmd->init(mw); fw->commandHistory()->push(cmd); } } void QDesignerTaskMenu::removeStatusBar() { if (QDesignerFormWindowInterface *fw = formWindow()) { QMainWindow *mw = qobject_cast(fw->mainContainer()); if (!mw) { // ### warning message return; } DeleteStatusBarCommand *cmd = new DeleteStatusBarCommand(fw); cmd->init(findStatusBar(mw)); fw->commandHistory()->push(cmd); } } QList QDesignerTaskMenu::taskActions() const { QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(widget()); Q_ASSERT(formWindow); const bool isMainContainer = formWindow->mainContainer() == widget(); QList actions; if (const QMainWindow *mw = qobject_cast(formWindow->mainContainer())) { if (isMainContainer || mw->centralWidget() == widget()) { if (!findMenuBar(mw)) { actions.append(d->m_addMenuBar); } actions.append(d->m_addToolBar); // ### create the status bar if (!findStatusBar(mw)) actions.append(d->m_addStatusBar); else actions.append(d->m_removeStatusBar); actions.append(d->m_separator); } } actions.append(d->m_changeObjectNameAction); d->m_morphMenu->populate(d->m_widget, formWindow, actions); d->m_formLayoutMenu->populate(d->m_widget, formWindow, actions); actions.append(d->m_separator2); actions.append(d->m_changeToolTip); actions.append(d->m_changeWhatsThis); actions.append(d->m_changeStyleSheet); actions.append(d->m_separator6); actions.append(d->m_sizeActionsSubMenu); if (d->m_layoutAlignmentMenu.setAlignment(formWindow->core(), d->m_widget)) actions.append(d->m_layoutAlignmentMenu.subMenuAction()); d->m_promotionTaskMenu->setMode(formWindow->isManaged(d->m_widget) ? PromotionTaskMenu::ModeManagedMultiSelection : PromotionTaskMenu::ModeUnmanagedMultiSelection); d->m_promotionTaskMenu->addActions(formWindow, PromotionTaskMenu::LeadingSeparator, actions); #ifdef WANT_SCRIPT_OPTION if (!isMainContainer) { actions.append(d->m_separator4); actions.append(d->m_changeScript); } #endif if (isMainContainer && !qt_extension(formWindow->core()->extensionManager(), formWindow->core())) { actions.append(d->m_separator5); actions.append(d->m_containerFakeMethods); } if (isSlotNavigationEnabled(formWindow->core())) { actions.append(d->m_separator7); actions.append(d->m_navigateToSlot); } return actions; } void QDesignerTaskMenu::changeObjectName() { QDesignerFormWindowInterface *fw = formWindow(); Q_ASSERT(fw != 0); const QString oldObjectName = objName(fw->core(), widget()); ObjectNameDialog dialog(fw, oldObjectName); if (dialog.exec() == QDialog::Accepted) { const QString newObjectName = dialog.newObjectName(); if (!newObjectName.isEmpty() && newObjectName != oldObjectName ) { const QString objectNameProperty = QLatin1String("objectName"); PropertySheetStringValue objectNameValue; objectNameValue.setValue(newObjectName); setProperty(fw, CurrentWidgetMode, objectNameProperty, QVariant::fromValue(objectNameValue)); } } } void QDesignerTaskMenu::changeTextProperty(const QString &propertyName, const QString &windowTitle, PropertyMode pm, Qt::TextFormat desiredFormat) { QDesignerFormWindowInterface *fw = formWindow(); if (!fw) return; Q_ASSERT(d->m_widget->parentWidget() != 0); const QDesignerPropertySheetExtension *sheet = qt_extension(fw->core()->extensionManager(), d->m_widget); const int index = sheet->indexOf(propertyName); if (index == -1) { qDebug() << "** WARNING Invalid property" << propertyName << " passed to changeTextProperty!"; return; } PropertySheetStringValue textValue = qvariant_cast(sheet->property(index)); const QString oldText = textValue.value(); // Pop up respective dialog bool accepted = false; QString newText; switch (desiredFormat) { case Qt::PlainText: { PlainTextEditorDialog dlg(fw->core(), fw); if (!windowTitle.isEmpty()) dlg.setWindowTitle(windowTitle); dlg.setDefaultFont(d->m_widget->font()); dlg.setText(oldText); accepted = dlg.showDialog() == QDialog::Accepted; newText = dlg.text(); } break; default: { RichTextEditorDialog dlg(fw->core(), fw); if (!windowTitle.isEmpty()) dlg.setWindowTitle(windowTitle); dlg.setDefaultFont(d->m_widget->font()); dlg.setText(oldText); accepted = dlg.showDialog() == QDialog::Accepted; newText = dlg.text(desiredFormat); } break; } // change property if (!accepted || oldText == newText) return; textValue.setValue(newText); setProperty(fw, pm, propertyName, QVariant::fromValue(textValue)); } void QDesignerTaskMenu::changeToolTip() { changeTextProperty(QLatin1String("toolTip"), tr("Edit ToolTip"), MultiSelectionMode, Qt::AutoText); } void QDesignerTaskMenu::changeWhatsThis() { changeTextProperty(QLatin1String("whatsThis"), tr("Edit WhatsThis"), MultiSelectionMode, Qt::AutoText); } void QDesignerTaskMenu::changeStyleSheet() { if (QDesignerFormWindowInterface *fw = formWindow()) { StyleSheetPropertyEditorDialog dlg(fw, fw, d->m_widget); dlg.exec(); } } void QDesignerTaskMenu::changeScript() { QDesignerFormWindowInterface *fw = formWindow(); if (!fw) return; MetaDataBase *metaDataBase = qobject_cast(fw->core()->metaDataBase()); if (!metaDataBase) return; const MetaDataBaseItem* item = metaDataBase->metaDataBaseItem(d->m_widget); if (!item) return; const QString oldScript = item->script(); QString newScript = oldScript; ScriptDialog scriptDialog(fw->core()->dialogGui(), fw); if (!scriptDialog.editScript(newScript)) return; // compile list of selected objects ScriptCommand *scriptCommand = new ScriptCommand(fw); if (!scriptCommand->init(applicableObjects(fw, MultiSelectionMode), newScript)) { delete scriptCommand; return; } fw->commandHistory()->push(scriptCommand); } void QDesignerTaskMenu::containerFakeMethods() { QDesignerFormWindowInterface *fw = formWindow(); if (!fw) return; SignalSlotDialog::editMetaDataBase(fw, d->m_widget, fw); } static QString declaredInClass(const QDesignerMetaObjectInterface *metaObject, const QString &member) { // Find class whose superclass does not contain the method. const QDesignerMetaObjectInterface *meta = metaObject; for (;;) { const QDesignerMetaObjectInterface *tmpMeta = meta->superClass(); if (tmpMeta == 0) break; if (tmpMeta->indexOfMethod(member) == -1) break; meta = tmpMeta; } return meta->className(); } bool QDesignerTaskMenu::isSlotNavigationEnabled(const QDesignerFormEditorInterface *core) { if (QDesignerIntegration *integr = integration(core)) return integr->isSlotNavigationEnabled(); return false; } void QDesignerTaskMenu::slotNavigateToSlot() { QDesignerFormEditorInterface *core = formWindow()->core(); Q_ASSERT(core); navigateToSlot(core, widget()); } void QDesignerTaskMenu::navigateToSlot(QDesignerFormEditorInterface *core, QObject *object, const QString &defaultSignal) { const QString objectName = objName(core, object); QMap > classToSignalList; QDesignerIntegration *integr = integration(core); // "real" signals if (const QDesignerMetaObjectInterface *metaObject = core->introspection()->metaObject(object)) { const int methodCount = metaObject->methodCount(); for (int i = 0; i < methodCount; ++i) { const QDesignerMetaMethodInterface *metaMethod = metaObject->method(i); if (metaMethod->methodType() == QDesignerMetaMethodInterface::Signal) { const QString signature = metaMethod->signature(); const QStringList parameterNames = metaMethod->parameterNames(); classToSignalList[declaredInClass(metaObject, signature)][signature] = parameterNames; } } } // fake signals if (qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast(core->metaDataBase())) { qdesigner_internal::MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(object); Q_ASSERT(item); const QStringList fakeSignals = item->fakeSignals(); foreach (const QString &fakeSignal, fakeSignals) classToSignalList[item->customClassName()][fakeSignal] = QStringList(); } if (object->isWidgetType()) { QWidget *widget = static_cast(object); if (WidgetDataBase *db = qobject_cast(core->widgetDataBase())) { const QString promotedClassName = promotedCustomClassName(core, widget); const int index = core->widgetDataBase()->indexOfClassName(promotedClassName); if (index >= 0) { WidgetDataBaseItem* item = static_cast(db->item(index)); const QStringList fakeSignals = item->fakeSignals(); foreach (const QString &fakeSignal, fakeSignals) classToSignalList[promotedClassName][fakeSignal] = QStringList(); } } } Ui::SelectSignalDialog dialogUi; QDialog selectSignalDialog(0, Qt::WindowTitleHint | Qt::WindowSystemMenuHint); dialogUi.setupUi(&selectSignalDialog); QMap >::const_iterator iter(classToSignalList.constBegin()); for (; iter != classToSignalList.constEnd(); ++iter) { const QString className = iter.key(); QMap signalNames = iter.value(); QMap::const_iterator itSignal(signalNames.constBegin()); for (; itSignal != signalNames.constEnd(); ++itSignal) { const QString signalName = itSignal.key(); QTreeWidgetItem *row = new QTreeWidgetItem(QStringList() << signalName << className); row->setData(0, Qt::UserRole, itSignal.value()); dialogUi.signalList->addTopLevelItem(row); } } if (dialogUi.signalList->topLevelItemCount() == 0) { QTreeWidgetItem *row = new QTreeWidgetItem(QStringList() << tr("no signals available")); dialogUi.signalList->addTopLevelItem(row); dialogUi.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); } else { connect(dialogUi.signalList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), &selectSignalDialog, SLOT(accept())); } if (defaultSignal.isEmpty()) { dialogUi.signalList->setCurrentItem(dialogUi.signalList->topLevelItem(0)); } else { const QList items = dialogUi.signalList->findItems (defaultSignal, Qt::MatchExactly, 0); if (!items.empty()) dialogUi.signalList->setCurrentItem(items.front()); } dialogUi.signalList->resizeColumnToContents(0); if (selectSignalDialog.exec() == QDialog::Accepted) { QTreeWidgetItem *selectedItem = dialogUi.signalList->selectedItems().first(); const QString signalSignature = selectedItem->text(0); const QStringList parameterNames = qvariant_cast(selectedItem->data(0, Qt::UserRole)); // TODO: Check whether signal is connected to slot integr->emitNavigateToSlot(objectName, signalSignature, parameterNames); } } // Add a command that takes over the value of the current geometry as // minimum/maximum size according to the flags. static void createSizeCommand(QDesignerFormWindowInterface *fw, QWidget *w, int flags) { const QSize size = w->size(); if (flags & (ApplyMinimumWidth|ApplyMinimumHeight)) { QSize minimumSize = w-> minimumSize(); if (flags & ApplyMinimumWidth) minimumSize.setWidth(size.width()); if (flags & ApplyMinimumHeight) minimumSize.setHeight(size.height()); SetPropertyCommand* cmd = new SetPropertyCommand(fw); cmd->init(w, QLatin1String("minimumSize"), minimumSize); fw->commandHistory()->push(cmd); } if (flags & (ApplyMaximumWidth|ApplyMaximumHeight)) { QSize maximumSize = w-> maximumSize(); if (flags & ApplyMaximumWidth) maximumSize.setWidth(size.width()); if (flags & ApplyMaximumHeight) maximumSize.setHeight(size.height()); SetPropertyCommand* cmd = new SetPropertyCommand(fw); cmd->init(w, QLatin1String("maximumSize"), maximumSize); fw->commandHistory()->push(cmd); } } void QDesignerTaskMenu::applySize(QAction *a) { QDesignerFormWindowInterface *fw = formWindow(); if (!fw) return; const QWidgetList selection = applicableWidgets(fw, MultiSelectionMode); if (selection.isEmpty()) return; const int mask = a->data().toInt(); const int size = selection.size(); fw->commandHistory()->beginMacro(tr("Set size constraint on %n widget(s)", 0, size)); for (int i = 0; i < size; i++) createSizeCommand(fw, selection.at(i), mask); fw->commandHistory()->endMacro(); } template static void getApplicableObjects(const QDesignerFormWindowInterface *fw, QWidget *current, QDesignerTaskMenu::PropertyMode pm, Container *c) { // Current is always first c->push_back(current); if (pm == QDesignerTaskMenu::CurrentWidgetMode) return; QDesignerObjectInspector *designerObjectInspector = qobject_cast(fw->core()->objectInspector()); if (!designerObjectInspector) return; // Ooops, someone plugged an old-style Object Inspector // Add managed or unmanaged selection according to current type, make current first Selection s; designerObjectInspector->getSelection(s); const QWidgetList &source = fw->isManaged(current) ? s.managed : s.unmanaged; const QWidgetList::const_iterator cend = source.constEnd(); for ( QWidgetList::const_iterator it = source.constBegin(); it != cend; ++it) if (*it != current) // was first c->push_back(*it); } QObjectList QDesignerTaskMenu::applicableObjects(const QDesignerFormWindowInterface *fw, PropertyMode pm) const { QObjectList rc; getApplicableObjects(fw, d->m_widget, pm, &rc); return rc; } QWidgetList QDesignerTaskMenu::applicableWidgets(const QDesignerFormWindowInterface *fw, PropertyMode pm) const { QWidgetList rc; getApplicableObjects(fw, d->m_widget, pm, &rc); return rc; } void QDesignerTaskMenu::setProperty(QDesignerFormWindowInterface *fw, PropertyMode pm, const QString &name, const QVariant &newValue) { SetPropertyCommand* setPropertyCommand = new SetPropertyCommand(fw); if (setPropertyCommand->init(applicableObjects(fw, pm), name, newValue, d->m_widget)) { fw->commandHistory()->push(setPropertyCommand); } else { delete setPropertyCommand; qDebug() << "Unable to set property " << name << '.'; } } void QDesignerTaskMenu::slotLayoutAlignment() { QDesignerFormWindowInterface *fw = formWindow(); const Qt::Alignment newAlignment = d->m_layoutAlignmentMenu.alignment(); LayoutAlignmentCommand *cmd = new LayoutAlignmentCommand(fw); if (cmd->init(d->m_widget, newAlignment)) { fw->commandHistory()->push(cmd); } else { delete cmd; } } } // namespace qdesigner_internal QT_END_NAMESPACE