jsonwizard.cpp 7.59 KB
Newer Older
Tobias Hunger's avatar
Tobias Hunger committed
1 2 3 4 5 6 7 8 9 10 11 12
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
Eike Ziller's avatar
Eike Ziller committed
13 14
** conditions see http://www.qt.io/licensing.  For further information
** use the contact form at http://www.qt.io/contact-us.
Tobias Hunger's avatar
Tobias Hunger committed
15 16 17
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
Eike Ziller's avatar
Eike Ziller committed
18 19 20 21 22 23
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
Tobias Hunger's avatar
Tobias Hunger committed
24 25 26 27 28 29 30 31 32 33 34
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "jsonwizard.h"

#include "jsonwizardgeneratorfactory.h"

35 36
#include <coreplugin/messagemanager.h>

Tobias Hunger's avatar
Tobias Hunger committed
37 38
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
39
#include <utils/wizardpage.h>
Tobias Hunger's avatar
Tobias Hunger committed
40 41 42 43 44 45 46 47

#include <QFileInfo>
#include <QMessageBox>
#include <QVariant>

namespace ProjectExplorer {

JsonWizard::JsonWizard(QWidget *parent) :
48 49
    Utils::Wizard(parent)
{
50
    setMinimumSize(800, 500);
51
    m_expander.registerExtraResolver([this](const QString &name, QString *ret) -> bool {
52 53
        *ret = stringValue(name);
        return !ret->isNull();
54
    });
55 56 57 58 59 60 61
    m_expander.registerPrefix("Exists", tr("Check whether a variable exists. Returns \"true\" if it does and an empty string if not."),
                   [this](const QString &value) -> QString
    {
        const QString key = QString::fromLatin1("%{") + value + QLatin1Char('}');
        return m_expander.expand(key) == key ? QString() : QLatin1String("true");
    });

62
}
Tobias Hunger's avatar
Tobias Hunger committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76

JsonWizard::~JsonWizard()
{
    qDeleteAll(m_generators);
}

void JsonWizard::addGenerator(JsonWizardGenerator *gen)
{
    QTC_ASSERT(gen, return);
    QTC_ASSERT(!m_generators.contains(gen), return);

    m_generators.append(gen);
}

77
Utils::MacroExpander *JsonWizard::expander()
Tobias Hunger's avatar
Tobias Hunger committed
78
{
79
    return &m_expander;
Tobias Hunger's avatar
Tobias Hunger committed
80 81
}

82
JsonWizard::GeneratorFiles JsonWizard::generateFileList()
Tobias Hunger's avatar
Tobias Hunger committed
83 84 85 86
{
    QString errorMessage;
    GeneratorFiles list;

87
    QString targetPath = stringValue(QLatin1String("TargetPath"));
88
    if (targetPath.isEmpty())
89
        errorMessage = tr("Could not determine target path. \"TargetPath\" was not set on any page.");
Tobias Hunger's avatar
Tobias Hunger committed
90

91
    if (m_files.isEmpty() && errorMessage.isEmpty()) {
Tobias Hunger's avatar
Tobias Hunger committed
92 93
        emit preGenerateFiles();
        foreach (JsonWizardGenerator *gen, m_generators) {
94
            Core::GeneratedFiles tmp = gen->fileList(&m_expander, stringValue(QStringLiteral("WizardDir")),
Tobias Hunger's avatar
Tobias Hunger committed
95 96 97 98
                                                     targetPath, &errorMessage);
            if (!errorMessage.isEmpty())
                break;
            list.append(Utils::transform(tmp, [&gen](const Core::GeneratedFile &f)
99
                                              { return JsonWizard::GeneratorFile(f, gen); }));
Tobias Hunger's avatar
Tobias Hunger committed
100 101 102 103 104 105 106 107 108 109 110
        }
    }

    if (!errorMessage.isEmpty()) {
        QMessageBox::critical(this, tr("File Generation Failed"),
                              tr("The wizard failed to generate files.<br>"
                                 "The error message was: \"%1\".").arg(errorMessage));
        reject();
        return GeneratorFiles();
    }

111 112 113 114 115 116 117
    return list;
}

void JsonWizard::commitToFileList(const JsonWizard::GeneratorFiles &list)
{
    m_files = list;
    emit postGenerateFiles(m_files);
Tobias Hunger's avatar
Tobias Hunger committed
118 119
}

120
QString JsonWizard::stringValue(const QString &n) const
Tobias Hunger's avatar
Tobias Hunger committed
121
{
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
    QVariant v = value(n);
    if (!v.isValid())
        return QString();

    if (v.type() == QVariant::Bool)
        return v.toBool() ? QString::fromLatin1("true") : QString();

    if (v.type() == QVariant::String)
        return m_expander.expand(v.toString());

    if (v.type() == QVariant::StringList) {
        QStringList tmp = Utils::transform(v.toStringList(), [this](const QString &i) -> QString {
            return m_expander.expand(i).replace(QLatin1Char('\''), QLatin1String("\\'"));
        });
        return QString(QString(QLatin1Char('\'')) + tmp.join(QLatin1String("', '")) + QString(QLatin1Char('\'')));
Tobias Hunger's avatar
Tobias Hunger committed
137
    }
138
    return v.toString();
Tobias Hunger's avatar
Tobias Hunger committed
139 140 141 142 143 144 145
}

void JsonWizard::setValue(const QString &key, const QVariant &value)
{
    setProperty(key.toUtf8(), value);
}

146 147 148 149 150 151 152 153 154 155
QVariant JsonWizard::value(const QString &n) const
{
    QVariant v = property(n.toUtf8());
    if (v.isValid())
        return v;
    if (hasField(n))
        return field(n); // Can not contain macros!
    return QVariant();
}

156
bool JsonWizard::boolFromVariant(const QVariant &v, Utils::MacroExpander *expander)
Tobias Hunger's avatar
Tobias Hunger committed
157 158
{
    if (v.type() == QVariant::String)
159
        return !expander->expand(v.toString()).isEmpty();
Tobias Hunger's avatar
Tobias Hunger committed
160 161 162
    return v.toBool();
}

163 164 165 166 167 168
void JsonWizard::removeAttributeFromAllFiles(Core::GeneratedFile::Attribute a)
{
    for (int i = 0; i < m_files.count(); ++i)
        m_files[i].file.setAttributes(m_files.at(i).file.attributes() ^ a);
}

Tobias Hunger's avatar
Tobias Hunger committed
169 170 171 172 173
void JsonWizard::accept()
{
    Utils::Wizard::accept();

    QString errorMessage;
174 175 176 177 178
    if (m_files.isEmpty()) {
        commitToFileList(generateFileList()); // The Summary page does this for us, but a wizard
                                              // does not need to have one.
    }
    QTC_ASSERT(!m_files.isEmpty(), return);
Tobias Hunger's avatar
Tobias Hunger committed
179 180 181

    emit prePromptForOverwrite(m_files);
    JsonWizardGenerator::OverwriteResult overwrite =
182
            JsonWizardGenerator::promptForOverwrite(&m_files, &errorMessage);
Tobias Hunger's avatar
Tobias Hunger committed
183 184 185 186 187 188 189
    if (overwrite == JsonWizardGenerator::OverwriteError) {
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Overwrite Files"), errorMessage);
        return;
    }

    emit preFormatFiles(m_files);
190
    if (!JsonWizardGenerator::formatFiles(this, &m_files, &errorMessage)) {
Tobias Hunger's avatar
Tobias Hunger committed
191 192 193 194 195 196
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Format Files"), errorMessage);
        return;
    }

    emit preWriteFiles(m_files);
197
    if (!JsonWizardGenerator::writeFiles(this, &m_files, &errorMessage)) {
Tobias Hunger's avatar
Tobias Hunger committed
198 199 200 201 202 203
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Write Files"), errorMessage);
        return;
    }

    emit postProcessFiles(m_files);
204
    if (!JsonWizardGenerator::postWrite(this, &m_files, &errorMessage)) {
Tobias Hunger's avatar
Tobias Hunger committed
205 206 207 208 209
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Post-Process Files"), errorMessage);
        return;
    }
    emit filesReady(m_files);
210
    if (!JsonWizardGenerator::allDone(this, &m_files, &errorMessage)) {
211 212 213 214 215 216
        if (!errorMessage.isEmpty())
            QMessageBox::warning(this, tr("Failed to Open Files"), errorMessage);
        return;
    }

    emit allDone(m_files);
Tobias Hunger's avatar
Tobias Hunger committed
217 218
}

219 220 221 222 223 224 225 226 227 228 229 230 231 232
void JsonWizard::handleNewPages(int pageId)
{
    Utils::WizardPage *wp = qobject_cast<Utils::WizardPage *>(page(pageId));
    if (!wp)
        return;

    connect(wp, &Utils::WizardPage::reportError, this, &JsonWizard::handleError);
}

void JsonWizard::handleError(const QString &message)
{
    Core::MessageManager::write(message, Core::MessageManager::ModeSwitch);
}

Tobias Hunger's avatar
Tobias Hunger committed
233
} // namespace ProjectExplorer