1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
10 ** GNU Lesser General Public License Usage
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at info@qt.nokia.com.
31 **************************************************************************/
33 #include "miniprojecttargetselector.h"
34 #include "buildconfigurationmodel.h"
35 #include "runconfigurationmodel.h"
38 #include <utils/qtcassert.h>
39 #include <utils/styledbar.h>
40 #include <utils/stylehelper.h>
42 #include <coreplugin/ifile.h>
43 #include <coreplugin/icore.h>
44 #include <coreplugin/coreconstants.h>
46 #include <projectexplorer/projectexplorer.h>
47 #include <projectexplorer/session.h>
48 #include <projectexplorer/project.h>
49 #include <projectexplorer/runconfiguration.h>
50 #include <projectexplorer/buildconfiguration.h>
52 #include <QtGui/QLayout>
53 #include <QtGui/QFormLayout>
54 #include <QtGui/QLabel>
55 #include <QtGui/QComboBox>
56 #include <QtGui/QListWidget>
57 #include <QtGui/QStatusBar>
58 #include <QtGui/QStackedWidget>
59 #include <QtGui/QKeyEvent>
60 #include <QtGui/QPainter>
61 #include <QtGui/QAction>
62 #include <QtGui/QItemDelegate>
63 #include <QtGui/QMainWindow>
65 #include <QtGui/QApplication>
67 static QIcon createCenteredIcon(const QIcon &icon, const QIcon &overlay)
70 targetPixmap = QPixmap(Core::Constants::TARGET_ICON_SIZE, Core::Constants::TARGET_ICON_SIZE);
71 targetPixmap.fill(Qt::transparent);
72 QPainter painter(&targetPixmap);
74 QPixmap pixmap = icon.pixmap(Core::Constants::TARGET_ICON_SIZE);
75 painter.drawPixmap((Core::Constants::TARGET_ICON_SIZE - pixmap.width())/2,
76 (Core::Constants::TARGET_ICON_SIZE - pixmap.height())/2, pixmap);
77 if (!overlay.isNull()) {
78 pixmap = overlay.pixmap(Core::Constants::TARGET_ICON_SIZE);
79 painter.drawPixmap((Core::Constants::TARGET_ICON_SIZE - pixmap.width())/2,
80 (Core::Constants::TARGET_ICON_SIZE - pixmap.height())/2, pixmap);
82 return QIcon(targetPixmap);
85 using namespace ProjectExplorer;
86 using namespace ProjectExplorer::Internal;
88 class TargetSelectorDelegate : public QItemDelegate
91 TargetSelectorDelegate(QObject *parent) : QItemDelegate(parent) { }
93 void paint(QPainter *painter,
94 const QStyleOptionViewItem &option,
95 const QModelIndex &index) const;
96 mutable QImage selectionGradient;
99 void TargetSelectorDelegate::paint(QPainter *painter,
100 const QStyleOptionViewItem &option,
101 const QModelIndex &) const
104 painter->setClipping(false);
106 if (selectionGradient.isNull())
107 selectionGradient.load(QLatin1String(":/projectexplorer/images/targetpanel_gradient.png"));
109 if (option.state & QStyle::State_Selected) {
110 QColor color =(option.state & QStyle::State_HasFocus) ?
111 option.palette.highlight().color() :
112 option.palette.dark().color();
113 painter->fillRect(option.rect, color.darker(140));
114 Utils::StyleHelper::drawCornerImage(selectionGradient, painter, option.rect.adjusted(0, 0, 0, -1), 5, 5, 5, 5);
115 painter->setPen(QColor(255, 255, 255, 60));
116 painter->drawLine(option.rect.topLeft(), option.rect.topRight());
117 painter->setPen(QColor(255, 255, 255, 30));
118 painter->drawLine(option.rect.bottomLeft() - QPoint(0,1), option.rect.bottomRight() - QPoint(0,1));
119 painter->setPen(QColor(0, 0, 0, 80));
120 painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
125 ProjectListWidget::ProjectListWidget(ProjectExplorer::Project *project, QWidget *parent)
126 : QListWidget(parent), m_project(project)
128 setFocusPolicy(Qt::NoFocus);
129 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
130 setAlternatingRowColors(false);
131 setFocusPolicy(Qt::WheelFocus);
132 setItemDelegate(new TargetSelectorDelegate(this));
133 setAttribute(Qt::WA_MacShowFocusRect, false);
135 connect(this, SIGNAL(currentRowChanged(int)), SLOT(setTarget(int)));
138 ProjectExplorer::Project *ProjectListWidget::project() const
143 QSize ProjectListWidget::sizeHint() const
147 for (int itemPos = 0; itemPos < count(); ++itemPos) {
148 height += item(itemPos)->sizeHint().height();
149 width = qMax(width, item(itemPos)->sizeHint().width());
152 // We try to keep the height of the popup equal to the actionbar
153 QSize size(width, height);
154 static QStatusBar *statusBar = Core::ICore::instance()->statusBar();
155 static QWidget *actionBar = Core::ICore::instance()->mainWindow()->findChild<QWidget*>("actionbar");
158 QMargins popupMargins = window()->contentsMargins();
160 size.setHeight(qMax(actionBar->height() - statusBar->height() -
161 (popupMargins.top() + popupMargins.bottom()), height));
165 void ProjectListWidget::setRunComboPopup()
167 QWidget *w = itemWidget(currentItem());
168 MiniTargetWidget *mtw = qobject_cast<MiniTargetWidget*>(w);
169 if (mtw->runSettingsComboBox())
170 mtw->runSettingsComboBox()->showPopup();
173 void ProjectListWidget::setBuildComboPopup()
175 QWidget *w = itemWidget(currentItem());
176 MiniTargetWidget *mtw = qobject_cast<MiniTargetWidget*>(w);
177 if (mtw->buildSettingsComboBox())
178 mtw->buildSettingsComboBox()->showPopup();
181 void ProjectListWidget::setTarget(int index)
183 MiniTargetWidget *mtw = qobject_cast<MiniTargetWidget *>(itemWidget(item(index)));
186 m_project->setActiveTarget(mtw->target());
189 MiniTargetWidget::MiniTargetWidget(Target *target, QWidget *parent) :
190 QWidget(parent), m_target(target)
194 if (hasBuildConfiguration()) {
195 m_buildComboBox = new QComboBox;
196 m_buildComboBox->setProperty("alignarrow", true);
197 m_buildComboBox->setProperty("hideborder", true);
198 m_buildComboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
199 m_buildComboBox->setToolTip(tr("Select active build configuration"));
200 m_buildComboBox->setModel(new BuildConfigurationModel(m_target, this));
205 m_runComboBox = new QComboBox;
206 m_runComboBox ->setProperty("alignarrow", true);
207 m_runComboBox ->setProperty("hideborder", true);
208 m_runComboBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
209 m_runComboBox->setToolTip(tr("Select active run configuration"));
210 RunConfigurationModel *model = new RunConfigurationModel(m_target, this);
211 m_runComboBox->setModel(model);
212 int fontSize = font().pointSize();
213 setStyleSheet(QString::fromLatin1("QLabel { font-size: %2pt; color: white; } "
214 "#target { font: bold %1pt;} "
215 "#buildLabel{ font: bold; color: rgba(255, 255, 255, 160)} "
216 "#runLabel { font: bold ; color: rgba(255, 255, 255, 160)} "
217 ).arg(fontSize).arg(fontSize - 2));
219 QGridLayout *gridLayout = new QGridLayout(this);
221 m_targetName = new QLabel(m_target->displayName());
222 m_targetName->setObjectName(QString::fromUtf8("target"));
223 m_targetIcon = new QLabel();
225 if (hasBuildConfiguration()) {
226 Q_FOREACH(BuildConfiguration* bc, m_target->buildConfigurations())
227 addBuildConfiguration(bc);
229 BuildConfigurationModel *model = static_cast<BuildConfigurationModel *>(m_buildComboBox->model());
230 m_buildComboBox->setCurrentIndex(model->indexFor(m_target->activeBuildConfiguration()).row());
232 connect(m_target, SIGNAL(addedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
233 SLOT(addBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
234 connect(m_target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
235 SLOT(removeBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
237 connect(m_target, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
238 SLOT(setActiveBuildConfiguration()));
239 connect(m_buildComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setActiveBuildConfiguration(int)));
242 m_runComboBox->setEnabled(m_target->runConfigurations().count() > 1);
243 m_runComboBox->setCurrentIndex(model->indexFor(m_target->activeRunConfiguration()).row());
245 connect(m_target, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)),
246 SLOT(addRunConfiguration(ProjectExplorer::RunConfiguration*)));
247 connect(m_target, SIGNAL(removedRunConfiguration(ProjectExplorer::RunConfiguration*)),
248 SLOT(removeRunConfiguration(ProjectExplorer::RunConfiguration*)));
250 connect(m_runComboBox, SIGNAL(currentIndexChanged(int)), SLOT(setActiveRunConfiguration(int)));
252 connect(m_target, SIGNAL(activeRunConfigurationChanged(ProjectExplorer::RunConfiguration*)),
253 SLOT(setActiveRunConfiguration()));
254 connect(m_target, SIGNAL(iconChanged()), this, SLOT(updateIcon()));
256 QHBoxLayout *buildHelperLayout = 0;
257 if (hasBuildConfiguration()) {
258 buildHelperLayout= new QHBoxLayout;
259 buildHelperLayout->setMargin(0);
260 buildHelperLayout->setSpacing(0);
261 buildHelperLayout->addWidget(m_buildComboBox);
264 QHBoxLayout *runHelperLayout = new QHBoxLayout;
265 runHelperLayout->setMargin(0);
266 runHelperLayout->setSpacing(0);
267 runHelperLayout->addWidget(m_runComboBox);
269 QFormLayout *formLayout = new QFormLayout;
270 formLayout->setLabelAlignment(Qt::AlignRight);
273 if (hasBuildConfiguration()) {
274 lbl = new QLabel(tr("Build:"));
275 lbl->setObjectName(QString::fromUtf8("buildLabel"));
276 lbl->setMinimumWidth(lbl->fontMetrics().width(lbl->text()) + indent + 4);
277 lbl->setIndent(indent);
279 formLayout->addRow(lbl, buildHelperLayout);
281 lbl = new QLabel(tr("Run:"));
282 lbl->setObjectName(QString::fromUtf8("runLabel"));
283 lbl->setMinimumWidth(lbl->fontMetrics().width(lbl->text()) + indent + 4);
284 lbl->setIndent(indent);
285 formLayout->addRow(lbl, runHelperLayout);
287 gridLayout->addWidget(m_targetName, 0, 0);
288 gridLayout->addWidget(m_targetIcon, 0, 1, 2, 1, Qt::AlignTop|Qt::AlignHCenter);
289 gridLayout->addLayout(formLayout, 1, 0);
292 void MiniTargetWidget::updateIcon()
294 m_targetIcon->setPixmap(createCenteredIcon(m_target->icon(), QIcon()).pixmap(Core::Constants::TARGET_ICON_SIZE));
297 ProjectExplorer::Target *MiniTargetWidget::target() const
302 void MiniTargetWidget::setActiveBuildConfiguration(int index)
304 BuildConfigurationModel *model = static_cast<BuildConfigurationModel *>(m_buildComboBox->model());
305 m_target->setActiveBuildConfiguration(model->buildConfigurationAt(index));
309 void MiniTargetWidget::setActiveRunConfiguration(int index)
311 RunConfigurationModel *model = static_cast<RunConfigurationModel *>(m_runComboBox->model());
312 m_target->setActiveRunConfiguration(model->runConfigurationAt(index));
317 void MiniTargetWidget::setActiveBuildConfiguration()
319 QTC_ASSERT(m_buildComboBox, return);
320 BuildConfigurationModel *model = static_cast<BuildConfigurationModel *>(m_buildComboBox->model());
321 m_buildComboBox->setCurrentIndex(model->indexFor(m_target->activeBuildConfiguration()).row());
324 void MiniTargetWidget::setActiveRunConfiguration()
326 RunConfigurationModel *model = static_cast<RunConfigurationModel *>(m_runComboBox->model());
327 m_runComboBox->setCurrentIndex(model->indexFor(m_target->activeRunConfiguration()).row());
330 void MiniTargetWidget::addRunConfiguration(ProjectExplorer::RunConfiguration* rc)
333 m_runComboBox->setEnabled(m_target->runConfigurations().count()>1);
336 void MiniTargetWidget::removeRunConfiguration(ProjectExplorer::RunConfiguration* rc)
339 m_runComboBox->setEnabled(m_target->runConfigurations().count()>1);
342 void MiniTargetWidget::addBuildConfiguration(ProjectExplorer::BuildConfiguration* bc)
345 connect(bc, SIGNAL(displayNameChanged()), SIGNAL(changed()), Qt::UniqueConnection);
346 m_buildComboBox->setEnabled(m_target->buildConfigurations().count() > 1);
349 void MiniTargetWidget::removeBuildConfiguration(ProjectExplorer::BuildConfiguration* bc)
352 QTC_ASSERT(m_buildComboBox, return);
353 m_buildComboBox->setEnabled(m_target->buildConfigurations().count() > 1);
356 bool MiniTargetWidget::hasBuildConfiguration() const
358 return (m_target->buildConfigurationFactory() != 0);
361 MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorAction, QWidget *parent) :
362 QWidget(parent), m_projectAction(targetSelectorAction), m_ignoreIndexChange(false)
364 setProperty("panelwidget", true);
365 setContentsMargins(QMargins(0, 1, 1, 8));
366 setWindowFlags(Qt::Popup);
368 targetSelectorAction->setIcon(style()->standardIcon(QStyle::SP_ComputerIcon));
369 targetSelectorAction->setProperty("titledAction", true);
371 QVBoxLayout *layout = new QVBoxLayout(this);
372 layout->setMargin(0);
373 layout->setSpacing(0);
375 Utils::StyledBar *bar = new Utils::StyledBar;
376 bar->setSingleRow(true);
377 layout->addWidget(bar);
378 QHBoxLayout *toolLayout = new QHBoxLayout(bar);
379 toolLayout->setMargin(0);
380 toolLayout->setSpacing(0);
382 QLabel *lbl = new QLabel(tr("Project"));
384 QFont f = lbl->font();
388 int panelHeight = lbl->fontMetrics().height() + 12;
389 bar->ensurePolished(); // Required since manhattanstyle overrides height
390 bar->setFixedHeight(panelHeight);
392 m_projectsBox = new QComboBox;
393 m_projectsBox->setToolTip(tr("Select active project"));
394 m_projectsBox->setFocusPolicy(Qt::TabFocus);
396 m_projectsBox->setFont(f);
397 m_projectsBox->ensurePolished();
398 m_projectsBox->setFixedHeight(panelHeight);
399 m_projectsBox->setProperty("hideborder", true);
400 m_projectsBox->setObjectName(QString::fromUtf8("ProjectsBox"));
401 m_projectsBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
402 m_projectsBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
404 toolLayout->addWidget(lbl);
405 toolLayout->addWidget(new Utils::StyledSeparator);
406 toolLayout->addWidget(m_projectsBox);
408 m_widgetStack = new QStackedWidget;
409 m_widgetStack->setFocusPolicy(Qt::NoFocus);
410 layout->addWidget(m_widgetStack);
412 connect(m_projectsBox, SIGNAL(activated(int)),
413 SLOT(emitStartupProjectChanged(int)));
416 void MiniProjectTargetSelector::setVisible(bool visible)
419 QSize sh = sizeHint();
421 QStatusBar *statusBar = Core::ICore::instance()->statusBar();
422 QPoint moveTo = statusBar->mapToGlobal(QPoint(0,0));
423 moveTo -= QPoint(0, sh.height());
427 QWidget::setVisible(visible);
429 if (m_widgetStack->currentWidget())
430 m_widgetStack->currentWidget()->setFocus();
432 m_projectAction->setChecked(visible);
435 // This is a workaround for the problem that Windows
436 // will let the mouse events through when you click
437 // outside a popup to close it. This causes the popup
438 // to open on mouse release if you hit the button, which
441 // A similar case can be found in QComboBox
442 void MiniProjectTargetSelector::mousePressEvent(QMouseEvent *e)
444 setAttribute(Qt::WA_NoMouseReplay);
445 QWidget::mousePressEvent(e);
448 QString MiniProjectTargetSelector::fullName(ProjectExplorer::Project *project)
450 return project->displayName() + " (" + project->file()->fileName() + QLatin1Char(')');
453 void MiniProjectTargetSelector::addProject(ProjectExplorer::Project *project)
455 QTC_ASSERT(project, return);
456 ProjectListWidget *targetList = new ProjectListWidget(project);
457 targetList->setStyleSheet(QString::fromLatin1("QListWidget { background: %1; border: none; }")
458 .arg(QColor(70, 70, 70).name()));
460 m_ignoreIndexChange = true;
462 QString sortName = fullName(project);
464 for (int i=0; i < m_projectsBox->count(); ++i) {
465 Project *p = m_projectsBox->itemData(i).value<Project*>();
466 QString itemSortName = fullName(p);
467 if (itemSortName > sortName)
471 m_widgetStack->insertWidget(pos, targetList);
473 bool useFullName = false;
474 for (int i = 0; i < m_projectsBox->count(); ++i) {
475 Project *p = m_projectsBox->itemData(i).value<Project*>();
476 if (p->displayName() == project->displayName()) {
478 m_projectsBox->setItemText(i, fullName(p));
482 QString displayName = useFullName ? fullName(project) : project->displayName();
483 m_projectsBox->insertItem(pos, displayName, QVariant::fromValue(project));
485 connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
486 SLOT(updateAction()));
488 connect(project, SIGNAL(addedTarget(ProjectExplorer::Target*)),
489 SLOT(addTarget(ProjectExplorer::Target*)));
490 connect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
491 SLOT(removeTarget(ProjectExplorer::Target*)));
492 connect(project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
493 SLOT(changeActiveTarget(ProjectExplorer::Target*)));
495 if (project == ProjectExplorerPlugin::instance()->startupProject()) {
496 m_projectsBox->setCurrentIndex(pos);
497 m_widgetStack->setCurrentIndex(pos);
500 m_ignoreIndexChange = false;
502 foreach (Target *t, project->targets())
503 addTarget(t, t == project->activeTarget());
505 m_projectsBox->setEnabled(m_projectsBox->count() > 1);
506 m_projectsBox->parentWidget()->layout()->activate();
509 void MiniProjectTargetSelector::removeProject(ProjectExplorer::Project* project)
511 int index = indexFor(project);
514 ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(index));
516 // We don't want to emit a startUpProject changed, even if we remove the current startup project
517 // The ProjectExplorer takes care of setting a new startup project.
518 m_ignoreIndexChange = true;
519 m_projectsBox->removeItem(index);
520 m_projectsBox->setEnabled(m_projectsBox->count() > 1);
523 // Update display names
524 QString name = project->displayName();
527 for (int i = 0; i < m_projectsBox->count(); ++i) {
528 Project *p = m_projectsBox->itemData(i).value<Project*>();
529 if (p->displayName() == name) {
535 Project *p = m_projectsBox->itemData(otherIndex).value<Project*>();
536 m_projectsBox->setItemText(otherIndex, p->displayName());
539 m_ignoreIndexChange = false;
540 m_projectsBox->parentWidget()->layout()->activate();
543 void MiniProjectTargetSelector::addTarget(ProjectExplorer::Target *target, bool activeTarget)
545 QTC_ASSERT(target, return);
547 int index = indexFor(target->project());
551 connect(target, SIGNAL(toolTipChanged()), this, SLOT(updateAction()));
552 connect(target, SIGNAL(iconChanged()), this, SLOT(updateAction()));
553 connect(target, SIGNAL(overlayIconChanged()), this, SLOT(updateAction()));
554 ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(index));
555 QListWidgetItem *lwi = new QListWidgetItem();
558 for (int idx = 0; idx <= plw->count(); ++idx) {
559 QListWidgetItem *itm(plw->item(idx));
560 MiniTargetWidget *mtw(qobject_cast<MiniTargetWidget *>(plw->itemWidget(itm)));
561 if (!mtw && idx < plw->count())
563 if (idx == plw->count() ||
564 mtw->target()->displayName() > target->displayName()) {
565 plw->insertItem(idx, lwi);
570 MiniTargetWidget *targetWidget = new MiniTargetWidget(target);
571 connect(targetWidget, SIGNAL(changed()), this, SLOT(updateAction()));
572 targetWidget->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
573 lwi->setSizeHint(targetWidget->sizeHint());
574 plw->setItemWidget(lwi, targetWidget);
577 plw->setCurrentItem(lwi, QItemSelectionModel::SelectCurrent);
579 m_widgetStack->updateGeometry();
582 void MiniProjectTargetSelector::removeTarget(ProjectExplorer::Target *target)
584 QTC_ASSERT(target, return);
586 int index = indexFor(target->project());
590 ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(index));
591 for (int i = 0; i < plw->count(); ++i) {
592 QListWidgetItem *itm(plw->item(i));
593 MiniTargetWidget *mtw(qobject_cast<MiniTargetWidget *>(plw->itemWidget(itm)));
596 if (target != mtw->target())
598 delete plw->takeItem(i);
602 disconnect(target, SIGNAL(toolTipChanged()), this, SLOT(updateAction()));
603 disconnect(target, SIGNAL(iconChanged()), this, SLOT(updateAction()));
604 disconnect(target, SIGNAL(overlayIconChanged()), this, SLOT(updateAction()));
606 m_widgetStack->updateGeometry();
609 void MiniProjectTargetSelector::changeActiveTarget(ProjectExplorer::Target *target)
611 int index = indexFor(target->project());
614 ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(index));
616 for (int i = 0; i < plw->count(); ++i) {
617 QListWidgetItem *itm = plw->item(i);
618 MiniTargetWidget *mtw = qobject_cast<MiniTargetWidget*>(plw->itemWidget(itm));
619 if (mtw->target() == target) {
620 plw->setCurrentItem(itm);
626 void MiniProjectTargetSelector::updateAction()
628 Project *project = ProjectExplorerPlugin::instance()->startupProject();
630 QString projectName;;
632 QString targetToolTipText;
635 QIcon targetIcon = style()->standardIcon(QStyle::SP_ComputerIcon);
637 const int extrawidth = 110; // Size of margins + icon width
638 // Some fudge numbers to ensure the menu does not grow unbounded
639 int maxLength = fontMetrics().averageCharWidth() * 140;
642 projectName = project->displayName();
644 if (Target *target = project->activeTarget()) {
645 if (project->targets().count() > 1) {
646 targetName = project->activeTarget()->displayName();
648 if (BuildConfiguration *bc = target->activeBuildConfiguration()) {
649 buildConfig = bc->displayName();
650 int minimumWidth = fontMetrics().width(bc->displayName() + tr("Build:")) + extrawidth;
651 m_widgetStack->setMinimumWidth(qMin(maxLength, qMax(minimumWidth, m_widgetStack->minimumWidth())));
654 if (RunConfiguration *rc = target->activeRunConfiguration()) {
655 runConfig = rc->displayName();
656 int minimumWidth = fontMetrics().width(rc->displayName() + tr("Run:")) + extrawidth;
657 m_widgetStack->setMinimumWidth(qMin(maxLength, qMax(minimumWidth, m_widgetStack->minimumWidth())));
659 targetToolTipText = target->toolTip();
660 targetIcon = createCenteredIcon(target->icon(), target->overlayIcon());
663 m_projectAction->setProperty("heading", projectName);
664 m_projectAction->setProperty("subtitle", buildConfig);
665 m_projectAction->setIcon(targetIcon);
666 QString toolTip = tr("<html><nobr><b>Project:</b> %1<br/>%2%3<b>Run:</b> %4%5</html>");
667 QString targetTip = targetName.isEmpty() ? QLatin1String("")
668 : tr("<b>Target:</b> %1<br/>").arg(targetName);
669 QString buildTip = buildConfig.isEmpty() ? QLatin1String("")
670 : tr("<b>Build:</b> %2<br/>").arg(buildConfig);
671 QString targetToolTip = targetToolTipText.isEmpty() ? QLatin1String("")
672 : tr("<br/>%1").arg(targetToolTipText);
673 m_projectAction->setToolTip(toolTip.arg(projectName, targetTip, buildTip, runConfig, targetToolTip));
676 int MiniProjectTargetSelector::indexFor(ProjectExplorer::Project *project) const
678 for (int i = 0; i < m_widgetStack->count(); ++i) {
679 ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(i));
680 if (plw && plw->project() == project)
686 void MiniProjectTargetSelector::emitStartupProjectChanged(int index)
688 if (m_ignoreIndexChange)
690 Project *project = m_projectsBox->itemData(index).value<Project*>();
691 QTC_ASSERT(project, return;)
692 emit startupProjectChanged(project);
695 void MiniProjectTargetSelector::changeStartupProject(ProjectExplorer::Project *project)
697 for (int i = 0; i < m_widgetStack->count(); ++i) {
698 ProjectListWidget *plw = qobject_cast<ProjectListWidget*>(m_widgetStack->widget(i));
699 if (plw && plw->project() == project) {
700 m_projectsBox->setCurrentIndex(i);
701 m_widgetStack->setCurrentIndex(i);
707 void MiniProjectTargetSelector::paintEvent(QPaintEvent *)
709 QPainter painter(this);
710 painter.setPen(Utils::StyleHelper::borderColor());
711 painter.drawLine(rect().topLeft(), rect().topRight());
712 painter.drawLine(rect().topRight(), rect().bottomRight());
714 QRect bottomRect(0, rect().height() - 8, rect().width(), 8);
715 static QImage image(QLatin1String(":/projectexplorer/images/targetpanel_bottom.png"));
716 Utils::StyleHelper::drawCornerImage(image, &painter, bottomRect, 1, 1, 1, 1);