cmakeopenprojectwizard.cpp 21 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
** If you have questions regarding the use of this file, please contact
Tobias Hunger's avatar
Tobias Hunger committed
29
** Nokia at info@qt.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>
47
#include <texteditor/fontsettings.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."));
con's avatar
con committed
258
    fl->addRow(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
{
    QFormLayout *fl = new QFormLayout;
con's avatar
con committed
285
    fl->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
286
    setLayout(fl);
287
    // Description Label
dt's avatar
dt committed
288
289
290
291
    m_descriptionLabel = new QLabel(this);
    m_descriptionLabel->setWordWrap(true);

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

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

con's avatar
con committed
308
309
310
        QLabel *cmakeLabel = new QLabel(text);
        cmakeLabel->setWordWrap(true);
        fl->addRow(cmakeLabel);
311
        // Show a field for the user to enter
312
        m_cmakeExecutable = new Utils::PathChooser(this);
313
        m_cmakeExecutable->setExpectedKind(Utils::PathChooser::ExistingCommand);
con's avatar
con committed
314
        fl->addRow("cmake Executable:", m_cmakeExecutable);
315
316
317
    }

    // Run CMake Line (with arguments)
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
318
    m_argumentsLineEdit = new QLineEdit(this);
319
    connect(m_argumentsLineEdit,SIGNAL(returnPressed()), this, SLOT(runCMake()));
con's avatar
con committed
320
    fl->addRow(tr("Arguments:"), m_argumentsLineEdit);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
321

322
    m_generatorComboBox = new QComboBox(this);
con's avatar
con committed
323
    fl->addRow(tr("Generator:"), m_generatorComboBox);
dt's avatar
dt committed
324

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

con's avatar
con committed
329
330
331
332
    QHBoxLayout *hbox2 = new QHBoxLayout;
    hbox2->addStretch(10);
    hbox2->addWidget(m_runCMake);
    fl->addRow(hbox2);
333

334
    // Bottom output window
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
335
    m_output = new QPlainTextEdit(this);
336
    m_output->setReadOnly(true);
con's avatar
con committed
337
338
339
    // set smaller minimum size to avoid vanishing descriptions if all of the
    // above is shown and the dialog not vertically resizing to fit stuff in (Mac)
    m_output->setMinimumHeight(15);
340
    QFont f(TextEditor::FontSettings::defaultFixedFontFamily());
341
342
    f.setStyleHint(QFont::TypeWriter);
    m_output->setFont(f);
343
344
345
    QSizePolicy pl = m_output->sizePolicy();
    pl.setVerticalStretch(1);
    m_output->setSizePolicy(pl);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
346
    fl->addRow(m_output);
347
348
349
350
351

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

352
    setTitle(tr("Run CMake"));
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
353
354
}

355
356
void CMakeRunPage::initializePage()
{
357
    if (m_mode == Initial) {
358
        m_complete = m_cmakeWizard->existsUpToDateXmlFile();
359
        m_buildDirectory = m_cmakeWizard->buildDirectory();
360
361
362

        if (m_cmakeWizard->existsUpToDateXmlFile()) {
            m_descriptionLabel->setText(
363
                    tr("The directory %1 already contains a cbp file, which is recent enough. "
364
                       "You can pass special arguments or change the used tool chain here and rerun CMake. "
365
                       "Or simply finish the wizard directly.").arg(m_buildDirectory));
366
367
        } else {
            m_descriptionLabel->setText(
368
369
                    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));
370
        }
371
    } else if (m_mode == CMakeRunPage::NeedToUpdate) {
372
        m_descriptionLabel->setText(tr("The directory %1 contains an outdated .cbp file. Qt "
373
                                       "Creator needs to update this file by running CMake. "
374
                                       "If you want to add additional command line arguments, "
375
                                       "add them below. Note that CMake remembers command "
Friedemann Kleint's avatar
Friedemann Kleint committed
376
                                       "line arguments from the previous runs.").arg(m_buildDirectory));
377
    } else if(m_mode == CMakeRunPage::Recreate) {
Friedemann Kleint's avatar
Friedemann Kleint committed
378
        m_descriptionLabel->setText(tr("The directory %1 specified in a build-configuration, "
379
                                       "does not contain a cbp file. Qt Creator needs to "
380
                                       "recreate this file, by running CMake. "
381
                                       "Some projects require command line arguments to "
382
                                       "the initial CMake call. Note that CMake remembers command "
Friedemann Kleint's avatar
Friedemann Kleint committed
383
                                       "line arguments from the previous runs.").arg(m_buildDirectory));
384
    } else if(m_mode == CMakeRunPage::ChangeDirectory) {
385
        m_buildDirectory = m_cmakeWizard->buildDirectory();
386
        m_descriptionLabel->setText(tr("Qt Creator needs to run CMake in the new build directory. "
387
                                       "Some projects require command line arguments to the "
388
                                       "initial CMake call."));
389
390
    } else if (m_mode == CMakeRunPage::WantToUpdate) {
        m_descriptionLabel->setText(tr("Refreshing cbp file in %1.").arg(m_buildDirectory));
391
    }
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411


    // Try figuring out generator and toolchain from CMakeCache.txt
    QString cachedGenerator;
    QString cmakeCxxCompiler;
    QFile fi(m_buildDirectory + "/CMakeCache.txt");
    if (fi.exists()) {
        // Cache exists, then read it...
        if (fi.open(QIODevice::ReadOnly | QIODevice::Text)) {
            while (!fi.atEnd()) {
                QString line = fi.readLine();
                if (line.startsWith("CMAKE_GENERATOR:INTERNAL=")) {
                    int splitpos = line.indexOf('=');
                    if (splitpos != -1)
                        cachedGenerator = line.mid(splitpos + 1).trimmed();
                }
                if (line.startsWith("CMAKE_CXX_COMPILER:FILEPATH=")) {
                    int splitpos = line.indexOf("=");
                    if (splitpos != -1)
                        cmakeCxxCompiler = line.mid(splitpos +1).trimmed();
412
                }
413
414
                if (!cachedGenerator.isEmpty() && !cmakeCxxCompiler.isEmpty())
                    break;
415
            }
416
        }
417
    }
dt's avatar
dt committed
418

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
    // Build the list of generators/toolchains we want to offer
    // todo restrict toolchains based on CMAKE_CXX_COMPILER ?
    Q_UNUSED(cmakeCxxCompiler);
    m_generatorComboBox->clear();
    bool hasCodeBlocksGenerator = m_cmakeWizard->cmakeManager()->hasCodeBlocksMsvcGenerator();
    ProjectExplorer::Abi abi = ProjectExplorer::Abi::hostAbi();
    abi = ProjectExplorer::Abi(abi.architecture(), abi.os(), ProjectExplorer::Abi::UnknownFlavor,
                               abi.binaryFormat(), abi.wordWidth() == 32 ? 32 : 0);
    QList<ProjectExplorer::ToolChain *> tcs =
            ProjectExplorer::ToolChainManager::instance()->findToolChains(abi);

    foreach (ProjectExplorer::ToolChain *tc, tcs) {
        ProjectExplorer::Abi targetAbi = tc->targetAbi();
        QVariant tcVariant = qVariantFromValue(static_cast<void *>(tc));
        if (targetAbi.os() == ProjectExplorer::Abi::WindowsOS) {
            if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2005Flavor
                    || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2008Flavor
                    || targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMsvc2010Flavor) {
                if (hasCodeBlocksGenerator && (cachedGenerator.isEmpty() || cachedGenerator == "NMake Makefiles"))
438
                    m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(tc->displayName()), tcVariant);
439
440
             } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) {
                if (cachedGenerator.isEmpty() || cachedGenerator == "MinGW Makefiles")
441
442
                    m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(tc->displayName()), tcVariant);
            }
443
444
445
446
        } else {
            // Non windows
            if (cachedGenerator.isEmpty() || cachedGenerator == "Unix Makefiles")
                m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(tc->displayName()), tcVariant);
447
        }
448
    }
449
450
}

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
451
452
void CMakeRunPage::runCMake()
{
453
454
455
    int index = m_generatorComboBox->currentIndex();

    ProjectExplorer::ToolChain *tc = 0;
456
    if (index >= 0)
457
        tc = static_cast<ProjectExplorer::ToolChain *>(m_generatorComboBox->itemData(index).value<void *>());
458
459

    m_cmakeWizard->setToolChain(tc);
460

qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
461
462
    m_runCMake->setEnabled(false);
    m_argumentsLineEdit->setEnabled(false);
463
    m_generatorComboBox->setEnabled(false);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
464
    CMakeManager *cmakeManager = m_cmakeWizard->cmakeManager();
465

dt's avatar
dt committed
466
    QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles");
hjk's avatar
hjk committed
467
    if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS) {
468
        if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor)
469
            generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
470
471
        else
            generator = QLatin1String("-GCodeBlocks - NMake Makefiles");
dt's avatar
dt committed
472
473
    }

474
475
476
477

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

478
479
480
481
482
483
484
485
    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()) {
486
        m_cmakeProcess = new Utils::QtcProcess();
487
488
        connect(m_cmakeProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(cmakeReadyReadStandardOutput()));
        connect(m_cmakeProcess, SIGNAL(readyReadStandardError()), this, SLOT(cmakeReadyReadStandardError()));
489
        connect(m_cmakeProcess, SIGNAL(finished(int)), this, SLOT(cmakeFinished()));
490
        cmakeManager->createXmlFile(m_cmakeProcess, m_argumentsLineEdit->text(), m_cmakeWizard->sourceDirectory(), m_buildDirectory, env, generator);
491
492
493
    } else {
        m_runCMake->setEnabled(true);
        m_argumentsLineEdit->setEnabled(true);
494
        m_generatorComboBox->setEnabled(true);
Jarek Kobus's avatar
Jarek Kobus committed
495
        m_output->appendPlainText(tr("No valid cmake executable specified."));
496
    }
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
497
498
}

499
500
501
502
503
504
505
506
507
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());
dt_'s avatar
dt_ committed
508
    cursor.movePosition(QTextCursor::End);
509
510
511
512
513
514
515
516
517
518
    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
519
{
520
521
522
523
524
525
526
527
528
529
    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
530
531
532
533
534
535
}

void CMakeRunPage::cmakeFinished()
{
    m_runCMake->setEnabled(true);
    m_argumentsLineEdit->setEnabled(true);
536
537
    m_generatorComboBox->setEnabled(true);

538
539
    if (m_cmakeProcess->exitCode() != 0) {
        m_exitCodeLabel->setVisible(true);
Jarek Kobus's avatar
Jarek Kobus committed
540
        m_exitCodeLabel->setText(tr("CMake exited with errors. Please check CMake output."));
541
542
543
544
545
        m_complete = false;
    } else {
        m_exitCodeLabel->setVisible(false);
        m_complete = true;
    }
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
546
547
    m_cmakeProcess->deleteLater();
    m_cmakeProcess = 0;
548
    m_cmakeWizard->setArguments(m_argumentsLineEdit->text());
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
549
550
551
552
553
554
555
556
    //TODO Actually test that running cmake was finished, for setting this bool
    emit completeChanged();
}

void CMakeRunPage::cleanupPage()
{
    m_output->clear();
    m_complete = false;
557
    m_exitCodeLabel->setVisible(false);
qtc-committer@nokia.com's avatar
qtc-committer@nokia.com committed
558
559
560
561
562
563
564
    emit completeChanged();
}

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