cmakeopenprojectwizard.cpp 19.9 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
**
hjk's avatar
hjk committed
7
** Contact: Nokia Corporation (info@qt.nokia.com)
8
9
10
11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12
13
14
15
16
17
** 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.
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21
22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23
24
25
26
27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
con's avatar
con committed
28
29
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
30
31
32
**
**************************************************************************/

33
34
35
36
37
38
39
40
41

/// 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
42
43
44
45
#include "cmakeopenprojectwizard.h"
#include "cmakeprojectmanager.h"

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

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

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

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

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

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

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

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

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

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

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

int CMakeOpenProjectWizard::nextId() const
{
dt's avatar
dt committed
152
153
    if (m_creatingCbpFiles)
        return QWizard::nextId();
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
154
155
    int cid = currentId();
    if (cid == InSourcePageId) {
156
        return CMakeRunPageId;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
157
    } else if (cid == ShadowBuildPageId) {
158
        return CMakeRunPageId;
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
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
195
196
197
198
199
200
    }
    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;
}

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

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

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

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

221

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

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

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

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

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

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

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

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

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

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

        fl->addRow(new QLabel(text, this));
        // Show a field for the user to enter
308
        m_cmakeExecutable = new Utils::PathChooser(this);
309
        m_cmakeExecutable->setExpectedKind(Utils::PathChooser::ExistingCommand);
Jarek Kobus's avatar
Jarek Kobus committed
310
        fl->addRow("cmake Executable", m_cmakeExecutable);
311
312
313
    }

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

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

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

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

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

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

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

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

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

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

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

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

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
432
433
void CMakeRunPage::runCMake()
{
434
435
436
437
438
439
440
441
442
443
444
445
446
    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
447
448
    m_runCMake->setEnabled(false);
    m_argumentsLineEdit->setEnabled(false);
449
    m_generatorComboBox->setEnabled(false);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
450
    CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager();
451

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

460
461
462
463

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

464
465
466
467
468
469
470
471
    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()) {
472
        m_cmakeProcess = new Utils::QtcProcess();
473
474
        connect(m_cmakeProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(cmakeReadyReadStandardOutput()));
        connect(m_cmakeProcess, SIGNAL(readyReadStandardError()), this, SLOT(cmakeReadyReadStandardError()));
475
        connect(m_cmakeProcess, SIGNAL(finished(int)), this, SLOT(cmakeFinished()));
476
        cmakeManager->createXmlFile(m_cmakeProcess, m_argumentsLineEdit->text(), m_cmakeWizard->sourceDirectory(), m_buildDirectory, env, generator);
477
478
479
    } else {
        m_runCMake->setEnabled(true);
        m_argumentsLineEdit->setEnabled(true);
480
        m_generatorComboBox->setEnabled(true);
Jarek Kobus's avatar
Jarek Kobus committed
481
        m_output->appendPlainText(tr("No valid cmake executable specified."));
482
    }
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
483
484
}

485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
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
504
{
505
506
507
508
509
510
511
512
513
514
    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
515
516
517
518
519
520
}

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

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

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

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