targetsetuppage.cpp 23.1 KB
Newer Older
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
con's avatar
con committed
5
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6
7
8
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
con's avatar
con committed
9
** No Commercial Usage
10
**
con's avatar
con committed
11
12
13
14
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
15
16
17
18
19
20
21
22
23
24
**
** GNU Lesser General Public License Usage
**
** 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.
**
con's avatar
con committed
25
26
27
28
29
30
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
31
32
33
34
35
**
**************************************************************************/

#include "targetsetuppage.h"

Tobias Hunger's avatar
Tobias Hunger committed
36
37
#include "ui_targetsetuppage.h"

38
#include "qt4project.h"
Tobias Hunger's avatar
Tobias Hunger committed
39
#include "qt4projectmanagerconstants.h"
40
#include "qt4target.h"
Tobias Hunger's avatar
Tobias Hunger committed
41
#include "qtversionmanager.h"
42

43
#include <extensionsystem/pluginmanager.h>
44
#include <projectexplorer/task.h>
dt's avatar
dt committed
45
#include <projectexplorer/taskhub.h>
46
#include <utils/qtcassert.h>
47
#include <utils/qtcprocess.h>
48

49
#include <QtGui/QAction>
50
#include <QtGui/QFileDialog>
51
52
53
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QLayout>
54
#include <QtGui/QMenu>
55
#include <QtGui/QMessageBox>
56
#include <QtGui/QPushButton>
57
58
#include <QtGui/QTreeWidget>

59
using namespace Qt4ProjectManager;
60
61
using namespace Qt4ProjectManager::Internal;

62
63
64
65
66
67
68
69
namespace {
enum Columns {
    NAME_COLUMN = 0,
    STATUS_COLUMN,
    DIRECTORY_COLUMN
};
} // namespace

70
TargetSetupPage::TargetSetupPage(QWidget *parent) :
Tobias Hunger's avatar
Tobias Hunger committed
71
    QWizardPage(parent),
Tobias Hunger's avatar
Tobias Hunger committed
72
    m_preferMobile(false),
73
    m_toggleWillCheck(false),
74
75
    m_ui(new Ui::TargetSetupPage),
    m_contextMenu(0)
76
{
Tobias Hunger's avatar
Tobias Hunger committed
77
78
79
    m_ui->setupUi(this);
    m_ui->versionTree->header()->setResizeMode(0, QHeaderView::ResizeToContents);
    m_ui->versionTree->header()->setResizeMode(1, QHeaderView::ResizeToContents);
80

81
82
83
    m_ui->versionTree->setContextMenuPolicy(Qt::CustomContextMenu);
    m_contextMenu = new QMenu(this);

Tobias Hunger's avatar
Tobias Hunger committed
84
    connect(m_ui->importButton, SIGNAL(clicked()),
85
            this, SLOT(addShadowBuildLocation()));
86
    connect(m_ui->uncheckButton, SIGNAL(clicked()),
87
            this, SLOT(checkAllButtonClicked()));
88
89
    connect(m_ui->versionTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
            this, SLOT(handleDoubleClicks(QTreeWidgetItem*,int)));
90
91
    connect(m_ui->versionTree, SIGNAL(customContextMenuRequested(QPoint)),
            this, SLOT(contextMenuRequested(QPoint)));
92
93

    setTitle(tr("Qt Versions"));
94
95
}

96
97
98
99
100
101
102
void TargetSetupPage::initializePage()
{
    // WORKAROUND: Somebody sets all buttons to autoDefault between the ctor and here!
    m_ui->importButton->setAutoDefault(false);
    m_ui->uncheckButton->setAutoDefault(false);
}

103
104
105
TargetSetupPage::~TargetSetupPage()
{
    resetInfos();
Tobias Hunger's avatar
Tobias Hunger committed
106
    delete m_ui;
107
108
109
110
}

void TargetSetupPage::setImportInfos(const QList<ImportInfo> &infos)
{
Tobias Hunger's avatar
Tobias Hunger committed
111
    disconnect(m_ui->versionTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
112
113
               this, SLOT(itemWasChanged()));

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    // Create a list of all temporary Qt versions we need to delete in our existing list
    QList<QtVersion *> toDelete;
    foreach (const ImportInfo &info, m_infos) {
        if (info.isTemporary)
            toDelete.append(info.version);
    }
    // Remove those that got copied into the new list to set up
    foreach (const ImportInfo &info, infos) {
        if (info.isTemporary)
            toDelete.removeAll(info.version);
    }
    // Delete the rest
    qDeleteAll(toDelete);
    // ... and clear the list
    m_infos.clear();
129
130
131
132

    // Find possible targets:
    QStringList targets;
    foreach (const ImportInfo &i, infos) {
133
        // Make sure we have no duplicate directories:
134
135
        bool skip = false;
        foreach (const ImportInfo &j, m_infos) {
136
            if (j.isExistingBuild && i.isExistingBuild && (j.directory == i.directory)) {
137
138
139
140
                skip = true;
                break;
            }
        }
141
142
143
        if (skip) {
            if (i.isTemporary)
                delete i.version;
144
            continue;
145
        }
146
147
148
149
150
151
152
153
154
155
156

        m_infos.append(i);

        QSet<QString> versionTargets = i.version->supportedTargetIds();
        foreach (const QString &t, versionTargets) {
            if (!targets.contains(t))
                targets.append(t);
        }
    }
    qSort(targets.begin(), targets.end());

Tobias Hunger's avatar
Tobias Hunger committed
157
    m_ui->versionTree->clear();
158
159
    Qt4TargetFactory factory;
    foreach (const QString &t, targets) {
Tobias Hunger's avatar
Tobias Hunger committed
160
161
        QTreeWidgetItem *targetItem = new QTreeWidgetItem(m_ui->versionTree);
        const QString targetName = factory.displayNameForId(t);
162
163
        targetItem->setText(NAME_COLUMN, targetName);
        targetItem->setToolTip(NAME_COLUMN, targetName);
164
        targetItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
165
        targetItem->setData(NAME_COLUMN, Qt::UserRole, t);
166
167
168
        targetItem->setExpanded(true);

        int pos = -1;
169
        foreach (const ImportInfo &i, m_infos) {
170
171
172
173
174
            ++pos;

            if (!i.version->supportsTargetId(t))
                continue;
            QTreeWidgetItem *versionItem = new QTreeWidgetItem(targetItem);
175
176
            updateVersionItem(versionItem, pos);

177
178
            // Prefer imports to creating new builds, but precheck any
            // Qt that exists (if there is no import with that version)
Tobias Hunger's avatar
Tobias Hunger committed
179
            bool shouldCheck = true;
180
181
182
            if (!i.isExistingBuild) {
                foreach (const ImportInfo &j, m_infos) {
                    if (j.isExistingBuild && j.version == i.version) {
Tobias Hunger's avatar
Tobias Hunger committed
183
                        shouldCheck = false;
184
185
186
187
                        break;
                    }
                }
            }
188

Tobias Hunger's avatar
Tobias Hunger committed
189
190
            shouldCheck = shouldCheck && (m_preferMobile == i.version->supportsMobileTarget());
            shouldCheck = shouldCheck || i.isExistingBuild; // always check imports
191
            shouldCheck = shouldCheck || m_infos.count() == 1; // always check only option
192
            versionItem->setCheckState(NAME_COLUMN, shouldCheck ? Qt::Checked : Qt::Unchecked);
193
194
195
        }
    }

Tobias Hunger's avatar
Tobias Hunger committed
196
    connect(m_ui->versionTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
197
198
199
200
201
202
203
204
205
206
207
208
            this, SLOT(itemWasChanged()));

    emit completeChanged();
}

QList<TargetSetupPage::ImportInfo> TargetSetupPage::importInfos() const
{
    return m_infos;
}

bool TargetSetupPage::hasSelection() const
{
Tobias Hunger's avatar
Tobias Hunger committed
209
210
    for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) {
        QTreeWidgetItem * current = m_ui->versionTree->topLevelItem(i);
211
212
        for (int j = 0; j < current->childCount(); ++j) {
            QTreeWidgetItem * child = current->child(j);
213
            if (child->checkState(NAME_COLUMN) == Qt::Checked)
214
215
216
217
218
219
220
221
                return true;
        }
    }
    return false;
}

bool TargetSetupPage::isTargetSelected(const QString &targetid) const
{
Tobias Hunger's avatar
Tobias Hunger committed
222
223
    for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) {
        QTreeWidgetItem * current = m_ui->versionTree->topLevelItem(i);
224
        if (current->data(NAME_COLUMN, Qt::UserRole).toString() != targetid)
225
226
227
            continue;
        for (int j = 0; j < current->childCount(); ++j) {
            QTreeWidgetItem * child = current->child(j);
228
            if (child->checkState(NAME_COLUMN) == Qt::Checked)
229
230
231
232
233
234
235
236
237
                return true;
        }
    }
    return false;
}

bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project)
{
    Q_ASSERT(project->targets().isEmpty());
238
    QtVersionManager *vm = QtVersionManager::instance();
239

240
241
242
243
    // TODO remove again
    Qt4TargetFactory *factory =
            ExtensionSystem::PluginManager::instance()->getObject<Qt4TargetFactory>();

Tobias Hunger's avatar
Tobias Hunger committed
244
245
    for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) {
        QTreeWidgetItem *current = m_ui->versionTree->topLevelItem(i);
246
        QString targetId = current->data(NAME_COLUMN, Qt::UserRole).toString();
247
248
249
250
251
252
253

        QList<BuildConfigurationInfo> targetInfos;
        for (int j = 0; j < current->childCount(); ++j) {
            QTreeWidgetItem *child = current->child(j);
            if (child->checkState(0) != Qt::Checked)
                continue;

254
            ImportInfo &info = m_infos[child->data(NAME_COLUMN, Qt::UserRole).toInt()];
255
256
257
258
259
260

            // Register temporary Qt version
            if (info.isTemporary) {
                vm->addVersion(info.version);
                info.isTemporary = false;
            }
261

262
263
264
265
            QString directory = info.directory;
            if (!info.isShadowBuild)
                directory = project->projectDirectory();

266
            // we want to havbe two BCs set up, one to build debug, the other to build release.
267
            targetInfos.append(BuildConfigurationInfo(info.version, info.buildConfig,
268
                                                      info.additionalArguments, directory));
269
            targetInfos.append(BuildConfigurationInfo(info.version, info.buildConfig ^ QtVersion::DebugBuild,
270
                                                      info.additionalArguments, directory));
271
272
273
274
        }

        // create the target:
        Qt4Target *target = 0;
275
        if (!targetInfos.isEmpty())
276
            target = factory->create(project, targetId, targetInfos);
277

Tobias Hunger's avatar
Tobias Hunger committed
278
        if (target) {
279
            project->addTarget(target);
Tobias Hunger's avatar
Tobias Hunger committed
280
281
282
            if (target->id() == QLatin1String(Constants::QT_SIMULATOR_TARGET_ID))
                project->setActiveTarget(target);
        }
283
284
    }

285
286
    // Create the default target if nothing else was set up:
    if (project->targets().isEmpty()) {
287
        Qt4Target *target = factory->create(project, Constants::DESKTOP_TARGET_ID);
288
289
290
291
        if (target)
            project->addTarget(target);
    }

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
    return !project->targets().isEmpty();
}

void TargetSetupPage::itemWasChanged()
{
    emit completeChanged();
}

bool TargetSetupPage::isComplete() const
{
    return hasSelection();
}

void TargetSetupPage::setImportDirectoryBrowsingEnabled(bool browsing)
{
Tobias Hunger's avatar
Tobias Hunger committed
307
308
    m_ui->importButton->setEnabled(browsing);
    m_ui->importButton->setVisible(browsing);
309
310
311
312
}

void TargetSetupPage::setImportDirectoryBrowsingLocation(const QString &directory)
{
313
    m_defaultShadowBuildLocation = directory;
314
315
}

Tobias Hunger's avatar
Tobias Hunger committed
316
317
318
319
320
void TargetSetupPage::setPreferMobile(bool mobile)
{
    m_preferMobile = mobile;
}

321
322
323
void TargetSetupPage::setProFilePath(const QString &path)
{
    m_proFilePath = path;
324
    if (!m_proFilePath.isEmpty()) {
325
        m_ui->descriptionLabel->setText(tr("Qt Creator can set up the following targets for<br>project <b>%1</b>:",
Tobias Hunger's avatar
Tobias Hunger committed
326
                                           "%1: Project name").arg(QFileInfo(m_proFilePath).baseName()));
327
    }
328
329
330
    // Force regeneration of tree widget contents:
    QList<ImportInfo> tmp = m_infos;
    setImportInfos(tmp);
331
332
}

333
QList<TargetSetupPage::ImportInfo> TargetSetupPage::importInfosForKnownQtVersions()
334
335
336
337
{
    QList<ImportInfo> results;
    QtVersionManager * vm = QtVersionManager::instance();
    QList<QtVersion *> validVersions = vm->validVersions();
338
339
340
    // Fallback in case no valid versions are found:
    if (validVersions.isEmpty())
        validVersions.append(vm->versions().at(0)); // there is always one!
341
342
343
344
    foreach (QtVersion *v, validVersions) {
        ImportInfo info;
        info.isExistingBuild = false;
        info.isTemporary = false;
345
        info.isShadowBuild = v->supportsShadowBuilds();
346
        info.version = v;
347
        info.buildConfig = v->defaultBuildConfig();
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
        results.append(info);
    }
    return results;
}

QList<TargetSetupPage::ImportInfo> TargetSetupPage::filterImportInfos(const QSet<QString> &validTargets,
                                                                      const QList<ImportInfo> &infos)
{
    QList<ImportInfo> results;
    foreach (const ImportInfo &info, infos) {
        Q_ASSERT(info.version);
        foreach (const QString &target, validTargets) {
            if (info.version->supportsTargetId(target))
                results.append(info);
        }
    }
    return results;
}

367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
QList<TargetSetupPage::ImportInfo>
TargetSetupPage::scanDefaultProjectDirectories(Qt4ProjectManager::Qt4Project *project)
{
    // Source directory:
    QList<ImportInfo> importVersions = TargetSetupPage::recursivelyCheckDirectoryForBuild(project->projectDirectory(),
                                                                                          project->file()->fileName());
    QtVersionManager *vm = QtVersionManager::instance();
    foreach(const QString &id, vm->supportedTargetIds()) {
        QString location = Qt4Target::defaultShadowBuildDirectory(project->defaultTopLevelBuildDirectory(), id);
        importVersions.append(TargetSetupPage::recursivelyCheckDirectoryForBuild(location,
                                                                                 project->file()->fileName()));
    }
    return importVersions;
}

382
QList<TargetSetupPage::ImportInfo>
383
TargetSetupPage::recursivelyCheckDirectoryForBuild(const QString &directory, const QString &proFile, int maxdepth)
384
385
386
{
    QList<ImportInfo> results;

387
    if (maxdepth <= 0 || directory.isEmpty())
388
389
390
        return results;

    // Check for in-source builds first:
391
    QString qmakeBinary = QtVersionManager::findQMakeBinaryFromMakefile(directory + "/Makefile");
392
    QDir dir(directory);
393
394

    // Recurse into subdirectories:
395
    if (qmakeBinary.isNull() || !QtVersionManager::makefileIsFor(directory + "/Makefile", proFile)) {
396
        QStringList subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
397
        foreach (QString subDir, subDirs)
398
            results.append(recursivelyCheckDirectoryForBuild(dir.absoluteFilePath(subDir),
399
                                                             proFile, maxdepth - 1));
400
401
402
403
404
405
        return results;
    }

    // Shiny fresh directory with a Makefile...
    QtVersionManager * vm = QtVersionManager::instance();
    TargetSetupPage::ImportInfo info;
406
    info.directory = dir.absolutePath();
407
    info.isShadowBuild = (info.directory != QFileInfo(proFile).absolutePath());
408
409
410
411
412
413
414
415
416
417
418
419

    // This also means we have a build in there
    // First get the qt version
    info.version = vm->qtVersionForQMakeBinary(qmakeBinary);
    info.isExistingBuild = true;

    // Okay does not yet exist, create
    if (!info.version) {
        info.version = new QtVersion(qmakeBinary);
        info.isTemporary = true;
    }

420
    QPair<QtVersion::QmakeBuildConfigs, QString> result =
421
            QtVersionManager::scanMakeFile(directory + "/Makefile", info.version->defaultBuildConfig());
422
    info.buildConfig = result.first;
423
424
    QString aa = result.second;
    QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&aa, directory, info.version);
425
426
427
428
429
430
    QString versionSpec = info.version->mkspec();

    // Compare mkspecs and add to additional arguments
    if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") {
        // using the default spec, don't modify additional arguments
    } else {
431
        info.additionalArguments = "-spec " + Utils::QtcProcess::quoteArg(parsedSpec);
432
    }
433
    Utils::QtcProcess::addArgs(&info.additionalArguments, aa);
434
435
436
437
438

    results.append(info);
    return results;
}

439
void TargetSetupPage::addShadowBuildLocation()
440
{
441
442
443
444
445
446
447
448
449
    QString newPath =
        QFileDialog::getExistingDirectory(this,
                                          tr("Choose a directory to scan for additional shadow builds"),
                                          m_defaultShadowBuildLocation);

    if (newPath.isEmpty())
        return;

    QFileInfo dir(QDir::fromNativeSeparators(newPath));
450
451
    if (!dir.exists() || !dir.isDir())
        return;
452

453
    QList<ImportInfo> tmp;
454
    tmp.append(recursivelyCheckDirectoryForBuild(dir.absoluteFilePath(), m_proFilePath));
455
    if (tmp.isEmpty()) {
Friedemann Kleint's avatar
Friedemann Kleint committed
456
457
        QMessageBox::warning(this, tr("No builds found"),
                             tr("No builds for project file \"%1\" were found in the folder \"%2\".",
458
459
460
461
462
                                "%1: pro-file, %2: directory that was checked.").
                             arg(m_proFilePath, dir.absoluteFilePath()));
        return;
    }
    tmp.append(m_infos);
463
464
465
    setImportInfos(tmp);
}

466
void TargetSetupPage::checkAll(bool checked)
467
468
469
{
    for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) {
        QTreeWidgetItem *current = m_ui->versionTree->topLevelItem(i);
470
471
        for (int j = 0; j < current->childCount(); ++j)
            checkOne(checked, current->child(j));
472
    }
473
474
475
476
477
478
479
480
481
482
483
484
}

void TargetSetupPage::checkOne(bool checked, QTreeWidgetItem *item)
{
    Q_ASSERT(item->parent()); // we are a version item
    item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked);
}

void TargetSetupPage::checkAllButtonClicked()
{
    checkAll(m_toggleWillCheck);

485
    m_toggleWillCheck = !m_toggleWillCheck;
486
    m_ui->uncheckButton->setText(m_toggleWillCheck ? tr("Check All") : tr("Uncheck All"));
487
488
    m_ui->uncheckButton->setToolTip(m_toggleWillCheck
                                    ? tr("Check all Qt versions") : tr("Uncheck all Qt versions"));
489
490
}

491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
void TargetSetupPage::checkAllTriggered()
{
    m_toggleWillCheck = true;
    checkAllButtonClicked();
}

void TargetSetupPage::uncheckAllTriggered()
{
    m_toggleWillCheck = false;
    checkAllButtonClicked();
}

void TargetSetupPage::checkOneTriggered()
{
    QAction * action = qobject_cast<QAction *>(sender());
    if (!action)
        return;
    QTreeWidgetItem *item = static_cast<QTreeWidgetItem *>(action->data().value<void *>());
    if (!item || !item->parent())
        return;

    checkAll(false);
    checkOne(true, item);
}

516
517
518
519
520
521
522
523
524
525
526
void TargetSetupPage::handleDoubleClicks(QTreeWidgetItem *item, int column)
{
    int idx = item->data(NAME_COLUMN, Qt::UserRole).toInt();
    if (column == DIRECTORY_COLUMN && item->parent()) {
        if (m_infos[idx].isExistingBuild || !m_infos[idx].version->supportsShadowBuilds())
            return;
        m_infos[idx].isShadowBuild = !m_infos[idx].isShadowBuild;
        updateVersionItem(item, idx);
    }
}

527
void TargetSetupPage::contextMenuRequested(const QPoint &position)
528
529
530
531
532
{
    m_contextMenu->clear();

    QTreeWidgetItem *item = m_ui->versionTree->itemAt(position);
    m_contextMenu = new QMenu(this);
533
    if (item && item->parent()) {
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
        // Qt version item
        QAction *onlyThisAction = new QAction(tr("Check only this version"), m_contextMenu);
        connect(onlyThisAction, SIGNAL(triggered()), this, SLOT(checkOneTriggered()));
        onlyThisAction->setData(QVariant::fromValue(static_cast<void *>(item)));
        m_contextMenu->addAction(onlyThisAction);

        QAction *checkAllAction = new QAction(tr("Check all versions"), m_contextMenu);
        connect(checkAllAction, SIGNAL(triggered()), this, SLOT(checkAllTriggered()));
        m_contextMenu->addAction(checkAllAction);

        QAction *uncheckAllAction = new QAction(tr("Uncheck all versions"), m_contextMenu);
        connect(uncheckAllAction, SIGNAL(triggered()), this, SLOT(uncheckAllTriggered()));
        m_contextMenu->addAction(uncheckAllAction);
    }
    if (!m_contextMenu->isEmpty())
        m_contextMenu->popup(m_ui->versionTree->mapToGlobal(position));
}

552
553
void TargetSetupPage::resetInfos()
{
Tobias Hunger's avatar
Tobias Hunger committed
554
    m_ui->versionTree->clear();
555
556
557
558
559
560
    foreach (const ImportInfo &info, m_infos) {
        if (info.isTemporary)
            delete info.version;
    }
    m_infos.clear();
}
561

562
563
QPair<QIcon, QString> TargetSetupPage::reportIssues(Qt4ProjectManager::QtVersion *version,
                                                    const QString &buildDir)
564
565
566
567
{
    if (m_proFilePath.isEmpty())
        return qMakePair(QIcon(), QString());

dt's avatar
dt committed
568
569
570
    const ProjectExplorer::TaskHub *taskHub = ExtensionSystem::PluginManager::instance()
                                              ->getObject<ProjectExplorer::TaskHub>();
    QTC_ASSERT(taskHub, return qMakePair(QIcon(), QString()));
571

572
    QList<ProjectExplorer::Task> issues = version->reportIssues(m_proFilePath, buildDir);
573

574
575
    QString text;
    QIcon icon;
576
    foreach (const ProjectExplorer::Task &t, issues) {
577
578
579
580
581
        if (!text.isEmpty())
            text.append(QLatin1String("<br>"));
        // set severity:
        QString severity;
        if (t.type == ProjectExplorer::Task::Error) {
dt's avatar
dt committed
582
            icon = taskHub->taskTypeIcon(t.type);
583
584
585
            severity = tr("<b>Error:</b> ", "Severity is Task::Error");
        } else if (t.type == ProjectExplorer::Task::Warning) {
               if (icon.isNull())
dt's avatar
dt committed
586
                   icon = taskHub->taskTypeIcon(t.type);
587
588
589
590
591
592
593
594
               severity = tr("<b>Warning:</b> ", "Severity is Task::Warning");
        }
        text.append(severity + t.description);
    }
    if (!text.isEmpty())
        text = QLatin1String("<nobr>") + text;
    return qMakePair(icon, text);
}
595
596
597
598

void TargetSetupPage::updateVersionItem(QTreeWidgetItem *versionItem, int index)
{
    ImportInfo &info = m_infos[index];
599
600
601
602
603
604
605
606
607
608
609
610
    const QString target = versionItem->parent()->data(NAME_COLUMN, Qt::UserRole).toString();
    QString dir;
    if (info.directory.isEmpty()) {
        Q_ASSERT(!info.isTemporary && !info.isExistingBuild);
        if (info.isShadowBuild)
            dir = Qt4Target::defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(m_proFilePath), target);
        else
            dir = Qt4Project::projectDirectory(m_proFilePath);
    } else {
        dir = info.directory;
    }
    QPair<QIcon, QString> issues = reportIssues(info.version, dir);
611

Tobias Hunger's avatar
Tobias Hunger committed
612
613
614
615
616
617
618
619
620
621
    //: We are going to build debug and release
    QString buildType = tr("debug and release");
    if ((info.buildConfig & QtVersion::BuildAll) == 0) {
        if (info.buildConfig & QtVersion::DebugBuild)
            //: Debug build
            buildType = tr("debug");
        else
            //: release build
            buildType = tr("release");
    }
622
623

    QString toolTip = info.version->displayName();
Tobias Hunger's avatar
Tobias Hunger committed
624
625
626
627
    //: %1: qmake used (incl. full path), %2: "debug", "release" or "debug and release"
    toolTip.append(tr("<br>using %1 (%2)").
            arg(QDir::toNativeSeparators(info.version->qmakeCommand())).
                   arg(buildType));
628
629
630
631
632
633
634
635
636
637
638
639
    if (!issues.second.isEmpty())
        toolTip.append(QString::fromLatin1("<br><br>%1").arg(issues.second));

    // Column 0:
    versionItem->setToolTip(NAME_COLUMN, toolTip);
    versionItem->setIcon(NAME_COLUMN, issues.first);
    versionItem->setText(NAME_COLUMN, info.version->displayName());
    versionItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
    versionItem->setData(NAME_COLUMN, Qt::UserRole, index);

    // Column 1 (status):
    const QString status = info.isExistingBuild ?
640
641
642
643
                           //: Is this an import of an existing build or a new one?
                           tr("Import") :
                           //: Is this an import of an existing build or a new one?
                           tr("New");
644
645
646
647
648
    versionItem->setText(STATUS_COLUMN, status);
    versionItem->setToolTip(STATUS_COLUMN, status);

    // Column 2 (directory):
    Q_ASSERT(versionItem->parent());
649
650
    versionItem->setText(DIRECTORY_COLUMN, QDir::toNativeSeparators(dir));
    versionItem->setToolTip(DIRECTORY_COLUMN, QDir::toNativeSeparators(dir));
651
}