diff options
author | Daniel Teske <daniel.teske@digia.com> | 2012-09-20 14:42:57 +0200 |
---|---|---|
committer | Daniel Teske <daniel.teske@digia.com> | 2012-09-28 12:49:57 +0200 |
commit | 733d5612fb7c1558ad0e28ebe2e2dd93477d07ed (patch) | |
tree | 0fa4c3d357a931ac11ba0afb4641fd36eeaa77b4 /src/plugins/projectexplorer | |
parent | d7993c717d08e2884963340d9017156b54b44c05 (diff) | |
download | qt-creator-733d5612fb7c1558ad0e28ebe2e2dd93477d07ed.tar.gz |
Change and Clone kit functionality
Change-Id: Ibdab8d9076d2f9c002cb69ad81809929c8697355
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
Diffstat (limited to 'src/plugins/projectexplorer')
17 files changed, 461 insertions, 88 deletions
diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index 2a13c26c10..eee87cbbc3 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -282,6 +282,7 @@ IBuildConfigurationFactory::IBuildConfigurationFactory(QObject *parent) : IBuildConfigurationFactory::~IBuildConfigurationFactory() { } +// restore IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, const QVariantMap &map) { QList<IBuildConfigurationFactory *> factories @@ -293,6 +294,7 @@ IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, con return 0; } +// create IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent) { QList<IBuildConfigurationFactory *> factories @@ -304,4 +306,15 @@ IBuildConfigurationFactory * IBuildConfigurationFactory::find(Target *parent) return 0; } +// clone +IBuildConfigurationFactory *IBuildConfigurationFactory::find(Target *parent, BuildConfiguration *bc) +{ + QList<IBuildConfigurationFactory *> factories + = ExtensionSystem::PluginManager::instance()->getObjects<IBuildConfigurationFactory>(); + foreach (IBuildConfigurationFactory *factory, factories) { + if (factory->canClone(parent, bc)) + return factory; + } + return 0; +} } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index be8e034e51..cb7ad748d9 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -145,6 +145,7 @@ public: static IBuildConfigurationFactory *find(Target *parent, const QVariantMap &map); static IBuildConfigurationFactory *find(Target *parent); + static IBuildConfigurationFactory *find(Target *parent, BuildConfiguration *bc); signals: void availableCreationIdsChanged(); diff --git a/src/plugins/projectexplorer/deployconfiguration.cpp b/src/plugins/projectexplorer/deployconfiguration.cpp index f5db9d320b..2c0796381a 100644 --- a/src/plugins/projectexplorer/deployconfiguration.cpp +++ b/src/plugins/projectexplorer/deployconfiguration.cpp @@ -65,7 +65,8 @@ DeployConfiguration::DeployConfiguration(Target *target, const Core::Id id) : } DeployConfiguration::DeployConfiguration(Target *target, DeployConfiguration *source) : - ProjectConfiguration(target, source) + ProjectConfiguration(target, source), + m_stepList(0) { Q_ASSERT(target); // Do not clone stepLists here, do that in the derived constructor instead @@ -256,6 +257,17 @@ DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent) return 0; } +DeployConfigurationFactory *DeployConfigurationFactory::find(Target *parent, DeployConfiguration *dc) +{ + QList<DeployConfigurationFactory *> factories + = ExtensionSystem::PluginManager::instance()->getObjects<DeployConfigurationFactory>(); + foreach (DeployConfigurationFactory *factory, factories) { + if (factory->canClone(parent, dc)) + return factory; + } + return 0; +} + bool DeployConfigurationFactory::canHandle(Target *parent) const { if (!parent->project()->supportsKit(parent->kit())) diff --git a/src/plugins/projectexplorer/deployconfiguration.h b/src/plugins/projectexplorer/deployconfiguration.h index 49482879dc..a5bef294d8 100644 --- a/src/plugins/projectexplorer/deployconfiguration.h +++ b/src/plugins/projectexplorer/deployconfiguration.h @@ -114,6 +114,7 @@ public: static DeployConfigurationFactory *find(Target *parent, const QVariantMap &map); static DeployConfigurationFactory *find(Target *parent); + static DeployConfigurationFactory *find(Target *parent, DeployConfiguration *dc); signals: void availableCreationIdsChanged(); diff --git a/src/plugins/projectexplorer/images/targetchangebutton.png b/src/plugins/projectexplorer/images/targetchangebutton.png Binary files differnew file mode 100644 index 0000000000..1311d38ef8 --- /dev/null +++ b/src/plugins/projectexplorer/images/targetchangebutton.png diff --git a/src/plugins/projectexplorer/images/targetchangebutton2.png b/src/plugins/projectexplorer/images/targetchangebutton2.png Binary files differnew file mode 100644 index 0000000000..d5d5cfefd9 --- /dev/null +++ b/src/plugins/projectexplorer/images/targetchangebutton2.png diff --git a/src/plugins/projectexplorer/images/targetremovebutton.png b/src/plugins/projectexplorer/images/targetremovebutton.png Binary files differdeleted file mode 100644 index 15e8502ccf..0000000000 --- a/src/plugins/projectexplorer/images/targetremovebutton.png +++ /dev/null diff --git a/src/plugins/projectexplorer/images/targetremovebuttondark.png b/src/plugins/projectexplorer/images/targetremovebuttondark.png Binary files differdeleted file mode 100644 index c1ec33f910..0000000000 --- a/src/plugins/projectexplorer/images/targetremovebuttondark.png +++ /dev/null diff --git a/src/plugins/projectexplorer/projectexplorer.qrc b/src/plugins/projectexplorer/projectexplorer.qrc index b36371d106..85ea369bbe 100644 --- a/src/plugins/projectexplorer/projectexplorer.qrc +++ b/src/plugins/projectexplorer/projectexplorer.qrc @@ -40,7 +40,7 @@ <file>images/unconfigured.png</file> <file>images/targetleftbutton.png</file> <file>images/targetrightbutton.png</file> - <file>images/targetremovebutton.png</file> - <file>images/targetremovebuttondark.png</file> + <file>images/targetchangebutton.png</file> + <file>images/targetchangebutton2.png</file> </qresource> </RCC> diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index c178451842..4dd89915d5 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -123,16 +123,17 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(RunConfiguration m_suppressQmlDebuggingSpinbox(false) {} -DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(DebuggerRunConfigurationAspect *other) : - m_runConfiguration(other->m_runConfiguration), - m_useCppDebugger(other->m_useCppDebugger), - m_useQmlDebugger(other->m_useQmlDebugger), - m_qmlDebugServerPort(other->m_qmlDebugServerPort), - m_useMultiProcess(other->m_useMultiProcess), - m_suppressDisplay(other->m_suppressDisplay), - m_suppressQmlDebuggingOptions(other->m_suppressQmlDebuggingOptions), - m_suppressCppDebuggingOptions(other->m_suppressCppDebuggingOptions), - m_suppressQmlDebuggingSpinbox(other->m_suppressQmlDebuggingSpinbox) +DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration, + DebuggerRunConfigurationAspect *other) + : m_runConfiguration(runConfiguration), + m_useCppDebugger(other->m_useCppDebugger), + m_useQmlDebugger(other->m_useQmlDebugger), + m_qmlDebugServerPort(other->m_qmlDebugServerPort), + m_useMultiProcess(other->m_useMultiProcess), + m_suppressDisplay(other->m_suppressDisplay), + m_suppressQmlDebuggingOptions(other->m_suppressQmlDebuggingOptions), + m_suppressCppDebuggingOptions(other->m_suppressCppDebuggingOptions), + m_suppressQmlDebuggingSpinbox(other->m_suppressQmlDebuggingSpinbox) {} RunConfiguration *DebuggerRunConfigurationAspect::runConfiguration() @@ -284,10 +285,18 @@ RunConfiguration::RunConfiguration(Target *target, const Core::Id id) : RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) : ProjectConfiguration(target, source), - m_debuggerAspect(new DebuggerRunConfigurationAspect(source->debuggerAspect())) + m_debuggerAspect(new DebuggerRunConfigurationAspect(this, source->debuggerAspect())) { Q_ASSERT(target); - addExtraAspects(); + QList<IRunControlFactory *> factories = ExtensionSystem::PluginManager::getObjects<IRunControlFactory>(); + foreach (IRunConfigurationAspect *aspect, source->m_aspects) { + foreach (IRunControlFactory *factory, factories) { + if (IRunConfigurationAspect *clone = factory->cloneRunConfigurationAspect(aspect)) { + m_aspects.append(clone); + break; + } + } + } } RunConfiguration::~RunConfiguration() @@ -455,6 +464,17 @@ IRunConfigurationFactory *IRunConfigurationFactory::find(Target *parent, const Q return 0; } +IRunConfigurationFactory *IRunConfigurationFactory::find(Target *parent, RunConfiguration *rc) +{ + QList<IRunConfigurationFactory *> factories + = ExtensionSystem::PluginManager::instance()->getObjects<IRunConfigurationFactory>(); + foreach (IRunConfigurationFactory *factory, factories) { + if (factory->canClone(parent, rc)) + return factory; + } + return 0; +} + QList<IRunConfigurationFactory *> IRunConfigurationFactory::find(Target *parent) { QList<IRunConfigurationFactory *> factories @@ -505,6 +525,11 @@ IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect() return 0; } +IRunConfigurationAspect *IRunControlFactory::cloneRunConfigurationAspect(IRunConfigurationAspect *source) +{ + return 0; +} + RunConfigWidget *IRunControlFactory::createConfigurationWidget(RunConfiguration *) { return 0; diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 05e6b9163c..337a1d0846 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -91,7 +91,7 @@ class PROJECTEXPLORER_EXPORT DebuggerRunConfigurationAspect public: DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration); - DebuggerRunConfigurationAspect(DebuggerRunConfigurationAspect *other); + DebuggerRunConfigurationAspect(RunConfiguration *runConfiguration, DebuggerRunConfigurationAspect *other); enum QmlDebuggerStatus { DisableQmlDebugger = 0, @@ -214,6 +214,7 @@ public: virtual RunConfiguration *clone(Target *parent, RunConfiguration *product) = 0; static IRunConfigurationFactory *find(Target *parent, const QVariantMap &map); + static IRunConfigurationFactory *find(Target *parent, RunConfiguration *rc); static QList<IRunConfigurationFactory *> find(Target *parent); signals: @@ -235,6 +236,7 @@ public: virtual QString displayName() const = 0; virtual IRunConfigurationAspect *createRunConfigurationAspect(); + virtual IRunConfigurationAspect *cloneRunConfigurationAspect(IRunConfigurationAspect *); virtual RunConfigWidget *createConfigurationWidget(RunConfiguration *runConfiguration); }; diff --git a/src/plugins/projectexplorer/targetselector.cpp b/src/plugins/projectexplorer/targetselector.cpp index 25288ba1e4..3b5e1272a4 100644 --- a/src/plugins/projectexplorer/targetselector.cpp +++ b/src/plugins/projectexplorer/targetselector.cpp @@ -37,10 +37,41 @@ #include <QMenu> #include <QMouseEvent> #include <QFontMetrics> +#include <QPushButton> static const int TARGET_HEIGHT = 43; static const int NAVBUTTON_WIDTH = 27; +namespace ProjectExplorer { +namespace Internal { +class QPixmapButton : public QPushButton +{ +public: + QPixmapButton(QWidget *parent, const QPixmap &first, const QPixmap &second) + : QPushButton(parent), m_showFirst(true), m_first(first), m_second(second) + { + setFixedSize(m_first.size()); + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.drawPixmap(0, 0, m_showFirst ? m_first : m_second); + } + + void setFirst(bool f) + { + m_showFirst = f; + } + +private: + bool m_showFirst; + const QPixmap m_first; + const QPixmap m_second; +}; +} +} + using namespace ProjectExplorer::Internal; TargetSelector::TargetSelector(QWidget *parent) : @@ -50,11 +81,12 @@ TargetSelector::TargetSelector(QWidget *parent) : m_buildselected(QLatin1String(":/projectexplorer/images/targetbuildselected.png")), m_targetRightButton(QLatin1String(":/projectexplorer/images/targetrightbutton.png")), m_targetLeftButton(QLatin1String(":/projectexplorer/images/targetleftbutton.png")), - m_targetRemoveButton(QLatin1String(":/projectexplorer/images/targetremovebutton.png")), - m_targetRemoveDarkButton(QLatin1String(":/projectexplorer/images/targetremovebuttondark.png")), + m_targetChangePixmap(QLatin1String(":/projectexplorer/images/targetchangebutton.png")), + m_targetChangePixmap2(QLatin1String(":/projectexplorer/images/targetchangebutton2.png")), m_currentTargetIndex(-1), m_currentHoveredTargetIndex(-1), - m_startIndex(0) + m_startIndex(0), + m_menuShown(false) { QFont f = font(); f.setPixelSize(10); @@ -62,6 +94,27 @@ TargetSelector::TargetSelector(QWidget *parent) : setFont(f); setMouseTracking(true); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + m_targetChangeButton = new QPixmapButton(this, m_targetChangePixmap2, m_targetChangePixmap); + m_targetChangeButton->hide(); + connect(m_targetChangeButton, SIGNAL(pressed()), this, SLOT(changeButtonPressed())); +} + +void TargetSelector::changeButtonPressed() +{ + emit menuShown(m_currentHoveredTargetIndex); +} + +void TargetSelector::menuAboutToShow() +{ + m_menuShown = true; + updateButtons(); +} + +void TargetSelector::menuAboutToHide() +{ + m_menuShown = false; + updateButtons(); } void TargetSelector::insertTarget(int index, const QString &name) @@ -137,6 +190,25 @@ TargetSelector::Target TargetSelector::targetAt(int index) const return m_targets.at(index); } +void TargetSelector::setTargetMenu(QMenu *menu) +{ + if (m_targetChangeButton->menu()) { + disconnect(m_targetChangeButton->menu(), SIGNAL(aboutToShow()), + this, SLOT(menuAboutToShow())); + disconnect(m_targetChangeButton->menu(), SIGNAL(aboutToHide()), + this, SLOT(menuAboutToHide())); + } + + m_targetChangeButton->setMenu(menu); + + if (menu) { + connect(m_targetChangeButton->menu(), SIGNAL(aboutToShow()), + this, SLOT(menuAboutToShow())); + connect(m_targetChangeButton->menu(), SIGNAL(aboutToHide()), + this, SLOT(menuAboutToHide())); + } +} + int TargetSelector::targetWidth() const { static int width = -1; @@ -158,7 +230,7 @@ int TargetSelector::maxVisibleTargets() const return (width() - ((NAVBUTTON_WIDTH + 1) * 2 + 3))/(targetWidth() + 1); } -void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex, bool *removeButton) +void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex) { if (buttonIndex) *buttonIndex = -1; @@ -166,8 +238,6 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd *targetIndex = -1; if (targetSubIndex) *targetSubIndex = -1; - if (removeButton) - *removeButton = false; // left button? if (m_startIndex > 0 /* button visible */ && x >= 0 && x < NAVBUTTON_WIDTH + 2) { @@ -197,6 +267,7 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd } --index; tx -= targetWidth() + 1; + if (index >= 0 && index < m_targets.size()) { if (targetIndex) *targetIndex = index; @@ -210,10 +281,6 @@ void TargetSelector::getControlAt(int x, int y, int *buttonIndex, int *targetInd if (targetSubIndex) *targetSubIndex = 0; } - } else if (y < m_targetRemoveButton.height() + 3 - && x >= tx + targetWidth() - m_targetRemoveButton.width() - 1) { - if (removeButton) - *removeButton = true; } } } @@ -223,8 +290,7 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) int buttonIndex; int targetIndex; int targetSubIndex; - bool removeButton; - getControlAt(event->x(), event->y(), &buttonIndex, &targetIndex, &targetSubIndex, &removeButton); + getControlAt(event->x(), event->y(), &buttonIndex, &targetIndex, &targetSubIndex); if (buttonIndex == 0) { event->accept(); --m_startIndex; @@ -236,7 +302,7 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) } else if (targetIndex != -1) { event->accept(); bool updateNeeded = false; - if (targetIndex != m_currentTargetIndex && !removeButton) { + if (targetIndex != m_currentTargetIndex) { m_currentTargetIndex = targetIndex; updateNeeded = true; } @@ -245,8 +311,6 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) m_targets[m_currentTargetIndex].currentSubIndex = targetSubIndex; updateNeeded = true; } - } else if (removeButton) { - emit removeButtonClicked(targetIndex); } if (updateNeeded) { update(); @@ -260,11 +324,12 @@ void TargetSelector::mousePressEvent(QMouseEvent *event) void TargetSelector::mouseMoveEvent(QMouseEvent *event) { int targetIndex; - getControlAt(event->x(), event->y(), 0, &targetIndex, 0, 0); + getControlAt(event->x(), event->y(), 0, &targetIndex, 0); if (m_currentHoveredTargetIndex != targetIndex) { m_currentHoveredTargetIndex = targetIndex; if (targetIndex != -1) event->accept(); + updateButtons(); update(); } } @@ -273,18 +338,34 @@ void TargetSelector::leaveEvent(QEvent *event) { Q_UNUSED(event) m_currentHoveredTargetIndex = -1; + updateButtons(); update(); } +void TargetSelector::updateButtons() +{ + if (m_menuShown) { + // Do nothing while the menu is show + } else if (m_currentHoveredTargetIndex == -1) { + m_targetChangeButton->hide(); + } else { + int tx = NAVBUTTON_WIDTH + 3 + (m_currentHoveredTargetIndex - m_startIndex) * (targetWidth() + 1); + + QPoint buttonTopLeft(tx + targetWidth() - m_targetChangePixmap.width() - 1, 3); + m_targetChangeButton->move(buttonTopLeft); + m_targetChangeButton->setVisible(true); + m_targetChangeButton->setFirst(m_currentHoveredTargetIndex == m_currentTargetIndex); + } +} + bool TargetSelector::event(QEvent *e) { if (e->type() == QEvent::ToolTip) { const QHelpEvent *helpEvent = static_cast<const QHelpEvent *>(e); int targetIndex; int subTargetIndex; - bool removeButton; - getControlAt(helpEvent->x(), helpEvent->y(), 0, &targetIndex, &subTargetIndex, &removeButton); - if (targetIndex >= 0 && subTargetIndex < 0 && !removeButton) { + getControlAt(helpEvent->x(), helpEvent->y(), 0, &targetIndex, &subTargetIndex); + if (targetIndex >= 0 && subTargetIndex < 0) { emit toolTipRequested(helpEvent->globalPos(), targetIndex); e->accept(); return true; @@ -341,12 +422,6 @@ void TargetSelector::paintEvent(QPaintEvent *event) p.drawText(x + (targetWidth()- fm.width(nameText))/2 + 1, 7 + fm.ascent(), nameText); - // remove button - if (m_currentHoveredTargetIndex == index) { - p.drawPixmap(x + targetWidth() - m_targetRemoveButton.width() - 2, 3, - index == m_currentTargetIndex ? m_targetRemoveDarkButton : m_targetRemoveButton); - } - // Build int margin = 2; // position centered within the rounded buttons QFontMetrics fm = fontMetrics(); diff --git a/src/plugins/projectexplorer/targetselector.h b/src/plugins/projectexplorer/targetselector.h index 874f820765..f69b13a3ed 100644 --- a/src/plugins/projectexplorer/targetselector.h +++ b/src/plugins/projectexplorer/targetselector.h @@ -36,10 +36,12 @@ QT_BEGIN_NAMESPACE class QMenu; +class QPushButton; QT_END_NAMESPACE namespace ProjectExplorer { namespace Internal { +class QPixmapButton; class TargetSelector : public QWidget { @@ -63,6 +65,8 @@ public: int currentIndex() const { return m_currentTargetIndex; } int currentSubIndex() const { return m_targets.at(m_currentTargetIndex).currentSubIndex; } + void setTargetMenu(QMenu *menu); + public: void insertTarget(int index, const QString &name); void renameTarget(int index, const QString &name); @@ -71,11 +75,11 @@ public: void setCurrentSubIndex(int subindex); signals: - void removeButtonClicked(int targetIndex); // This signal is emitted whenever the target pointed to by the indices // has changed. void currentChanged(int targetIndex, int subIndex); void toolTipRequested(const QPoint &globalPosition, int targetIndex); + void menuShown(int targetIndex); protected: void paintEvent(QPaintEvent *event); @@ -84,8 +88,13 @@ protected: void leaveEvent(QEvent *event); bool event(QEvent *e); +private slots: + void changeButtonPressed(); + void updateButtons(); + void menuAboutToShow(); + void menuAboutToHide(); private: - void getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex, bool *removeButton); + void getControlAt(int x, int y, int *buttonIndex, int *targetIndex, int *targetSubIndex); int maxVisibleTargets() const; const QImage m_unselected; @@ -93,14 +102,17 @@ private: const QImage m_buildselected; const QPixmap m_targetRightButton; const QPixmap m_targetLeftButton; - const QPixmap m_targetRemoveButton; - const QPixmap m_targetRemoveDarkButton; + const QPixmap m_targetChangePixmap; + const QPixmap m_targetChangePixmap2; + + QPixmapButton *m_targetChangeButton; QList<Target> m_targets; int m_currentTargetIndex; int m_currentHoveredTargetIndex; int m_startIndex; + bool m_menuShown; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index b8075e71e0..c07e305a06 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -45,6 +45,9 @@ #include <projectexplorer/kitmanager.h> #include <projectexplorer/buildmanager.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/buildconfiguration.h> +#include <projectexplorer/deployconfiguration.h> +#include <projectexplorer/runconfiguration.h> #include <utils/qtcassert.h> #include <QCoreApplication> @@ -70,6 +73,8 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : m_project(project), m_selector(0), m_centralWidget(0), + m_changeMenu(0), + m_duplicateMenu(0), m_lastAction(0) { Q_ASSERT(m_project); @@ -78,6 +83,7 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : m_panelWidgets[1] = 0; m_addMenu = new QMenu(this); + m_targetMenu = new QMenu(this); setFocusPolicy(Qt::NoFocus); @@ -92,7 +98,7 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) : this, SLOT(activeTargetChanged(ProjectExplorer::Target*))); connect(KitManager::instance(), SIGNAL(kitsChanged()), - this, SLOT(updateTargetAddAndRemoveButtons())); + this, SLOT(updateTargetButtons())); } TargetSettingsPanelWidget::~TargetSettingsPanelWidget() @@ -102,21 +108,35 @@ TargetSettingsPanelWidget::~TargetSettingsPanelWidget() bool TargetSettingsPanelWidget::event(QEvent *event) { if (event->type() == QEvent::StatusTip) { + QAction *act = 0; + QMenu *menu = 0; + if (m_addMenu->activeAction()) { + menu = m_addMenu; + act = m_addMenu->activeAction(); + } else if (m_changeMenu && m_changeMenu->activeAction()) { + menu = m_changeMenu; + act = m_changeMenu->activeAction(); + } else if (m_duplicateMenu && m_duplicateMenu->activeAction()) { + menu = m_duplicateMenu; + act = m_duplicateMenu->activeAction(); + } else { + return QWidget::event(event); + } + QStatusTipEvent *ev = static_cast<QStatusTipEvent *>(event); ev->accept(); - QAction *act = m_addMenu->activeAction(); if (act != m_lastAction) QToolTip::showText(QPoint(), QString()); m_lastAction = act; if (act) { - QRect actionRect = m_addMenu->actionGeometry(act); - actionRect.translate(m_addMenu->pos()); + QRect actionRect = menu->actionGeometry(act); + actionRect.translate(menu->pos()); QPoint p = QCursor::pos(); if (!actionRect.contains(p)) p = actionRect.center(); p.setY(actionRect.center().y()); - QToolTip::showText(p, ev->tip(), m_addMenu, m_addMenu->actionGeometry(act)); + QToolTip::showText(p, ev->tip(), menu, menu->actionGeometry(act)); } else { QToolTip::showText(QPoint(), QString()); } @@ -169,18 +189,20 @@ void TargetSettingsPanelWidget::setupUi() connect(m_selector, SIGNAL(currentChanged(int,int)), this, SLOT(currentTargetChanged(int,int))); - connect(m_selector, SIGNAL(removeButtonClicked(int)), - this, SLOT(removeTarget(int))); connect(m_selector, SIGNAL(manageButtonClicked()), this, SLOT(openTargetPreferences())); connect(m_selector, SIGNAL(toolTipRequested(QPoint,int)), this, SLOT(showTargetToolTip(QPoint,int))); + connect(m_selector, SIGNAL(menuShown(int)), + this, SLOT(menuShown(int))); - m_selector->setAddButtonMenu(m_addMenu); connect(m_addMenu, SIGNAL(triggered(QAction*)), - this, SLOT(addTarget(QAction*))); + this, SLOT(addActionTriggered(QAction*))); - updateTargetAddAndRemoveButtons(); + m_selector->setAddButtonMenu(m_addMenu); + m_selector->setTargetMenu(m_targetMenu); + + updateTargetButtons(); } void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subIndex) @@ -243,7 +265,36 @@ void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subInd m_project->setActiveTarget(target); } -void TargetSettingsPanelWidget::addTarget(QAction *action) +void TargetSettingsPanelWidget::menuShown(int targetIndex) +{ + m_menuTargetIndex = targetIndex; +} + +void TargetSettingsPanelWidget::changeActionTriggered(QAction *action) +{ + Kit *k = KitManager::instance()->find(action->data().value<Core::Id>()); + Target *sourceTarget = m_targets.at(m_menuTargetIndex); + Target *newTarget = cloneTarget(sourceTarget, k); + + if (newTarget) { + m_project->addTarget(newTarget); + m_project->setActiveTarget(newTarget); + m_project->removeTarget(sourceTarget); + } +} + +void TargetSettingsPanelWidget::duplicateActionTriggered(QAction *action) +{ + Kit *k = KitManager::instance()->find(action->data().value<Core::Id>()); + Target *newTarget = cloneTarget(m_targets.at(m_menuTargetIndex), k); + + if (newTarget) { + m_project->addTarget(newTarget); + m_project->setActiveTarget(newTarget); + } +} + +void TargetSettingsPanelWidget::addActionTriggered(QAction *action) { Kit *k = KitManager::instance()->find(action->data().value<Core::Id>()); QTC_ASSERT(!m_project->target(k), return); @@ -254,10 +305,146 @@ void TargetSettingsPanelWidget::addTarget(QAction *action) m_project->addTarget(target); } -void TargetSettingsPanelWidget::removeTarget(int targetIndex) +Target *TargetSettingsPanelWidget::cloneTarget(Target *sourceTarget, Kit *k) +{ + Target *newTarget = new Target(m_project, k); + + QStringList buildconfigurationError; + QStringList deployconfigurationError; + QStringList runconfigurationError; + + foreach (BuildConfiguration *sourceBc, sourceTarget->buildConfigurations()) { + IBuildConfigurationFactory *factory = IBuildConfigurationFactory::find(newTarget, sourceBc); + if (!factory) { + buildconfigurationError << sourceBc->displayName(); + continue; + } + BuildConfiguration *newBc = factory->clone(newTarget, sourceBc); + if (!newBc) { + buildconfigurationError << sourceBc->displayName(); + continue; + } + newBc->setDisplayName(sourceBc->displayName()); + newTarget->addBuildConfiguration(newBc); + if (sourceTarget->activeBuildConfiguration() == sourceBc) + newTarget->setActiveBuildConfiguration(newBc); + } + if (!newTarget->activeBuildConfiguration()) { + QList<BuildConfiguration *> bcs = newTarget->buildConfigurations(); + if (!bcs.isEmpty()) + newTarget->setActiveBuildConfiguration(bcs.first()); + } + + foreach (DeployConfiguration *sourceDc, sourceTarget->deployConfigurations()) { + DeployConfigurationFactory *factory = DeployConfigurationFactory::find(newTarget, sourceDc); + if (!factory) { + deployconfigurationError << sourceDc->displayName(); + continue; + } + DeployConfiguration *newDc = factory->clone(newTarget, sourceDc); + if (!newDc) { + deployconfigurationError << sourceDc->displayName(); + continue; + } + newDc->setDisplayName(sourceDc->displayName()); + newTarget->addDeployConfiguration(newDc); + if (sourceTarget->activeDeployConfiguration() == sourceDc) + newTarget->setActiveDeployConfiguration(newDc); + } + if (!newTarget->activeBuildConfiguration()) { + QList<DeployConfiguration *> dcs = newTarget->deployConfigurations(); + if (!dcs.isEmpty()) + newTarget->setActiveDeployConfiguration(dcs.first()); + } + + foreach (RunConfiguration *sourceRc, sourceTarget->runConfigurations()) { + IRunConfigurationFactory *factory = IRunConfigurationFactory::find(newTarget, sourceRc); + if (!factory) { + runconfigurationError << sourceRc->displayName(); + continue; + } + RunConfiguration *newRc = factory->clone(newTarget, sourceRc); + if (!newRc) { + runconfigurationError << sourceRc->displayName(); + continue; + } + newRc->setDisplayName(sourceRc->displayName()); + newTarget->addRunConfiguration(newRc); + if (sourceTarget->activeRunConfiguration() == sourceRc) + newTarget->setActiveRunConfiguration(newRc); + } + if (!newTarget->activeRunConfiguration()) { + QList<RunConfiguration *> rcs = newTarget->runConfigurations(); + if (!rcs.isEmpty()) + newTarget->setActiveRunConfiguration(rcs.first()); + } + + bool fatalError = false; + if (buildconfigurationError.count() == sourceTarget->buildConfigurations().count()) + fatalError = true; + + if (deployconfigurationError.count() == sourceTarget->deployConfigurations().count()) + fatalError = true; + + if (runconfigurationError.count() == sourceTarget->runConfigurations().count()) + fatalError = true; + + if (fatalError) { + // That could be a more granular error message + QMessageBox::critical(Core::ICore::mainWindow(), + tr("Incompatible Kit"), + tr("The Kit %1 is incompatible with Kit %2.") + .arg(sourceTarget->kit()->displayName()) + .arg(k->displayName())); + + delete newTarget; + newTarget = 0; + } else if (!buildconfigurationError.isEmpty() + || !deployconfigurationError.isEmpty() + || ! runconfigurationError.isEmpty()) { + + QString error; + if (!buildconfigurationError.isEmpty()) + error += tr("Build configurations:\n") + + buildconfigurationError.join(QLatin1String("\n")); + + if (!deployconfigurationError.isEmpty()) { + if (!error.isEmpty()) + error.append(QLatin1Char('\n')); + error += tr("Deploy configurations:\n") + + deployconfigurationError.join(QLatin1String("\n")); + } + + if (!runconfigurationError.isEmpty()) { + if (!error.isEmpty()) + error.append(QLatin1Char('\n')); + error += tr("Run configurations ") + + runconfigurationError.join(QLatin1String("\n")); + } + + QMessageBox msgBox(Core::ICore::mainWindow()); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setWindowTitle(tr("Partial Incompatible Kit")); + msgBox.setText(tr("Some configurations could not be copied.")); + msgBox.setDetailedText(error); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + if (msgBox.exec() != QDialog::Accepted) { + delete newTarget; + newTarget = 0; + } + } + + return newTarget; +} + +void TargetSettingsPanelWidget::removeTarget() { - Target *t = m_targets.at(targetIndex); + Target *t = m_targets.at(m_menuTargetIndex); + removeTarget(t); +} +void TargetSettingsPanelWidget::removeTarget(Target *t) +{ ProjectExplorer::BuildManager *bm = ProjectExplorerPlugin::instance()->buildManager(); if (bm->isBuilding(t)) { QMessageBox box; @@ -308,7 +495,7 @@ void TargetSettingsPanelWidget::targetAdded(ProjectExplorer::Target *target) } connect(target, SIGNAL(displayNameChanged()), this, SLOT(renameTarget())); - updateTargetAddAndRemoveButtons(); + updateTargetButtons(); } void TargetSettingsPanelWidget::removedTarget(ProjectExplorer::Target *target) @@ -323,7 +510,7 @@ void TargetSettingsPanelWidget::removedTarget(ProjectExplorer::Target *target) m_selector->removeTarget(index); - updateTargetAddAndRemoveButtons(); + updateTargetButtons(); } void TargetSettingsPanelWidget::activeTargetChanged(ProjectExplorer::Target *target) @@ -334,37 +521,61 @@ void TargetSettingsPanelWidget::activeTargetChanged(ProjectExplorer::Target *tar m_selector->setCurrentIndex(index); } -void TargetSettingsPanelWidget::updateTargetAddAndRemoveButtons() +namespace { +bool diplayNameSorter(Kit *a, Kit *b) +{ + return a->displayName() < b->displayName(); +} +} + +void TargetSettingsPanelWidget::createAction(Kit *k, QMenu *menu) +{ + QAction *action = new QAction(k->displayName(), menu); + action->setData(QVariant::fromValue(k->id())); + QString errorMessage; + if (!m_project->supportsKit(k, &errorMessage)) { + action->setEnabled(false); + action->setStatusTip(errorMessage); + } + menu->addAction(action); +} + +void TargetSettingsPanelWidget::updateTargetButtons() { if (!m_selector) return; m_addMenu->clear(); + m_targetMenu->clear(); - foreach (Kit *k, KitManager::instance()->kits()) { - if (m_project->target(k)) - continue; + m_changeMenu = m_targetMenu->addMenu(tr("Change Kit")); + m_duplicateMenu = m_targetMenu->addMenu(tr("Copy to Kit")); + QAction *removeAction = m_targetMenu->addAction(tr("Remove Kit")); - QAction *action = new QAction(k->displayName(), m_addMenu); - action->setData(QVariant::fromValue(k->id())); - QString errorMessage; - if (!m_project->supportsKit(k, &errorMessage)) { - action->setEnabled(false); - action->setStatusTip(errorMessage); - } + if (m_project->targets().size() < 2) + removeAction->setEnabled(false); - bool inserted = false; - foreach (QAction *existing, m_addMenu->actions()) { - if (existing->text() > action->text()) { - m_addMenu->insertAction(existing, action); - inserted = true; - break; - } - } - if (!inserted) - m_addMenu->addAction(action); + connect(m_changeMenu, SIGNAL(triggered(QAction*)), + this, SLOT(changeActionTriggered(QAction*))); + connect(m_duplicateMenu, SIGNAL(triggered(QAction*)), + this, SLOT(duplicateActionTriggered(QAction*))); + connect(removeAction, SIGNAL(triggered()), this, SLOT(removeTarget())); + + QList<Kit *> kits = KitManager::instance()->kits(); + qSort(kits.begin(), kits.end(), diplayNameSorter); + foreach (Kit *k, kits) { + if (m_project->target(k)) + continue; + createAction(k, m_addMenu); + createAction(k, m_changeMenu); + createAction(k, m_duplicateMenu); } + if (m_changeMenu->actions().isEmpty()) + m_changeMenu->setEnabled(false); + if (m_duplicateMenu->actions().isEmpty()) + m_duplicateMenu->setEnabled(false); + m_selector->setAddButtonEnabled(!m_addMenu->actions().isEmpty()); } diff --git a/src/plugins/projectexplorer/targetsettingspanel.h b/src/plugins/projectexplorer/targetsettingspanel.h index 4d78e58738..5f93c6785b 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.h +++ b/src/plugins/projectexplorer/targetsettingspanel.h @@ -43,6 +43,7 @@ namespace ProjectExplorer { class Target; class Project; +class Kit; namespace Internal { @@ -65,17 +66,24 @@ protected: bool event(QEvent *event); private slots: void currentTargetChanged(int targetIndex, int subIndex); - void removeTarget(int targetIndex); void showTargetToolTip(const QPoint &globalPos, int targetIndex); - void addTarget(QAction *); void targetAdded(ProjectExplorer::Target *target); void removedTarget(ProjectExplorer::Target *target); void activeTargetChanged(ProjectExplorer::Target *target); - void updateTargetAddAndRemoveButtons(); + void updateTargetButtons(); void renameTarget(); void openTargetPreferences(); + void removeTarget(); + void menuShown(int targetIndex); + void addActionTriggered(QAction *action); + void changeActionTriggered(QAction *action); + void duplicateActionTriggered(QAction *action); private: + Target *cloneTarget(Target *sourceTarget, Kit *k); + void removeTarget(Target *t); + void createAction(Kit *k, QMenu *menu); + Target *m_currentTarget; Project *m_project; TargetSettingsWidget *m_selector; @@ -83,8 +91,12 @@ private: QWidget *m_noTargetLabel; PanelsWidget *m_panelWidgets[2]; QList<Target *> m_targets; + QMenu *m_targetMenu; + QMenu *m_changeMenu; + QMenu *m_duplicateMenu; QMenu *m_addMenu; QAction *m_lastAction; + int m_menuTargetIndex; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/targetsettingswidget.cpp b/src/plugins/projectexplorer/targetsettingswidget.cpp index 1b6c8cd5b0..90e2884460 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.cpp +++ b/src/plugins/projectexplorer/targetsettingswidget.cpp @@ -63,12 +63,12 @@ TargetSettingsWidget::TargetSettingsWidget(QWidget *parent) : headerLayout->addWidget(m_targetSelector, 0, Qt::AlignBottom); headerLayout->addStretch(10); - connect(m_targetSelector, SIGNAL(removeButtonClicked(int)), - this, SIGNAL(removeButtonClicked(int))); connect(m_targetSelector, SIGNAL(currentChanged(int,int)), this, SIGNAL(currentChanged(int,int))); connect(m_targetSelector, SIGNAL(toolTipRequested(QPoint,int)), this, SIGNAL(toolTipRequested(QPoint,int))); + connect(m_targetSelector, SIGNAL(menuShown(int)), + this, SIGNAL(menuShown(int))); QPalette shadowPal = palette(); QLinearGradient grad(0, 0, 0, 2); @@ -119,6 +119,11 @@ void TargetSettingsWidget::setAddButtonMenu(QMenu *menu) m_addButton->setMenu(menu); } +void TargetSettingsWidget::setTargetMenu(QMenu *menu) +{ + m_targetSelector->setTargetMenu(menu); +} + QString TargetSettingsWidget::targetNameAt(int index) const { return m_targetSelector->targetAt(index).name; diff --git a/src/plugins/projectexplorer/targetsettingswidget.h b/src/plugins/projectexplorer/targetsettingswidget.h index 4650b878fd..3918987c50 100644 --- a/src/plugins/projectexplorer/targetsettingswidget.h +++ b/src/plugins/projectexplorer/targetsettingswidget.h @@ -39,6 +39,8 @@ class QPushButton; QT_END_NAMESPACE namespace ProjectExplorer { +class Target; +class Kit; namespace Internal { namespace Ui { @@ -67,12 +69,14 @@ public: void setCurrentSubIndex(int index); void setAddButtonEnabled(bool enabled); void setAddButtonMenu(QMenu *menu); - + void setTargetMenu(QMenu *menu); signals: - void removeButtonClicked(int targetIndex); void currentChanged(int targetIndex, int subIndex); void manageButtonClicked(); + void duplicateButtonClicked(); + void changeKitButtonClicked(); void toolTipRequested(const QPoint &globalPosition, int targetIndex); + void menuShown(int targetIndex); protected: void changeEvent(QEvent *e); |