cmakeopenprojectwizard.cpp 19.8 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
** Contact: Nokia Corporation (qt-info@nokia.com)
8
**
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
36
37
38
39
40
41
42

/// TODO
/// To check
/// a) with an old cmake
/// => should not show combobox always use mingw generator
/// b) with an new cmake
/// always show combo box, defaulting if there's already a existing build


qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
43
44
45
46
#include "cmakeopenprojectwizard.h"
#include "cmakeprojectmanager.h"

#include <utils/pathchooser.h>
47
#include <projectexplorer/toolchainmanager.h>
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
48
49
50
51
52
53
54

#include <QtGui/QVBoxLayout>
#include <QtGui/QFormLayout>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QPlainTextEdit>
#include <QtCore/QDateTime>
dt's avatar
dt committed
55
#include <QtCore/QStringList>
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;

///////
//  Page Flow:
//   Start (No .user file)
//    |
//    |---> In Source Build --> Page: Tell the user about that
//                               |--> Already existing cbp file (and new enough) --> Page: Ready to load the project
//                               |--> Page: Ask for cmd options, run generator
//    |---> No in source Build --> Page: Ask the user for the build directory
//                                   |--> Already existing cbp file (and new enough) --> Page: Ready to load the project
//                                   |--> Page: Ask for cmd options, run generator

71
CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory, const Utils::Environment &env)
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
72
    : m_cmakeManager(cmakeManager),
dt's avatar
dt committed
73
      m_sourceDirectory(sourceDirectory),
74
      m_creatingCbpFiles(false),
75
76
      m_environment(env),
      m_toolChain(0)
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
77
78
79
80
81
82
83
{
    int startid;
    if (hasInSourceBuild()) {
        startid = InSourcePageId;
        m_buildDirectory = m_sourceDirectory;
    } else {
        startid = ShadowBuildPageId;
dt's avatar
dt committed
84
85
86
        QDir dir(m_sourceDirectory);
        dir.cdUp();
        m_buildDirectory = dir.absolutePath() + "/qtcreator-build";
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
87
88
89
90
91
92
    }

    setPage(InSourcePageId, new InSourceBuildPage(this));
    setPage(ShadowBuildPageId, new ShadowBuildPage(this));
    setPage(CMakeRunPageId, new CMakeRunPage(this));

93
94
95
96
97
98
99
    Utils::WizardProgress *wp = wizardProgress();
    Utils::WizardProgressItem *inSourceItem = wp->item(InSourcePageId);
    Utils::WizardProgressItem *shadowBuildItem = wp->item(ShadowBuildPageId);
    Utils::WizardProgressItem *cmakeRunItem = wp->item(CMakeRunPageId);
    inSourceItem->setNextItems(QList<Utils::WizardProgressItem *>() << cmakeRunItem);
    shadowBuildItem->setNextItems(QList<Utils::WizardProgressItem *>() << cmakeRunItem);

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
100
    setStartId(startid);
dt's avatar
dt committed
101
    init();
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
102
103
}

dt's avatar
dt committed
104
CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory,
105
                                               const QString &buildDirectory, CMakeOpenProjectWizard::Mode mode,
106
                                               const Utils::Environment &env)
dt's avatar
dt committed
107
108
    : m_cmakeManager(cmakeManager),
      m_sourceDirectory(sourceDirectory),
109
      m_creatingCbpFiles(true),
110
111
      m_environment(env),
      m_toolChain(0)
dt's avatar
dt committed
112
{
113
114

    CMakeRunPage::Mode rmode;
115
    if (mode == CMakeOpenProjectWizard::NeedToCreate)
116
117
118
        rmode = CMakeRunPage::Recreate;
    else if (mode == CMakeOpenProjectWizard::WantToUpdate)
        rmode = CMakeRunPage::WantToUpdate;
119
    else
120
121
        rmode = CMakeRunPage::NeedToUpdate;
    addPage(new CMakeRunPage(this, rmode, buildDirectory));
dt's avatar
dt committed
122
    init();
dt's avatar
dt committed
123
124
}

125
CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory,
126
                                               const QString &oldBuildDirectory,
127
                                               const Utils::Environment &env)
128
129
    : m_cmakeManager(cmakeManager),
      m_sourceDirectory(sourceDirectory),
130
      m_creatingCbpFiles(true),
131
132
      m_environment(env),
      m_toolChain(0)
133
134
135
{
    m_buildDirectory = oldBuildDirectory;
    addPage(new ShadowBuildPage(this, true));
136
    addPage(new CMakeRunPage(this, CMakeRunPage::ChangeDirectory));
dt's avatar
dt committed
137
138
139
140
141
    init();
}

void CMakeOpenProjectWizard::init()
{
142
    setOption(QWizard::NoBackButtonOnStartPage);
dt's avatar
dt committed
143
    setWindowTitle(tr("CMake Wizard"));
144
145
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
146
147
148
149
150
151
152
CMakeManager *CMakeOpenProjectWizard::cmakeManager() const
{
    return m_cmakeManager;
}

int CMakeOpenProjectWizard::nextId() const
{
dt's avatar
dt committed
153
154
    if (m_creatingCbpFiles)
        return QWizard::nextId();
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
155
156
    int cid = currentId();
    if (cid == InSourcePageId) {
157
        return CMakeRunPageId;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
158
    } else if (cid == ShadowBuildPageId) {
159
        return CMakeRunPageId;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    }
    return -1;
}


bool CMakeOpenProjectWizard::hasInSourceBuild() const
{
    QFileInfo fi(m_sourceDirectory + "/CMakeCache.txt");
    if (fi.exists())
        return true;
    return false;
}

bool CMakeOpenProjectWizard::existsUpToDateXmlFile() const
{
    QString cbpFile = CMakeManager::findCbpFile(QDir(buildDirectory()));
    if (!cbpFile.isEmpty()) {
        // We already have a cbp file
        QFileInfo cbpFileInfo(cbpFile);
        QFileInfo cmakeListsFileInfo(sourceDirectory() + "/CMakeLists.txt");

        if (cbpFileInfo.lastModified() > cmakeListsFileInfo.lastModified())
            return true;
    }
    return false;
}

QString CMakeOpenProjectWizard::buildDirectory() const
{
    return m_buildDirectory;
}

QString CMakeOpenProjectWizard::sourceDirectory() const
{
    return m_sourceDirectory;
}

void CMakeOpenProjectWizard::setBuildDirectory(const QString &directory)
{
    m_buildDirectory = directory;
}

202
QString CMakeOpenProjectWizard::arguments() const
dt's avatar
dt committed
203
{
204
    return m_arguments;
dt's avatar
dt committed
205
206
}

207
void CMakeOpenProjectWizard::setArguments(const QString &args)
dt's avatar
dt committed
208
{
209
    m_arguments = args;
dt's avatar
dt committed
210
211
}

212
ProjectExplorer::ToolChain *CMakeOpenProjectWizard::toolChain() const
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
213
{
214
    return m_toolChain;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
215
216
}

217
void CMakeOpenProjectWizard::setToolChain(ProjectExplorer::ToolChain *tc)
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
218
{
219
    m_toolChain = tc;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
220
221
}

222

223
Utils::Environment CMakeOpenProjectWizard::environment() const
224
225
226
227
{
    return m_environment;
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
228
229
230
231
232
233
234

InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard)
    : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
{
    setLayout(new QVBoxLayout);
    QLabel *label = new QLabel(this);
    label->setWordWrap(true);
235
    label->setText(tr("Qt Creator has detected an <b>in-source-build in %1</b> "
Friedemann Kleint's avatar
Friedemann Kleint committed
236
                   "which prevents shadow builds. Qt Creator will not allow you to change the build directory. "
237
238
                   "If you want a shadow build, clean your source directory and re-open the project.")
                   .arg(m_cmakeWizard->buildDirectory()));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
239
    layout()->addWidget(label);
240
    setTitle(tr("Build Location"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
241
242
}

243
ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change)
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
244
245
246
247
248
249
250
    : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
{
    QFormLayout *fl = new QFormLayout;
    this->setLayout(fl);

    QLabel *label = new QLabel(this);
    label->setWordWrap(true);
251
252
253
254
255
256
257
    if (change)
        label->setText(tr("Please enter the directory in which you want to build your project. "));
    else
        label->setText(tr("Please enter the directory in which you want to build your project. "
                          "Qt Creator recommends to not use the source directory for building. "
                          "This ensures that the source directory remains clean and enables multiple builds "
                          "with different settings."));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
258
    fl->addWidget(label);
259
    m_pc = new Utils::PathChooser(this);
260
    m_pc->setBaseDirectory(m_cmakeWizard->sourceDirectory());
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
261
    m_pc->setPath(m_cmakeWizard->buildDirectory());
con's avatar
con committed
262
    connect(m_pc, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged()));
263
    fl->addRow(tr("Build directory:"), m_pc);
264
    setTitle(tr("Build Location"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
265
266
267
268
269
270
271
}

void ShadowBuildPage::buildDirectoryChanged()
{
    m_cmakeWizard->setBuildDirectory(m_pc->path());
}

272
CMakeRunPage::CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode, const QString &buildDirectory)
dt's avatar
dt committed
273
274
275
    : QWizardPage(cmakeWizard),
      m_cmakeWizard(cmakeWizard),
      m_complete(false),
276
277
      m_mode(mode),
      m_buildDirectory(buildDirectory)
dt's avatar
dt committed
278
279
280
281
282
{
    initWidgets();
}

void CMakeRunPage::initWidgets()
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
283
284
285
{
    QFormLayout *fl = new QFormLayout;
    setLayout(fl);
286
    // Description Label
dt's avatar
dt committed
287
288
289
290
    m_descriptionLabel = new QLabel(this);
    m_descriptionLabel->setWordWrap(true);

    fl->addRow(m_descriptionLabel);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
291

292
293
294
    if (m_cmakeWizard->cmakeManager()->isCMakeExecutableValid()) {
        m_cmakeExecutable = 0;
    } else {
295
        QString text = tr("Please specify the path to the CMake executable. No CMake executable was found in the path.");
296
297
298
299
        QString cmakeExecutable = m_cmakeWizard->cmakeManager()->cmakeExecutable();
        if (!cmakeExecutable.isEmpty()) {
            QFileInfo fi(cmakeExecutable);
            if (!fi.exists())
300
                text += tr(" The CMake executable (%1) does not exist.").arg(cmakeExecutable);
301
302
303
            else if (!fi.isExecutable())
                text += tr(" The path %1 is not a executable.").arg(cmakeExecutable);
            else
304
                text += tr(" The path %1 is not a valid CMake.").arg(cmakeExecutable);
305
306
307
308
        }

        fl->addRow(new QLabel(text, this));
        // Show a field for the user to enter
309
        m_cmakeExecutable = new Utils::PathChooser(this);
310
        m_cmakeExecutable->setExpectedKind(Utils::PathChooser::ExistingCommand);
311
312
313
314
        fl->addRow("CMake Executable", m_cmakeExecutable);
    }

    // Run CMake Line (with arguments)
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
315
    m_argumentsLineEdit = new QLineEdit(this);
316
    connect(m_argumentsLineEdit,SIGNAL(returnPressed()), this, SLOT(runCMake()));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
317

318
    m_generatorComboBox = new QComboBox(this);
dt's avatar
dt committed
319

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
320
    m_runCMake = new QPushButton(this);
321
    m_runCMake->setText(tr("Run CMake"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
322
    connect(m_runCMake, SIGNAL(clicked()), this, SLOT(runCMake()));
323
324
325

    QHBoxLayout *hbox = new QHBoxLayout;
    hbox->addWidget(m_argumentsLineEdit);
326
    hbox->addWidget(m_generatorComboBox);
327
328
329
330
    hbox->addWidget(m_runCMake);

    fl->addRow(tr("Arguments"), hbox);

331
    // Bottom output window
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
332
    m_output = new QPlainTextEdit(this);
333
    m_output->setReadOnly(true);
334
335
336
    QSizePolicy pl = m_output->sizePolicy();
    pl.setVerticalStretch(1);
    m_output->setSizePolicy(pl);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
337
    fl->addRow(m_output);
338
339
340
341
342

    m_exitCodeLabel = new QLabel(this);
    m_exitCodeLabel->setVisible(false);
    fl->addRow(m_exitCodeLabel);

343
    setTitle(tr("Run CMake"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
344
345
}

346
347
void CMakeRunPage::initializePage()
{
348
    if (m_mode == Initial) {
349
        m_complete = m_cmakeWizard->existsUpToDateXmlFile();
350
        m_buildDirectory = m_cmakeWizard->buildDirectory();
351
352
353

        if (m_cmakeWizard->existsUpToDateXmlFile()) {
            m_descriptionLabel->setText(
354
                    tr("The directory %1 already contains a cbp file, which is recent enough. "
355
356
                       "You can pass special arguments or change the used toolchain here and rerun CMake. "
                       "Or simply finish the wizard directly.").arg(m_buildDirectory));
357
358
        } else {
            m_descriptionLabel->setText(
359
360
                    tr("The directory %1 does not contain a cbp file. Qt Creator needs to create this file by running CMake. "
                       "Some projects require command line arguments to the initial CMake call.").arg(m_buildDirectory));
361
        }
362
    } else if (m_mode == CMakeRunPage::NeedToUpdate) {
363
        m_descriptionLabel->setText(tr("The directory %1 contains an outdated .cbp file. Qt "
364
                                       "Creator needs to update this file by running CMake. "
365
                                       "If you want to add additional command line arguments, "
366
                                       "add them below. Note that CMake remembers command "
Friedemann Kleint's avatar
Friedemann Kleint committed
367
                                       "line arguments from the previous runs.").arg(m_buildDirectory));
368
    } else if(m_mode == CMakeRunPage::Recreate) {
Friedemann Kleint's avatar
Friedemann Kleint committed
369
        m_descriptionLabel->setText(tr("The directory %1 specified in a build-configuration, "
370
                                       "does not contain a cbp file. Qt Creator needs to "
371
                                       "recreate this file, by running CMake. "
372
                                       "Some projects require command line arguments to "
373
                                       "the initial CMake call. Note that CMake remembers command "
Friedemann Kleint's avatar
Friedemann Kleint committed
374
                                       "line arguments from the previous runs.").arg(m_buildDirectory));
375
    } else if(m_mode == CMakeRunPage::ChangeDirectory) {
376
        m_buildDirectory = m_cmakeWizard->buildDirectory();
377
        m_descriptionLabel->setText(tr("Qt Creator needs to run CMake in the new build directory. "
378
                                       "Some projects require command line arguments to the "
379
                                       "initial CMake call."));
380
381
    } else if (m_mode == CMakeRunPage::WantToUpdate) {
        m_descriptionLabel->setText(tr("Refreshing cbp file in %1.").arg(m_buildDirectory));
382
    }
383
    if (m_cmakeWizard->cmakeManager()->hasCodeBlocksMsvcGenerator()) {
384
        // Try to find out generator from CMakeCache file, if it exists
dt's avatar
dt committed
385
        QString cachedGenerator;
386

387
388
389
        QFile fi(m_buildDirectory + "/CMakeCache.txt");
        if (fi.exists()) {
            // Cache exists, then read it...
390
            if (fi.open(QIODevice::ReadOnly | QIODevice::Text)) {
391
                while (!fi.atEnd()) {
392
393
394
395
                    QString line = fi.readLine();
                    if (line.startsWith("CMAKE_GENERATOR:INTERNAL=")) {
                        int splitpos = line.indexOf('=');
                        if (splitpos != -1) {
396
                            cachedGenerator = line.mid(splitpos + 1).trimmed();
397
398
399
400
401
                        }
                        break;
                    }
                }
            }
402
        }
dt's avatar
dt committed
403

404
405
406
407
408
409
410
        m_generatorComboBox->setVisible(true);
        m_generatorComboBox->clear();
        QList<ProjectExplorer::ToolChain *> tcs =
                ProjectExplorer::ToolChainManager::instance()->findToolChains(ProjectExplorer::Abi::hostAbi());
        foreach (ProjectExplorer::ToolChain *tc, tcs) {
            ProjectExplorer::Abi targetAbi = tc->targetAbi();
            QVariant tcVariant = qVariantFromValue(static_cast<void *>(tc));
hjk's avatar
hjk committed
411
412
            if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) {
                if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvcFlavor)
413
                    m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(tc->displayName()), tcVariant);
hjk's avatar
hjk committed
414
                else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor)
415
416
417
418
                    m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(tc->displayName()), tcVariant);
                else
                    continue;
            }
419
        }
420
421
422
    } else {
        // No new enough cmake, simply hide the combo box
        m_generatorComboBox->setVisible(false);
423
424
425
426
427
        QList<ProjectExplorer::ToolChain *> tcs =
                ProjectExplorer::ToolChainManager::instance()->findToolChains(ProjectExplorer::Abi::hostAbi());
        if (tcs.isEmpty())
            return;
        m_cmakeWizard->setToolChain(tcs.at(0));
428
    }
429
430
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
431
432
void CMakeRunPage::runCMake()
{
433
434
435
436
437
438
439
440
441
442
443
444
445
    int index = m_generatorComboBox->currentIndex();

    ProjectExplorer::ToolChain *tc = 0;
    if (index >= 0) {
        tc = static_cast<ProjectExplorer::ToolChain *>(m_generatorComboBox->itemData(index).value<void *>());
        if (!tc)
            return;
        m_cmakeWizard->setToolChain(tc);
    } else {
        tc = m_cmakeWizard->toolChain();
    }
    Q_ASSERT(tc);

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
446
447
    m_runCMake->setEnabled(false);
    m_argumentsLineEdit->setEnabled(false);
448
    m_generatorComboBox->setEnabled(false);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
449
    CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager();
450

dt's avatar
dt committed
451
    QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles");
hjk's avatar
hjk committed
452
453
    if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS) {
        if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMsvcFlavor)
454
455
456
            generator = QLatin1String("-GCodeBlocks - NMake Makefiles");
        else
            generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
dt's avatar
dt committed
457
458
    }

459
460
461
462

    Utils::Environment env = m_cmakeWizard->environment();
    tc->addToEnvironment(env);

463
464
465
466
467
468
469
470
    if (m_cmakeExecutable) {
        // We asked the user for the cmake executable
        m_cmakeWizard->cmakeManager()->setCMakeExecutable(m_cmakeExecutable->path());
    }

    m_output->clear();

    if (m_cmakeWizard->cmakeManager()->isCMakeExecutableValid()) {
471
        m_cmakeProcess = new Utils::QtcProcess();
472
473
        connect(m_cmakeProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(cmakeReadyReadStandardOutput()));
        connect(m_cmakeProcess, SIGNAL(readyReadStandardError()), this, SLOT(cmakeReadyReadStandardError()));
474
        connect(m_cmakeProcess, SIGNAL(finished(int)), this, SLOT(cmakeFinished()));
475
        cmakeManager->createXmlFile(m_cmakeProcess, m_argumentsLineEdit->text(), m_cmakeWizard->sourceDirectory(), m_buildDirectory, env, generator);
476
477
478
    } else {
        m_runCMake->setEnabled(true);
        m_argumentsLineEdit->setEnabled(true);
479
        m_generatorComboBox->setEnabled(true);
480
        m_output->appendPlainText(tr("No valid CMake executable specified."));
481
    }
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
482
483
}

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
static QColor mix_colors(QColor a, QColor b)
{
    return QColor((a.red() + 2 * b.red()) / 3, (a.green() + 2 * b.green()) / 3,
                  (a.blue() + 2* b.blue()) / 3, (a.alpha() + 2 * b.alpha()) / 3);
}

void CMakeRunPage::cmakeReadyReadStandardOutput()
{
    QTextCursor cursor(m_output->document());
    QTextCharFormat tf;

    QFont font = m_output->font();
    tf.setFont(font);
    tf.setForeground(m_output->palette().color(QPalette::Text));

    cursor.insertText(m_cmakeProcess->readAllStandardOutput(), tf);
}

void CMakeRunPage::cmakeReadyReadStandardError()
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
503
{
504
505
506
507
508
509
510
511
512
513
    QTextCursor cursor(m_output->document());
    QTextCharFormat tf;

    QFont font = m_output->font();
    QFont boldFont = font;
    boldFont.setBold(true);
    tf.setFont(boldFont);
    tf.setForeground(mix_colors(m_output->palette().color(QPalette::Text), QColor(Qt::red)));

    cursor.insertText(m_cmakeProcess->readAllStandardError(), tf);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
514
515
516
517
518
519
}

void CMakeRunPage::cmakeFinished()
{
    m_runCMake->setEnabled(true);
    m_argumentsLineEdit->setEnabled(true);
520
521
    m_generatorComboBox->setEnabled(true);

522
523
524
525
526
527
528
529
    if (m_cmakeProcess->exitCode() != 0) {
        m_exitCodeLabel->setVisible(true);
        m_exitCodeLabel->setText(tr("CMake exited with errors. Please check cmake output."));
        m_complete = false;
    } else {
        m_exitCodeLabel->setVisible(false);
        m_complete = true;
    }
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
530
531
    m_cmakeProcess->deleteLater();
    m_cmakeProcess = 0;
532
    m_cmakeWizard->setArguments(m_argumentsLineEdit->text());
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
533
534
535
536
537
538
539
540
    //TODO Actually test that running cmake was finished, for setting this bool
    emit completeChanged();
}

void CMakeRunPage::cleanupPage()
{
    m_output->clear();
    m_complete = false;
541
    m_exitCodeLabel->setVisible(false);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
542
543
544
545
546
547
548
    emit completeChanged();
}

bool CMakeRunPage::isComplete() const
{
    return m_complete;
}