summaryrefslogtreecommitdiff
path: root/src/plugins/projectexplorer
diff options
context:
space:
mode:
authorDaniel Teske <daniel.teske@digia.com>2012-09-20 14:42:57 +0200
committerDaniel Teske <daniel.teske@digia.com>2012-09-28 12:49:57 +0200
commit733d5612fb7c1558ad0e28ebe2e2dd93477d07ed (patch)
tree0fa4c3d357a931ac11ba0afb4641fd36eeaa77b4 /src/plugins/projectexplorer
parentd7993c717d08e2884963340d9017156b54b44c05 (diff)
downloadqt-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')
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.cpp13
-rw-r--r--src/plugins/projectexplorer/buildconfiguration.h1
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.cpp14
-rw-r--r--src/plugins/projectexplorer/deployconfiguration.h1
-rw-r--r--src/plugins/projectexplorer/images/targetchangebutton.pngbin0 -> 1605 bytes
-rw-r--r--src/plugins/projectexplorer/images/targetchangebutton2.pngbin0 -> 1578 bytes
-rw-r--r--src/plugins/projectexplorer/images/targetremovebutton.pngbin566 -> 0 bytes
-rw-r--r--src/plugins/projectexplorer/images/targetremovebuttondark.pngbin1533 -> 0 bytes
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qrc4
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp49
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h4
-rw-r--r--src/plugins/projectexplorer/targetselector.cpp125
-rw-r--r--src/plugins/projectexplorer/targetselector.h20
-rw-r--r--src/plugins/projectexplorer/targetsettingspanel.cpp283
-rw-r--r--src/plugins/projectexplorer/targetsettingspanel.h18
-rw-r--r--src/plugins/projectexplorer/targetsettingswidget.cpp9
-rw-r--r--src/plugins/projectexplorer/targetsettingswidget.h8
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
new file mode 100644
index 0000000000..1311d38ef8
--- /dev/null
+++ b/src/plugins/projectexplorer/images/targetchangebutton.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/targetchangebutton2.png b/src/plugins/projectexplorer/images/targetchangebutton2.png
new file mode 100644
index 0000000000..d5d5cfefd9
--- /dev/null
+++ b/src/plugins/projectexplorer/images/targetchangebutton2.png
Binary files differ
diff --git a/src/plugins/projectexplorer/images/targetremovebutton.png b/src/plugins/projectexplorer/images/targetremovebutton.png
deleted file mode 100644
index 15e8502ccf..0000000000
--- a/src/plugins/projectexplorer/images/targetremovebutton.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/projectexplorer/images/targetremovebuttondark.png b/src/plugins/projectexplorer/images/targetremovebuttondark.png
deleted file mode 100644
index c1ec33f910..0000000000
--- a/src/plugins/projectexplorer/images/targetremovebuttondark.png
+++ /dev/null
Binary files differ
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);