miniprojecttargetselector.cpp 53.9 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
Tobias Hunger's avatar
Tobias Hunger committed
2
**
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
hjk's avatar
hjk committed
4
** Contact: http://www.qt-project.org/legal
Tobias Hunger's avatar
Tobias Hunger committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
Tobias Hunger's avatar
Tobias Hunger committed
7
**
hjk's avatar
hjk committed
8 9 10 11 12 13 14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
Tobias Hunger's avatar
Tobias Hunger committed
15 16
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
17 18 19 20 21 22 23 24 25
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
con's avatar
con committed
26 27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
28
****************************************************************************/
Tobias Hunger's avatar
Tobias Hunger committed
29

30
#include "miniprojecttargetselector.h"
31
#include "target.h"
32 33 34 35 36

#include <utils/styledbar.h>
#include <utils/stylehelper.h>

#include <coreplugin/icore.h>
con's avatar
con committed
37
#include <coreplugin/coreconstants.h>
38
#include <coreplugin/modemanager.h>
39 40 41 42 43

#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/project.h>
#include <projectexplorer/buildconfiguration.h>
Daniel Teske's avatar
Daniel Teske committed
44
#include <projectexplorer/deployconfiguration.h>
Tobias Hunger's avatar
Tobias Hunger committed
45
#include <projectexplorer/kitmanager.h>
46
#include <projectexplorer/projectmodels.h>
Daniel Teske's avatar
Daniel Teske committed
47
#include <projectexplorer/runconfiguration.h>
48

49 50 51 52 53 54 55 56 57
#include <QTimer>
#include <QLayout>
#include <QLabel>
#include <QListWidget>
#include <QStatusBar>
#include <QKeyEvent>
#include <QPainter>
#include <QAction>
#include <QItemDelegate>
58

59 60 61 62 63 64 65
static QIcon createCenteredIcon(const QIcon &icon, const QIcon &overlay)
{
    QPixmap targetPixmap;
    targetPixmap = QPixmap(Core::Constants::TARGET_ICON_SIZE, Core::Constants::TARGET_ICON_SIZE);
    targetPixmap.fill(Qt::transparent);
    QPainter painter(&targetPixmap);

66 67 68
    QPixmap pixmap = icon.pixmap(Core::Constants::TARGET_ICON_SIZE);
    painter.drawPixmap((Core::Constants::TARGET_ICON_SIZE - pixmap.width())/2,
                       (Core::Constants::TARGET_ICON_SIZE - pixmap.height())/2, pixmap);
69
    if (!overlay.isNull()) {
70 71 72
        pixmap = overlay.pixmap(Core::Constants::TARGET_ICON_SIZE);
        painter.drawPixmap((Core::Constants::TARGET_ICON_SIZE - pixmap.width())/2,
                           (Core::Constants::TARGET_ICON_SIZE - pixmap.height())/2, pixmap);
73 74 75 76
    }
    return QIcon(targetPixmap);
}

77 78 79
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

80 81 82 83 84 85 86 87 88
static bool projectLesserThan(Project *p1, Project *p2)
{
    int result = caseFriendlyCompare(p1->displayName(), p2->displayName());
    if (result != 0)
        return result < 0;
    else
        return p1 < p2;
}

Daniel Teske's avatar
Daniel Teske committed
89 90 91
////////
// TargetSelectorDelegate
////////
92 93 94
class TargetSelectorDelegate : public QItemDelegate
{
public:
95
    TargetSelectorDelegate(ListWidget *parent) : QItemDelegate(parent), m_listWidget(parent) { }
96
private:
Daniel Teske's avatar
Daniel Teske committed
97
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
98 99 100 101
    void paint(QPainter *painter,
               const QStyleOptionViewItem &option,
               const QModelIndex &index) const;
    mutable QImage selectionGradient;
102
    ListWidget *m_listWidget;
103 104
};

Daniel Teske's avatar
Daniel Teske committed
105 106 107 108
QSize TargetSelectorDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(option)
    Q_UNUSED(index)
109
    return QSize(m_listWidget->size().width(), 30);
Daniel Teske's avatar
Daniel Teske committed
110 111
}

112 113
void TargetSelectorDelegate::paint(QPainter *painter,
                                   const QStyleOptionViewItem &option,
Daniel Teske's avatar
Daniel Teske committed
114
                                   const QModelIndex &index) const
115 116 117 118 119 120 121 122
{
    painter->save();
    painter->setClipping(false);

    if (selectionGradient.isNull())
        selectionGradient.load(QLatin1String(":/projectexplorer/images/targetpanel_gradient.png"));

    if (option.state & QStyle::State_Selected) {
123 124 125 126
        QColor color =(option.state & QStyle::State_HasFocus) ?
                      option.palette.highlight().color() :
                      option.palette.dark().color();
        painter->fillRect(option.rect, color.darker(140));
127 128 129 130 131 132 133 134
        Utils::StyleHelper::drawCornerImage(selectionGradient, painter, option.rect.adjusted(0, 0, 0, -1), 5, 5, 5, 5);
        painter->setPen(QColor(255, 255, 255, 60));
        painter->drawLine(option.rect.topLeft(), option.rect.topRight());
        painter->setPen(QColor(255, 255, 255, 30));
        painter->drawLine(option.rect.bottomLeft() - QPoint(0,1), option.rect.bottomRight() -  QPoint(0,1));
        painter->setPen(QColor(0, 0, 0, 80));
        painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight());
    }
Daniel Teske's avatar
Daniel Teske committed
135 136 137 138 139 140 141 142

    QFontMetrics fm(option.font);
    QString text = index.data(Qt::DisplayRole).toString();
    painter->setPen(QColor(255, 255, 255, 160));
    QString elidedText = fm.elidedText(text, Qt::ElideMiddle, option.rect.width() - 12);
    if (elidedText != text)
        const_cast<QAbstractItemModel *>(index.model())->setData(index, text, Qt::ToolTipRole);
    else
143
        const_cast<QAbstractItemModel *>(index.model())->setData(index, QString(), Qt::ToolTipRole);
Daniel Teske's avatar
Daniel Teske committed
144 145
    painter->drawText(option.rect.left() + 6, option.rect.top() + (option.rect.height() - fm.height()) / 2 + fm.ascent(), elidedText);

146 147 148
    painter->restore();
}

Daniel Teske's avatar
Daniel Teske committed
149 150 151 152
////////
// ListWidget
////////
ListWidget::ListWidget(QWidget *parent)
153
    : QListWidget(parent), m_maxCount(0), m_optimalWidth(0)
Tobias Hunger's avatar
Tobias Hunger committed
154 155 156 157 158
{
    setFocusPolicy(Qt::NoFocus);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setAlternatingRowColors(false);
    setFocusPolicy(Qt::WheelFocus);
159
    setItemDelegate(new TargetSelectorDelegate(this));
160
    setAttribute(Qt::WA_MacShowFocusRect, false);
Daniel Teske's avatar
Daniel Teske committed
161 162
    setStyleSheet(QString::fromLatin1("QListWidget { background: #464646; border-style: none; }"));
    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
Tobias Hunger's avatar
Tobias Hunger committed
163 164
}

Daniel Teske's avatar
Daniel Teske committed
165
void ListWidget::keyPressEvent(QKeyEvent *event)
Tobias Hunger's avatar
Tobias Hunger committed
166
{
Daniel Teske's avatar
Daniel Teske committed
167 168 169 170 171 172
    if (event->key() == Qt::Key_Left)
        focusPreviousChild();
    else if (event->key() == Qt::Key_Right)
        focusNextChild();
    else
        QListWidget::keyPressEvent(event);
Tobias Hunger's avatar
Tobias Hunger committed
173 174
}

Daniel Teske's avatar
Daniel Teske committed
175
void ListWidget::keyReleaseEvent(QKeyEvent *event)
Tobias Hunger's avatar
Tobias Hunger committed
176
{
177
    if (event->key() != Qt::Key_Left && event->key() != Qt::Key_Right)
Daniel Teske's avatar
Daniel Teske committed
178 179
        QListWidget::keyReleaseEvent(event);
}
Tobias Hunger's avatar
Tobias Hunger committed
180

Daniel Teske's avatar
Daniel Teske committed
181 182 183 184 185
void ListWidget::setMaxCount(int maxCount)
{
    m_maxCount = maxCount;
    updateGeometry();
}
Tobias Hunger's avatar
Tobias Hunger committed
186

187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
int ListWidget::maxCount()
{
    return m_maxCount;
}

int ListWidget::optimalWidth() const
{
    return m_optimalWidth;
}

void ListWidget::setOptimalWidth(int width)
{
    m_optimalWidth = width;
    updateGeometry();
}

int ListWidget::padding()
{
    // there needs to be enough extra pixels to show a scrollbar
    return 30;
}

Daniel Teske's avatar
Daniel Teske committed
209 210 211 212 213 214 215 216 217 218 219 220
////////
// ProjectListWidget
////////
ProjectListWidget::ProjectListWidget(SessionManager *sessionManager, QWidget *parent)
    : ListWidget(parent), m_sessionManager(sessionManager), m_ignoreIndexChange(false)
{
    connect(m_sessionManager, SIGNAL(projectAdded(ProjectExplorer::Project*)),
            this, SLOT(addProject(ProjectExplorer::Project*)));
    connect(m_sessionManager, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)),
            this, SLOT(removeProject(ProjectExplorer::Project*)));
    connect(m_sessionManager, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
            this, SLOT(changeStartupProject(ProjectExplorer::Project*)));
221 222
    connect(m_sessionManager, SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)),
            this, SLOT(projectDisplayNameChanged(ProjectExplorer::Project*)));
Daniel Teske's avatar
Daniel Teske committed
223 224 225 226 227 228 229 230 231 232
    connect(this, SIGNAL(currentRowChanged(int)),
            this, SLOT(setProject(int)));
}

QListWidgetItem *ProjectListWidget::itemForProject(Project *project)
{
    for (int i = 0; i < count(); ++i) {
        QListWidgetItem *currentItem = item(i);
        if (currentItem->data(Qt::UserRole).value<Project*>() == project)
            return currentItem;
Tobias Hunger's avatar
Tobias Hunger committed
233
    }
Daniel Teske's avatar
Daniel Teske committed
234 235 236 237 238
    return 0;
}

QString ProjectListWidget::fullName(ProjectExplorer::Project *project)
{
239
    return tr("%1 (%2)").arg(project->displayName(), project->projectFilePath());
Daniel Teske's avatar
Daniel Teske committed
240
}
241

Daniel Teske's avatar
Daniel Teske committed
242 243 244
void ProjectListWidget::addProject(Project *project)
{
    m_ignoreIndexChange = true;
245

246
    int pos = count();
Daniel Teske's avatar
Daniel Teske committed
247 248
    for (int i=0; i < count(); ++i) {
        Project *p = item(i)->data(Qt::UserRole).value<Project*>();
249
        if (projectLesserThan(project, p)) {
Daniel Teske's avatar
Daniel Teske committed
250
            pos = i;
251 252
            break;
        }
Daniel Teske's avatar
Daniel Teske committed
253
    }
254

Daniel Teske's avatar
Daniel Teske committed
255 256 257 258 259 260 261 262
    bool useFullName = false;
    for (int i = 0; i < count(); ++i) {
        Project *p = item(i)->data(Qt::UserRole).value<Project*>();
        if (p->displayName() == project->displayName()) {
            useFullName = true;
            item(i)->setText(fullName(p));
        }
    }
263

Daniel Teske's avatar
Daniel Teske committed
264 265 266 267 268
    QString displayName = useFullName ? fullName(project) : project->displayName();
    QListWidgetItem *item = new QListWidgetItem();
    item->setData(Qt::UserRole, QVariant::fromValue(project));
    item->setText(displayName);
    insertItem(pos, item);
Tobias Hunger's avatar
Tobias Hunger committed
269

270
    if (project == ProjectExplorerPlugin::instance()->startupProject())
Daniel Teske's avatar
Daniel Teske committed
271
        setCurrentItem(item);
272

273
    QFontMetrics fn(font());
274
    int width = fn.width(displayName) + padding();
275 276 277
    if (width > optimalWidth())
        setOptimalWidth(width);

Daniel Teske's avatar
Daniel Teske committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
    m_ignoreIndexChange = false;
}

void ProjectListWidget::removeProject(Project *project)
{
    m_ignoreIndexChange = true;

    QListWidgetItem *listItem = itemForProject(project);
    delete listItem;

    // Update display names
    QString name = project->displayName();
    int countDisplayName = 0;
    int otherIndex = -1;
    for (int i = 0; i < count(); ++i) {
        Project *p = item(i)->data(Qt::UserRole).value<Project *>();
        if (p->displayName() == name) {
            ++countDisplayName;
            otherIndex = i;
        }
    }
    if (countDisplayName == 1) {
        Project *p = item(otherIndex)->data(Qt::UserRole).value<Project *>();
        item(otherIndex)->setText(p->displayName());
Tobias Hunger's avatar
Tobias Hunger committed
302
    }
303

304 305 306 307
    QFontMetrics fn(font());

    // recheck optimal width
    int width = 0;
308 309
    for (int i = 0; i < count(); ++i)
        width = qMax(fn.width(item(i)->text()) + padding(), width);
310
    setOptimalWidth(width);
Daniel Teske's avatar
Daniel Teske committed
311

312
    m_ignoreIndexChange = false;
313 314
}

315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
void ProjectListWidget::projectDisplayNameChanged(Project *project)
{
    m_ignoreIndexChange = true;

    int oldPos = 0;
    bool useFullName = false;
    for (int i = 0; i < count(); ++i) {
        Project *p = item(i)->data(Qt::UserRole).value<Project*>();
        if (p == project) {
            oldPos = i;
        } else if (p->displayName() == project->displayName()) {
            useFullName = true;
            item(i)->setText(fullName(p));
        }
    }

    bool isCurrentItem = (oldPos == currentRow());
    QListWidgetItem *projectItem = takeItem(oldPos);

    int pos = count();
    for (int i = 0; i < count(); ++i) {
        Project *p = item(i)->data(Qt::UserRole).value<Project*>();
337
        if (projectLesserThan(project, p)) {
338 339 340 341 342 343 344 345 346 347 348
            pos = i;
            break;
        }
    }

    QString displayName = useFullName ? fullName(project) : project->displayName();
    projectItem->setText(displayName);
    insertItem(pos, projectItem);
    if (isCurrentItem)
        setCurrentRow(pos);

349 350 351
    // recheck optimal width
    QFontMetrics fn(font());
    int width = 0;
352 353
    for (int i = 0; i < count(); ++i)
        width = qMax(fn.width(item(i)->text()) + padding(), width);
354 355
    setOptimalWidth(width);

356 357 358
    m_ignoreIndexChange = false;
}

Daniel Teske's avatar
Daniel Teske committed
359
void ProjectListWidget::setProject(int index)
con's avatar
con committed
360
{
Daniel Teske's avatar
Daniel Teske committed
361 362 363 364 365 366
    if (m_ignoreIndexChange)
        return;
    if (index < 0)
        return;
    Project *p = item(index)->data(Qt::UserRole).value<Project *>();
    m_sessionManager->setStartupProject(p);
con's avatar
con committed
367 368
}

Daniel Teske's avatar
Daniel Teske committed
369
void ProjectListWidget::changeStartupProject(Project *project)
Tobias Hunger's avatar
Tobias Hunger committed
370
{
Daniel Teske's avatar
Daniel Teske committed
371
    setCurrentItem(itemForProject(project));
Tobias Hunger's avatar
Tobias Hunger committed
372 373
}

Daniel Teske's avatar
Daniel Teske committed
374 375 376 377 378 379
/////////
// GenericListWidget
/////////

GenericListWidget::GenericListWidget(QWidget *parent)
    : ListWidget(parent), m_ignoreIndexChange(false)
380
{
Daniel Teske's avatar
Daniel Teske committed
381 382
    connect(this, SIGNAL(currentRowChanged(int)),
            this, SLOT(rowChanged(int)));
383 384
}

Daniel Teske's avatar
Daniel Teske committed
385
void GenericListWidget::setProjectConfigurations(const QList<ProjectConfiguration *> &list, ProjectConfiguration *active)
386
{
Daniel Teske's avatar
Daniel Teske committed
387 388 389 390 391 392 393
    m_ignoreIndexChange = true;
    clear();
    for (int i = 0; i < count(); ++i) {
        ProjectConfiguration *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
        disconnect(p, SIGNAL(displayNameChanged()),
                   this, SLOT(displayNameChanged()));
    }
394 395 396 397

    QFontMetrics fn(font());
    int width = 0;
    foreach (ProjectConfiguration *pc, list) {
Daniel Teske's avatar
Daniel Teske committed
398
        addProjectConfiguration(pc);
399 400 401
        width = qMax(width, fn.width(pc->displayName()) + padding());
    }
    setOptimalWidth(width);
Daniel Teske's avatar
Daniel Teske committed
402
    setActiveProjectConfiguration(active);
403

Daniel Teske's avatar
Daniel Teske committed
404
    m_ignoreIndexChange = false;
405
}
dt's avatar
dt committed
406

Daniel Teske's avatar
Daniel Teske committed
407
void GenericListWidget::setActiveProjectConfiguration(ProjectConfiguration *active)
408
{
Daniel Teske's avatar
Daniel Teske committed
409 410
    QListWidgetItem *item = itemForProjectConfiguration(active);
    setCurrentItem(item);
411 412
}

Daniel Teske's avatar
Daniel Teske committed
413
void GenericListWidget::addProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc)
414
{
Daniel Teske's avatar
Daniel Teske committed
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
    m_ignoreIndexChange = true;
    QListWidgetItem *lwi = new QListWidgetItem();
    lwi->setText(pc->displayName());
    lwi->setData(Qt::UserRole, QVariant::fromValue(pc));

    // Figure out pos
    int pos = count();
    for (int i = 0; i < count(); ++i) {
        ProjectConfiguration *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
        if (pc->displayName() < p->displayName()) {
            pos = i;
            break;
        }
    }
    insertItem(pos, lwi);

    connect(pc, SIGNAL(displayNameChanged()),
            this, SLOT(displayNameChanged()));
433 434 435 436 437

    QFontMetrics fn(font());
    int width = fn.width(pc->displayName()) + padding();
    if (width > optimalWidth())
        setOptimalWidth(width);
Daniel Teske's avatar
Daniel Teske committed
438
    m_ignoreIndexChange = false;
439 440
}

Daniel Teske's avatar
Daniel Teske committed
441
void GenericListWidget::removeProjectConfiguration(ProjectExplorer::ProjectConfiguration *pc)
442
{
Daniel Teske's avatar
Daniel Teske committed
443 444 445 446
    m_ignoreIndexChange = true;
    disconnect(pc, SIGNAL(displayNameChanged()),
               this, SLOT(displayNameChanged()));
    delete itemForProjectConfiguration(pc);
447 448 449 450 451 452 453 454 455

    QFontMetrics fn(font());
    int width = 0;
    for (int i = 0; i < count(); ++i) {
        ProjectConfiguration *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
        width = qMax(width, fn.width(p->displayName()) + padding());
    }
    setOptimalWidth(width);

Daniel Teske's avatar
Daniel Teske committed
456
    m_ignoreIndexChange = false;
457 458
}

Daniel Teske's avatar
Daniel Teske committed
459
void GenericListWidget::rowChanged(int index)
460
{
Daniel Teske's avatar
Daniel Teske committed
461 462 463 464 465
    if (m_ignoreIndexChange)
        return;
    if (index < 0)
        return;
    emit changeActiveProjectConfiguration(item(index)->data(Qt::UserRole).value<ProjectConfiguration *>());
466 467
}

Daniel Teske's avatar
Daniel Teske committed
468
void GenericListWidget::displayNameChanged()
469
{
Daniel Teske's avatar
Daniel Teske committed
470
    m_ignoreIndexChange = true;
471 472 473 474
    ProjectConfiguration *activeProjectConfiguration = 0;
    if (currentItem())
        activeProjectConfiguration = currentItem()->data(Qt::UserRole).value<ProjectConfiguration *>();

Daniel Teske's avatar
Daniel Teske committed
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
    ProjectConfiguration *pc = qobject_cast<ProjectConfiguration *>(sender());
    int index = -1;
    int i = 0;
    for (; i < count(); ++i) {
        QListWidgetItem *lwi = item(i);
        if (lwi->data(Qt::UserRole).value<ProjectConfiguration *>() == pc) {
            index = i;
            break;
        }
    }
    if (index == -1)
        return;
    QListWidgetItem *lwi = takeItem(i);
    lwi->setText(pc->displayName());
    int pos = count();
    for (int i = 0; i < count(); ++i) {
        ProjectConfiguration *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
        if (pc->displayName() < p->displayName()) {
            pos = i;
            break;
        }
    }
    insertItem(pos, lwi);
498 499
    if (activeProjectConfiguration)
        setCurrentItem(itemForProjectConfiguration(activeProjectConfiguration));
500 501 502 503 504 505 506 507 508

    QFontMetrics fn(font());
    int width = 0;
    for (int i = 0; i < count(); ++i) {
        ProjectConfiguration *p = item(i)->data(Qt::UserRole).value<ProjectConfiguration *>();
        width = qMax(width, fn.width(p->displayName()) + padding());
    }
    setOptimalWidth(width);

Daniel Teske's avatar
Daniel Teske committed
509
    m_ignoreIndexChange = false;
510 511
}

Daniel Teske's avatar
Daniel Teske committed
512
QListWidgetItem *GenericListWidget::itemForProjectConfiguration(ProjectConfiguration *pc)
513
{
Daniel Teske's avatar
Daniel Teske committed
514 515
    for (int i = 0; i < count(); ++i) {
        QListWidgetItem *lwi = item(i);
516
        if (lwi->data(Qt::UserRole).value<ProjectConfiguration *>() == pc)
Daniel Teske's avatar
Daniel Teske committed
517 518 519
            return lwi;
    }
    return 0;
520 521
}

522
QWidget *MiniProjectTargetSelector::createTitleLabel(const QString &text)
Tobias Hunger's avatar
Tobias Hunger committed
523
{
524
    Utils::StyledBar *bar = new Utils::StyledBar(this);
Daniel Teske's avatar
Daniel Teske committed
525 526
    bar->setSingleRow(true);
    QVBoxLayout *toolLayout = new QVBoxLayout(bar);
527
    toolLayout->setContentsMargins(6, 0, 6, 0);
Daniel Teske's avatar
Daniel Teske committed
528 529 530 531 532 533 534 535 536 537 538 539
    toolLayout->setSpacing(0);

    QLabel *l = new QLabel(text);
    QFont f = l->font();
    f.setBold(true);
    l->setFont(f);
    toolLayout->addWidget(l);

    int panelHeight = l->fontMetrics().height() + 12;
    bar->ensurePolished(); // Required since manhattanstyle overrides height
    bar->setFixedHeight(panelHeight);
    return bar;
Tobias Hunger's avatar
Tobias Hunger committed
540 541
}

Daniel Teske's avatar
Daniel Teske committed
542 543 544 545 546 547 548 549 550 551 552 553
MiniProjectTargetSelector::MiniProjectTargetSelector(QAction *targetSelectorAction, SessionManager *sessionManager, QWidget *parent) :
    QWidget(parent), m_projectAction(targetSelectorAction), m_sessionManager(sessionManager),
    m_project(0),
    m_target(0),
    m_buildConfiguration(0),
    m_deployConfiguration(0),
    m_runConfiguration(0),
    m_hideOnRelease(false)
{
    QPalette p = palette();
    p.setColor(QPalette::Text, QColor(255, 255, 255, 160));
    setPalette(p);
554 555
    setProperty("panelwidget", true);
    setContentsMargins(QMargins(0, 1, 1, 8));
556 557 558 559 560
    setWindowFlags(Qt::Popup);

    targetSelectorAction->setIcon(style()->standardIcon(QStyle::SP_ComputerIcon));
    targetSelectorAction->setProperty("titledAction", true);

Daniel Teske's avatar
Daniel Teske committed
561 562 563 564
    m_summaryLabel = new QLabel(this);
    m_summaryLabel->setMargin(3);
    m_summaryLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    m_summaryLabel->setStyleSheet(QString::fromLatin1("background: #464646;"));
565 566
    m_summaryLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
    m_summaryLabel->setTextInteractionFlags(m_summaryLabel->textInteractionFlags() | Qt::LinksAccessibleByMouse);
Daniel Teske's avatar
Daniel Teske committed
567 568 569 570 571 572 573 574 575

    m_listWidgets.resize(LAST);
    m_titleWidgets.resize(LAST);
    m_listWidgets[PROJECT] = 0; //project is not a generic list widget

    m_titleWidgets[PROJECT] = createTitleLabel(tr("Project"));
    m_projectListWidget = new ProjectListWidget(m_sessionManager, this);

    QStringList titles;
Tobias Hunger's avatar
Tobias Hunger committed
576
    titles << tr("Kit") << tr("Build")
Daniel Teske's avatar
Daniel Teske committed
577 578 579 580 581 582 583 584 585 586 587
           << tr("Deploy") << tr("Run");

    for (int i = TARGET; i < LAST; ++i) {
        m_titleWidgets[i] = createTitleLabel(titles.at(i -1));
        m_listWidgets[i] = new GenericListWidget(this);
    }

    changeStartupProject(m_sessionManager->startupProject());
    if (m_sessionManager->startupProject())
        activeTargetChanged(m_sessionManager->startupProject()->activeTarget());

588 589 590
    connect(m_summaryLabel, SIGNAL(linkActivated(QString)),
            this, SLOT(switchToProjectsMode()));

Daniel Teske's avatar
Daniel Teske committed
591 592 593 594 595 596 597
    connect(m_sessionManager, SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
            this, SLOT(changeStartupProject(ProjectExplorer::Project*)));

    connect(m_sessionManager, SIGNAL(projectAdded(ProjectExplorer::Project*)),
            this, SLOT(projectAdded(ProjectExplorer::Project*)));
    connect(m_sessionManager, SIGNAL(projectRemoved(ProjectExplorer::Project*)),
            this, SLOT(projectRemoved(ProjectExplorer::Project*)));
598 599
    connect(m_sessionManager, SIGNAL(projectDisplayNameChanged(ProjectExplorer::Project*)),
            this, SLOT(updateActionAndSummary()));
Daniel Teske's avatar
Daniel Teske committed
600

Tobias Hunger's avatar
Tobias Hunger committed
601
    // for icon changes:
Tobias Hunger's avatar
Tobias Hunger committed
602 603
    connect(ProjectExplorer::KitManager::instance(), SIGNAL(kitUpdated(ProjectExplorer::Kit*)),
            this, SLOT(kitChanged(ProjectExplorer::Kit*)));
Tobias Hunger's avatar
Tobias Hunger committed
604

Daniel Teske's avatar
Daniel Teske committed
605
    connect(m_listWidgets[TARGET], SIGNAL(changeActiveProjectConfiguration(ProjectExplorer::ProjectConfiguration*)),
Robert Loehning's avatar
Robert Loehning committed
606
            this, SLOT(setActiveTarget(ProjectExplorer::ProjectConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
607
    connect(m_listWidgets[BUILD], SIGNAL(changeActiveProjectConfiguration(ProjectExplorer::ProjectConfiguration*)),
Robert Loehning's avatar
Robert Loehning committed
608
            this, SLOT(setActiveBuildConfiguration(ProjectExplorer::ProjectConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
609
    connect(m_listWidgets[DEPLOY], SIGNAL(changeActiveProjectConfiguration(ProjectExplorer::ProjectConfiguration*)),
Robert Loehning's avatar
Robert Loehning committed
610
            this, SLOT(setActiveDeployConfiguration(ProjectExplorer::ProjectConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
611
    connect(m_listWidgets[RUN], SIGNAL(changeActiveProjectConfiguration(ProjectExplorer::ProjectConfiguration*)),
Robert Loehning's avatar
Robert Loehning committed
612
            this, SLOT(setActiveRunConfiguration(ProjectExplorer::ProjectConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
613
}
614

615 616
bool MiniProjectTargetSelector::event(QEvent *event)
{
617 618 619 620 621 622 623 624 625 626 627
    if (event->type() == QEvent::LayoutRequest) {
        doLayout(true);
        return true;
    } else if (event->type() == QEvent::ShortcutOverride) {
        if (static_cast<QKeyEvent *>(event)->key() == Qt::Key_Escape) {
            event->accept();
            return true;
        }
    }
    return QWidget::event(event);

628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
}

class IndexSorter
{
public:
    enum SortOrder { Less = 0, Greater = 1};

    IndexSorter(QVector<int> result, SortOrder order)
        : m_result(result), m_order(order)
    { }

    bool operator()(int i, int j)
    { return (m_result[i] < m_result[j]) ^ bool(m_order); }

private:
    QVector<int> m_result;
    SortOrder m_order;
};

// does some fancy calculations to ensure proper widths for the list widgets
QVector<int> MiniProjectTargetSelector::listWidgetWidths(int minSize, int maxSize)
{
    QVector<int> result;
    result.resize(LAST);
    if (m_projectListWidget->isVisibleTo(this))
        result[PROJECT] = m_projectListWidget->optimalWidth();
    else
        result[PROJECT] = -1;

    for (int i = TARGET; i < LAST; ++i) {
        if (m_listWidgets[i]->isVisibleTo(this))
            result[i] = m_listWidgets[i]->optimalWidth();
        else
            result[i] = -1;
    }

    int totalWidth = 0;
    // Adjust to minimum width of title
    for (int i = PROJECT; i < LAST; ++i) {
        if (result[i] != -1) {
            // We want at least 100 pixels per column
            int width = qMax(m_titleWidgets[i]->sizeHint().width(), 100);
            if (result[i] < width)
                result[i] = width;
            totalWidth += result[i];
        }
    }

    if (totalWidth == 0) // All hidden
        return result;

    bool tooSmall;
    if (totalWidth < minSize)
        tooSmall = true;
    else if (totalWidth > maxSize)
        tooSmall = false;
    else
        return result;

    int widthToDistribute = tooSmall ? (minSize - totalWidth)
                                     : (totalWidth - maxSize);
    QVector<int> indexes;
    indexes.reserve(LAST);
    for (int i = PROJECT; i < LAST; ++i)
        if (result[i] != -1)
            indexes.append(i);

    IndexSorter indexSorter(result, tooSmall ? IndexSorter::Less : IndexSorter::Greater);
    qSort(indexes.begin(), indexes.end(), indexSorter);

    int i = 0;
    int first = result[indexes.first()]; // biggest or smallest

    // we resize the biggest columns until they are the same size as the second biggest
    // since it looks prettiest if all the columns are the same width
    while (true) {
        for (; i < indexes.size(); ++i) {
            if (result[indexes[i]] != first)
                break;
        }
        int next = tooSmall ? INT_MAX : 0;
        if (i < indexes.size())
            next = result[indexes[i]];

        int delta;
        if (tooSmall)
            delta = qMin(next - first, widthToDistribute / i);
        else
            delta = qMin(first - next, widthToDistribute / i);

        if (delta == 0)
            return result;

        if (tooSmall) {
            for (int j = 0; j < i; ++j)
                result[indexes[j]] += delta;
        } else {
            for (int j = 0; j < i; ++j)
                result[indexes[j]] -= delta;
        }

        widthToDistribute -= delta * i;
        if (widthToDistribute == 0)
            return result;

        first = result[indexes.first()];
        i = 0; // TODO can we do better?
    }
}

void MiniProjectTargetSelector::doLayout(bool keepSize)
{
    // An unconfigured project shows empty build/deploy/run sections
    // if there's a configured project in the seesion
    // that could be improved
    static QStatusBar *statusBar = Core::ICore::statusBar();
    static QWidget *actionBar = Core::ICore::mainWindow()->findChild<QWidget*>(QLatin1String("actionbar"));
    Q_ASSERT(actionBar);

    // 1. Calculate the summary label height
    int summaryLabelY = 1;
    int summaryLabelHeight = 0;
    int oldSummaryLabelHeight = m_summaryLabel->height();
    bool onlySummary = false;
    // Count the number of lines
    int visibleLineCount = m_projectListWidget->isVisibleTo(this) ? 0 : 1;
    for (int i = TARGET; i < LAST; ++i)
        visibleLineCount += m_listWidgets[i]->isVisibleTo(this) ? 0 : 1;

    if (visibleLineCount == LAST) {
        summaryLabelHeight = visibleLineCount * QFontMetrics(m_summaryLabel->font()).height()
                + m_summaryLabel->margin() *2;
        onlySummary = true;
    } else {
        if (visibleLineCount < 3) {
            foreach (Project *p, m_sessionManager->projects()) {
                if (p->needsConfiguration()) {
                    visibleLineCount = 3;
                    break;
                }
            }
        }
        if (visibleLineCount)
            summaryLabelHeight = visibleLineCount * QFontMetrics(m_summaryLabel->font()).height()
                    + m_summaryLabel->margin() *2;
    }

    if (keepSize && oldSummaryLabelHeight > summaryLabelHeight)
        summaryLabelHeight = oldSummaryLabelHeight;

    m_summaryLabel->move(0, summaryLabelY);

    // Height to be aligned with side bar button
781 782 783
    int alignedWithActionHeight = 210;
    if (actionBar->isVisible())
        alignedWithActionHeight = actionBar->height() - statusBar->height();
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853
    int bottomMargin = 9;
    int totalHeight = 0;

    if (!onlySummary) {
        // list widget heigth
        int maxItemCount = m_projectListWidget->maxCount();
        for (int i = TARGET; i < LAST; ++i)
            maxItemCount = qMax(maxItemCount, m_listWidgets[i]->maxCount());

        int titleWidgetsHeight = m_titleWidgets.first()->height();
        if (keepSize) {
            totalHeight = height();
        } else {
            // Clamp the size of the listwidgets to be
            // at least as high as the the sidebar button
            // and at most twice as high
            totalHeight = summaryLabelHeight + qBound(alignedWithActionHeight,
                                                      maxItemCount * 30 + bottomMargin + titleWidgetsHeight,
                                                      alignedWithActionHeight * 2);
        }

        int titleY = summaryLabelY + summaryLabelHeight;
        int listY = titleY + titleWidgetsHeight;
        int listHeight = totalHeight - bottomMargin - listY + 1;

        // list widget widths
        int minWidth = qMax(m_summaryLabel->sizeHint().width(), 250);
        if (keepSize) {
            // Do not make the widget smaller then it was before
            int oldTotalListWidgetWidth = m_projectListWidget->isVisibleTo(this) ?
                    m_projectListWidget->width() : 0;
            for (int i = TARGET; i < LAST; ++i)
                oldTotalListWidgetWidth += m_listWidgets[i]->width();
            minWidth = qMax(minWidth, oldTotalListWidgetWidth);
        }

        QVector<int> widths = listWidgetWidths(minWidth, 1000);
        int x = 0;
        for (int i = PROJECT; i < LAST; ++i) {
            int optimalWidth = widths[i];
            if (i == PROJECT) {
                m_projectListWidget->resize(optimalWidth, listHeight);
                m_projectListWidget->move(x, listY);
            } else {
                m_listWidgets[i]->resize(optimalWidth, listHeight);
                m_listWidgets[i]->move(x, listY);
            }
            m_titleWidgets[i]->resize(optimalWidth, titleWidgetsHeight);
            m_titleWidgets[i]->move(x, titleY);
            x += optimalWidth + 1; //1 extra pixel for the separators or the right border
        }

        m_summaryLabel->resize(x - 1, summaryLabelHeight);
        setFixedSize(x, totalHeight);
    } else {
        if (keepSize)
            totalHeight = height();
        else
            totalHeight = qMax(summaryLabelHeight + bottomMargin, alignedWithActionHeight);
        m_summaryLabel->resize(m_summaryLabel->sizeHint().width(), totalHeight - bottomMargin);
        setFixedSize(m_summaryLabel->width() + 1, totalHeight); //1 extra pixel for the border
    }

    if (isVisibleTo(parentWidget())) {
        QPoint moveTo = statusBar->mapToGlobal(QPoint(0,0));
        moveTo -= QPoint(0, totalHeight);
        move(moveTo);
    }
}

Daniel Teske's avatar
Daniel Teske committed
854 855 856 857
void MiniProjectTargetSelector::setActiveTarget(ProjectExplorer::ProjectConfiguration *pc)
{
    m_project->setActiveTarget(static_cast<Target *>(pc));
}
858

Daniel Teske's avatar
Daniel Teske committed
859 860 861 862
void MiniProjectTargetSelector::setActiveBuildConfiguration(ProjectExplorer::ProjectConfiguration *pc)
{
    m_target->setActiveBuildConfiguration(static_cast<BuildConfiguration *>(pc));
}
863

Daniel Teske's avatar
Daniel Teske committed
864 865 866 867 868 869 870 871 872
void MiniProjectTargetSelector::setActiveDeployConfiguration(ProjectExplorer::ProjectConfiguration *pc)
{
    m_target->setActiveDeployConfiguration(static_cast<DeployConfiguration *>(pc));
}

void MiniProjectTargetSelector::setActiveRunConfiguration(ProjectExplorer::ProjectConfiguration *pc)
{
    m_target->setActiveRunConfiguration(static_cast<RunConfiguration *>(pc));
}
873

Daniel Teske's avatar
Daniel Teske committed
874 875 876
void MiniProjectTargetSelector::projectAdded(ProjectExplorer::Project *project)
{
    connect(project, SIGNAL(addedTarget(ProjectExplorer::Target*)),
877
            this, SLOT(slotAddedTarget(ProjectExplorer::Target*)));
878

Daniel Teske's avatar
Daniel Teske committed
879
    connect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
880
            this, SLOT(slotRemovedTarget(ProjectExplorer::Target*)));
881

Daniel Teske's avatar
Daniel Teske committed
882 883
    foreach (Target *t, project->targets())
        addedTarget(t);
884

Daniel Teske's avatar
Daniel Teske committed
885 886 887 888 889
    updateProjectListVisible();
    updateTargetListVisible();
    updateBuildListVisible();
    updateDeployListVisible();
    updateRunListVisible();
890 891
}

Daniel Teske's avatar
Daniel Teske committed
892
void MiniProjectTargetSelector::projectRemoved(ProjectExplorer::Project *project)
893
{
Daniel Teske's avatar
Daniel Teske committed
894
    disconnect(project, SIGNAL(addedTarget(ProjectExplorer::Target*)),
895
               this, SLOT(slotAddedTarget(ProjectExplorer::Target*)));
896

Daniel Teske's avatar
Daniel Teske committed
897
    disconnect(project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
898
               this, SLOT(slotRemovedTarget(ProjectExplorer::Target*)));
899

Daniel Teske's avatar
Daniel Teske committed
900 901
    foreach (Target *t, project->targets())
        removedTarget(t);
902

Daniel Teske's avatar
Daniel Teske committed
903 904 905 906 907
    updateProjectListVisible();
    updateTargetListVisible();
    updateBuildListVisible();
    updateDeployListVisible();
    updateRunListVisible();
908 909
}

Daniel Teske's avatar
Daniel Teske committed
910
void MiniProjectTargetSelector::addedTarget(ProjectExplorer::Target *target)
911
{
Daniel Teske's avatar
Daniel Teske committed
912
    connect(target, SIGNAL(addedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
913
            this, SLOT(slotAddedBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
914
    connect(target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
915
            this, SLOT(slotRemovedBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
916 917

    connect(target, SIGNAL(addedDeployConfiguration(ProjectExplorer::DeployConfiguration*)),
918
            this, SLOT(slotAddedDeployConfiguration(ProjectExplorer::DeployConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
919
    connect(target, SIGNAL(removedDeployConfiguration(ProjectExplorer::DeployConfiguration*)),
920
            this, SLOT(slotRemovedDeployConfiguration(ProjectExplorer::DeployConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
921 922

    connect(target, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)),
923
            this, SLOT(slotAddedRunConfiguration(ProjectExplorer::RunConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
924
    connect(target, SIGNAL(removedRunConfiguration(ProjectExplorer::RunConfiguration*)),
925
            this, SLOT(slotRemovedRunConfiguration(ProjectExplorer::RunConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
926 927 928 929 930 931 932 933 934 935

    if (target->project() == m_project)
        m_listWidgets[TARGET]->addProjectConfiguration(target);

    foreach (BuildConfiguration *bc, target->buildConfigurations())
        addedBuildConfiguration(bc);
    foreach (DeployConfiguration *dc, target->deployConfigurations())
        addedDeployConfiguration(dc);
    foreach (RunConfiguration *rc, target->runConfigurations())
        addedRunConfiguration(rc);
936
}
Daniel Teske's avatar
Daniel Teske committed
937

938 939 940
void MiniProjectTargetSelector::slotAddedTarget(ProjectExplorer::Target *target)
{
    addedTarget(target);
Daniel Teske's avatar
Daniel Teske committed
941 942 943 944
    updateTargetListVisible();
    updateBuildListVisible();
    updateDeployListVisible();
    updateRunListVisible();
945 946
}

Daniel Teske's avatar
Daniel Teske committed
947
void MiniProjectTargetSelector::removedTarget(ProjectExplorer::Target *target)
948
{
Daniel Teske's avatar
Daniel Teske committed
949
    disconnect(target, SIGNAL(addedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
950
               this, SLOT(slotAddedBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
951
    disconnect(target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
952
               this, SLOT(slotRemovedBuildConfiguration(ProjectExplorer::BuildConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
953 954

    disconnect(target, SIGNAL(addedDeployConfiguration(ProjectExplorer::DeployConfiguration*)),
955
               this, SLOT(slotAddedDeployConfiguration(ProjectExplorer::DeployConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
956
    disconnect(target, SIGNAL(removedDeployConfiguration(ProjectExplorer::DeployConfiguration*)),
957
               this, SLOT(slotRemovedDeployConfiguration(ProjectExplorer::DeployConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
958 959

    disconnect(target, SIGNAL(addedRunConfiguration(ProjectExplorer::RunConfiguration*)),
960
               this, SLOT(slotAddedRunConfiguration(ProjectExplorer::RunConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
961
    disconnect(target, SIGNAL(removedRunConfiguration(ProjectExplorer::RunConfiguration*)),
962
               this, SLOT(slotRemovedRunConfiguration(ProjectExplorer::RunConfiguration*)));
Daniel Teske's avatar
Daniel Teske committed
963 964 965 966 967 968 969 970 971 972

    if (target->project() == m_project)
        m_listWidgets[TARGET]->removeProjectConfiguration(target);

    foreach (BuildConfiguration *bc, target->buildConfigurations())
        removedBuildConfiguration(bc);
    foreach (DeployConfiguration *dc, target->deployConfigurations())
        removedDeployConfiguration(dc);
    foreach (RunConfiguration *rc, target->runConfigurations())
        removedRunConfiguration(rc);
973 974 975 976 977
}

void MiniProjectTargetSelector::slotRemovedTarget(ProjectExplorer::Target *target)
{
    removedTarget(target);
Daniel Teske's avatar
Daniel Teske committed
978 979 980 981 982

    updateTargetListVisible();
    updateBuildListVisible();
    updateDeployListVisible();
    updateRunListVisible();
983 984
}

985

Daniel Teske's avatar
Daniel Teske committed
986
void MiniProjectTargetSelector::addedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc)
987 988 989 990 991 992
{
    if (bc->target() == m_target)
        m_listWidgets[BUILD]->addProjectConfiguration(bc);
}

void MiniProjectTargetSelector::slotAddedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc)
993
{
Daniel Teske's avatar
Daniel Teske committed
994 995 996 997
    if (bc->target() == m_target)
        m_listWidgets[BUILD]->addProjectConfiguration(bc);
    updateBuildListVisible();
}
998

Daniel Teske's avatar
Daniel Teske committed
999
void MiniProjectTargetSelector::removedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc)
1000 1001 1002 1003 1004 1005
{
    if (bc->target() == m_target)
        m_listWidgets[BUILD]->removeProjectConfiguration(bc);
}

void MiniProjectTargetSelector::slotRemovedBuildConfiguration(ProjectExplorer::BuildConfiguration *bc)
Daniel Teske's avatar
Daniel Teske committed
1006 1007 1008 1009 1010
{
    if (bc->target() == m_target)
        m_listWidgets[BUILD]->removeProjectConfiguration(bc);
    updateBuildListVisible();
}
dt's avatar
dt committed
1011

Daniel Teske's avatar
Daniel Teske committed
1012
void MiniProjectTargetSelector::addedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc)
1013 1014 1015 1016 1017 1018
{
    if (dc->target() == m_target)
        m_listWidgets[DEPLOY]->addProjectConfiguration(dc);
}

void MiniProjectTargetSelector::slotAddedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc)
Daniel Teske's avatar
Daniel Teske committed
1019 1020 1021 1022 1023
{
    if (dc->target() == m_target)
        m_listWidgets[DEPLOY]->addProjectConfiguration(dc);
    updateDeployListVisible();
}
dt's avatar
dt committed
1024

Daniel Teske's avatar
Daniel Teske committed
1025
void MiniProjectTargetSelector::removedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc)
1026 1027 1028 1029 1030 1031
{
    if (dc->target() == m_target)
        m_listWidgets[DEPLOY]->removeProjectConfiguration(dc);
}

void MiniProjectTargetSelector::slotRemovedDeployConfiguration(ProjectExplorer::DeployConfiguration *dc)
Daniel Teske's avatar
Daniel Teske committed
1032 1033 1034 1035 1036
{
    if (dc->target() == m_target)
        m_listWidgets[DEPLOY]->removeProjectConfiguration(dc);
    updateDeployListVisible();
}
dt's avatar
dt committed
1037

Daniel Teske's avatar
Daniel Teske committed
1038
void MiniProjectTargetSelector::addedRunConfiguration(ProjectExplorer::RunConfiguration *rc)
1039 1040 1041 1042 1043 1044
{
    if (rc->target() == m_target)
        m_listWidgets[RUN]->addProjectConfiguration(rc);
}

void MiniProjectTargetSelector::slotAddedRunConfiguration(ProjectExplorer::RunConfiguration *rc)
Daniel Teske's avatar
Daniel Teske committed
1045 1046 1047 1048 1049
{
    if (rc->target() == m_target)
        m_listWidgets[RUN]->addProjectConfiguration(rc);
    updateRunListVisible();
}
1050

Daniel Teske's avatar
Daniel Teske committed
1051
void MiniProjectTargetSelector::removedRunConfiguration(ProjectExplorer::RunConfiguration *rc)
1052 1053 1054 1055 1056 1057
{
    if (rc->target() == m_target)
        m_listWidgets[RUN]->removeProjectConfiguration(rc);
}

void MiniProjectTargetSelector::slotRemovedRunConfiguration(ProjectExplorer::RunConfiguration *rc)
Daniel Teske's avatar
Daniel Teske committed
1058 1059 1060 1061 1062
{
    if (rc->target() == m_target)
        m_listWidgets[RUN]->removeProjectConfiguration(rc);
    updateRunListVisible();
}
1063

Daniel Teske's avatar
Daniel Teske committed
1064 1065 1066
void MiniProjectTargetSelector::updateProjectListVisible()
{
    bool visible = m_sessionManager->projects().size() > 1;
1067

Daniel Teske's avatar
Daniel Teske committed
1068 1069 1070
    m_projectListWidget->setVisible(visible);
    m_projectListWidget->setMaxCount(m_sessionManager->projects().size());
    m_titleWidgets[PROJECT]->setVisible(visible);
1071

Daniel Teske's avatar
Daniel Teske committed
1072 1073
    updateSummary();
}
Tobias Hunger's avatar
Tobias Hunger committed
1074

Daniel Teske's avatar
Daniel Teske committed
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
void MiniProjectTargetSelector::updateTargetListVisible()
{
    int maxCount = 0;
    foreach (Project *p, m_sessionManager->projects())
        maxCount = qMax(p->targets().size(), maxCount);

    bool visible = maxCount > 1;
    m_listWidgets[TARGET]->setVisible(visible);
    m_listWidgets[TARGET]->setMaxCount(maxCount);
    m_titleWidgets[TARGET]->setVisible(visible);
    updateSummary();
}
dt's avatar
dt committed
1087

Daniel Teske's avatar
Daniel Teske committed
1088