From 2b8e81893aaa9b034cc37522b656dce1af0756a2 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 16 Sep 2014 18:23:25 +0200 Subject: [PATCH] JsonWizard: Add FileGenerator Add a generator that takes template files and turns them into the real thing. Change-Id: I565d6aabdcd391adc34886f4741e0dbbad5e13ec Reviewed-by: Daniel Teske --- .../projectexplorer/jsonwizard/jsonwizard.pri | 2 + .../jsonwizard/jsonwizardfilegenerator.cpp | 206 ++++++++++++++++++ .../jsonwizard/jsonwizardfilegenerator.h | 77 +++++++ .../jsonwizard/jsonwizardgeneratorfactory.cpp | 49 +++++ .../jsonwizard/jsonwizardgeneratorfactory.h | 13 ++ .../projectexplorer/projectexplorer.cpp | 5 +- .../projectexplorer/projectexplorer.qbs | 1 + 7 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp create mode 100644 src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri b/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri index 78b6b7dee44..3b8713de315 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizard.pri @@ -1,11 +1,13 @@ HEADERS += $$PWD/jsonwizard.h \ $$PWD/jsonwizardexpander.h \ $$PWD/jsonwizardfactory.h \ + $$PWD/jsonwizardfilegenerator.h \ $$PWD/jsonwizardgeneratorfactory.h \ $$PWD/jsonwizardpagefactory.h SOURCES += $$PWD/jsonwizard.cpp \ $$PWD/jsonwizardexpander.cpp \ $$PWD/jsonwizardfactory.cpp \ + $$PWD/jsonwizardfilegenerator.cpp \ $$PWD/jsonwizardgeneratorfactory.cpp \ $$PWD/jsonwizardpagefactory.cpp diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp new file mode 100644 index 00000000000..aad694ba13c --- /dev/null +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp @@ -0,0 +1,206 @@ +/**************************************************************************** +** +** 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 +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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. +** +** 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 "jsonwizardfilegenerator.h" + +#include "../customwizard/customwizardpreprocessor.h" +#include "../project.h" +#include "../projectexplorer.h" +#include "jsonwizard.h" +#include "jsonwizardfactory.h" + +#include + +#include +#include +#include + +#include +#include +#include + +namespace ProjectExplorer { +namespace Internal { + +static QString processTextFileContents(Utils::AbstractMacroExpander *expander, + const QString &input, QString *errorMessage) +{ + errorMessage->clear(); + + if (input.isEmpty()) + return input; + + QString result; + if (!customWizardPreprocess(Utils::expandMacros(input, expander), &result, errorMessage)) + return QString(); + return result; +} + +bool JsonWizardFileGenerator::setup(const QVariant &data, QString *errorMessage) +{ + QVariantList list = JsonWizardFactory::objectOrList(data, errorMessage); + if (list.isEmpty()) + return false; + + foreach (const QVariant &d, list) { + if (d.type() != QVariant::Map) { + *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", + "Files data list entry is not an object."); + return false; + } + + File f; + + QVariantMap tmp = d.toMap(); + f.source = tmp.value(QLatin1String("source")).toString(); + f.target = tmp.value(QLatin1String("target")).toString(); + f.condition = tmp.value(QLatin1String("condition"), true); + f.isBinary = tmp.value(QLatin1String("isBinary"), false); + f.overwrite = tmp.value(QLatin1String("overwrite"), false); + f.openInEditor = tmp.value(QLatin1String("openInEditor"), false); + f.openAsProject = tmp.value(QLatin1String("openAsProject"), false); + + if (f.source.isEmpty()) { + *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonFieldPage", + "No source given for file in file list."); + return false; + } + + if (f.target.isEmpty()) + f.target = f.source; + + m_fileList << f; + } + + return true; +} + +Core::GeneratedFiles JsonWizardFileGenerator::fileList(Utils::AbstractMacroExpander *expander, + const QString &wizardDir, const QString &projectDir, + QString *errorMessage) +{ + errorMessage->clear(); + + QDir wizard(wizardDir); + QDir project(projectDir); + + Core::GeneratedFiles result; + + foreach (const File &f, m_fileList) { + if (!JsonWizard::boolFromVariant(f.condition, expander)) + continue; + + // Read contents of source file + const QString src = wizard.absoluteFilePath(Utils::expandMacros(f.source, expander)); + const QFile::OpenMode openMode + = JsonWizard::boolFromVariant(f.isBinary, expander) + ? QIODevice::ReadOnly : (QIODevice::ReadOnly|QIODevice::Text); + + Utils::FileReader reader; + if (!reader.fetch(src, openMode, errorMessage)) + return Core::GeneratedFiles(); + + // Generate file information: + Core::GeneratedFile gf; + gf.setPath(project.absoluteFilePath(Utils::expandMacros(f.target, expander))); + + if (JsonWizard::boolFromVariant(f.isBinary, expander)) { + gf.setBinary(true); + gf.setBinaryContents(reader.data()); + } else { + // TODO: Document that input files are UTF8 encoded! + gf.setBinary(false); + gf.setContents(processTextFileContents(expander, QString::fromUtf8(reader.data()), errorMessage)); + if (!errorMessage->isEmpty()) { + *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizard", "When processing \"%1\":
%2") + .arg(src, *errorMessage); + return Core::GeneratedFiles(); + } + } + + Core::GeneratedFile::Attributes attributes = 0; + if (JsonWizard::boolFromVariant(f.openInEditor, expander)) + attributes |= Core::GeneratedFile::OpenEditorAttribute; + if (JsonWizard::boolFromVariant(f.openAsProject, expander)) + attributes |= Core::GeneratedFile::OpenProjectAttribute; + if (JsonWizard::boolFromVariant(f.overwrite, expander)) + attributes |= Core::GeneratedFile::ForceOverwrite; + gf.setAttributes(attributes); + result.append(gf); + } + + return result; +} + +bool JsonWizardFileGenerator::formatFile(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage) +{ + Q_UNUSED(wizard); + Q_UNUSED(file); + Q_UNUSED(errorMessage); + // TODO: Implement me! + return true; +} + +bool JsonWizardFileGenerator::writeFile(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage) +{ + Q_UNUSED(wizard); + if (!(file->attributes() & Core::GeneratedFile::KeepExistingFileAttribute)) { + if (!file->write(errorMessage)) + return false; + } + return true; +} + +bool JsonWizardFileGenerator::postWrite(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage) +{ + Q_UNUSED(wizard); + if (file->attributes() & Core::GeneratedFile::OpenProjectAttribute) { + Project *project = ProjectExplorerPlugin::instance()->openProject(file->path(), errorMessage); + if (!project) { + *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizard", + "Failed to open \"%1\" as a project.") + .arg(QDir::toNativeSeparators(file->path())); + + return false; + } + } + if (file->attributes() & Core::GeneratedFile::OpenEditorAttribute) { + if (!Core::EditorManager::openEditor(file->path(), file->editorId())) { + if (errorMessage) + *errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizard", + "Failed to open an editor for \"%1\".") + .arg(QDir::toNativeSeparators(file->path())); + return false; + } + } + return true; +} + +} // namespace Internal +} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h new file mode 100644 index 00000000000..2c051c0bac7 --- /dev/null +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** 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 +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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. +** +** 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. +** +****************************************************************************/ + +#ifndef JSONWIZARDFILEGENERATOR_H +#define JSONWIZARDFILEGENERATOR_H + +#include "jsonwizardgeneratorfactory.h" + +#include + +namespace ProjectExplorer { +namespace Internal { + +// Documentation inside. +class JsonWizardFileGenerator : public JsonWizardGenerator +{ +public: + bool setup(const QVariant &data, QString *errorMessage); + + Core::GeneratedFiles fileList(Utils::AbstractMacroExpander *expander, + const QString &wizardDir, const QString &projectDir, + QString *errorMessage); + + bool formatFile(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage); + bool writeFile(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage); + bool postWrite(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage); + +private: + class File { + public: + File() : + condition(true), isBinary(false), overwrite(false), + openInEditor(false), openAsProject(false) + { } + + QString source; + QString target; + QVariant condition; + QVariant isBinary; + QVariant overwrite; + QVariant openInEditor; + QVariant openAsProject; + }; + + QList m_fileList; +}; + +} // namespace Internal +} // namespace ProjectExplorer + +#endif // JSONWIZARDFILEGENERATOR_H diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp index 7cb1af98c19..7356781ea0c 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.cpp @@ -30,6 +30,7 @@ #include "jsonwizardgeneratorfactory.h" #include "jsonwizard.h" +#include "jsonwizardfilegenerator.h" #include "../projectexplorerconstants.h" @@ -169,4 +170,52 @@ void JsonWizardGeneratorFactory::setTypeIdsSuffix(const QString &suffix) setTypeIdsSuffixes(QStringList() << suffix); } +// -------------------------------------------------------------------- +// FileGeneratorFactory: +// -------------------------------------------------------------------- + + +FileGeneratorFactory::FileGeneratorFactory() +{ + setTypeIdsSuffix(QLatin1String("File")); +} + +JsonWizardGenerator *FileGeneratorFactory::create(Core::Id typeId, const QVariant &data, + const QString &path, const QString &platform, + const QVariantMap &variables) +{ + Q_UNUSED(data); + Q_UNUSED(path); + Q_UNUSED(platform); + Q_UNUSED(variables); + + QTC_ASSERT(canCreate(typeId), return 0); + + auto *gen = new Internal::JsonWizardFileGenerator(); + QString errorMessage; + gen->setup(data, &errorMessage); + + if (!errorMessage.isEmpty()) { + qWarning() << "FileGeneratorFactory setup error:" << errorMessage; + delete gen; + return 0; + } + + return gen; +} + +bool FileGeneratorFactory::validateData(Core::Id typeId, const QVariant &data, QString *errorMessage) +{ + Q_UNUSED(data); + Q_UNUSED(errorMessage); + + QTC_ASSERT(canCreate(typeId), return false); + + QScopedPointer gen(new Internal::JsonWizardFileGenerator()); + if (!gen->setup(data, errorMessage)) + return false; + + return true; +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.h index d043237ec4d..9f22446781d 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardgeneratorfactory.h @@ -89,6 +89,19 @@ private: QList m_typeIds; }; +class FileGeneratorFactory : public JsonWizardGeneratorFactory +{ + Q_OBJECT + +public: + FileGeneratorFactory(); + + JsonWizardGenerator *create(Core::Id typeId, const QVariant &data, + const QString &path, const QString &platform, + const QVariantMap &variables); + bool validateData(Core::Id typeId, const QVariant &data, QString *errorMessage); +}; + } // namespace ProjectExplorer #endif // JSONWIZARDGENERATORFACTORY_H diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 50d2745faef..3ba059c349a 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -35,8 +35,8 @@ #include "deployablefile.h" #include "deployconfiguration.h" #include "gcctoolchainfactories.h" -#include "jsonwizard/jsonwizardexpander.h" #include "jsonwizard/jsonwizardfactory.h" +#include "jsonwizard/jsonwizardgeneratorfactory.h" #include "project.h" #include "projectexplorersettings.h" #include "projectmacroexpander.h" @@ -439,6 +439,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er addAutoReleasedObject(new CustomWizardMetaFactory(Core::IWizardFactory::FileWizard)); addAutoReleasedObject(new CustomWizardMetaFactory(Core::IWizardFactory::ClassWizard)); + // For JsonWizard: + JsonWizardFactory::registerGeneratorFactory(new FileGeneratorFactory); + d->m_proWindow = new ProjectWindow; addAutoReleasedObject(d->m_proWindow); diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 562287542d3..45e8f5c92bd 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -173,6 +173,7 @@ QtcPlugin { "jsonwizard.cpp", "jsonwizard.h", "jsonwizardexpander.cpp", "jsonwizardexpander.h", "jsonwizardfactory.cpp", "jsonwizardfactory.h", + "jsonwizardfilegenerator.cpp", "jsonwizardfilegenerator.h", "jsonwizardgeneratorfactory.cpp", "jsonwizardgeneratorfactory.h", "jsonwizardpagefactory.cpp", "jsonwizardpagefactory.h" ]