cmakeopenprojectwizard.cpp 19.7 KB
Newer Older
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
27
28
29
**
**************************************************************************/

30
31
32
33
34
35
36
37
38

/// 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
39
40
41
42
#include "cmakeopenprojectwizard.h"
#include "cmakeprojectmanager.h"

#include <utils/pathchooser.h>
dt's avatar
dt committed
43
#include <projectexplorer/toolchain.h>
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
44
45
46
47
48
49
50

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

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

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

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

88
89
90
91
92
93
94
    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
95
    setStartId(startid);
dt's avatar
dt committed
96
    init();
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
97
98
}

dt's avatar
dt committed
99
CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory,
100
                                               const QString &buildDirectory, CMakeOpenProjectWizard::Mode mode,
101
                                               const Utils::Environment &env)
dt's avatar
dt committed
102
103
    : m_cmakeManager(cmakeManager),
      m_sourceDirectory(sourceDirectory),
104
105
      m_creatingCbpFiles(true),
      m_environment(env)
dt's avatar
dt committed
106
{
107
108

    CMakeRunPage::Mode rmode;
109
    if (mode == CMakeOpenProjectWizard::NeedToCreate)
110
111
112
        rmode = CMakeRunPage::Recreate;
    else if (mode == CMakeOpenProjectWizard::WantToUpdate)
        rmode = CMakeRunPage::WantToUpdate;
113
    else
114
115
        rmode = CMakeRunPage::NeedToUpdate;
    addPage(new CMakeRunPage(this, rmode, buildDirectory));
dt's avatar
dt committed
116
    init();
dt's avatar
dt committed
117
118
}

119
CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const QString &sourceDirectory,
120
                                               const QString &oldBuildDirectory,
121
                                               const Utils::Environment &env)
122
123
    : m_cmakeManager(cmakeManager),
      m_sourceDirectory(sourceDirectory),
124
125
      m_creatingCbpFiles(true),
      m_environment(env)
126
127
128
{
    m_buildDirectory = oldBuildDirectory;
    addPage(new ShadowBuildPage(this, true));
129
    addPage(new CMakeRunPage(this, CMakeRunPage::ChangeDirectory));
dt's avatar
dt committed
130
131
132
133
134
    init();
}

void CMakeOpenProjectWizard::init()
{
135
    setOption(QWizard::NoBackButtonOnStartPage);
dt's avatar
dt committed
136
    setWindowTitle(tr("CMake Wizard"));
137
138
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
139
140
141
142
143
144
145
CMakeManager *CMakeOpenProjectWizard::cmakeManager() const
{
    return m_cmakeManager;
}

int CMakeOpenProjectWizard::nextId() const
{
dt's avatar
dt committed
146
147
    if (m_creatingCbpFiles)
        return QWizard::nextId();
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
148
149
    int cid = currentId();
    if (cid == InSourcePageId) {
150
        return CMakeRunPageId;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
151
    } else if (cid == ShadowBuildPageId) {
152
        return CMakeRunPageId;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
153
154
155
156
157
158
159
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
    }
    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;
}

dt's avatar
dt committed
195
196
197
198
199
200
201
202
203
204
QString CMakeOpenProjectWizard::msvcVersion() const
{
    return m_msvcVersion;
}

void CMakeOpenProjectWizard::setMsvcVersion(const QString &version)
{
    m_msvcVersion = version;
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
205
206
207
208
209
210
211
212
213
214
QStringList CMakeOpenProjectWizard::arguments() const
{
    return m_arguments;
}

void CMakeOpenProjectWizard::setArguments(const QStringList &args)
{
    m_arguments = args;
}

215
Utils::Environment CMakeOpenProjectWizard::environment() const
216
217
218
219
{
    return m_environment;
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
220
221
222
223
224
225
226

InSourceBuildPage::InSourceBuildPage(CMakeOpenProjectWizard *cmakeWizard)
    : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
{
    setLayout(new QVBoxLayout);
    QLabel *label = new QLabel(this);
    label->setWordWrap(true);
227
    label->setText(tr("Qt Creator has detected an <b>in-source-build in %1</b> "
Friedemann Kleint's avatar
Friedemann Kleint committed
228
                   "which prevents shadow builds. Qt Creator will not allow you to change the build directory. "
229
230
                   "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
231
    layout()->addWidget(label);
232
    setTitle(tr("Build Location"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
233
234
235
}


236
ShadowBuildPage::ShadowBuildPage(CMakeOpenProjectWizard *cmakeWizard, bool change)
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
237
238
239
240
241
242
243
    : QWizardPage(cmakeWizard), m_cmakeWizard(cmakeWizard)
{
    QFormLayout *fl = new QFormLayout;
    this->setLayout(fl);

    QLabel *label = new QLabel(this);
    label->setWordWrap(true);
244
245
246
247
248
249
250
    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
251
    fl->addWidget(label);
252
    m_pc = new Utils::PathChooser(this);
253
    m_pc->setBaseDirectory(m_cmakeWizard->sourceDirectory());
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
254
    m_pc->setPath(m_cmakeWizard->buildDirectory());
con's avatar
con committed
255
    connect(m_pc, SIGNAL(changed(QString)), this, SLOT(buildDirectoryChanged()));
256
    fl->addRow(tr("Build directory:"), m_pc);
257
    setTitle(tr("Build Location"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
258
259
260
261
262
263
264
}

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

265
CMakeRunPage::CMakeRunPage(CMakeOpenProjectWizard *cmakeWizard, Mode mode, const QString &buildDirectory)
dt's avatar
dt committed
266
267
268
    : QWizardPage(cmakeWizard),
      m_cmakeWizard(cmakeWizard),
      m_complete(false),
269
270
      m_mode(mode),
      m_buildDirectory(buildDirectory)
dt's avatar
dt committed
271
272
273
274
275
{
    initWidgets();
}

void CMakeRunPage::initWidgets()
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
276
277
278
{
    QFormLayout *fl = new QFormLayout;
    setLayout(fl);
279
    // Description Label
dt's avatar
dt committed
280
281
282
283
    m_descriptionLabel = new QLabel(this);
    m_descriptionLabel->setWordWrap(true);

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

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

        fl->addRow(new QLabel(text, this));
        // Show a field for the user to enter
302
        m_cmakeExecutable = new Utils::PathChooser(this);
303
        m_cmakeExecutable->setExpectedKind(Utils::PathChooser::ExistingCommand);
304
305
306
307
        fl->addRow("CMake Executable", m_cmakeExecutable);
    }

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

311
    m_generatorComboBox = new QComboBox(this);
dt's avatar
dt committed
312

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
313
    m_runCMake = new QPushButton(this);
314
    m_runCMake->setText(tr("Run CMake"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
315
    connect(m_runCMake, SIGNAL(clicked()), this, SLOT(runCMake()));
316
317
318

    QHBoxLayout *hbox = new QHBoxLayout;
    hbox->addWidget(m_argumentsLineEdit);
319
    hbox->addWidget(m_generatorComboBox);
320
321
322
323
    hbox->addWidget(m_runCMake);

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

324
    // Bottom output window
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
325
    m_output = new QPlainTextEdit(this);
326
    m_output->setReadOnly(true);
327
328
329
    QSizePolicy pl = m_output->sizePolicy();
    pl.setVerticalStretch(1);
    m_output->setSizePolicy(pl);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
330
    fl->addRow(m_output);
331
332
333
334
335

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

336
    setTitle(tr("Run CMake"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
337
338
}

339
340
void CMakeRunPage::initializePage()
{
341
    if (m_mode == Initial) {
342
        m_complete = m_cmakeWizard->existsUpToDateXmlFile();
343
        m_buildDirectory = m_cmakeWizard->buildDirectory();
344
345
346

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

381
382
383
        QFile fi(m_buildDirectory + "/CMakeCache.txt");
        if (fi.exists()) {
            // Cache exists, then read it...
384
            if (fi.open(QIODevice::ReadOnly | QIODevice::Text)) {
385
                while (!fi.atEnd()) {
386
387
388
389
                    QString line = fi.readLine();
                    if (line.startsWith("CMAKE_GENERATOR:INTERNAL=")) {
                        int splitpos = line.indexOf('=');
                        if (splitpos != -1) {
390
                            cachedGenerator = line.mid(splitpos + 1).trimmed();
391
392
393
394
395
                        }
                        break;
                    }
                }
            }
396
        }
dt's avatar
dt committed
397
        m_generatorComboBox->clear();
398
        // Find out whether we have multiple msvc versions
dt's avatar
dt committed
399
400
401
402
403
404
405
406
        QStringList msvcVersions = ProjectExplorer::ToolChain::availableMSVCVersions();
        if (msvcVersions.isEmpty()) {

        } else if (msvcVersions.count() == 1) {
            m_generatorComboBox->addItem(tr("NMake Generator"), msvcVersions.first());
        } else {
            foreach (const QString &msvcVersion, msvcVersions)
                m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(msvcVersion), msvcVersion);
407
        }
dt's avatar
dt committed
408

409
        if (cachedGenerator == "NMake Makefiles" && !msvcVersions.isEmpty()) {
dt's avatar
dt committed
410
            m_generatorComboBox->setCurrentIndex(0);
411
412
            m_cmakeWizard->setMsvcVersion(msvcVersions.first());
        }
dt's avatar
dt committed
413
414

        m_generatorComboBox->addItem(tr("MinGW Generator"), "mingw");
415
        if (cachedGenerator == "MinGW Makefiles") {
dt's avatar
dt committed
416
            m_generatorComboBox->setCurrentIndex(m_generatorComboBox->count() - 1);
417
418
            m_cmakeWizard->setMsvcVersion("");
        }
419
420
421
422
    } else {
        // No new enough cmake, simply hide the combo box
        m_generatorComboBox->setVisible(false);
    }
423
424
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
425
426
427
428
void CMakeRunPage::runCMake()
{
    m_runCMake->setEnabled(false);
    m_argumentsLineEdit->setEnabled(false);
429
    QStringList arguments = Utils::Environment::parseCombinedArgString(m_argumentsLineEdit->text());
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
430
    CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager();
431
432

#ifdef Q_OS_WIN
dt's avatar
dt committed
433
434
435
436
437
438
439
440
441
442
    m_cmakeWizard->setMsvcVersion(QString());
    QString generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
    if (m_generatorComboBox->isVisible()) {
         // the combobox is shown, check which generator is selected
        int index = m_generatorComboBox->currentIndex();
        if (index != -1) {
            QString version = m_generatorComboBox->itemData(index).toString();
            if (version != "mingw") {
                generator = "-GCodeBlocks - NMake Makefiles";
                m_cmakeWizard->setMsvcVersion(version);
443
444
            } else {
                m_cmakeWizard->setMsvcVersion("");
dt's avatar
dt committed
445
            }
446
        }
dt's avatar
dt committed
447
    }
448
#else // Q_OS_WIN
dt's avatar
dt committed
449
    QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles");
450
#endif
451
    Utils::Environment env = m_cmakeWizard->environment();
dt's avatar
dt committed
452
453
454
455
456
457
458
    if (!m_cmakeWizard->msvcVersion().isEmpty()) {
        // Add the environment of that msvc version to environment
        ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChain::createMSVCToolChain(m_cmakeWizard->msvcVersion(), false);
        tc->addToEnvironment(env);
        delete tc;
    }

459
460
461
462
463
464
465
466
    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()) {
467
        m_cmakeProcess = new QProcess();
468
469
        connect(m_cmakeProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(cmakeReadyReadStandardOutput()));
        connect(m_cmakeProcess, SIGNAL(readyReadStandardError()), this, SLOT(cmakeReadyReadStandardError()));
470
        connect(m_cmakeProcess, SIGNAL(finished(int)), this, SLOT(cmakeFinished()));
471
        cmakeManager->createXmlFile(m_cmakeProcess, arguments, m_cmakeWizard->sourceDirectory(), m_buildDirectory, env, generator);
472
473
474
    } else {
        m_runCMake->setEnabled(true);
        m_argumentsLineEdit->setEnabled(true);
475
        m_output->appendPlainText(tr("No valid CMake executable specified."));
476
    }
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
477
478
}

479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
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
498
{
499
500
501
502
503
504
505
506
507
508
    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
509
510
511
512
513
514
}

void CMakeRunPage::cmakeFinished()
{
    m_runCMake->setEnabled(true);
    m_argumentsLineEdit->setEnabled(true);
515
516
517
518
519
520
521
522
    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
523
524
    m_cmakeProcess->deleteLater();
    m_cmakeProcess = 0;
525
    m_cmakeWizard->setArguments(Utils::Environment::parseCombinedArgString(m_argumentsLineEdit->text()));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
526
527
528
529
530
531
532
533
    //TODO Actually test that running cmake was finished, for setting this bool
    emit completeChanged();
}

void CMakeRunPage::cleanupPage()
{
    m_output->clear();
    m_complete = false;
534
    m_exitCodeLabel->setVisible(false);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
535
536
537
538
539
540
541
542
    emit completeChanged();
}

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