diff options
Diffstat (limited to 'src/plugins/qmakeprojectmanager')
53 files changed, 1050 insertions, 2255 deletions
diff --git a/src/plugins/qmakeprojectmanager/CMakeLists.txt b/src/plugins/qmakeprojectmanager/CMakeLists.txt new file mode 100644 index 0000000000..5cd7b6cc19 --- /dev/null +++ b/src/plugins/qmakeprojectmanager/CMakeLists.txt @@ -0,0 +1,53 @@ +add_qtc_plugin(QmakeProjectManager + DEPENDS qmljs + PLUGIN_DEPENDS Core CppTools QtSupport ResourceEditor TextEditor + PLUGIN_RECOMMENDS Designer + SOURCES + addlibrarywizard.cpp addlibrarywizard.h + applicationlauncher.h + customwidgetwizard/classdefinition.cpp customwidgetwizard/classdefinition.h customwidgetwizard/classdefinition.ui + customwidgetwizard/classlist.cpp customwidgetwizard/classlist.h + customwidgetwizard/customwidgetpluginwizardpage.cpp customwidgetwizard/customwidgetpluginwizardpage.h customwidgetwizard/customwidgetpluginwizardpage.ui + customwidgetwizard/customwidgetwidgetswizardpage.cpp customwidgetwizard/customwidgetwidgetswizardpage.h customwidgetwizard/customwidgetwidgetswizardpage.ui + customwidgetwizard/customwidgetwizard.cpp customwidgetwizard/customwidgetwizard.h + customwidgetwizard/customwidgetwizarddialog.cpp customwidgetwizard/customwidgetwizarddialog.h + customwidgetwizard/filenamingparameters.h + customwidgetwizard/plugingenerator.cpp customwidgetwizard/plugingenerator.h + customwidgetwizard/pluginoptions.h + desktopqmakerunconfiguration.cpp desktopqmakerunconfiguration.h + externaleditors.cpp externaleditors.h + librarydetailscontroller.cpp librarydetailscontroller.h + librarydetailswidget.ui + makefileparse.cpp makefileparse.h + profilecompletionassist.cpp profilecompletionassist.h + profileeditor.cpp profileeditor.h + profilehighlighter.cpp profilehighlighter.h + profilehoverhandler.cpp profilehoverhandler.h + qmakebuildconfiguration.cpp qmakebuildconfiguration.h + qmakebuildinfo.h + qmakekitinformation.cpp qmakekitinformation.h + qmakemakestep.cpp qmakemakestep.h + qmakenodes.cpp qmakenodes.h + qmakenodetreebuilder.cpp qmakenodetreebuilder.h + qmakeparser.cpp qmakeparser.h + qmakeparsernodes.cpp qmakeparsernodes.h + qmakeproject.cpp qmakeproject.h + qmakeprojectconfigwidget.cpp qmakeprojectconfigwidget.h + qmakeprojectimporter.cpp qmakeprojectimporter.h + qmakeprojectmanager.cpp qmakeprojectmanager.h + qmakeprojectmanager.qrc + qmakeprojectmanager_global.h + qmakeprojectmanagerconstants.h + qmakeprojectmanagerplugin.cpp qmakeprojectmanagerplugin.h + qmakesettings.cpp qmakesettings.h + qmakestep.cpp qmakestep.h qmakestep.ui + qtmodulesinfo.cpp qtmodulesinfo.h + wizards/filespage.cpp wizards/filespage.h + wizards/modulespage.cpp wizards/modulespage.h + wizards/qtprojectparameters.cpp wizards/qtprojectparameters.h + wizards/qtwizard.cpp wizards/qtwizard.h + wizards/simpleprojectwizard.cpp wizards/simpleprojectwizard.h + wizards/subdirsprojectwizard.cpp wizards/subdirsprojectwizard.h + wizards/subdirsprojectwizarddialog.cpp wizards/subdirsprojectwizarddialog.h + wizards/wizards.qrc +) diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp index 94f7d7b70d..bfef5875e3 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp @@ -54,7 +54,7 @@ QStringList qt_clean_filter_list(const QString &filter) return f.split(QLatin1Char(' '), QString::SkipEmptyParts); } -static bool validateLibraryPath(const Utils::FileName &filePath, +static bool validateLibraryPath(const Utils::FilePath &filePath, const Utils::PathChooser *pathChooser, QString *errorMessage) { diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.h b/src/plugins/qmakeprojectmanager/addlibrarywizard.h index 196d31885c..ad2372f007 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.h +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.h @@ -92,8 +92,6 @@ private: QString m_proFile; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(AddLibraryWizard::Platforms) - class LibraryTypePage : public QWizardPage { Q_OBJECT @@ -139,3 +137,5 @@ private: } // namespace Internal } // namespace QmakeProjectManager + +Q_DECLARE_OPERATORS_FOR_FLAGS(QmakeProjectManager::Internal::AddLibraryWizard::Platforms) diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp index be08ea5ff2..b93595bba1 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/plugingenerator.cpp @@ -130,7 +130,7 @@ QList<Core::GeneratedFile> PluginGenerator::generatePlugin(const GenerationPara QString iconResource; if (!wo.iconFile.isEmpty()) { iconResource = QLatin1String("QLatin1String(\":/"); - iconResource += Utils::FileName::fromString(wo.iconFile).fileName(); + iconResource += Utils::FilePath::fromString(wo.iconFile).fileName(); iconResource += QLatin1String("\")"); } sm.insert(QLatin1String("WIDGET_ICON"),iconResource); diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp index 8ac2a1cd0b..8cf53db49b 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp @@ -31,6 +31,7 @@ #include <projectexplorer/project.h> #include <projectexplorer/projectnodes.h> #include <projectexplorer/runconfigurationaspects.h> +#include <projectexplorer/runcontrol.h> #include <projectexplorer/target.h> #include <qtsupport/qtkitinformation.h> @@ -61,13 +62,16 @@ namespace Internal { DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target, Core::Id id) : RunConfiguration(target, id) { - auto envAspect = addAspect<LocalEnvironmentAspect>(target, [this](Environment &env) { - addToBaseEnvironment(env); - }); + auto envAspect = addAspect<LocalEnvironmentAspect>(target); + envAspect->addModifier([this](Environment &env) { + BuildTargetInfo bti = buildTargetInfo(); + if (bti.runEnvModifier) + bti.runEnvModifier(env, aspect<UseLibraryPathsAspect>()->value()); + }); addAspect<ExecutableAspect>(); addAspect<ArgumentsAspect>(); - addAspect<WorkingDirectoryAspect>(envAspect); + addAspect<WorkingDirectoryAspect>(); addAspect<TerminalAspect>(); setOutputFormatter<QtSupport::QtOutputFormatter>(); @@ -80,6 +84,10 @@ DesktopQmakeRunConfiguration::DesktopQmakeRunConfiguration(Target *target, Core: auto dyldAspect = addAspect<UseDyldSuffixAspect>(); connect(dyldAspect, &UseLibraryPathsAspect::changed, envAspect, &EnvironmentAspect::environmentChanged); + envAspect->addModifier([dyldAspect](Environment &env) { + if (dyldAspect->value()) + env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug")); + }); } connect(target->project(), &Project::parsingFinished, @@ -99,8 +107,7 @@ void DesktopQmakeRunConfiguration::updateTargetInformation() wda->pathChooser()->setBaseFileName(target()->project()->projectDirectory()); auto terminalAspect = aspect<TerminalAspect>(); - if (!terminalAspect->isUserSet()) - terminalAspect->setUseTerminal(bti.usesTerminal); + terminalAspect->setUseTerminalHint(bti.usesTerminal); aspect<ExecutableAspect>()->setExecutable(bti.targetFilePath); } @@ -118,31 +125,14 @@ void DesktopQmakeRunConfiguration::doAdditionalSetup(const RunConfigurationCreat updateTargetInformation(); } -void DesktopQmakeRunConfiguration::addToBaseEnvironment(Environment &env) const +FilePath DesktopQmakeRunConfiguration::proFilePath() const { - BuildTargetInfo bti = buildTargetInfo(); - if (bti.runEnvModifier) - bti.runEnvModifier(env, aspect<UseLibraryPathsAspect>()->value()); - - if (auto dyldAspect = aspect<UseDyldSuffixAspect>()) { - if (dyldAspect->value()) - env.set(QLatin1String("DYLD_IMAGE_SUFFIX"), QLatin1String("_debug")); - } -} - -bool DesktopQmakeRunConfiguration::canRunForNode(const Node *node) const -{ - return node->filePath() == proFilePath(); -} - -FileName DesktopQmakeRunConfiguration::proFilePath() const -{ - return FileName::fromString(buildKey()); + return FilePath::fromString(buildKey()); } QString DesktopQmakeRunConfiguration::defaultDisplayName() { - FileName profile = proFilePath(); + FilePath profile = proFilePath(); if (!profile.isEmpty()) return profile.toFileInfo().completeBaseName(); return tr("Qt Run Configuration"); @@ -157,8 +147,6 @@ DesktopQmakeRunConfigurationFactory::DesktopQmakeRunConfigurationFactory() registerRunConfiguration<DesktopQmakeRunConfiguration>("Qt4ProjectManager.Qt4RunConfiguration:"); addSupportedProjectType(QmakeProjectManager::Constants::QMAKEPROJECT_ID); addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); - - addRunWorkerFactory<SimpleTargetRunner>(ProjectExplorer::Constants::NORMAL_RUN_MODE); } } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h index 2a4ccd564b..27bfb430b1 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h @@ -39,17 +39,13 @@ class DesktopQmakeRunConfiguration : public ProjectExplorer::RunConfiguration public: DesktopQmakeRunConfiguration(ProjectExplorer::Target *target, Core::Id id); - void addToBaseEnvironment(Utils::Environment &env) const; - private: void updateTargetInformation(); bool fromMap(const QVariantMap &map) final; void doAdditionalSetup(const ProjectExplorer::RunConfigurationCreationInfo &info) final; QString defaultDisplayName(); - bool canRunForNode(const ProjectExplorer::Node *node) const final; - - Utils::FileName proFilePath() const; + Utils::FilePath proFilePath() const; }; class DesktopQmakeRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory diff --git a/src/plugins/qmakeprojectmanager/externaleditors.cpp b/src/plugins/qmakeprojectmanager/externaleditors.cpp index 39de1e8ac7..50983370c3 100644 --- a/src/plugins/qmakeprojectmanager/externaleditors.cpp +++ b/src/plugins/qmakeprojectmanager/externaleditors.cpp @@ -168,21 +168,21 @@ bool ExternalQtEditor::getEditorLaunchData(const QString &fileName, // As fallback check PATH data->workingDirectory.clear(); QVector<QtSupport::BaseQtVersion *> qtVersionsToCheck; // deduplicated after being filled - if (const Project *project = SessionManager::projectForFile(Utils::FileName::fromString(fileName))) { + if (const Project *project = SessionManager::projectForFile(Utils::FilePath::fromString(fileName))) { data->workingDirectory = project->projectDirectory().toString(); // active kit if (const Target *target = project->activeTarget()) { - qtVersionsToCheck << QtSupport::QtKitInformation::qtVersion(target->kit()); + qtVersionsToCheck << QtSupport::QtKitAspect::qtVersion(target->kit()); } // all kits of project qtVersionsToCheck += Utils::transform<QVector>(project->targets(), [](Target *t) { - return QTC_GUARD(t) ? QtSupport::QtKitInformation::qtVersion(t->kit()) : nullptr; + return QTC_GUARD(t) ? QtSupport::QtKitAspect::qtVersion(t->kit()) : nullptr; }); } // default kit - qtVersionsToCheck << QtSupport::QtKitInformation::qtVersion(KitManager::defaultKit()); + qtVersionsToCheck << QtSupport::QtKitAspect::qtVersion(KitManager::defaultKit()); // all kits - qtVersionsToCheck += Utils::transform<QVector>(KitManager::kits(), QtSupport::QtKitInformation::qtVersion); + qtVersionsToCheck += Utils::transform<QVector>(KitManager::kits(), QtSupport::QtKitAspect::qtVersion); qtVersionsToCheck = Utils::filteredUnique(qtVersionsToCheck); // can still contain nullptr data->binary = findFirstCommand(qtVersionsToCheck, m_commandForQtVersion); // fallback @@ -288,8 +288,7 @@ bool DesignerExternalEditor::startEditor(const QString &fileName, QString *error m_processCache.insert(binary, socket); auto mapSlot = [this, binary] { processTerminated(binary); }; connect(socket, &QAbstractSocket::disconnected, this, mapSlot); - connect(socket, - static_cast<void (QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), + connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error), this, mapSlot); } return true; diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp index 1d3509f813..1f7a96eee5 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp @@ -860,7 +860,7 @@ QString PackageLibraryDetailsController::snippet() const bool PackageLibraryDetailsController::isLinkPackageGenerated() const { - const Project *project = SessionManager::projectForFile(Utils::FileName::fromString(proFile())); + const Project *project = SessionManager::projectForFile(Utils::FilePath::fromString(proFile())); if (!project) return false; @@ -947,7 +947,7 @@ InternalLibraryDetailsController::InternalLibraryDetailsController( libraryDetailsWidget()->useSubfoldersCheckBox->setEnabled(true); connect(libraryDetailsWidget()->libraryComboBox, - static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + QOverload<int>::of(&QComboBox::currentIndexChanged), this, &InternalLibraryDetailsController::slotCurrentLibraryChanged); updateProFile(); @@ -1010,7 +1010,7 @@ void InternalLibraryDetailsController::updateProFile() libraryDetailsWidget()->libraryComboBox->clear(); const QmakeProject *project - = dynamic_cast<QmakeProject *>(SessionManager::projectForFile(Utils::FileName::fromString(proFile()))); + = dynamic_cast<QmakeProject *>(SessionManager::projectForFile(Utils::FilePath::fromString(proFile()))); if (!project) return; @@ -1092,7 +1092,7 @@ QString InternalLibraryDetailsController::snippet() const const QString proRelavitePath = rootDir.relativeFilePath(proFile()); // project for which we insert the snippet - const Project *project = SessionManager::projectForFile(Utils::FileName::fromString(proFile())); + const Project *project = SessionManager::projectForFile(Utils::FilePath::fromString(proFile())); // the build directory of the active build configuration QDir rootBuildDir = rootDir; // If the project is unconfigured use the project dir diff --git a/src/plugins/qmakeprojectmanager/makefileparse.cpp b/src/plugins/qmakeprojectmanager/makefileparse.cpp index b73c75244e..5fd6d5b0be 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.cpp +++ b/src/plugins/qmakeprojectmanager/makefileparse.cpp @@ -39,7 +39,7 @@ using namespace QmakeProjectManager; using namespace Internal; -using Utils::FileName; +using Utils::FilePath; using Utils::QtcProcess; using QtSupport::QtVersionManager; using QtSupport::BaseQtVersion; @@ -242,7 +242,7 @@ void MakeFileParse::parseAssignments(QList<QMakeAssignment> *assignments) } } -static FileName findQMakeBinaryFromMakefile(const QString &makefile) +static FilePath findQMakeBinaryFromMakefile(const QString &makefile) { QFile fi(makefile); if (fi.exists() && fi.open(QFile::ReadOnly)) { @@ -260,11 +260,11 @@ static FileName findQMakeBinaryFromMakefile(const QString &makefile) // Is qmake still installed? QFileInfo fi(qmakePath); if (fi.exists()) - return FileName(fi); + return FilePath::fromFileInfo(fi); } } } - return FileName(); + return FilePath(); } MakeFileParse::MakeFileParse(const QString &makefile) @@ -312,7 +312,7 @@ MakeFileParse::MakefileState MakeFileParse::makeFileState() const return m_state; } -Utils::FileName MakeFileParse::qmakePath() const +Utils::FilePath MakeFileParse::qmakePath() const { return m_qmakePath; } diff --git a/src/plugins/qmakeprojectmanager/makefileparse.h b/src/plugins/qmakeprojectmanager/makefileparse.h index 9a2abeb00e..90d3415662 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.h +++ b/src/plugins/qmakeprojectmanager/makefileparse.h @@ -47,7 +47,7 @@ public: enum MakefileState { MakefileMissing, CouldNotParse, Okay }; MakefileState makeFileState() const; - Utils::FileName qmakePath() const; + Utils::FilePath qmakePath() const; QString srcProFile() const; QMakeStepConfig config() const; @@ -75,7 +75,7 @@ private: }; MakefileState m_state; - Utils::FileName m_qmakePath; + Utils::FilePath m_qmakePath; QString m_srcProFile; QmakeBuildConfig m_qmakeBuildConfig; diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp index cb26142767..346f119782 100644 --- a/src/plugins/qmakeprojectmanager/profileeditor.cpp +++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp @@ -28,6 +28,8 @@ #include "profilecompletionassist.h" #include "profilehighlighter.h" #include "profilehoverhandler.h" +#include "qmakenodes.h" +#include "qmakeproject.h" #include "qmakeprojectmanager.h" #include "qmakeprojectmanagerconstants.h" #include "qmakeprojectmanagerconstants.h" @@ -36,6 +38,7 @@ #include <extensionsystem/pluginmanager.h> #include <qtsupport/qtsupportconstants.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/session.h> #include <texteditor/texteditoractionhandler.h> #include <texteditor/textdocument.h> #include <utils/qtcassert.h> @@ -48,6 +51,7 @@ #include <algorithm> +using namespace ProjectExplorer; using namespace TextEditor; using namespace Utils; @@ -56,12 +60,14 @@ namespace Internal { class ProFileEditorWidget : public TextEditorWidget { -protected: +private: void findLinkAt(const QTextCursor &, Utils::ProcessLinkCallback &&processLinkCallback, bool resolveTarget = true, bool inNextSplit = false) override; void contextMenuEvent(QContextMenuEvent *) override; + + QString checkForPrfFile(const QString &baseName) const; }; static bool isValidFileNameChar(const QChar &c) @@ -74,6 +80,36 @@ static bool isValidFileNameChar(const QChar &c) || c == QLatin1Char('\\'); } +QString ProFileEditorWidget::checkForPrfFile(const QString &baseName) const +{ + const FilePath projectFile = textDocument()->filePath(); + const QmakePriFileNode *projectNode = nullptr; + for (const Project * const project : SessionManager::projects()) { + if (project->isParsing()) + continue; + projectNode = dynamic_cast<const QmakePriFileNode *>(project->rootProjectNode() + ->findProjectNode([&projectFile](const ProjectNode *pn) { + return pn->filePath() == projectFile; + })); + if (projectNode) + break; + } + if (!projectNode) + return QString(); + const QmakeProFileNode * const proFileNode = projectNode->proFileNode(); + if (!proFileNode) + return QString(); + const QmakeProFile * const proFile = proFileNode->proFile(); + if (!proFile) + return QString(); + for (const QString &featureRoot : proFile->featureRoots()) { + const QFileInfo candidate(featureRoot + '/' + baseName + ".prf"); + if (candidate.exists()) + return candidate.filePath(); + } + return QString(); +} + void ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, Utils::ProcessLinkCallback &&processLinkCallback, bool /*resolveTarget*/, @@ -189,6 +225,10 @@ void ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, return processLinkCallback(link); } link.targetFileName = QDir::cleanPath(fileName); + } else { + link.targetFileName = checkForPrfFile(buffer); + } + if (!link.targetFileName.isEmpty()) { link.linkTextStart = cursor.position() - positionInBlock + beginPos + 1; link.linkTextEnd = cursor.position() - positionInBlock + endPos; } @@ -229,7 +269,9 @@ ProFileEditorFactory::ProFileEditorFactory() setDocumentCreator(createProFileDocument); setEditorWidgetCreator([]() { return new ProFileEditorWidget; }); - setCompletionAssistProvider(new KeywordsCompletionAssistProvider(qmakeKeywords())); + const auto completionAssistProvider = new KeywordsCompletionAssistProvider(qmakeKeywords()); + completionAssistProvider->setDynamicCompletionFunction(&TextEditor::pathComplete); + setCompletionAssistProvider(completionAssistProvider); setCommentDefinition(Utils::CommentDefinition::HashStyle); setEditorActionHandlers(TextEditorActionHandler::UnCommentSelection diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 9435155b44..0bb6eed49f 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -31,6 +31,7 @@ #include "qmakeprojectconfigwidget.h" #include "qmakeprojectmanagerconstants.h" #include "qmakenodes.h" +#include "qmakesettings.h" #include "qmakestep.h" #include "qmakemakestep.h" #include "makefileparse.h" @@ -86,17 +87,17 @@ QString QmakeBuildConfiguration::shadowBuildDirectory(const QString &proFilePath const QString projectName = QFileInfo(proFilePath).completeBaseName(); ProjectMacroExpander expander(proFilePath, projectName, k, suffix, buildType); - QString projectDir = Project::projectDirectory(FileName::fromString(proFilePath)).toString(); + QString projectDir = Project::projectDirectory(FilePath::fromString(proFilePath)).toString(); QString buildPath = expander.expand(ProjectExplorerPlugin::buildDirectoryTemplate()); return FileUtils::resolvePath(projectDir, buildPath); } -static FileName defaultBuildDirectory(const QString &projectPath, +static FilePath defaultBuildDirectory(const QString &projectPath, const Kit *k, const QString &suffix, BuildConfiguration::BuildType type) { - return FileName::fromString(QmakeBuildConfiguration::shadowBuildDirectory(projectPath, k, + return FilePath::fromString(QmakeBuildConfiguration::shadowBuildDirectory(projectPath, k, suffix, type)); } @@ -140,7 +141,7 @@ void QmakeBuildConfiguration::initialize(const BuildInfo &info) cleanSteps->appendStep(new QmakeMakeStep(cleanSteps)); const QmakeExtraBuildInfo qmakeExtra = info.extraInfo.value<QmakeExtraBuildInfo>(); - BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *version = QtKitAspect::qtVersion(target()->kit()); BaseQtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); if (info.buildType == BuildConfiguration::Debug) @@ -157,7 +158,7 @@ void QmakeBuildConfiguration::initialize(const BuildInfo &info) setQMakeBuildConfiguration(config); - FileName directory = info.buildDirectory; + FilePath directory = info.buildDirectory; if (directory.isEmpty()) { directory = defaultBuildDirectory(target()->project()->projectFilePath().toString(), target()->kit(), info.displayName, buildType()); @@ -165,7 +166,7 @@ void QmakeBuildConfiguration::initialize(const BuildInfo &info) setBuildDirectory(directory); - if (DeviceTypeKitInformation::deviceTypeId(target()->kit()) + if (DeviceTypeKitAspect::deviceTypeId(target()->kit()) == Android::Constants::ANDROID_DEVICE_TYPE) { buildSteps->appendStep(Android::Constants::ANDROID_PACKAGE_INSTALLATION_STEP_ID); buildSteps->appendStep(Android::Constants::ANDROID_BUILD_APK_ID); @@ -210,13 +211,13 @@ void QmakeBuildConfiguration::kitChanged() void QmakeBuildConfiguration::toolChainUpdated(ToolChain *tc) { - if (ToolChainKitInformation::toolChain(target()->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID) == tc) + if (ToolChainKitAspect::toolChain(target()->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID) == tc) emitProFileEvaluateNeeded(); } void QmakeBuildConfiguration::qtVersionsChanged(const QList<int> &,const QList<int> &, const QList<int> &changed) { - if (changed.contains(QtKitInformation::qtVersionId(target()->kit()))) + if (changed.contains(QtKitAspect::qtVersionId(target()->kit()))) emitProFileEvaluateNeeded(); } @@ -293,6 +294,23 @@ void QmakeBuildConfiguration::emitProFileEvaluateNeeded() static_cast<QmakeProject *>(p)->scheduleAsyncUpdate(); } +QString QmakeBuildConfiguration::unalignedBuildDirWarning() +{ + return tr("The build directory should be at the same level as the source directory."); +} + +bool QmakeBuildConfiguration::isBuildDirAtSafeLocation(const QString &sourceDir, + const QString &buildDir) +{ + return buildDir.count('/') == sourceDir.count('/'); +} + +bool QmakeBuildConfiguration::isBuildDirAtSafeLocation() const +{ + return isBuildDirAtSafeLocation(project()->projectDirectory().toString(), + buildDirectory().toString()); +} + void QmakeBuildConfiguration::emitQMakeBuildConfigurationChanged() { emit qmakeBuildConfigurationChanged(); @@ -301,7 +319,7 @@ void QmakeBuildConfiguration::emitQMakeBuildConfigurationChanged() QStringList QmakeBuildConfiguration::configCommandLineArguments() const { QStringList result; - BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *version = QtKitAspect::qtVersion(target()->kit()); BaseQtVersion::QmakeBuildConfigs defaultBuildConfiguration = version ? version->defaultBuildConfig() : BaseQtVersion::QmakeBuildConfigs(BaseQtVersion::DebugBuild | BaseQtVersion::BuildAll); BaseQtVersion::QmakeBuildConfigs userBuildConfiguration = m_qmakeBuildConfiguration; @@ -364,13 +382,13 @@ QmakeBuildConfiguration::MakefileState QmakeBuildConfiguration::compareToImportF return MakefileMissing; } - BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *version = QtKitAspect::qtVersion(target()->kit()); if (!version) { qCDebug(logs) << "**No qt version in kit"; return MakefileForWrongProject; } - const Utils::FileName projectPath = + const Utils::FilePath projectPath = m_subNodeBuild ? m_subNodeBuild->filePath() : qs->project()->projectFilePath(); if (parse.srcProFile() != projectPath.toString()) { qCDebug(logs) << "**Different profile used to generate the Makefile:" @@ -406,16 +424,17 @@ QmakeBuildConfiguration::MakefileState QmakeBuildConfiguration::compareToImportF // This copies the settings from userArgs to actualArgs (minus some we // are not interested in), splitting them up into individual strings: extractSpecFromArguments(&userArgs, workingDirectory, version, &actualArgs); - FileName actualSpec = qs->mkspec(); + const QString actualSpec = qs->mkspec(); QString qmakeArgs = parse.unparsedArguments(); QStringList parsedArgs; - FileName parsedSpec = extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs); + QString parsedSpec = + extractSpecFromArguments(&qmakeArgs, workingDirectory, version, &parsedArgs); qCDebug(logs) << " Actual args:" << actualArgs; qCDebug(logs) << " Parsed args:" << parsedArgs; - qCDebug(logs) << " Actual spec:" << actualSpec.toString(); - qCDebug(logs) << " Parsed spec:" << parsedSpec.toString(); + qCDebug(logs) << " Actual spec:" << actualSpec; + qCDebug(logs) << " Parsed spec:" << parsedSpec; qCDebug(logs) << " Actual config:" << qs->deducedArguments(); qCDebug(logs) << " Parsed config:" << parse.config(); @@ -456,8 +475,8 @@ QmakeBuildConfiguration::MakefileState QmakeBuildConfiguration::compareToImportF } // Actual spec is the default one // qDebug() << "AS vs VS" << actualSpec << version->mkspec(); - if ((actualSpec == version->mkspec() || actualSpec == FileName::fromLatin1("default")) - && (parsedSpec == version->mkspec() || parsedSpec == FileName::fromLatin1("default") || parsedSpec.isEmpty())) { + if ((actualSpec == version->mkspec() || actualSpec == "default") + && (parsedSpec == version->mkspec() || parsedSpec == "default" || parsedSpec.isEmpty())) { qCDebug(logs) << "**Matched specs (2)"; return MakefileMatches; } @@ -468,11 +487,11 @@ QmakeBuildConfiguration::MakefileState QmakeBuildConfiguration::compareToImportF return MakefileIncompatible; } -FileName QmakeBuildConfiguration::extractSpecFromArguments(QString *args, +QString QmakeBuildConfiguration::extractSpecFromArguments(QString *args, const QString &directory, const BaseQtVersion *version, QStringList *outArgs) { - FileName parsedSpec; + FilePath parsedSpec; bool ignoreNext = false; bool nextIsSpec = false; @@ -482,7 +501,7 @@ FileName QmakeBuildConfiguration::extractSpecFromArguments(QString *args, ait.deleteArg(); } else if (nextIsSpec) { nextIsSpec = false; - parsedSpec = FileName::fromUserInput(ait.value()); + parsedSpec = FilePath::fromUserInput(ait.value()); ait.deleteArg(); } else if (ait.value() == QLatin1String("-spec") || ait.value() == QLatin1String("-platform")) { nextIsSpec = true; @@ -502,11 +521,11 @@ FileName QmakeBuildConfiguration::extractSpecFromArguments(QString *args, } if (parsedSpec.isEmpty()) - return FileName(); + return {}; - FileName baseMkspecDir = FileName::fromUserInput( + FilePath baseMkspecDir = FilePath::fromUserInput( version->qmakeProperty("QT_HOST_DATA") + QLatin1String("/mkspecs")); - baseMkspecDir = FileName::fromString(baseMkspecDir.toFileInfo().canonicalFilePath()); + baseMkspecDir = FilePath::fromString(baseMkspecDir.toFileInfo().canonicalFilePath()); // if the path is relative it can be // relative to the working directory (as found in the Makefiles) @@ -515,26 +534,26 @@ FileName QmakeBuildConfiguration::extractSpecFromArguments(QString *args, // for the other one we don't need to do anything if (parsedSpec.toFileInfo().isRelative()) { if (QFileInfo::exists(directory + QLatin1Char('/') + parsedSpec.toString())) - parsedSpec = FileName::fromUserInput(directory + QLatin1Char('/') + parsedSpec.toString()); + parsedSpec = FilePath::fromUserInput(directory + QLatin1Char('/') + parsedSpec.toString()); else - parsedSpec = FileName::fromUserInput(baseMkspecDir.toString() + QLatin1Char('/') + parsedSpec.toString()); + parsedSpec = FilePath::fromUserInput(baseMkspecDir.toString() + QLatin1Char('/') + parsedSpec.toString()); } QFileInfo f2 = parsedSpec.toFileInfo(); while (f2.isSymLink()) { - parsedSpec = FileName::fromString(f2.symLinkTarget()); + parsedSpec = FilePath::fromString(f2.symLinkTarget()); f2.setFile(parsedSpec.toString()); } if (parsedSpec.isChildOf(baseMkspecDir)) { parsedSpec = parsedSpec.relativeChildPath(baseMkspecDir); } else { - FileName sourceMkSpecPath = FileName::fromString(version->sourcePath().toString() + FilePath sourceMkSpecPath = FilePath::fromString(version->sourcePath().toString() + QLatin1String("/mkspecs")); if (parsedSpec.isChildOf(sourceMkSpecPath)) parsedSpec = parsedSpec.relativeChildPath(sourceMkSpecPath); } - return parsedSpec; + return parsedSpec.toString(); } bool QmakeBuildConfiguration::isEnabled() const @@ -567,23 +586,15 @@ QmakeBuildConfigurationFactory::QmakeBuildConfigurationFactory() setSupportedProjectType(Constants::QMAKEPROJECT_ID); setSupportedProjectMimeTypeName(Constants::PROFILE_MIMETYPE); setIssueReporter([](Kit *k, const QString &projectPath, const QString &buildDir) { - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); - QList<Task> issues; + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k); + Tasks issues; if (version) issues << version->reportIssues(projectPath, buildDir); - - QString tmpBuildDir = QDir(buildDir).absolutePath(); - const QChar slash = QLatin1Char('/'); - if (!tmpBuildDir.endsWith(slash)) - tmpBuildDir.append(slash); - QString sourcePath = QFileInfo(projectPath).absolutePath(); - if (!sourcePath.endsWith(slash)) - sourcePath.append(slash); - if (tmpBuildDir.count(slash) != sourcePath.count(slash)) { - const QString msg = QCoreApplication::translate("QmakeProjectManager::QtVersion", - "The build directory needs to be at the same level as the source directory."); - - issues.append(Task(Task::Warning, msg, Utils::FileName(), -1, + if (QmakeSettings::warnAgainstUnalignedBuildDir() + && !QmakeBuildConfiguration::isBuildDirAtSafeLocation( + QFileInfo(projectPath).absoluteDir().path(), QDir(buildDir).absolutePath())) { + issues.append(Task(Task::Warning, QmakeBuildConfiguration::unalignedBuildDirWarning(), + Utils::FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); } return issues; @@ -594,7 +605,7 @@ BuildInfo QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k, const QString &projectPath, BuildConfiguration::BuildType type) const { - BaseQtVersion *version = QtKitInformation::qtVersion(k); + BaseQtVersion *version = QtKitAspect::qtVersion(k); QmakeExtraBuildInfo extraInfo; BuildInfo info(this); QString suffix; @@ -628,7 +639,7 @@ BuildInfo QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k, info.kitId = k->id(); // check if this project is in the source directory: - FileName projectFilePath = FileName::fromString(projectPath); + FilePath projectFilePath = FilePath::fromString(projectPath); if (version && version->isInSourceDirectory(projectFilePath)) { // assemble build directory QString projectDirectory = projectFilePath.toFileInfo().absolutePath(); @@ -637,7 +648,7 @@ BuildInfo QmakeBuildConfigurationFactory::createBuildInfo(const Kit *k, QString qtBuildDir = version->qmakeProperty("QT_INSTALL_PREFIX"); QString absoluteBuildPath = QDir::cleanPath(qtBuildDir + QLatin1Char('/') + relativeProjectPath); - info.buildDirectory = FileName::fromString(absoluteBuildPath); + info.buildDirectory = FilePath::fromString(absoluteBuildPath); } else { info.buildDirectory = defaultBuildDirectory(projectPath, k, suffix, type); } @@ -662,7 +673,7 @@ QList<BuildInfo> QmakeBuildConfigurationFactory::availableBuilds(const Target *p const QString projectFilePath = parent->project()->projectFilePath().toString(); foreach (BuildConfiguration::BuildType buildType, - availableBuildTypes(QtKitInformation::qtVersion(parent->kit()))) { + availableBuildTypes(QtKitAspect::qtVersion(parent->kit()))) { BuildInfo info = createBuildInfo(parent->kit(), projectFilePath, buildType); info.displayName.clear(); // ask for a name info.buildDirectory.clear(); // This depends on the displayName @@ -675,7 +686,7 @@ QList<BuildInfo> QmakeBuildConfigurationFactory::availableBuilds(const Target *p QList<BuildInfo> QmakeBuildConfigurationFactory::availableSetups(const Kit *k, const QString &projectPath) const { QList<BuildInfo> result; - BaseQtVersion *qtVersion = QtKitInformation::qtVersion(k); + BaseQtVersion *qtVersion = QtKitAspect::qtVersion(k); if (!qtVersion || !qtVersion->isValid()) return result; @@ -704,7 +715,7 @@ void QmakeBuildConfiguration::addToEnvironment(Environment &env) const void QmakeBuildConfiguration::setupBuildEnvironment(Kit *k, Environment &env) { prependCompilerPathToEnvironment(k, env); - const BaseQtVersion *qt = QtKitInformation::qtVersion(k); + const BaseQtVersion *qt = QtKitAspect::qtVersion(k); if (qt && !qt->binPath().isEmpty()) env.prependOrSetPath(qt->binPath().toString()); } @@ -712,11 +723,11 @@ void QmakeBuildConfiguration::setupBuildEnvironment(Kit *k, Environment &env) QmakeBuildConfiguration::LastKitState::LastKitState() = default; QmakeBuildConfiguration::LastKitState::LastKitState(Kit *k) - : m_qtVersion(QtKitInformation::qtVersionId(k)), - m_sysroot(SysRootKitInformation::sysRoot(k).toString()), - m_mkspec(QmakeKitInformation::mkspec(k).toString()) + : m_qtVersion(QtKitAspect::qtVersionId(k)), + m_sysroot(SysRootKitAspect::sysRoot(k).toString()), + m_mkspec(QmakeKitAspect::mkspec(k)) { - ToolChain *tc = ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + ToolChain *tc = ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); m_toolchain = tc ? tc->id() : QByteArray(); } diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h index 480226e119..20b98103e8 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h @@ -83,7 +83,7 @@ public: enum MakefileState { MakefileMatches, MakefileForWrongProject, MakefileIncompatible, MakefileMissing }; MakefileState compareToImportFrom(const QString &makefile, QString *errorString = nullptr); - static Utils::FileName extractSpecFromArguments( + static QString extractSpecFromArguments( QString *arguments, const QString &directory, const QtSupport::BaseQtVersion *version, QStringList *outArgs = nullptr); @@ -101,6 +101,10 @@ public: void emitProFileEvaluateNeeded(); + static QString unalignedBuildDirWarning(); + static bool isBuildDirAtSafeLocation(const QString &sourceDir, const QString &buildDir); + bool isBuildDirAtSafeLocation() const; + signals: /// emitted for setQMakeBuildConfig, not emitted for Qt version changes, even /// if those change the qmakebuildconfig diff --git a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp deleted file mode 100644 index ba90baf6f1..0000000000 --- a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "qmakekitconfigwidget.h" - -#include "qmakekitinformation.h" - -#include <utils/fileutils.h> - -#include <QLineEdit> - -namespace QmakeProjectManager { -namespace Internal { - -QmakeKitConfigWidget::QmakeKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki) : - ProjectExplorer::KitConfigWidget(k, ki), - m_lineEdit(new QLineEdit) -{ - refresh(); // set up everything according to kit - m_lineEdit->setToolTip(toolTip()); - connect(m_lineEdit, &QLineEdit::textEdited, this, &QmakeKitConfigWidget::mkspecWasChanged); -} - -QmakeKitConfigWidget::~QmakeKitConfigWidget() -{ - delete m_lineEdit; -} - -QWidget *QmakeKitConfigWidget::mainWidget() const -{ - return m_lineEdit; -} - -QString QmakeKitConfigWidget::displayName() const -{ - return tr("Qt mkspec"); -} - -QString QmakeKitConfigWidget::toolTip() const -{ - return tr("The mkspec to use when building the project with qmake.<br>" - "This setting is ignored when using other build systems."); -} - -void QmakeKitConfigWidget::makeReadOnly() -{ - m_lineEdit->setEnabled(false); -} - -void QmakeKitConfigWidget::refresh() -{ - if (!m_ignoreChange) - m_lineEdit->setText(QmakeKitInformation::mkspec(m_kit).toUserOutput()); -} - -void QmakeKitConfigWidget::mkspecWasChanged(const QString &text) -{ - m_ignoreChange = true; - QmakeKitInformation::setMkspec(m_kit, Utils::FileName::fromString(text)); - m_ignoreChange = false; -} - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h b/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h deleted file mode 100644 index f1faa861f1..0000000000 --- a/src/plugins/qmakeprojectmanager/qmakekitconfigwidget.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include <projectexplorer/kitconfigwidget.h> - -QT_BEGIN_NAMESPACE -class QLineEdit; -QT_END_NAMESPACE - -namespace QmakeProjectManager { -namespace Internal { - -class QmakeKitConfigWidget : public ProjectExplorer::KitConfigWidget -{ - Q_OBJECT - -public: - QmakeKitConfigWidget(ProjectExplorer::Kit *k, const ProjectExplorer::KitInformation *ki); - ~QmakeKitConfigWidget() override; - - QWidget *mainWidget() const override; - QString displayName() const override; - QString toolTip() const override; - - void makeReadOnly() override; - void refresh() override; - -private: - void mkspecWasChanged(const QString &text); - int findQtVersion(const int id) const; - - QLineEdit *m_lineEdit = nullptr; - bool m_ignoreChange = false; -}; - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp index 94f3efcbe7..95b7c8eb5b 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp +++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.cpp @@ -25,7 +25,6 @@ #include "qmakekitinformation.h" -#include "qmakekitconfigwidget.h" #include "qmakeprojectmanagerconstants.h" #include <projectexplorer/projectexplorerconstants.h> @@ -37,42 +36,80 @@ #include <utils/algorithm.h> #include <utils/qtcassert.h> +#include <QDir> +#include <QLineEdit> + using namespace ProjectExplorer; using namespace Utils; namespace QmakeProjectManager { +namespace Internal { -QmakeKitInformation::QmakeKitInformation() +class QmakeKitAspectWidget : public KitAspectWidget { - setObjectName(QLatin1String("QmakeKitInformation")); - setId(QmakeKitInformation::id()); - setPriority(24000); -} + Q_DECLARE_TR_FUNCTIONS(QmakeProjectManager::Internal::QmakeKitAspect) + +public: + QmakeKitAspectWidget(Kit *k, const KitAspect *ki) + : KitAspectWidget(k, ki), m_lineEdit(new QLineEdit) + { + refresh(); // set up everything according to kit + m_lineEdit->setToolTip(ki->description()); + connect(m_lineEdit, &QLineEdit::textEdited, this, &QmakeKitAspectWidget::mkspecWasChanged); + } -QVariant QmakeKitInformation::defaultValue(const Kit *k) const + ~QmakeKitAspectWidget() override { delete m_lineEdit; } + +private: + QWidget *mainWidget() const override { return m_lineEdit; } + void makeReadOnly() override { m_lineEdit->setEnabled(false); } + + void refresh() override + { + if (!m_ignoreChange) + m_lineEdit->setText(QDir::toNativeSeparators(QmakeKitAspect::mkspec(m_kit))); + } + + void mkspecWasChanged(const QString &text) + { + m_ignoreChange = true; + QmakeKitAspect::setMkspec(m_kit, text, QmakeKitAspect::MkspecSource::User); + m_ignoreChange = false; + } + + QLineEdit *m_lineEdit = nullptr; + bool m_ignoreChange = false; +}; + + +QmakeKitAspect::QmakeKitAspect() { - Q_UNUSED(k); - return QString(); + setObjectName(QLatin1String("QmakeKitAspect")); + setId(QmakeKitAspect::id()); + setDisplayName(tr("Qt mkspec")); + setDescription(tr("The mkspec to use when building the project with qmake.<br>" + "This setting is ignored when using other build systems.")); + setPriority(24000); } -QList<Task> QmakeKitInformation::validate(const Kit *k) const +Tasks QmakeKitAspect::validate(const Kit *k) const { - QList<Task> result; - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); + Tasks result; + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k); - FileName mkspec = QmakeKitInformation::mkspec(k); + const QString mkspec = QmakeKitAspect::mkspec(k); if (!version && !mkspec.isEmpty()) result << Task(Task::Warning, tr("No Qt version set, so mkspec is ignored."), - FileName(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); + FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); if (version && !version->hasMkspec(mkspec)) result << Task(Task::Error, tr("Mkspec not found for Qt version."), - FileName(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); + FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); return result; } -void QmakeKitInformation::setup(Kit *k) +void QmakeKitAspect::setup(Kit *k) { - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k); if (!version) return; @@ -80,11 +117,11 @@ void QmakeKitInformation::setup(Kit *k) if (version->type() == "Boot2Qt.QtVersionType" || version->type() == "Qdb.EmbeddedLinuxQt") return; - FileName spec = QmakeKitInformation::mkspec(k); + QString spec = QmakeKitAspect::mkspec(k); if (spec.isEmpty()) spec = version->mkspec(); - ToolChain *tc = ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + ToolChain *tc = ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); if (!tc || (!tc->suggestedMkspecList().empty() && !tc->suggestedMkspecList().contains(spec))) { const QList<ToolChain *> possibleTcs = ToolChainManager::toolChains( @@ -110,65 +147,67 @@ void QmakeKitInformation::setup(Kit *k) bestTc = goodTcs.isEmpty() ? possibleTcs.last() : goodTcs.last(); } if (bestTc) - ToolChainKitInformation::setAllToolChainsToMatch(k, bestTc); + ToolChainKitAspect::setAllToolChainsToMatch(k, bestTc); } } } -KitConfigWidget *QmakeKitInformation::createConfigWidget(Kit *k) const +KitAspectWidget *QmakeKitAspect::createConfigWidget(Kit *k) const { - return new Internal::QmakeKitConfigWidget(k, this); + return new Internal::QmakeKitAspectWidget(k, this); } -KitInformation::ItemList QmakeKitInformation::toUserOutput(const Kit *k) const +KitAspect::ItemList QmakeKitAspect::toUserOutput(const Kit *k) const { - return ItemList() << qMakePair(tr("mkspec"), mkspec(k).toUserOutput()); + return {qMakePair(tr("mkspec"), QDir::toNativeSeparators(mkspec(k)))}; } -void QmakeKitInformation::addToMacroExpander(Kit *kit, MacroExpander *expander) const +void QmakeKitAspect::addToMacroExpander(Kit *kit, MacroExpander *expander) const { - expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the Kit."), + expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the kit."), [kit]() -> QString { - return QmakeKitInformation::mkspec(kit).toUserOutput(); + return QDir::toNativeSeparators(mkspec(kit)); }); } -Core::Id QmakeKitInformation::id() +Core::Id QmakeKitAspect::id() { return Constants::KIT_INFORMATION_ID; } -FileName QmakeKitInformation::mkspec(const Kit *k) +QString QmakeKitAspect::mkspec(const Kit *k) { if (!k) - return FileName(); - return FileName::fromString(k->value(QmakeKitInformation::id()).toString()); + return {}; + return k->value(QmakeKitAspect::id()).toString(); } -FileName QmakeKitInformation::effectiveMkspec(const Kit *k) +QString QmakeKitAspect::effectiveMkspec(const Kit *k) { if (!k) - return FileName(); - FileName spec = mkspec(k); + return {}; + const QString spec = mkspec(k); if (spec.isEmpty()) return defaultMkspec(k); return spec; } -void QmakeKitInformation::setMkspec(Kit *k, const FileName &fn) +void QmakeKitAspect::setMkspec(Kit *k, const QString &mkspec, MkspecSource source) { QTC_ASSERT(k, return); - k->setValue(QmakeKitInformation::id(), fn == defaultMkspec(k) ? QString() : fn.toString()); + k->setValue(QmakeKitAspect::id(), source == MkspecSource::Code && mkspec == defaultMkspec(k) + ? QString() : mkspec); } -FileName QmakeKitInformation::defaultMkspec(const Kit *k) +QString QmakeKitAspect::defaultMkspec(const Kit *k) { - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k); if (!version) // No version, so no qmake - return FileName(); + return {}; - return version->mkspecFor(ToolChainKitInformation::toolChain(k, + return version->mkspecFor(ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } +} // namespace Internal } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakekitinformation.h b/src/plugins/qmakeprojectmanager/qmakekitinformation.h index 686ece1246..1de908396f 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitinformation.h +++ b/src/plugins/qmakeprojectmanager/qmakekitinformation.h @@ -25,35 +25,34 @@ #pragma once -#include "qmakeprojectmanager_global.h" - #include <projectexplorer/kitmanager.h> namespace QmakeProjectManager { +namespace Internal { -class QMAKEPROJECTMANAGER_EXPORT QmakeKitInformation : public ProjectExplorer::KitInformation +class QmakeKitAspect : public ProjectExplorer::KitAspect { Q_OBJECT public: - QmakeKitInformation(); - - QVariant defaultValue(const ProjectExplorer::Kit *k) const override; + QmakeKitAspect(); - QList<ProjectExplorer::Task> validate(const ProjectExplorer::Kit *k) const override; + ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *k) const override; void setup(ProjectExplorer::Kit *k) override; - ProjectExplorer::KitConfigWidget *createConfigWidget(ProjectExplorer::Kit *k) const override; + ProjectExplorer::KitAspectWidget *createConfigWidget(ProjectExplorer::Kit *k) const override; ItemList toUserOutput(const ProjectExplorer::Kit *k) const override; void addToMacroExpander(ProjectExplorer::Kit *kit, Utils::MacroExpander *expander) const override; static Core::Id id(); - static void setMkspec(ProjectExplorer::Kit *k, const Utils::FileName &fn); - static Utils::FileName mkspec(const ProjectExplorer::Kit *k); - static Utils::FileName effectiveMkspec(const ProjectExplorer::Kit *k); - static Utils::FileName defaultMkspec(const ProjectExplorer::Kit *k); + enum class MkspecSource { User, Code }; + static void setMkspec(ProjectExplorer::Kit *k, const QString &mkspec, MkspecSource source); + static QString mkspec(const ProjectExplorer::Kit *k); + static QString effectiveMkspec(const ProjectExplorer::Kit *k); + static QString defaultMkspec(const ProjectExplorer::Kit *k); }; +} // namespace Internal } // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp index be03c1affc..3b4642a6df 100644 --- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp @@ -30,6 +30,8 @@ #include "qmakenodes.h" #include "qmakebuildconfiguration.h" #include "qmakeprojectmanagerconstants.h" +#include "qmakesettings.h" +#include "qmakestep.h" #include <coreplugin/variablechooser.h> #include <projectexplorer/target.h> @@ -38,6 +40,7 @@ #include <projectexplorer/gnumakeparser.h> #include <projectexplorer/processparameters.h> #include <projectexplorer/projectexplorer.h> +#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/kitinformation.h> #include <projectexplorer/xcodebuildparser.h> #include <utils/qtcprocess.h> @@ -61,18 +64,13 @@ QmakeMakeStep::QmakeMakeStep(BuildStepList *bsl) } } -QmakeBuildConfiguration *QmakeMakeStep::qmakeBuildConfiguration() const -{ - return static_cast<QmakeBuildConfiguration *>(buildConfiguration()); -} - bool QmakeMakeStep::init() { - QmakeBuildConfiguration *bc = qmakeBuildConfiguration(); + const auto bc = static_cast<QmakeBuildConfiguration *>(buildConfiguration()); if (!bc) emit addTask(Task::buildConfigurationMissingTask()); - const QString make = effectiveMakeCommand(); + Utils::FilePath make = effectiveMakeCommand(); if (make.isEmpty()) emit addTask(makeCommandMissingTask()); @@ -81,6 +79,10 @@ bool QmakeMakeStep::init() return false; } + // Ignore all but the first make step for a non-top-level build. See QTCREATORBUG-15794. + m_ignoredNonTopLevelBuild = (bc->fileNodeBuild() || bc->subNodeBuild()) + && static_cast<BuildStepList *>(parent())->firstOfType<QmakeMakeStep>() != this; + ProcessParameters *pp = processParameters(); pp->setMacroExpander(bc->macroExpander()); @@ -89,7 +91,7 @@ bool QmakeMakeStep::init() workingDirectory = bc->subNodeBuild()->buildDir(); else workingDirectory = bc->buildDirectory().toString(); - pp->setWorkingDirectory(workingDirectory); + pp->setWorkingDirectory(Utils::FilePath::fromString(workingDirectory)); pp->setCommand(make); @@ -141,7 +143,8 @@ bool QmakeMakeStep::init() objectsDir += "/release"; } } - QString relObjectsDir = QDir(pp->workingDirectory()).relativeFilePath(objectsDir); + QString relObjectsDir = QDir(pp->workingDirectory().toString()) + .relativeFilePath(objectsDir); if (relObjectsDir == ".") relObjectsDir.clear(); if (!relObjectsDir.isEmpty()) @@ -156,7 +159,7 @@ bool QmakeMakeStep::init() pp->resolveAll(); setOutputParser(new ProjectExplorer::GnuMakeParser()); - ToolChain *tc = ToolChainKitInformation::toolChain(target()->kit(), + ToolChain *tc = ToolChainKitAspect::toolChain(target()->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID); if (tc && tc->targetAbi().os() == Abi::DarwinOS) appendOutputParser(new XcodebuildParser); @@ -168,13 +171,23 @@ bool QmakeMakeStep::init() // it has a low priority. m_scriptTarget = (static_cast<QmakeProject *>(bc->target()->project())->rootProjectNode()->projectType() == ProjectType::ScriptTemplate); + m_unalignedBuildDir = !bc->isBuildDirAtSafeLocation(); + + // A user doing "make clean" indicates they want a proper rebuild, so make sure to really + // execute qmake on the next build. + if (static_cast<BuildStepList *>(parent())->id() + == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) { + const auto qmakeStep = bc->qmakeStep(); + if (qmakeStep) + qmakeStep->setForced(true); + } return AbstractProcessStep::init(); } void QmakeMakeStep::doRun() { - if (m_scriptTarget) { + if (m_scriptTarget || m_ignoredNonTopLevelBuild) { emit finished(true); return; } @@ -190,6 +203,18 @@ void QmakeMakeStep::doRun() AbstractProcessStep::doRun(); } +void QmakeMakeStep::finish(bool success) +{ + if (!success && !isCanceled() && m_unalignedBuildDir + && QmakeSettings::warnAgainstUnalignedBuildDir()) { + const QString msg = tr("The build directory is not at the same level as the source " + "directory, which could be the reason for the build failure."); + emit addTask(Task(Task::Warning, msg, Utils::FilePath(), -1, + ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); + } + MakeStep::finish(success); +} + /// // QmakeMakeStepFactory /// diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.h b/src/plugins/qmakeprojectmanager/qmakemakestep.h index 0a1cbe9198..a1bd2b1649 100644 --- a/src/plugins/qmakeprojectmanager/qmakemakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakemakestep.h @@ -30,9 +30,6 @@ #include <projectexplorer/makestep.h> namespace QmakeProjectManager { - -class QmakeBuildConfiguration; - namespace Internal { class QmakeMakeStepFactory : public ProjectExplorer::BuildStepFactory @@ -52,14 +49,15 @@ class QMAKEPROJECTMANAGER_EXPORT QmakeMakeStep : public ProjectExplorer::MakeSte public: explicit QmakeMakeStep(ProjectExplorer::BuildStepList *bsl); - QmakeBuildConfiguration *qmakeBuildConfiguration() const; - +private: + void finish(bool success) override; bool init() override; void doRun() override; -private: bool m_scriptTarget = false; QString m_makeFileToCheck; + bool m_unalignedBuildDir; + bool m_ignoredNonTopLevelBuild = false; }; } // QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 1fc048e3ce..a71ab8c3d6 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -36,6 +36,7 @@ #include <utils/stringutils.h> #include <android/androidconstants.h> +#include <ios/iosconstants.h> #include <QJsonDocument> #include <QJsonObject> @@ -52,7 +53,7 @@ namespace QmakeProjectManager { */ QmakePriFileNode::QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmakeProFileNode, - const FileName &filePath, QmakePriFile *pf) : + const FilePath &filePath, QmakePriFile *pf) : ProjectNode(filePath), m_project(project), m_qmakeProFileNode(qmakeProFileNode), @@ -112,7 +113,7 @@ bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) co return !(pro && pro->knowsFile(node->filePath())); bool addExistingFiles = true; - if (node->nodeType() == NodeType::VirtualFolder) { + if (node->isVirtualFolderType()) { // A virtual folder, we do what the projectexplorer does const FolderNode *folder = node->asFolderNode(); if (folder) { @@ -132,21 +133,13 @@ bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) co break; } case ProjectType::SubDirsTemplate: - if (action == AddSubProject) + if (action == AddSubProject || action == AddExistingProject) return true; break; default: break; } - if (action == HasSubProjectRunConfigurations) { - if (Target *t = m_project->activeTarget()) { - auto canRunForNode = [node](RunConfiguration *rc) { return rc->canRunForNode(node); }; - if (Utils::anyOf(t->runConfigurations(), canRunForNode)) - return true; - } - } - return false; } @@ -168,13 +161,18 @@ bool QmakePriFileNode::removeSubProject(const QString &proFilePath) return pri ? pri->removeSubProjects(proFilePath) : false; } +QStringList QmakePriFileNode::subProjectFileNamePatterns() const +{ + return QStringList("*.pro"); +} + bool QmakePriFileNode::addFiles(const QStringList &filePaths, QStringList *notAdded) { QmakePriFile *pri = priFile(); if (!pri) return false; QList<Node *> matchingNodes = findNodes([filePaths](const Node *n) { - return n->nodeType() == NodeType::File && filePaths.contains(n->filePath().toString()); + return n->asFileNode() && filePaths.contains(n->filePath().toString()); }); matchingNodes = filtered(matchingNodes, [](const Node *n) { for (const Node *parent = n->parentFolderNode(); parent; @@ -229,9 +227,11 @@ FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringL \class QmakeProFileNode Implements abstract ProjectNode class */ -QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FileName &filePath, QmakeProFile *pf) : +QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FilePath &filePath, QmakeProFile *pf) : QmakePriFileNode(project, this, filePath, pf) -{ } +{ + setIsProduct(); +} bool QmakeProFileNode::showInSimpleTree() const { @@ -281,16 +281,32 @@ QVariant QmakeProFileNode::data(Core::Id role) const if (role == Android::Constants::AndroidSoLibPath) { TargetInformation info = targetInformation(); QStringList res = {info.buildDir.toString()}; - Utils::FileName destDir = info.destDir; + Utils::FilePath destDir = info.destDir; if (!destDir.isEmpty()) { if (destDir.toFileInfo().isRelative()) - destDir = Utils::FileName::fromString(QDir::cleanPath(info.buildDir.toString() + destDir = Utils::FilePath::fromString(QDir::cleanPath(info.buildDir.toString() + '/' + destDir.toString())); res.append(destDir.toString()); } res.removeDuplicates(); return res; } + + if (role == Android::Constants::AndroidTargets) + return {}; + + if (role == Ios::Constants::IosTarget) { + const TargetInformation info = targetInformation(); + if (info.valid) + return info.target; + } + + if (role == Ios::Constants::IosBuildDir) { + const TargetInformation info = targetInformation(); + if (info.valid) + return info.buildDir.toString(); + } + QTC_CHECK(false); return {}; } @@ -397,10 +413,10 @@ QString QmakeProFileNode::buildDir() const return QString(); } -FileName QmakeProFileNode::buildDir(QmakeBuildConfiguration *bc) const +FilePath QmakeProFileNode::buildDir(QmakeBuildConfiguration *bc) const { const QmakeProFile *pro = proFile(); - return pro ? pro->buildDir(bc) : FileName(); + return pro ? pro->buildDir(bc) : FilePath(); } QString QmakeProFileNode::objectExtension() const diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 2f29eac5e4..92b84fbcb0 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -30,7 +30,7 @@ #include <projectexplorer/projectnodes.h> -namespace Utils { class FileName; } +namespace Utils { class FilePath; } namespace QmakeProjectManager { class QmakeProFileNode; @@ -41,7 +41,7 @@ class QMAKEPROJECTMANAGER_EXPORT QmakePriFileNode : public ProjectExplorer::Proj { public: QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmakeProFileNode, - const Utils::FileName &filePath, QmakePriFile *pf); + const Utils::FilePath &filePath, QmakePriFile *pf); QmakePriFile *priFile() const; @@ -51,9 +51,9 @@ public: bool showInSimpleTree() const override { return false; } bool canAddSubProject(const QString &proFilePath) const override; - bool addSubProject(const QString &proFilePath) override; bool removeSubProject(const QString &proFilePath) override; + QStringList subProjectFileNamePatterns() const override; bool addFiles(const QStringList &filePaths, QStringList *notAdded = nullptr) override; bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = nullptr) override; @@ -78,7 +78,7 @@ private: class QMAKEPROJECTMANAGER_EXPORT QmakeProFileNode : public QmakePriFileNode { public: - QmakeProFileNode(QmakeProject *project, const Utils::FileName &filePath, QmakeProFile *pf); + QmakeProFileNode(QmakeProject *project, const Utils::FilePath &filePath, QmakeProFile *pf); QmakeProFile *proFile() const; @@ -104,7 +104,7 @@ public: QmakeProjectManager::ProjectType projectType() const; QString buildDir() const; - Utils::FileName buildDir(QmakeBuildConfiguration *bc) const; + Utils::FilePath buildDir(QmakeBuildConfiguration *bc) const; QStringList variableValue(const Variable var) const; QString singleVariableValue(const Variable var) const; diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp index 253f9939d2..d2fc8051de 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp @@ -128,7 +128,7 @@ void clearQmakeStaticData() namespace QmakeProjectManager { -static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const FileNameList &toExclude) +static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const FilePathList &toExclude) { QTC_ASSERT(pri, return); QTC_ASSERT(node, return); @@ -137,24 +137,35 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi node->setIcon(qmakeStaticData()->projectIcon); // .pro/.pri-file itself: - node->addNode(std::make_unique<FileNode>(pri->filePath(), FileType::Project, false)); + node->addNode(std::make_unique<FileNode>(pri->filePath(), FileType::Project)); // other normal files: const QVector<QmakeStaticData::FileTypeData> &fileTypes = qmakeStaticData()->fileTypeData; + FilePathList generatedFiles; + const auto proFile = dynamic_cast<const QmakeProFile *>(pri); for (int i = 0; i < fileTypes.size(); ++i) { FileType type = fileTypes.at(i).type; - const QSet<FileName> &newFilePaths = Utils::filtered(pri->files(type), [&toExclude](const Utils::FileName &fn) { - return !Utils::contains(toExclude, [&fn](const Utils::FileName &ex) { return fn.isChildOf(ex); }); + const QSet<FilePath> &newFilePaths = Utils::filtered(pri->files(type), [&toExclude](const Utils::FilePath &fn) { + return !Utils::contains(toExclude, [&fn](const Utils::FilePath &ex) { return fn.isChildOf(ex); }); }); + if (proFile) { + for (const FilePath &fp : newFilePaths) { + for (const ExtraCompiler *ec : proFile->extraCompilers()) { + if (ec->source() == fp) + generatedFiles << ec->targets(); + } + } + } if (!newFilePaths.isEmpty()) { - auto vfolder = std::make_unique<VirtualFolderNode>(pri->filePath().parentDir(), Node::DefaultVirtualFolderPriority - i); + auto vfolder = std::make_unique<VirtualFolderNode>(pri->filePath().parentDir()); + vfolder->setPriority(Node::DefaultVirtualFolderPriority - i); vfolder->setIcon(fileTypes.at(i).icon); vfolder->setDisplayName(fileTypes.at(i).typeName); vfolder->setAddFileFilter(fileTypes.at(i).addFileFilter); if (type == FileType::Resource) { - for (const FileName &file : newFilePaths) { + for (const FilePath &file : newFilePaths) { auto vfs = pri->project()->qmakeVfs(); QString contents; QString errorMessage; @@ -167,18 +178,20 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi int eid = vfs->idForFileName(file.toString(), QMakeVfs::VfsExact); vfs->readFile(eid, &contents, &errorMessage); } + auto topLevel = std::make_unique<ResourceEditor::ResourceTopLevelNode> + (file, vfolder->filePath(), contents); const QString baseName = file.toFileInfo().completeBaseName(); - const bool generated = baseName.startsWith("qmake_") - || baseName.endsWith("_qmlcache"); - vfolder->addNode(std::make_unique<ResourceEditor::ResourceTopLevelNode>(file, generated, contents, vfolder.get())); + topLevel->setIsGenerated(baseName.startsWith("qmake_") + || baseName.endsWith("_qmlcache")); + vfolder->addNode(std::move(topLevel)); } } else { - for (const FileName &fn : newFilePaths) { + for (const FilePath &fn : newFilePaths) { // Qmake will flag everything in SOURCES as source, even when the // qt quick compiler moves qrc files into it:-/ Get better data based on // the filename. type = FileNode::fileTypeForFileName(fn); - vfolder->addNestedNode(std::make_unique<FileNode>(fn, type, false)); + vfolder->addNestedNode(std::make_unique<FileNode>(fn, type)); } for (FolderNode *fn : vfolder->folderNodes()) fn->compress(); @@ -187,6 +200,22 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi } } + if (!generatedFiles.empty()) { + QTC_CHECK(proFile); + const FilePath baseDir = generatedFiles.size() == 1 ? generatedFiles.first().parentDir() + : proFile->buildDir(); + auto genFolder = std::make_unique<VirtualFolderNode>(baseDir); + genFolder->setDisplayName(QCoreApplication::translate("QmakeProjectManager::QmakePriFile", + "Generated Files")); + genFolder->setIsGenerated(true); + for (const FilePath &fp : generatedFiles) { + auto fileNode = std::make_unique<FileNode>(fp, FileNode::fileTypeForFileName(fp)); + fileNode->setIsGenerated(true); + genFolder->addNestedNode(std::move(fileNode)); + } + node->addNode(std::move(genFolder)); + } + // Virtual folders: for (QmakePriFile *c : pri->children()) { std::unique_ptr<QmakePriFileNode> newNode; @@ -204,9 +233,9 @@ std::unique_ptr<QmakeProFileNode> QmakeNodeTreeBuilder::buildTree(QmakeProject * // Remove qmake implementation details that litter up the project data: Target *t = project->activeTarget(); Kit *k = t ? t->kit() : KitManager::defaultKit(); - BaseQtVersion *qt = k ? QtKitInformation::qtVersion(k) : nullptr; + BaseQtVersion *qt = k ? QtKitAspect::qtVersion(k) : nullptr; - const FileNameList toExclude = qt ? qt->directoriesToIgnoreInProjectTree() : FileNameList(); + const FilePathList toExclude = qt ? qt->directoriesToIgnoreInProjectTree() : FilePathList(); auto root = std::make_unique<QmakeProFileNode>(project, project->projectFilePath(), project->rootProFile()); diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h index 2206ac904e..be3240da3c 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h +++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.h @@ -29,7 +29,7 @@ #include "qmakeparsernodes.h" #include "qmakenodes.h" -namespace Utils { class FileName; } +namespace Utils { class FilePath; } namespace ProjectExplorer { class RunConfiguration; } namespace QmakeProjectManager { diff --git a/src/plugins/qmakeprojectmanager/qmakeparser.cpp b/src/plugins/qmakeprojectmanager/qmakeparser.cpp index 4af888cc2c..ed6abf5ca7 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparser.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparser.cpp @@ -59,7 +59,7 @@ void QMakeParser::stdError(const QString &line) type = Task::Error; Task task = Task(type, description, - Utils::FileName::fromUserInput(fileName), + Utils::FilePath::fromUserInput(fileName), m_error.cap(2).toInt() /* line */, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); emit addTask(task, 1); @@ -70,7 +70,7 @@ void QMakeParser::stdError(const QString &line) const QString description = lne.mid(lne.indexOf(QLatin1Char(':')) + 2); Task task = Task(Task::Error, description, - Utils::FileName() /* filename */, + Utils::FilePath() /* filename */, -1 /* linenumber */, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); emit addTask(task, 1); @@ -81,7 +81,7 @@ void QMakeParser::stdError(const QString &line) const QString description = lne.mid(lne.indexOf(QLatin1Char(':')) + 2); Task task = Task(Task::Warning, description, - Utils::FileName() /* filename */, + Utils::FilePath() /* filename */, -1 /* linenumber */, Core::Id(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); emit addTask(task, 1); @@ -110,29 +110,29 @@ void QmakeProjectManagerPlugin::testQmakeOutputParsers_data() QTest::addColumn<OutputParserTester::Channel>("inputChannel"); QTest::addColumn<QString>("childStdOutLines"); QTest::addColumn<QString>("childStdErrLines"); - QTest::addColumn<QList<ProjectExplorer::Task> >("tasks"); + QTest::addColumn<Tasks >("tasks"); QTest::addColumn<QString>("outputLines"); QTest::newRow("pass-through stdout") << QString::fromLatin1("Sometext") << OutputParserTester::STDOUT << QString::fromLatin1("Sometext\n") << QString() - << QList<ProjectExplorer::Task>() + << Tasks() << QString(); QTest::newRow("pass-through stderr") << QString::fromLatin1("Sometext") << OutputParserTester::STDERR << QString() << QString::fromLatin1("Sometext\n") - << QList<ProjectExplorer::Task>() + << Tasks() << QString(); QTest::newRow("qMake error") << QString::fromLatin1("Project ERROR: undefined file") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() + << (Tasks() << Task(Task::Error, QLatin1String("undefined file"), - Utils::FileName(), -1, + Utils::FilePath(), -1, categoryBuildSystem)) << QString(); @@ -140,10 +140,10 @@ void QmakeProjectManagerPlugin::testQmakeOutputParsers_data() << QString::fromLatin1("e:\\project.pro:14: Parse Error ('sth odd')") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() + << (Tasks() << Task(Task::Error, QLatin1String("Parse Error ('sth odd')"), - Utils::FileName::fromUserInput(QLatin1String("e:\\project.pro")), + Utils::FilePath::fromUserInput(QLatin1String("e:\\project.pro")), 14, categoryBuildSystem)) << QString(); @@ -152,10 +152,10 @@ void QmakeProjectManagerPlugin::testQmakeOutputParsers_data() << QString::fromLatin1("Project WARNING: bearer module might require ReadUserData capability") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() + << (Tasks() << Task(Task::Warning, QLatin1String("bearer module might require ReadUserData capability"), - Utils::FileName(), -1, + Utils::FilePath(), -1, categoryBuildSystem)) << QString(); @@ -163,10 +163,10 @@ void QmakeProjectManagerPlugin::testQmakeOutputParsers_data() << QString::fromLatin1("WARNING: Failure to find: blackberrycreatepackagestepconfigwidget.cpp") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() + << (Tasks() << Task(Task::Warning, QLatin1String("Failure to find: blackberrycreatepackagestepconfigwidget.cpp"), - Utils::FileName(), -1, + Utils::FilePath(), -1, categoryBuildSystem)) << QString(); @@ -174,20 +174,20 @@ void QmakeProjectManagerPlugin::testQmakeOutputParsers_data() << QString::fromLatin1("WARNING: e:\\QtSDK\\Simulator\\Qt\\msvc2008\\lib\\qtmaind.prl:1: Unescaped backslashes are deprecated.") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() + << (Tasks() << Task(Task::Warning, QLatin1String("Unescaped backslashes are deprecated."), - Utils::FileName::fromUserInput(QLatin1String("e:\\QtSDK\\Simulator\\Qt\\msvc2008\\lib\\qtmaind.prl")), 1, + Utils::FilePath::fromUserInput(QLatin1String("e:\\QtSDK\\Simulator\\Qt\\msvc2008\\lib\\qtmaind.prl")), 1, categoryBuildSystem)) << QString(); QTest::newRow("moc note") << QString::fromLatin1("/home/qtwebkithelpviewer.h:0: Note: No relevant classes found. No output generated.") << OutputParserTester::STDERR << QString() << QString() - << (QList<ProjectExplorer::Task>() + << (Tasks() << Task(Task::Unknown, QLatin1String("Note: No relevant classes found. No output generated."), - Utils::FileName::fromUserInput(QLatin1String("/home/qtwebkithelpviewer.h")), 0, + Utils::FilePath::fromUserInput(QLatin1String("/home/qtwebkithelpviewer.h")), 0, categoryBuildSystem) ) << QString();} @@ -198,7 +198,7 @@ void QmakeProjectManagerPlugin::testQmakeOutputParsers() testbench.appendOutputParser(new QMakeParser); QFETCH(QString, input); QFETCH(OutputParserTester::Channel, inputChannel); - QFETCH(QList<Task>, tasks); + QFETCH(Tasks, tasks); QFETCH(QString, childStdOutLines); QFETCH(QString, childStdErrLines); QFETCH(QString, outputLines); diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index dad44e2f6b..c9fce5bb9a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -29,7 +29,6 @@ #include "qmakeprojectmanagerconstants.h" #include "qmakebuildconfiguration.h" -#include <coreplugin/dialogs/readonlyfilesdialog.h> #include <coreplugin/documentmanager.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/icore.h> @@ -69,7 +68,7 @@ namespace { class QmakePriFileDocument : public Core::IDocument { public: - QmakePriFileDocument(QmakePriFile *qmakePriFile, const Utils::FileName &filePath) : + QmakePriFileDocument(QmakePriFile *qmakePriFile, const Utils::FilePath &filePath) : IDocument(nullptr), m_priFile(qmakePriFile) { setId("Qmake.PriFile"); @@ -111,9 +110,9 @@ class QmakeEvalInput { public: QString projectDir; - FileName projectFilePath; - FileName buildDirectory; - FileName sysroot; + FilePath projectFilePath; + FilePath buildDirectory; + FilePath sysroot; QtSupport::ProFileReader *readerExact; QtSupport::ProFileReader *readerCumulative; QMakeGlobals *qmakeGlobals; @@ -123,18 +122,18 @@ public: class QmakePriFileEvalResult { public: - QSet<FileName> folders; - QSet<FileName> recursiveEnumerateFiles; - QMap<FileType, QSet<FileName>> foundFiles; + QSet<FilePath> folders; + QSet<FilePath> recursiveEnumerateFiles; + QMap<FileType, QSet<FilePath>> foundFiles; }; class QmakeIncludedPriFile { public: ProFile *proFile; - Utils::FileName name; + Utils::FilePath name; QmakePriFileEvalResult result; - QMap<Utils::FileName, QmakeIncludedPriFile *> children; + QMap<Utils::FilePath, QmakeIncludedPriFile *> children; ~QmakeIncludedPriFile() { @@ -150,7 +149,7 @@ public: ProjectType projectType; QStringList subProjectsNotToDeploy; - QSet<FileName> exactSubdirs; + QSet<FilePath> exactSubdirs; QmakeIncludedPriFile includedFiles; TargetInformation targetInformation; InstallsList installsList; @@ -162,7 +161,7 @@ public: } // namespace Internal QmakePriFile::QmakePriFile(QmakeProject *project, QmakeProFile *qmakeProFile, - const FileName &filePath) : + const FilePath &filePath) : m_project(project), m_qmakeProFile(qmakeProFile) { @@ -171,12 +170,12 @@ QmakePriFile::QmakePriFile(QmakeProject *project, QmakeProFile *qmakeProFile, Core::DocumentManager::addDocument(m_priFileDocument.get()); } -FileName QmakePriFile::filePath() const +FilePath QmakePriFile::filePath() const { return m_priFileDocument->filePath(); } -FileName QmakePriFile::directoryPath() const +FilePath QmakePriFile::directoryPath() const { return filePath().parentDir(); } @@ -201,7 +200,7 @@ QVector<QmakePriFile *> QmakePriFile::children() const return m_children; } -QmakePriFile *QmakePriFile::findPriFile(const FileName &fileName) +QmakePriFile *QmakePriFile::findPriFile(const FilePath &fileName) { if (fileName == filePath()) return this; @@ -212,7 +211,7 @@ QmakePriFile *QmakePriFile::findPriFile(const FileName &fileName) return nullptr; } -const QmakePriFile *QmakePriFile::findPriFile(const FileName &fileName) const +const QmakePriFile *QmakePriFile::findPriFile(const FilePath &fileName) const { if (fileName == filePath()) return this; @@ -229,14 +228,14 @@ void QmakePriFile::makeEmpty() m_children.clear(); } -QSet<FileName> QmakePriFile::files(const FileType &type) const +QSet<FilePath> QmakePriFile::files(const FileType &type) const { return m_files.value(type); } -const QSet<FileName> QmakePriFile::collectFiles(const FileType &type) const +const QSet<FilePath> QmakePriFile::collectFiles(const FileType &type) const { - QSet<FileName> allFiles = files(type); + QSet<FilePath> allFiles = files(type); for (const QmakePriFile * const priFile : qAsConst(m_children)) { if (!dynamic_cast<const QmakeProFile *>(priFile)) allFiles.unite(priFile->collectFiles(type)); @@ -281,16 +280,16 @@ QStringList QmakePriFile::fullVPaths(const QStringList &baseVPaths, QtSupport::P return vPaths; } -QSet<FileName> QmakePriFile::recursiveEnumerate(const QString &folder) +QSet<FilePath> QmakePriFile::recursiveEnumerate(const QString &folder) { - QSet<FileName> result; + QSet<FilePath> result; QDir dir(folder); dir.setFilter(dir.filter() | QDir::NoDotAndDotDot); foreach (const QFileInfo &file, dir.entryInfoList()) { if (file.isDir() && !file.isSymLink()) result += recursiveEnumerate(file.absoluteFilePath()); else if (!Core::EditorManager::isAutoSaveFile(file.fileName())) - result += FileName(file); + result += FilePath::fromFileInfo(file); } return result; } @@ -315,7 +314,7 @@ void QmakePriFile::extractSources( auto *result = proToResult.value(source.proFileId); if (!result) result = fallback; - result->foundFiles[type].insert(FileName::fromString(source.fileName)); + result->foundFiles[type].insert(FilePath::fromString(source.fileName)); } } @@ -328,7 +327,7 @@ void QmakePriFile::extractInstalls( auto *result = proToResult.value(source.proFileId); if (!result) result = fallback; - result->folders.insert(FileName::fromString(source.fileName)); + result->folders.insert(FilePath::fromString(source.fileName)); } } } @@ -357,9 +356,9 @@ void QmakePriFile::processValues(QmakePriFileEvalResult &result) for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) { auto type = static_cast<FileType>(i); - QSet<FileName> &foundFiles = result.foundFiles[type]; + QSet<FilePath> &foundFiles = result.foundFiles[type]; result.recursiveEnumerateFiles.subtract(foundFiles); - QSet<FileName> newFilePaths = filterFilesProVariables(type, foundFiles); + QSet<FilePath> newFilePaths = filterFilesProVariables(type, foundFiles); newFilePaths += filterFilesRecursiveEnumerata(type, result.recursiveEnumerateFiles); foundFiles = newFilePaths; } @@ -376,10 +375,10 @@ void QmakePriFile::update(const Internal::QmakePriFileEvalResult &result) } } -void QmakePriFile::watchFolders(const QSet<FileName> &folders) +void QmakePriFile::watchFolders(const QSet<FilePath> &folders) { const QSet<QString> folderStrings = - Utils::transform(folders, &FileName::toString); + Utils::transform(folders, &FilePath::toString); QSet<QString> toUnwatch = m_watchedFolders; toUnwatch.subtract(folderStrings); @@ -405,23 +404,23 @@ QString QmakePriFile::continuationIndent() const return QString(tabSettings.m_indentSize, ' '); } -bool QmakePriFile::knowsFile(const FileName &filePath) const +bool QmakePriFile::knowsFile(const FilePath &filePath) const { return m_recursiveEnumerateFiles.contains(filePath); } -bool QmakePriFile::folderChanged(const QString &changedFolder, const QSet<FileName> &newFiles) +bool QmakePriFile::folderChanged(const QString &changedFolder, const QSet<FilePath> &newFiles) { qCDebug(qmakeParse()) << "QmakePriFile::folderChanged"; - QSet<FileName> addedFiles = newFiles; + QSet<FilePath> addedFiles = newFiles; addedFiles.subtract(m_recursiveEnumerateFiles); - QSet<FileName> removedFiles = m_recursiveEnumerateFiles; + QSet<FilePath> removedFiles = m_recursiveEnumerateFiles; removedFiles.subtract(newFiles); - foreach (const FileName &file, removedFiles) { - if (!file.isChildOf(FileName::fromString(changedFolder))) + foreach (const FilePath &file, removedFiles) { + if (!file.isChildOf(FilePath::fromString(changedFolder))) removedFiles.remove(file); } @@ -433,8 +432,8 @@ bool QmakePriFile::folderChanged(const QString &changedFolder, const QSet<FileNa // Apply the differences per file type for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) { auto type = static_cast<FileType>(i); - QSet<FileName> add = filterFilesRecursiveEnumerata(type, addedFiles); - QSet<FileName> remove = filterFilesRecursiveEnumerata(type, removedFiles); + QSet<FilePath> add = filterFilesRecursiveEnumerata(type, addedFiles); + QSet<FilePath> remove = filterFilesRecursiveEnumerata(type, removedFiles); if (!add.isEmpty() || !remove.isEmpty()) { qCDebug(qmakeParse()) << "For type" << static_cast<int>(type) <<"\n" @@ -508,7 +507,7 @@ static QString simplifyProFilePath(const QString &proFilePath) bool QmakePriFile::addSubProject(const QString &proFile) { QStringList uniqueProFilePaths; - if (!m_recursiveEnumerateFiles.contains(FileName::fromString(proFile))) + if (!m_recursiveEnumerateFiles.contains(FilePath::fromString(proFile))) uniqueProFilePaths.append(simplifyProFilePath(proFile)); QStringList failedFiles; @@ -560,13 +559,13 @@ bool QmakePriFile::addFiles(const QStringList &filePaths, QStringList *notAdded) QStringList uniqueQrcFiles; foreach (const QString &file, qrcFiles) { - if (!m_recursiveEnumerateFiles.contains(FileName::fromString(file))) + if (!m_recursiveEnumerateFiles.contains(FilePath::fromString(file))) uniqueQrcFiles.append(file); } QStringList uniqueFilePaths; foreach (const QString &file, typeFiles) { - if (!m_recursiveEnumerateFiles.contains(FileName::fromString(file))) + if (!m_recursiveEnumerateFiles.contains(FilePath::fromString(file))) uniqueFilePaths.append(file); } uniqueFilePaths.sort(); @@ -633,13 +632,6 @@ bool QmakePriFile::renameFile(const QString &filePath, const QString &newFilePat return changeProFileOptional; } -bool QmakePriFile::priFileWritable(const QString &path) -{ - ReadOnlyFilesDialog roDialog(path, ICore::mainWindow()); - roDialog.setShowFailWarning(true); - return roDialog.exec() != ReadOnlyFilesDialog::RO_Cancel; -} - bool QmakePriFile::saveModifiedEditors() { Core::IDocument *document @@ -886,8 +878,7 @@ QStringList QmakePriFile::varNames(FileType type, QtSupport::ProFileReader *read QStringList vars; switch (type) { case FileType::Header: - vars << QLatin1String("HEADERS"); - vars << QLatin1String("PRECOMPILED_HEADER"); + vars << "HEADERS" << "OBJECTIVE_HEADERS" << "PRECOMPILED_HEADER"; break; case FileType::Source: { vars << QLatin1String("SOURCES"); @@ -896,12 +887,15 @@ QStringList QmakePriFile::varNames(FileType type, QtSupport::ProFileReader *read QStringList inputs = readerExact->values(var + QLatin1String(".input")); foreach (const QString &input, inputs) // FORMS, RESOURCES, and STATECHARTS are handled below, HEADERS and SOURCES above - if (input != QLatin1String("FORMS") - && input != QLatin1String("STATECHARTS") - && input != QLatin1String("RESOURCES") - && input != QLatin1String("SOURCES") - && input != QLatin1String("HEADERS")) + if (input != "FORMS" + && input != "STATECHARTS" + && input != "RESOURCES" + && input != "SOURCES" + && input != "HEADERS" + && input != "OBJECTIVE_HEADERS" + && input != "PRECOMPILED_HEADER") { vars << input; + } } break; } @@ -994,34 +988,34 @@ QStringList QmakePriFile::varNamesForRemoving() return vars; } -QSet<FileName> QmakePriFile::filterFilesProVariables(FileType fileType, const QSet<FileName> &files) +QSet<FilePath> QmakePriFile::filterFilesProVariables(FileType fileType, const QSet<FilePath> &files) { if (fileType != FileType::QML && fileType != FileType::Unknown) return files; - QSet<FileName> result; + QSet<FilePath> result; if (fileType == FileType::QML) { - foreach (const FileName &file, files) + foreach (const FilePath &file, files) if (file.toString().endsWith(QLatin1String(".qml"))) result << file; } else { - foreach (const FileName &file, files) + foreach (const FilePath &file, files) if (!file.toString().endsWith(QLatin1String(".qml"))) result << file; } return result; } -QSet<FileName> QmakePriFile::filterFilesRecursiveEnumerata(FileType fileType, const QSet<FileName> &files) +QSet<FilePath> QmakePriFile::filterFilesRecursiveEnumerata(FileType fileType, const QSet<FilePath> &files) { - QSet<FileName> result; + QSet<FilePath> result; if (fileType != FileType::QML && fileType != FileType::Unknown) return result; if (fileType == FileType::QML) { - foreach (const FileName &file, files) + foreach (const FilePath &file, files) if (file.toString().endsWith(QLatin1String(".qml"))) result << file; } else { - foreach (const FileName &file, files) + foreach (const FilePath &file, files) if (!file.toString().endsWith(QLatin1String(".qml"))) result << file; } @@ -1051,12 +1045,12 @@ static ProjectType proFileTemplateTypeToProjectType(ProFileEvaluator::TemplateTy } } -QmakeProFile *QmakeProFile::findProFile(const FileName &fileName) +QmakeProFile *QmakeProFile::findProFile(const FilePath &fileName) { return static_cast<QmakeProFile *>(findPriFile(fileName)); } -const QmakeProFile *QmakeProFile::findProFile(const FileName &fileName) const +const QmakeProFile *QmakeProFile::findProFile(const FilePath &fileName) const { return static_cast<const QmakeProFile *>(findPriFile(fileName)); } @@ -1093,7 +1087,7 @@ QByteArray QmakeProFile::cxxDefines() const \class QmakeProFile Implements abstract ProjectNode class */ -QmakeProFile::QmakeProFile(QmakeProject *project, const FileName &filePath) : +QmakeProFile::QmakeProFile(QmakeProject *project, const FilePath &filePath) : QmakePriFile(project, this, filePath) { // The lifetime of the m_parserFutureWatcher is shorter @@ -1221,7 +1215,7 @@ QmakeEvalInput QmakeProFile::evalInput() const input.projectDir = directoryPath().toString(); input.projectFilePath = filePath(); input.buildDirectory = buildDir(); - input.sysroot = FileName::fromString(m_project->qmakeSysroot()); + input.sysroot = FilePath::fromString(m_project->qmakeSysroot()); input.readerExact = m_readerExact; input.readerCumulative = m_readerCumulative; input.qmakeGlobals = m_project->qmakeGlobals(); @@ -1308,10 +1302,10 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input) if (result->state == QmakeEvalResult::EvalOk) { if (result->projectType == ProjectType::SubDirsTemplate) { QStringList errors; - FileNameList subDirs = subDirsPaths(input.readerExact, input.projectDir, &result->subProjectsNotToDeploy, &errors); + FilePathList subDirs = subDirsPaths(input.readerExact, input.projectDir, &result->subProjectsNotToDeploy, &errors); result->errors.append(errors); - foreach (const Utils::FileName &subDirName, subDirs) { + foreach (const Utils::FilePath &subDirName, subDirs) { auto subDir = new QmakeIncludedPriFile; subDir->proFile = nullptr; subDir->name = subDirName; @@ -1330,7 +1324,7 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input) continue; // Don't attempt to map subdirs here QVector<ProFile *> children = includeFiles.value(current->proFile); foreach (ProFile *child, children) { - const Utils::FileName childName = Utils::FileName::fromString(child->fileName()); + const Utils::FilePath childName = Utils::FilePath::fromString(child->fileName()); auto it = current->children.find(childName); if (it == current->children.end()) { auto childTree = new QmakeIncludedPriFile; @@ -1345,8 +1339,8 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input) } if (result->projectType == ProjectType::SubDirsTemplate) { - FileNameList subDirs = subDirsPaths(input.readerCumulative, input.projectDir, nullptr, nullptr); - foreach (const Utils::FileName &subDirName, subDirs) { + FilePathList subDirs = subDirsPaths(input.readerCumulative, input.projectDir, nullptr, nullptr); + foreach (const Utils::FilePath &subDirName, subDirs) { auto it = result->includedFiles.children.find(subDirName); if (it == result->includedFiles.children.end()) { auto subDir = new QmakeIncludedPriFile; @@ -1366,7 +1360,7 @@ QmakeEvalResult *QmakeProFile::evaluate(const QmakeEvalInput &input) continue; // Don't attempt to map subdirs here QVector<ProFile *> children = includeFiles.value(current->proFile); foreach (ProFile *child, children) { - const Utils::FileName childName = Utils::FileName::fromString(child->fileName()); + const Utils::FilePath childName = Utils::FilePath::fromString(child->fileName()); auto it = current->children.find(childName); if (it == current->children.end()) { auto childTree = new QmakeIncludedPriFile; @@ -1564,7 +1558,7 @@ void QmakeProFile::applyEvaluate(QmakeEvalResult *evalResult) // Add/Remove pri files, sub projects // - FileName buildDirectory = buildDir(); + FilePath buildDirectory = buildDir(); QList<QPair<QmakePriFile *, QmakeIncludedPriFile *>> toCompare; @@ -1619,13 +1613,14 @@ void QmakeProFile::applyEvaluate(QmakeEvalResult *evalResult) m_subProjectsNotToDeploy = Utils::transform(result->subProjectsNotToDeploy, - [](const QString &s) { return FileName::fromString(s); }); + [](const QString &s) { return FilePath::fromString(s); }); m_installsList = result->installsList; if (m_varValues != result->newVarValues) m_varValues = result->newVarValues; m_displayName = singleVariableValue(Variable::QmakeProjectName); + m_featureRoots = m_readerExact->featureRoots(); } // result == EvalOk if (!result->directoriesWithWildcards.isEmpty()) { @@ -1686,7 +1681,7 @@ void QmakeProFile::cleanupProFileReaders() m_readerCumulative = nullptr; } -QString QmakeProFile::uiDirPath(QtSupport::ProFileReader *reader, const FileName &buildDir) +QString QmakeProFile::uiDirPath(QtSupport::ProFileReader *reader, const FilePath &buildDir) { QString path = reader->value(QLatin1String("UI_DIR")); if (QFileInfo(path).isRelative()) @@ -1694,7 +1689,7 @@ QString QmakeProFile::uiDirPath(QtSupport::ProFileReader *reader, const FileName return path; } -QString QmakeProFile::mocDirPath(QtSupport::ProFileReader *reader, const FileName &buildDir) +QString QmakeProFile::mocDirPath(QtSupport::ProFileReader *reader, const FilePath &buildDir) { QString path = reader->value(QLatin1String("MOC_DIR")); if (QFileInfo(path).isRelative()) @@ -1718,8 +1713,8 @@ QString QmakeProFile::sysrootify(const QString &path, const QString &sysroot, return !IoUtils::exists(sysrooted) ? path : sysrooted; } -QStringList QmakeProFile::includePaths(QtSupport::ProFileReader *reader, const FileName &sysroot, - const FileName &buildDir, const QString &projectDir) +QStringList QmakeProFile::includePaths(QtSupport::ProFileReader *reader, const FilePath &sysroot, + const FilePath &buildDir, const QString &projectDir) { QStringList paths; bool nextIsAnIncludePath = false; @@ -1757,12 +1752,12 @@ QStringList QmakeProFile::libDirectories(QtSupport::ProFileReader *reader) return result; } -FileNameList QmakeProFile::subDirsPaths(QtSupport::ProFileReader *reader, +FilePathList QmakeProFile::subDirsPaths(QtSupport::ProFileReader *reader, const QString &projectDir, QStringList *subProjectsNotToDeploy, QStringList *errors) { - FileNameList subProjectPaths; + FilePathList subProjectPaths; const QStringList subDirVars = reader->values(QLatin1String("SUBDIRS")); @@ -1796,7 +1791,7 @@ FileNameList QmakeProFile::subDirsPaths(QtSupport::ProFileReader *reader, if (QFile::exists(realFile)) { realFile = QDir::cleanPath(realFile); - subProjectPaths << FileName::fromString(realFile); + subProjectPaths << FilePath::fromString(realFile); if (subProjectsNotToDeploy && !subProjectsNotToDeploy->contains(realFile) && reader->values(subDirVar + QLatin1String(".CONFIG")) .contains(QLatin1String("no_default_target"))) { @@ -1814,8 +1809,8 @@ FileNameList QmakeProFile::subDirsPaths(QtSupport::ProFileReader *reader, TargetInformation QmakeProFile::targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, - const FileName &buildDir, - const FileName &projectFilePath) + const FilePath &buildDir, + const FilePath &projectFilePath) { TargetInformation result; if (!reader || !readerBuildPass) @@ -1831,7 +1826,7 @@ TargetInformation QmakeProFile::targetInformation(QtSupport::ProFileReader *read result.buildDir = buildDir; if (readerBuildPass->contains(QLatin1String("DESTDIR"))) - result.destDir = FileName::fromString(readerBuildPass->value(QLatin1String("DESTDIR"))); + result.destDir = FilePath::fromString(readerBuildPass->value(QLatin1String("DESTDIR"))); // Target result.target = readerBuildPass->value(QLatin1String("TARGET")); @@ -1905,12 +1900,12 @@ InstallsList QmakeProFile::installsList() const return m_installsList; } -FileName QmakeProFile::sourceDir() const +FilePath QmakeProFile::sourceDir() const { return directoryPath(); } -FileName QmakeProFile::buildDir(QmakeBuildConfiguration *bc) const +FilePath QmakeProFile::buildDir(QmakeBuildConfiguration *bc) const { const QDir srcDirRoot = QDir(m_project->projectDirectory().toString()); const QString relativeDir = srcDirRoot.relativeFilePath(directoryPath().toString()); @@ -1920,11 +1915,11 @@ FileName QmakeProFile::buildDir(QmakeBuildConfiguration *bc) const const QString buildDir = buildConfigBuildDir.isEmpty() ? m_project->projectDirectory().toString() : buildConfigBuildDir; - return FileName::fromString(QDir::cleanPath(QDir(buildDir).absoluteFilePath(relativeDir))); + return FilePath::fromString(QDir::cleanPath(QDir(buildDir).absoluteFilePath(relativeDir))); } -FileNameList QmakeProFile::generatedFiles(const FileName &buildDir, - const FileName &sourceFile, +FilePathList QmakeProFile::generatedFiles(const FilePath &buildDir, + const FilePath &sourceFile, const FileType &sourceFileType) const { // The mechanism for finding the file names is rather crude, but as we @@ -1933,29 +1928,26 @@ FileNameList QmakeProFile::generatedFiles(const FileName &buildDir, // cannot help doing this here. if (sourceFileType == FileType::Form) { - FileName location; + FilePath location; auto it = m_varValues.constFind(Variable::UiDir); if (it != m_varValues.constEnd() && !it.value().isEmpty()) - location = FileName::fromString(it.value().front()); + location = FilePath::fromString(it.value().front()); else location = buildDir; if (location.isEmpty()) return { }; - location.appendPath(QLatin1String("ui_") - + sourceFile.toFileInfo().completeBaseName() - + singleVariableValue(Variable::HeaderExtension)); - return { Utils::FileName::fromString(QDir::cleanPath(location.toString())) }; + location = location.pathAppended("ui_" + + sourceFile.toFileInfo().completeBaseName() + + singleVariableValue(Variable::HeaderExtension)); + return { Utils::FilePath::fromString(QDir::cleanPath(location.toString())) }; } else if (sourceFileType == FileType::StateChart) { if (buildDir.isEmpty()) return { }; - FileName location = buildDir; - location.appendPath(sourceFile.toFileInfo().completeBaseName()); - FileName header = location; - header.appendString(singleVariableValue(Variable::HeaderExtension)); - FileName cpp = location; - cpp.appendString(singleVariableValue(Variable::CppExtension)); - - return { header, cpp }; + const FilePath location = buildDir.pathAppended(sourceFile.toFileInfo().completeBaseName()); + return { + location.stringAppended(singleVariableValue(Variable::HeaderExtension)), + location.stringAppended(singleVariableValue(Variable::CppExtension)) + }; } return { }; } @@ -1965,17 +1957,17 @@ QList<ExtraCompiler *> QmakeProFile::extraCompilers() const return m_extraCompilers; } -void QmakeProFile::setupExtraCompiler(const FileName &buildDir, +void QmakeProFile::setupExtraCompiler(const FilePath &buildDir, const FileType &fileType, ExtraCompilerFactory *factory) { - for (const FileName &fn : collectFiles(fileType)) { - const FileNameList generated = generatedFiles(buildDir, fn, fileType); + for (const FilePath &fn : collectFiles(fileType)) { + const FilePathList generated = generatedFiles(buildDir, fn, fileType); if (!generated.isEmpty()) m_extraCompilers.append(factory->create(m_project, fn, generated)); } } -void QmakeProFile::updateGeneratedFiles(const FileName &buildDir) +void QmakeProFile::updateGeneratedFiles(const FilePath &buildDir) { // We can do this because other plugins are not supposed to keep the compilers around. qDeleteAll(m_extraCompilers); diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h index 4c5b7048eb..3827957d57 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h @@ -40,7 +40,7 @@ #include <memory> namespace Utils { -class FileName; +class FilePath; class FileSystemWatcher; } // namespace Utils; @@ -115,29 +115,29 @@ class InstallsList; class QMAKEPROJECTMANAGER_EXPORT QmakePriFile { public: - QmakePriFile(QmakeProject *project, QmakeProFile *qmakeProFile, const Utils::FileName &filePath); + QmakePriFile(QmakeProject *project, QmakeProFile *qmakeProFile, const Utils::FilePath &filePath); virtual ~QmakePriFile(); - Utils::FileName filePath() const; - Utils::FileName directoryPath() const; + Utils::FilePath filePath() const; + Utils::FilePath directoryPath() const; virtual QString displayName() const; QmakePriFile *parent() const; QmakeProject *project() const; QVector<QmakePriFile *> children() const; - QmakePriFile *findPriFile(const Utils::FileName &fileName); - const QmakePriFile *findPriFile(const Utils::FileName &fileName) const; + QmakePriFile *findPriFile(const Utils::FilePath &fileName); + const QmakePriFile *findPriFile(const Utils::FilePath &fileName) const; - bool knowsFile(const Utils::FileName &filePath) const; + bool knowsFile(const Utils::FilePath &filePath) const; void makeEmpty(); // Files of the specified type declared in this file. - QSet<Utils::FileName> files(const ProjectExplorer::FileType &type) const; + QSet<Utils::FilePath> files(const ProjectExplorer::FileType &type) const; // Files of the specified type declared in this file and in included .pri files. - const QSet<Utils::FileName> collectFiles(const ProjectExplorer::FileType &type) const; + const QSet<Utils::FilePath> collectFiles(const ProjectExplorer::FileType &type) const; void update(const Internal::QmakePriFileEvalResult &result); @@ -156,7 +156,7 @@ public: const QString &scope = QString(), int flags = QmakeProjectManager::Internal::ProWriter::ReplaceValues); - bool folderChanged(const QString &changedFolder, const QSet<Utils::FileName> &newFiles); + bool folderChanged(const QString &changedFolder, const QSet<Utils::FilePath> &newFiles); bool deploysFolder(const QString &folder) const; @@ -166,7 +166,7 @@ public: // Set by parent bool includedInExactParse() const; - static QSet<Utils::FileName> recursiveEnumerate(const QString &folder); + static QSet<Utils::FilePath> recursiveEnumerate(const QString &folder); void scheduleUpdate(); @@ -175,8 +175,8 @@ protected: static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact); static QStringList varNamesForRemoving(); static QString varNameForAdding(const QString &mimeType); - static QSet<Utils::FileName> filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files); - static QSet<Utils::FileName> filterFilesRecursiveEnumerata(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files); + static QSet<Utils::FilePath> filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FilePath> &files); + static QSet<Utils::FilePath> filterFilesRecursiveEnumerata(ProjectExplorer::FileType fileType, const QSet<Utils::FilePath> &files); enum ChangeType { AddToProFile, @@ -204,7 +204,6 @@ private: static QPair<ProFile *, QStringList> readProFile(const QString &file); static QPair<ProFile *, QStringList> readProFileFromContents(const QString &contents); void save(const QStringList &lines); - bool priFileWritable(const QString &absoluteFilePath); bool saveModifiedEditors(); QStringList formResources(const QString &formFile) const; static QStringList baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir); @@ -218,7 +217,7 @@ private: Internal::QmakePriFileEvalResult *fallback, const InstallsList &installList); static void processValues(Internal::QmakePriFileEvalResult &result); - void watchFolders(const QSet<Utils::FileName> &folders); + void watchFolders(const QSet<Utils::FilePath> &folders); QString continuationIndent() const; @@ -230,8 +229,8 @@ private: std::unique_ptr<Core::IDocument> m_priFileDocument; // Memory is cheap... - QMap<ProjectExplorer::FileType, QSet<Utils::FileName>> m_files; - QSet<Utils::FileName> m_recursiveEnumerateFiles; // FIXME: Remove this?! + QMap<ProjectExplorer::FileType, QSet<Utils::FilePath>> m_files; + QSet<Utils::FilePath> m_recursiveEnumerateFiles; // FIXME: Remove this?! QSet<QString> m_watchedFolders; bool m_includedInExactParse = true; @@ -243,8 +242,8 @@ class QMAKEPROJECTMANAGER_EXPORT TargetInformation public: bool valid = false; QString target; - Utils::FileName destDir; - Utils::FileName buildDir; + Utils::FilePath destDir; + Utils::FilePath buildDir; QString buildTarget; bool operator==(const TargetInformation &other) const { @@ -284,35 +283,36 @@ public: class QMAKEPROJECTMANAGER_EXPORT QmakeProFile : public QmakePriFile { public: - QmakeProFile(QmakeProject *project, const Utils::FileName &filePath); + QmakeProFile(QmakeProject *project, const Utils::FilePath &filePath); ~QmakeProFile() override; bool isParent(QmakeProFile *node); QString displayName() const final; QList<QmakeProFile *> allProFiles(); - QmakeProFile *findProFile(const Utils::FileName &fileName); - const QmakeProFile *findProFile(const Utils::FileName &fileName) const; + QmakeProFile *findProFile(const Utils::FilePath &fileName); + const QmakeProFile *findProFile(const Utils::FilePath &fileName) const; ProjectType projectType() const; QStringList variableValue(const Variable var) const; QString singleVariableValue(const Variable var) const; - bool isSubProjectDeployable(const Utils::FileName &filePath) const { + bool isSubProjectDeployable(const Utils::FilePath &filePath) const { return !m_subProjectsNotToDeploy.contains(filePath); } - Utils::FileName sourceDir() const; - Utils::FileName buildDir(QmakeBuildConfiguration *bc = nullptr) const; + Utils::FilePath sourceDir() const; + Utils::FilePath buildDir(QmakeBuildConfiguration *bc = nullptr) const; - Utils::FileNameList generatedFiles(const Utils::FileName &buildDirectory, - const Utils::FileName &sourceFile, + Utils::FilePathList generatedFiles(const Utils::FilePath &buildDirectory, + const Utils::FilePath &sourceFile, const ProjectExplorer::FileType &sourceFileType) const; QList<ProjectExplorer::ExtraCompiler *> extraCompilers() const; TargetInformation targetInformation() const; InstallsList installsList() const; + const QStringList featureRoots() const { return m_featureRoots; } QByteArray cxxDefines() const; @@ -342,19 +342,19 @@ private: void asyncEvaluate(QFutureInterface<Internal::QmakeEvalResult *> &fi, Internal::QmakeEvalInput input); void cleanupProFileReaders(); - void updateGeneratedFiles(const Utils::FileName &buildDir); + void updateGeneratedFiles(const Utils::FilePath &buildDir); - static QString uiDirPath(QtSupport::ProFileReader *reader, const Utils::FileName &buildDir); - static QString mocDirPath(QtSupport::ProFileReader *reader, const Utils::FileName &buildDir); + static QString uiDirPath(QtSupport::ProFileReader *reader, const Utils::FilePath &buildDir); + static QString mocDirPath(QtSupport::ProFileReader *reader, const Utils::FilePath &buildDir); static QString sysrootify(const QString &path, const QString &sysroot, const QString &baseDir, const QString &outputDir); - static QStringList includePaths(QtSupport::ProFileReader *reader, const Utils::FileName &sysroot, const Utils::FileName &buildDir, const QString &projectDir); + static QStringList includePaths(QtSupport::ProFileReader *reader, const Utils::FilePath &sysroot, const Utils::FilePath &buildDir, const QString &projectDir); static QStringList libDirectories(QtSupport::ProFileReader *reader); - static Utils::FileNameList subDirsPaths(QtSupport::ProFileReader *reader, const QString &projectDir, QStringList *subProjectsNotToDeploy, QStringList *errors); + static Utils::FilePathList subDirsPaths(QtSupport::ProFileReader *reader, const QString &projectDir, QStringList *subProjectsNotToDeploy, QStringList *errors); - static TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const Utils::FileName &buildDir, const Utils::FileName &projectFilePath); + static TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const Utils::FilePath &buildDir, const Utils::FilePath &projectFilePath); static InstallsList installsList(const QtSupport::ProFileReader *reader, const QString &projectFilePath, const QString &projectDir, const QString &buildDir); - void setupExtraCompiler(const Utils::FileName &buildDir, + void setupExtraCompiler(const Utils::FilePath &buildDir, const ProjectExplorer::FileType &fileType, ProjectExplorer::ExtraCompilerFactory *factory); @@ -370,8 +370,9 @@ private: QList<ProjectExplorer::ExtraCompiler *> m_extraCompilers; TargetInformation m_qmakeTargetInformation; - Utils::FileNameList m_subProjectsNotToDeploy; + Utils::FilePathList m_subProjectsNotToDeploy; InstallsList m_installsList; + QStringList m_featureRoots; std::unique_ptr<Utils::FileSystemWatcher> m_wildcardWatcher; QMap<QString, QStringList> m_wildcardDirectoryContents; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index a1bf62007a..dee31c56af 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -58,6 +58,7 @@ #include <projectexplorer/taskhub.h> #include <projectexplorer/toolchain.h> #include <proparser/qmakevfs.h> +#include <proparser/qmakeglobals.h> #include <qtsupport/profilereader.h> #include <qtsupport/qtcppkitinfo.h> #include <qtsupport/qtkitinformation.h> @@ -109,51 +110,6 @@ private: QSet<QString> m_changedFolders; }; -// QmakeProjectFiles: Struct for (Cached) lists of files in a project -class QmakeProjectFiles { -public: - void clear(); - bool equals(const QmakeProjectFiles &f) const; - - QStringList files[static_cast<int>(FileType::FileTypeSize)]; - QStringList generatedFiles[static_cast<int>(FileType::FileTypeSize)]; - QStringList proFiles; -}; - -void QmakeProjectFiles::clear() -{ - for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) { - files[i].clear(); - generatedFiles[i].clear(); - } - proFiles.clear(); -} - -bool QmakeProjectFiles::equals(const QmakeProjectFiles &f) const -{ - for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) - if (files[i] != f.files[i] || generatedFiles[i] != f.generatedFiles[i]) - return false; - if (proFiles != f.proFiles) - return false; - return true; -} - -inline bool operator==(const QmakeProjectFiles &f1, const QmakeProjectFiles &f2) -{ return f1.equals(f2); } - -inline bool operator!=(const QmakeProjectFiles &f1, const QmakeProjectFiles &f2) -{ return !f1.equals(f2); } - -QDebug operator<<(QDebug d, const QmakeProjectFiles &f) -{ - QDebug nsp = d.nospace(); - nsp << "QmakeProjectFiles: proFiles=" << f.proFiles << '\n'; - for (int i = 0; i < static_cast<int>(FileType::FileTypeSize); ++i) - nsp << "Type " << i << " files=" << f.files[i] << " generated=" << f.generatedFiles[i] << '\n'; - return d; -} - static QList<QmakeProject *> s_projects; } // namespace Internal @@ -164,7 +120,7 @@ static QList<QmakeProject *> s_projects; QmakeProject manages information about an individual Qt 4 (.pro) project file. */ -QmakeProject::QmakeProject(const FileName &fileName) : +QmakeProject::QmakeProject(const FilePath &fileName) : Project(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName), m_qmakeVfs(new QMakeVfs), m_cppCodeModelUpdater(new CppTools::CppProjectUpdater) @@ -248,6 +204,11 @@ Project::RestoreResult QmakeProject::fromMap(const QVariantMap &map, QString *er return RestoreResult::Ok; } +DeploymentKnowledge QmakeProject::deploymentKnowledge() const +{ + return DeploymentKnowledge::Approximative; // E.g. QTCREATORBUG-21855 +} + void QmakeProject::updateCodeModels() { if (activeTarget() && !activeTarget()->activeBuildConfiguration()) @@ -308,7 +269,7 @@ void QmakeProject::updateCppCodeModel() QStringList fileList = pro->variableValue(Variable::ExactSource) + cumulativeSourceFiles; QList<ProjectExplorer::ExtraCompiler *> proGenerators = pro->extraCompilers(); foreach (ProjectExplorer::ExtraCompiler *ec, proGenerators) { - ec->forEachTarget([&](const Utils::FileName &generatedFile) { + ec->forEachTarget([&](const Utils::FilePath &generatedFile) { fileList += generatedFile.toString(); }); } @@ -344,7 +305,7 @@ void QmakeProject::updateQmlJSCodeModel() bool hasQmlLib = false; for (QmakeProFile *file : proFiles) { for (const QString &path : file->variableValue(Variable::QmlImportPath)) { - projectInfo.importPaths.maybeInsert(FileName::fromString(path), + projectInfo.importPaths.maybeInsert(FilePath::fromString(path), QmlJS::Dialect::Qml); } const QStringList &exactResources = file->variableValue(Variable::ExactResource); @@ -562,6 +523,21 @@ void QmakeProject::asyncUpdate() m_asyncUpdateFutureInterface->reportStarted(); + const Kit * const kit = activeTarget() ? activeTarget()->kit() : nullptr; + QtSupport::BaseQtVersion * const qtVersion = QtSupport::QtKitAspect::qtVersion(kit); + if (!qtVersion || !qtVersion->isValid()) { + const QString errorMessage = kit + ? tr("Cannot parse project \"%1\": The currently selected kit \"%2\" does not " + "have a valid Qt.").arg(displayName(), kit->displayName()) + : tr("Cannot parse project \"%1\": No kit selected.").arg(displayName()); + proFileParseError(errorMessage); + m_asyncUpdateFutureInterface->reportCanceled(); + m_asyncUpdateFutureInterface->reportFinished(); + delete m_asyncUpdateFutureInterface; + m_asyncUpdateFutureInterface = nullptr; + return; + } + if (m_asyncUpdateState == AsyncFullUpdatePending) { rootProFile()->asyncUpdate(); } else { @@ -579,20 +555,20 @@ void QmakeProject::buildFinished(bool success) m_invalidateQmakeVfsContents = true; } -QList<Task> QmakeProject::projectIssues(const Kit *k) const +Tasks QmakeProject::projectIssues(const Kit *k) const { - QList<Task> result = Project::projectIssues(k); - if (!QtSupport::QtKitInformation::qtVersion(k)) + Tasks result = Project::projectIssues(k); + if (!QtSupport::QtKitAspect::qtVersion(k)) result.append(createProjectTask(Task::TaskType::Error, tr("No Qt version set in kit."))); - else if (!QtSupport::QtKitInformation::qtVersion(k)->isValid()) + else if (!QtSupport::QtKitAspect::qtVersion(k)->isValid()) result.append(createProjectTask(Task::TaskType::Error, tr("Qt version is invalid."))); - if (!ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)) + if (!ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)) result.append(createProjectTask(Task::TaskType::Error, tr("No C++ compiler set in kit."))); return result; } // Find the folder that contains a file with a certain name (recurse down) -static FolderNode *folderOf(FolderNode *in, const FileName &fileName) +static FolderNode *folderOf(FolderNode *in, const FilePath &fileName) { foreach (FileNode *fn, in->fileNodes()) if (fn->filePath() == fileName) @@ -605,7 +581,7 @@ static FolderNode *folderOf(FolderNode *in, const FileName &fileName) // Find the QmakeProFileNode that contains a certain file. // First recurse down to folder, then find the pro-file. -static FileNode *fileNodeOf(FolderNode *in, const FileName &fileName) +static FileNode *fileNodeOf(FolderNode *in, const FilePath &fileName) { for (FolderNode *folder = folderOf(in, fileName); folder; folder = folder->parentFolderNode()) { if (auto *proFile = dynamic_cast<QmakeProFileNode *>(folder)) { @@ -623,13 +599,13 @@ QStringList QmakeProject::filesGeneratedFrom(const QString &input) const if (!rootProjectNode()) return { }; - if (const FileNode *file = fileNodeOf(rootProjectNode(), FileName::fromString(input))) { + if (const FileNode *file = fileNodeOf(rootProjectNode(), FilePath::fromString(input))) { const QmakeProFileNode *pro = static_cast<QmakeProFileNode *>(file->parentFolderNode()); QTC_ASSERT(pro, return {}); if (const QmakeProFile *proFile = pro->proFile()) - return Utils::transform(proFile->generatedFiles(FileName::fromString(pro->buildDir()), + return Utils::transform(proFile->generatedFiles(FilePath::fromString(pro->buildDir()), file->filePath(), file->fileType()), - &FileName::toString); + &FilePath::toString); } return { }; } @@ -665,8 +641,8 @@ QtSupport::ProFileReader *QmakeProject::createProFileReader(const QmakeProFile * k->addToEnvironment(env); } - QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k); - m_qmakeSysroot = SysRootKitInformation::sysRoot(k).toString(); + QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(k); + m_qmakeSysroot = SysRootKitAspect::sysRoot(k).toString(); if (qtVersion && qtVersion->isValid()) { m_qmakeGlobals->qmake_abslocation = QDir::cleanPath(qtVersion->qmakeCommand().toString()); @@ -770,7 +746,7 @@ void QmakeProject::setAllBuildConfigurationsEnabled(bool enabled) } } -static void notifyChangedHelper(const FileName &fileName, QmakeProFile *file) +static void notifyChangedHelper(const FilePath &fileName, QmakeProFile *file) { if (file->filePath() == fileName) { QtSupport::ProFileCacheManager::instance()->discardFile( @@ -784,7 +760,7 @@ static void notifyChangedHelper(const FileName &fileName, QmakeProFile *file) } } -void QmakeProject::notifyChanged(const FileName &name) +void QmakeProject::notifyChanged(const FilePath &name) { for (QmakeProject *project : s_projects) { if (project->files(QmakeProject::SourceFiles).contains(name)) @@ -921,7 +897,7 @@ void CentralizedFolderWatcher::delayedFolderChanged(const QString &folder) QList<QmakePriFile *> files = m_map.values(dir); if (!files.isEmpty()) { // Collect all the files - QSet<FileName> newFiles; + QSet<FilePath> newFiles; newFiles += QmakePriFile::recursiveEnumerate(folder); foreach (QmakePriFile *file, files) newOrRemovedFiles = newOrRemovedFiles || file->folderChanged(folder, newFiles); @@ -962,7 +938,7 @@ void QmakeProject::configureAsExampleProject(const QSet<Core::Id> &platforms) QList<BuildInfo> infoList; QList<Kit *> kits = KitManager::kits(); foreach (Kit *k, kits) { - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k); if (!version || (!platforms.isEmpty() && !Utils::contains(version->targetDeviceTypes(), [platforms](Core::Id i) { return platforms.contains(i); }))) @@ -987,7 +963,7 @@ void QmakeProject::updateBuildSystemData() collectData(file, deploymentData); target->setDeploymentData(deploymentData); - BuildTargetInfoList appTargetList; + QList<BuildTargetInfo> appTargetList; rootProjectNode()->forEachProjectNode([this, target, &appTargetList](const ProjectNode *pn) { auto node = dynamic_cast<const QmakeProFileNode *>(pn); @@ -1025,11 +1001,11 @@ void QmakeProject::updateBuildSystemData() workingDir += '/' + ti.target + ".app/Contents/MacOS"; BuildTargetInfo bti; - bti.targetFilePath = FileName::fromString(executableFor(node->proFile())); + bti.targetFilePath = FilePath::fromString(executableFor(node->proFile())); bti.projectFilePath = node->filePath(); - bti.workingDirectory = FileName::fromString(workingDir); + bti.workingDirectory = FilePath::fromString(workingDir); bti.displayName = bti.projectFilePath.toFileInfo().completeBaseName(); - const FileName relativePathInProject + const FilePath relativePathInProject = bti.projectFilePath.relativeChildPath(projectDirectory()); if (!relativePathInProject.isEmpty()) { bti.displayNameUniquifier = QString::fromLatin1(" (%1)") @@ -1061,7 +1037,7 @@ void QmakeProject::updateBuildSystemData() libraryPaths.append(dir); } } - QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(target->kit()); + QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target->kit()); if (qtVersion) libraryPaths.append(qtVersion->librarySearchPath().toString()); @@ -1071,7 +1047,7 @@ void QmakeProject::updateBuildSystemData() env.prependOrSetLibrarySearchPaths(libraryPaths); }; - appTargetList.list.append(bti); + appTargetList.append(bti); }); target->setApplicationTargets(appTargetList); @@ -1119,12 +1095,12 @@ void QmakeProject::collectApplicationData(const QmakeProFile *file, DeploymentDa DeployableFile::TypeExecutable); } -static FileName destDirFor(const TargetInformation &ti) +static FilePath destDirFor(const TargetInformation &ti) { if (ti.destDir.isEmpty()) return ti.buildDir; if (QDir::isRelativePath(ti.destDir.toString())) - return FileName::fromString(QDir::cleanPath(ti.buildDir.toString() + '/' + ti.destDir.toString())); + return FilePath::fromString(QDir::cleanPath(ti.buildDir.toString() + '/' + ti.destDir.toString())); return ti.destDir; } @@ -1134,7 +1110,7 @@ void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData & if (targetPath.isEmpty()) return; const Kit * const kit = activeTarget()->kit(); - const ToolChain * const toolchain = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + const ToolChain * const toolchain = ToolChainKitAspect::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); if (!toolchain) return; @@ -1161,9 +1137,9 @@ void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData & break; } case Abi::DarwinOS: { - FileName destDir = destDirFor(ti); + FilePath destDir = destDirFor(ti); if (config.contains(QLatin1String("lib_bundle"))) { - destDir.appendPath(ti.target + ".framework"); + destDir = destDir.pathAppended(ti.target + ".framework"); } else { if (!(isPlugin && config.contains(QLatin1String("no_plugin_name_prefix")))) targetFileName.prepend(QLatin1String("lib")); @@ -1220,15 +1196,15 @@ void QmakeProject::collectLibraryData(const QmakeProFile *file, DeploymentData & bool QmakeProject::matchesKit(const Kit *kit) { - FileName filePath = projectFilePath(); - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(kit); + FilePath filePath = projectFilePath(); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(kit); return QtSupport::QtVersionManager::version([&filePath, version](const QtSupport::BaseQtVersion *v) { return v->isValid() && v->isSubProject(filePath) && v == version; }); } -static Utils::FileName getFullPathOf(const QmakeProFile *pro, Variable variable, +static Utils::FilePath getFullPathOf(const QmakeProFile *pro, Variable variable, const BuildConfiguration *bc) { // Take last non-flag value, to cover e.g. '@echo $< && $$QMAKE_CC' or 'ccache gcc' @@ -1237,22 +1213,22 @@ static Utils::FileName getFullPathOf(const QmakeProFile *pro, Variable variable, return !value.startsWith('-'); }); if (values.isEmpty()) - return Utils::FileName(); + return Utils::FilePath(); const QString exe = values.last(); - QTC_ASSERT(bc, return Utils::FileName::fromString(exe)); + QTC_ASSERT(bc, return Utils::FilePath::fromString(exe)); QFileInfo fi(exe); if (fi.isAbsolute()) - return Utils::FileName::fromString(exe); + return Utils::FilePath::fromString(exe); return bc->environment().searchInPath(exe); } -void QmakeProject::testToolChain(ToolChain *tc, const Utils::FileName &path) const +void QmakeProject::testToolChain(ToolChain *tc, const Utils::FilePath &path) const { if (!tc || path.isEmpty()) return; - const Utils::FileName expected = tc->compilerCommand(); + const Utils::FilePath expected = tc->compilerCommand(); Environment env = Environment::systemEnvironment(); Kit *k = nullptr; @@ -1267,7 +1243,7 @@ void QmakeProject::testToolChain(ToolChain *tc, const Utils::FileName &path) con if (env.isSameExecutable(path.toString(), expected.toString())) return; - const QPair<Utils::FileName, Utils::FileName> pair = qMakePair(expected, path); + const QPair<Utils::FilePath, Utils::FilePath> pair = qMakePair(expected, path); if (m_toolChainWarnings.contains(pair)) return; // Suppress warnings on Apple machines where compilers in /usr/bin point into Xcode. @@ -1285,7 +1261,7 @@ void QmakeProject::testToolChain(ToolChain *tc, const Utils::FileName &path) con "Please update your kit (%3) or choose a mkspec for qmake that matches " "your target environment better.") .arg(path.toUserOutput()).arg(expected.toUserOutput()).arg(k->displayName()), - Utils::FileName(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); + Utils::FilePath(), -1, ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM)); m_toolChainWarnings.insert(pair); } @@ -1296,16 +1272,16 @@ void QmakeProject::warnOnToolChainMismatch(const QmakeProFile *pro) const if (!bc) return; - testToolChain(ToolChainKitInformation::toolChain(t->kit(), ProjectExplorer::Constants::C_LANGUAGE_ID), + testToolChain(ToolChainKitAspect::toolChain(t->kit(), ProjectExplorer::Constants::C_LANGUAGE_ID), getFullPathOf(pro, Variable::QmakeCc, bc)); - testToolChain(ToolChainKitInformation::toolChain(t->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID), + testToolChain(ToolChainKitAspect::toolChain(t->kit(), ProjectExplorer::Constants::CXX_LANGUAGE_ID), getFullPathOf(pro, Variable::QmakeCxx, bc)); } QString QmakeProject::executableFor(const QmakeProFile *file) { const Kit *const kit = activeTarget() ? activeTarget()->kit() : nullptr; - const ToolChain *const tc = ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + const ToolChain *const tc = ToolChainKitAspect::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); if (!tc) return QString(); @@ -1344,7 +1320,7 @@ QmakeProject::AsyncUpdateState QmakeProject::asyncUpdateState() const return m_asyncUpdateState; } -QString QmakeProject::mapProFilePathToTarget(const FileName &proFilePath) +QString QmakeProject::mapProFilePathToTarget(const FilePath &proFilePath) { const QmakeProFile *pro = rootProFile()->findProFile(proFilePath); return pro ? pro->targetInformation().target : QString(); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index bdcb1c477a..42e8e57ec0 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -30,6 +30,7 @@ #include "qmakenodes.h" #include "qmakeparsernodes.h" +#include <projectexplorer/deploymentdata.h> #include <projectexplorer/project.h> #include <QStringList> @@ -55,18 +56,18 @@ class QMAKEPROJECTMANAGER_EXPORT QmakeProject : public ProjectExplorer::Project Q_OBJECT public: - explicit QmakeProject(const Utils::FileName &proFile); + explicit QmakeProject(const Utils::FilePath &proFile); ~QmakeProject() final; QmakeProFile *rootProFile() const; - QList<ProjectExplorer::Task> projectIssues(const ProjectExplorer::Kit *k) const final; + ProjectExplorer::Tasks projectIssues(const ProjectExplorer::Kit *k) const final; QmakeProFileNode *rootProjectNode() const final; QStringList filesGeneratedFrom(const QString &file) const final; - static void notifyChanged(const Utils::FileName &name); + static void notifyChanged(const Utils::FilePath &name); /// \internal QtSupport::ProFileReader *createProFileReader(const QmakeProFile *qmakeProFile); @@ -104,7 +105,7 @@ public: enum AsyncUpdateState { Base, AsyncFullUpdatePending, AsyncPartialUpdatePending, AsyncUpdateInProgress, ShuttingDown }; AsyncUpdateState asyncUpdateState() const; - QString mapProFilePathToTarget(const Utils::FileName &proFilePath); + QString mapProFilePathToTarget(const Utils::FilePath &proFilePath); QVariant additionalData(Core::Id id, const ProjectExplorer::Target *target) const final; @@ -120,6 +121,9 @@ protected: RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final; private: + ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override; + bool hasMakeInstallEquivalent() const override { return true; } + void asyncUpdate(); void buildFinished(bool success); void activeTargetWasChanged(); @@ -144,9 +148,9 @@ private: bool matchesKit(const ProjectExplorer::Kit *kit); void warnOnToolChainMismatch(const QmakeProFile *pro) const; - void testToolChain(ProjectExplorer::ToolChain *tc, const Utils::FileName &path) const; + void testToolChain(ProjectExplorer::ToolChain *tc, const Utils::FilePath &path) const; - mutable QSet<const QPair<Utils::FileName, Utils::FileName>> m_toolChainWarnings; + mutable QSet<const QPair<Utils::FilePath, Utils::FilePath>> m_toolChainWarnings; // Current configuration QString m_oldQtIncludePath; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp index 241bd5a4f5..a5a2d673a1 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.cpp @@ -28,8 +28,9 @@ #include "qmakeproject.h" #include "qmakebuildconfiguration.h" #include "qmakenodes.h" -#include "ui_qmakeprojectconfigwidget.h" +#include "qmakesettings.h" +#include <QBoxLayout> #include <coreplugin/coreicons.h> #include <coreplugin/variablechooser.h> #include <projectexplorer/target.h> @@ -47,57 +48,96 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc) : NamedWidget(), m_buildConfiguration(bc) { + const bool isShadowBuild = bc->isShadowBuild(); + Project *project = bc->target()->project(); + m_defaultShadowBuildDir - = QmakeBuildConfiguration::shadowBuildDirectory(bc->target()->project()->projectFilePath().toString(), + = QmakeBuildConfiguration::shadowBuildDirectory(project->projectFilePath().toString(), bc->target()->kit(), Utils::FileUtils::qmakeFriendlyName(bc->displayName()), bc->buildType()); - auto *vbox = new QVBoxLayout(this); - vbox->setMargin(0); m_detailsContainer = new Utils::DetailsWidget(this); m_detailsContainer->setState(Utils::DetailsWidget::NoSummary); + + auto vbox = new QVBoxLayout(this); + vbox->setMargin(0); vbox->addWidget(m_detailsContainer); - QWidget *details = new QWidget(m_detailsContainer); + + auto details = new QWidget(m_detailsContainer); m_detailsContainer->setWidget(details); - m_ui = new Ui::QmakeProjectConfigWidget(); - m_ui->setupUi(details); - - m_browseButton = m_ui->shadowBuildDirEdit->buttonAtIndex(0); - - m_ui->warningLabel->setPixmap(Utils::Icons::WARNING.pixmap()); - m_ui->shadowBuildDirEdit->setPromptDialogTitle(tr("Shadow Build Directory")); - m_ui->shadowBuildDirEdit->setExpectedKind(Utils::PathChooser::ExistingDirectory); - m_ui->shadowBuildDirEdit->setHistoryCompleter(QLatin1String("Qmake.BuildDir.History")); - m_ui->shadowBuildDirEdit->setEnvironment(bc->environment()); - m_ui->shadowBuildDirEdit->setBaseFileName(bc->target()->project()->projectDirectory()); - bool isShadowBuild = bc->isShadowBuild(); + + shadowBuildLabel = new QLabel(details); + shadowBuildLabel->setText(tr("Shadow build:")); + + shadowBuildCheckBox = new QCheckBox(details); + shadowBuildCheckBox->setChecked(isShadowBuild); + + buildDirLabel = new QLabel(details); + buildDirLabel->setText(tr("Build directory:")); + + shadowBuildDirEdit = new Utils::PathChooser(details); + + inSourceBuildDirEdit = new Utils::PathChooser(details); + + warningLabel = new QLabel(details); + warningLabel->setPixmap(Utils::Icons::WARNING.pixmap()); + + problemLabel = new QLabel(details); + QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy2.setHorizontalStretch(10); + sizePolicy2.setVerticalStretch(0); + problemLabel->setSizePolicy(sizePolicy2); + problemLabel->setWordWrap(true); + + auto horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->addWidget(warningLabel); + horizontalLayout_2->addWidget(problemLabel); + + auto horizontalLayout = new QHBoxLayout(); + horizontalLayout->addWidget(shadowBuildDirEdit); + horizontalLayout->addWidget(inSourceBuildDirEdit); + + auto layout = new QGridLayout(details); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(shadowBuildLabel, 0, 0, 1, 1); + layout->addWidget(shadowBuildCheckBox, 0, 1, 1, 1); + layout->addWidget(buildDirLabel, 1, 0, 1, 1); + layout->addLayout(horizontalLayout, 1, 1, 1, 1); + layout->addLayout(horizontalLayout_2, 2, 1, 1, 1); + + problemLabel->setText(tr("problemLabel")); + + m_browseButton = shadowBuildDirEdit->buttonAtIndex(0); + + shadowBuildDirEdit->setPromptDialogTitle(tr("Shadow Build Directory")); + shadowBuildDirEdit->setExpectedKind(Utils::PathChooser::ExistingDirectory); + shadowBuildDirEdit->setHistoryCompleter(QLatin1String("Qmake.BuildDir.History")); + shadowBuildDirEdit->setEnvironment(bc->environment()); + shadowBuildDirEdit->setBaseFileName(project->projectDirectory()); if (isShadowBuild) { - m_ui->shadowBuildDirEdit->setPath(bc->rawBuildDirectory().toString()); - m_ui->inSourceBuildDirEdit->setVisible(false); + shadowBuildDirEdit->setPath(bc->rawBuildDirectory().toString()); + inSourceBuildDirEdit->setVisible(false); } else { - m_ui->shadowBuildDirEdit->setPath(m_defaultShadowBuildDir); - m_ui->shadowBuildDirEdit->setVisible(false); + shadowBuildDirEdit->setPath(m_defaultShadowBuildDir); + shadowBuildDirEdit->setVisible(false); } - m_ui->inSourceBuildDirEdit->setFileName(bc->target()->project()->projectDirectory()); - m_ui->inSourceBuildDirEdit->setReadOnly(true); - m_ui->inSourceBuildDirEdit->setEnabled(false); + inSourceBuildDirEdit->setFileName(project->projectDirectory()); + inSourceBuildDirEdit->setReadOnly(true); + inSourceBuildDirEdit->setEnabled(false); auto chooser = new Core::VariableChooser(this); - chooser->addSupportedWidget(m_ui->shadowBuildDirEdit->lineEdit()); - - m_ui->shadowBuildCheckBox->setChecked(isShadowBuild); + chooser->addSupportedWidget(shadowBuildDirEdit->lineEdit()); - connect(m_ui->shadowBuildCheckBox, &QAbstractButton::clicked, + connect(shadowBuildCheckBox, &QAbstractButton::clicked, this, &QmakeProjectConfigWidget::shadowBuildClicked); - connect(m_ui->shadowBuildDirEdit, &Utils::PathChooser::beforeBrowsing, + connect(shadowBuildDirEdit, &Utils::PathChooser::beforeBrowsing, this, &QmakeProjectConfigWidget::onBeforeBeforeShadowBuildDirBrowsed); - connect(m_ui->shadowBuildDirEdit, &Utils::PathChooser::rawPathChanged, + connect(shadowBuildDirEdit, &Utils::PathChooser::rawPathChanged, this, &QmakeProjectConfigWidget::shadowBuildEdited); - auto *project = static_cast<QmakeProject *>(bc->target()->project()); project->subscribeSignal(&BuildConfiguration::environmentChanged, this, [this]() { if (static_cast<BuildConfiguration *>(sender())->isActive()) environmentChanged(); @@ -107,9 +147,13 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc) if (pc && pc->isActive()) environmentChanged(); }); - connect(project, &QmakeProject::buildDirectoryInitialized, + + auto qmakeProject = static_cast<QmakeProject *>(bc->target()->project()); + connect(qmakeProject, &QmakeProject::buildDirectoryInitialized, this, &QmakeProjectConfigWidget::updateProblemLabel); - connect(project, &Project::parsingFinished, + connect(qmakeProject, &Project::parsingFinished, + this, &QmakeProjectConfigWidget::updateProblemLabel); + connect(&QmakeSettings::instance(), &QmakeSettings::settingsChanged, this, &QmakeProjectConfigWidget::updateProblemLabel); connect(bc->target(), &Target::kitChanged, this, &QmakeProjectConfigWidget::updateProblemLabel); @@ -125,11 +169,6 @@ QmakeProjectConfigWidget::QmakeProjectConfigWidget(QmakeBuildConfiguration *bc) updateProblemLabel(); } -QmakeProjectConfigWidget::~QmakeProjectConfigWidget() -{ - delete m_ui; -} - void QmakeProjectConfigWidget::updateDetails() { m_detailsContainer->setSummaryText( @@ -139,14 +178,14 @@ void QmakeProjectConfigWidget::updateDetails() void QmakeProjectConfigWidget::setProblemLabel(const QString &text) { - m_ui->warningLabel->setVisible(!text.isEmpty()); - m_ui->problemLabel->setVisible(!text.isEmpty()); - m_ui->problemLabel->setText(text); + warningLabel->setVisible(!text.isEmpty()); + problemLabel->setVisible(!text.isEmpty()); + problemLabel->setText(text); } void QmakeProjectConfigWidget::environmentChanged() { - m_ui->shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment()); + shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment()); } void QmakeProjectConfigWidget::buildDirectoryChanged() @@ -154,14 +193,14 @@ void QmakeProjectConfigWidget::buildDirectoryChanged() if (m_ignoreChange) return; - bool shadowBuild = m_ui->shadowBuildCheckBox->isChecked(); - m_ui->inSourceBuildDirEdit->setVisible(!shadowBuild); + bool shadowBuild = shadowBuildCheckBox->isChecked(); + inSourceBuildDirEdit->setVisible(!shadowBuild); - m_ui->shadowBuildDirEdit->setVisible(shadowBuild); - m_ui->shadowBuildDirEdit->setEnabled(shadowBuild); + shadowBuildDirEdit->setVisible(shadowBuild); + shadowBuildDirEdit->setEnabled(shadowBuild); m_browseButton->setEnabled(shadowBuild); - m_ui->shadowBuildDirEdit->setPath(m_buildConfiguration->rawBuildDirectory().toString()); + shadowBuildDirEdit->setPath(m_buildConfiguration->rawBuildDirectory().toString()); updateDetails(); updateProblemLabel(); @@ -169,24 +208,24 @@ void QmakeProjectConfigWidget::buildDirectoryChanged() void QmakeProjectConfigWidget::onBeforeBeforeShadowBuildDirBrowsed() { - Utils::FileName initialDirectory = m_buildConfiguration->target()->project()->projectDirectory(); + Utils::FilePath initialDirectory = m_buildConfiguration->target()->project()->projectDirectory(); if (!initialDirectory.isEmpty()) - m_ui->shadowBuildDirEdit->setInitialBrowsePathBackup(initialDirectory.toString()); + shadowBuildDirEdit->setInitialBrowsePathBackup(initialDirectory.toString()); } void QmakeProjectConfigWidget::shadowBuildClicked(bool checked) { - m_ui->shadowBuildDirEdit->setEnabled(checked); + shadowBuildDirEdit->setEnabled(checked); m_browseButton->setEnabled(checked); - m_ui->shadowBuildDirEdit->setVisible(checked); - m_ui->inSourceBuildDirEdit->setVisible(!checked); + shadowBuildDirEdit->setVisible(checked); + inSourceBuildDirEdit->setVisible(!checked); m_ignoreChange = true; if (checked) - m_buildConfiguration->setBuildDirectory(Utils::FileName::fromString(m_ui->shadowBuildDirEdit->rawPath())); + m_buildConfiguration->setBuildDirectory(Utils::FilePath::fromString(shadowBuildDirEdit->rawPath())); else - m_buildConfiguration->setBuildDirectory(Utils::FileName::fromString(m_ui->inSourceBuildDirEdit->rawPath())); + m_buildConfiguration->setBuildDirectory(Utils::FilePath::fromString(inSourceBuildDirEdit->rawPath())); m_ignoreChange = false; updateDetails(); @@ -195,22 +234,22 @@ void QmakeProjectConfigWidget::shadowBuildClicked(bool checked) void QmakeProjectConfigWidget::shadowBuildEdited() { - if (m_buildConfiguration->rawBuildDirectory().toString() == m_ui->shadowBuildDirEdit->rawPath()) + if (m_buildConfiguration->rawBuildDirectory().toString() == shadowBuildDirEdit->rawPath()) return; m_ignoreChange = true; - m_buildConfiguration->setBuildDirectory(Utils::FileName::fromString(m_ui->shadowBuildDirEdit->rawPath())); + m_buildConfiguration->setBuildDirectory(Utils::FilePath::fromString(shadowBuildDirEdit->rawPath())); m_ignoreChange = false; } void QmakeProjectConfigWidget::updateProblemLabel() { - m_ui->shadowBuildDirEdit->triggerChanged(); + shadowBuildDirEdit->triggerChanged(); ProjectExplorer::Kit *k = m_buildConfiguration->target()->kit(); const QString proFileName = m_buildConfiguration->target()->project()->projectFilePath().toString(); // Check for Qt version: - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k); if (!version) { setProblemLabel(tr("This kit cannot build this project since it does not define a Qt version.")); return; @@ -250,11 +289,16 @@ void QmakeProjectConfigWidget::updateProblemLabel() } } + const bool unalignedBuildDir = QmakeSettings::warnAgainstUnalignedBuildDir() + && !m_buildConfiguration->isBuildDirAtSafeLocation(); + if (unalignedBuildDir) + allGood = false; + if (allGood) { QString buildDirectory = m_buildConfiguration->target()->project()->projectDirectory().toString(); if (m_buildConfiguration->isShadowBuild()) buildDirectory = m_buildConfiguration->buildDirectory().toString(); - QList<ProjectExplorer::Task> issues; + Tasks issues; issues = version->reportIssues(proFileName, buildDirectory); Utils::sort(issues); @@ -293,6 +337,9 @@ void QmakeProjectConfigWidget::updateProblemLabel() .arg(errorString) .arg(m_buildConfiguration->buildDirectory().toUserOutput())); return; + } else if (unalignedBuildDir) { + setProblemLabel(m_buildConfiguration->unalignedBuildDirWarning()); + return; } setProblemLabel(QString()); diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h index 0c5c0ef6fd..c0dc7653b6 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.h @@ -27,6 +27,11 @@ #include <projectexplorer/namedwidget.h> +#include <utils/pathchooser.h> + +#include <QCheckBox> +#include <QLabel> + QT_BEGIN_NAMESPACE class QAbstractButton; QT_END_NAMESPACE @@ -37,14 +42,12 @@ namespace QmakeProjectManager { class QmakeBuildConfiguration; namespace Internal { -namespace Ui { class QmakeProjectConfigWidget; } class QmakeProjectConfigWidget : public ProjectExplorer::NamedWidget { Q_OBJECT public: QmakeProjectConfigWidget(QmakeBuildConfiguration *bc); - ~QmakeProjectConfigWidget() override; private: // User changes in our widgets @@ -60,12 +63,19 @@ private: void updateDetails(); void setProblemLabel(const QString &text); - Ui::QmakeProjectConfigWidget *m_ui; QAbstractButton *m_browseButton; QmakeBuildConfiguration *m_buildConfiguration; Utils::DetailsWidget *m_detailsContainer; QString m_defaultShadowBuildDir; bool m_ignoreChange = false; + + QLabel *shadowBuildLabel; + QCheckBox *shadowBuildCheckBox; + QLabel *buildDirLabel; + Utils::PathChooser *shadowBuildDirEdit; + Utils::PathChooser *inSourceBuildDirEdit; + QLabel *warningLabel; + QLabel *problemLabel; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.ui b/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.ui deleted file mode 100644 index db15315897..0000000000 --- a/src/plugins/qmakeprojectmanager/qmakeprojectconfigwidget.ui +++ /dev/null @@ -1,105 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>QmakeProjectManager::Internal::QmakeProjectConfigWidget</class> - <widget class="QWidget" name="QmakeProjectManager::Internal::QmakeProjectConfigWidget"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>408</width> - <height>62</height> - </rect> - </property> - <layout class="QGridLayout" name="gridLayout"> - <property name="leftMargin"> - <number>0</number> - </property> - <property name="topMargin"> - <number>0</number> - </property> - <property name="rightMargin"> - <number>0</number> - </property> - <property name="bottomMargin"> - <number>0</number> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="shadowBuildLabel"> - <property name="text"> - <string>Shadow build:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="shadowBuildCheckBox"> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="buildDirLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Build directory:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="Utils::PathChooser" name="shadowBuildDirEdit" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - </widget> - </item> - <item> - <widget class="Utils::PathChooser" name="inSourceBuildDirEdit" native="true"/> - </item> - </layout> - </item> - <item row="2" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="warningLabel"/> - </item> - <item> - <widget class="QLabel" name="problemLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>10</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>problemLabel</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>Utils::PathChooser</class> - <extends>QWidget</extends> - <header location="global">utils/pathchooser.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <resources/> - <connections/> -</ui> diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index a04657aa40..fe3d1bf67d 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -64,10 +64,10 @@ namespace { struct DirectoryData { QString makefile; - Utils::FileName buildDirectory; - Utils::FileName canonicalQmakeBinary; + Utils::FilePath buildDirectory; + Utils::FilePath canonicalQmakeBinary; QtProjectImporter::QtVersionData qtVersionData; - FileName parsedSpec; + QString parsedSpec; BaseQtVersion::QmakeBuildConfigs buildConfig; QString additionalArguments; QMakeStepConfig config; @@ -83,7 +83,7 @@ namespace Internal { const Core::Id QT_IS_TEMPORARY("Qmake.TempQt"); const char IOSQT[] = "Qt4ProjectManager.QtVersion.Ios"; // ugly -QmakeProjectImporter::QmakeProjectImporter(const FileName &path) : +QmakeProjectImporter::QmakeProjectImporter(const FilePath &path) : QtProjectImporter(path) { } @@ -109,7 +109,7 @@ QStringList QmakeProjectImporter::importCandidates() return candidates; } -QList<void *> QmakeProjectImporter::examineDirectory(const FileName &importPath) const +QList<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath) const { QList<void *> result; const QLoggingCategory &logs = MakeFileParse::logging(); @@ -136,7 +136,7 @@ QList<void *> QmakeProjectImporter::examineDirectory(const FileName &importPath) } QFileInfo qmakeFi = parse.qmakePath().toFileInfo(); - data->canonicalQmakeBinary = FileName::fromString(qmakeFi.canonicalFilePath()); + data->canonicalQmakeBinary = FilePath::fromString(qmakeFi.canonicalFilePath()); if (data->canonicalQmakeBinary.isEmpty()) { qCDebug(logs) << " " << parse.qmakePath() << "doesn't exist anymore"; continue; @@ -164,7 +164,7 @@ QList<void *> QmakeProjectImporter::examineDirectory(const FileName &importPath) } if (version->type() == QtSupport::Constants::DESKTOPQT) { - const QList<ProjectExplorer::Abi> abis = version->qtAbis(); + const ProjectExplorer::Abis abis = version->qtAbis(); if (!abis.isEmpty()) { ProjectExplorer::Abi abi = abis.first(); if (abi.os() == ProjectExplorer::Abi::DarwinOS) { @@ -185,8 +185,8 @@ QList<void *> QmakeProjectImporter::examineDirectory(const FileName &importPath) qCDebug(logs) << " Extracted spec:" << data->parsedSpec; qCDebug(logs) << " Arguments now:" << data->additionalArguments; - FileName versionSpec = version->mkspec(); - if (data->parsedSpec.isEmpty() || data->parsedSpec == FileName::fromLatin1("default")) { + const QString versionSpec = version->mkspec(); + if (data->parsedSpec.isEmpty() || data->parsedSpec == "default") { data->parsedSpec = versionSpec; qCDebug(logs) << " No parsed spec or default spec => parsed spec now:" << data->parsedSpec; } @@ -203,9 +203,9 @@ bool QmakeProjectImporter::matchKit(void *directoryData, const Kit *k) const auto *data = static_cast<DirectoryData *>(directoryData); const QLoggingCategory &logs = MakeFileParse::logging(); - BaseQtVersion *kitVersion = QtKitInformation::qtVersion(k); - FileName kitSpec = QmakeKitInformation::mkspec(k); - ToolChain *tc = ToolChainKitInformation::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + BaseQtVersion *kitVersion = QtKitAspect::qtVersion(k); + QString kitSpec = QmakeKitAspect::mkspec(k); + ToolChain *tc = ToolChainKitAspect::toolChain(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID); if (kitSpec.isEmpty() && kitVersion) kitSpec = kitVersion->mkspecFor(tc); QMakeStepConfig::TargetArchConfig kitTargetArch = QMakeStepConfig::NoArch; @@ -265,13 +265,13 @@ void QmakeProjectImporter::deleteDirectoryData(void *directoryData) const delete static_cast<DirectoryData *>(directoryData); } -static const QList<ToolChain *> preferredToolChains(BaseQtVersion *qtVersion, const FileName &ms, +static const QList<ToolChain *> preferredToolChains(BaseQtVersion *qtVersion, const QString &ms, const QMakeStepConfig::TargetArchConfig &archConfig) { - const FileName spec = ms.isEmpty() ? qtVersion->mkspec() : ms; + const QString spec = ms.isEmpty() ? qtVersion->mkspec() : ms; const QList<ToolChain *> toolchains = ToolChainManager::toolChains(); - QList<Abi> qtAbis = qtVersion->qtAbis(); + const Abis qtAbis = qtVersion->qtAbis(); const auto matcher = [&](const ToolChain *tc) { return qtAbis.contains(tc->targetAbi()) && tc->suggestedMkspecList().contains(spec) @@ -292,7 +292,7 @@ static const QList<ToolChain *> preferredToolChains(BaseQtVersion *qtVersion, co } Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersionData &data, - const FileName &parsedSpec, + const QString &parsedSpec, const QMakeStepConfig::TargetArchConfig &archConfig, const QMakeStepConfig::OsType &osType) const { @@ -300,9 +300,9 @@ Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersion return QtProjectImporter::createTemporaryKit(data, [&data, parsedSpec, archConfig](Kit *k) -> void { for (ToolChain * const tc : preferredToolChains(data.qt, parsedSpec, archConfig)) - ToolChainKitInformation::setToolChain(k, tc); + ToolChainKitAspect::setToolChain(k, tc); if (parsedSpec != data.qt->mkspec()) - QmakeKitInformation::setMkspec(k, parsedSpec); + QmakeKitAspect::setMkspec(k, parsedSpec, QmakeKitAspect::MkspecSource::Code); }); } diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h index 13dad12de5..c6f364210a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.h @@ -36,12 +36,12 @@ namespace Internal { class QmakeProjectImporter : public QtSupport::QtProjectImporter { public: - QmakeProjectImporter(const Utils::FileName &path); + QmakeProjectImporter(const Utils::FilePath &path); QStringList importCandidates() final; private: - QList<void *> examineDirectory(const Utils::FileName &importPath) const final; + QList<void *> examineDirectory(const Utils::FilePath &importPath) const final; bool matchKit(void *directoryData, const ProjectExplorer::Kit *k) const final; ProjectExplorer::Kit *createKit(void *directoryData) const final; const QList<ProjectExplorer::BuildInfo> buildInfoListForKit(const ProjectExplorer::Kit *k, @@ -50,7 +50,7 @@ private: void deleteDirectoryData(void *directoryData) const final; ProjectExplorer::Kit *createTemporaryKit(const QtProjectImporter::QtVersionData &data, - const Utils::FileName &parsedSpec, + const QString &parsedSpec, const QmakeProjectManager::QMakeStepConfig::TargetArchConfig &archConfig, const QMakeStepConfig::OsType &osType) const; }; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp index 3af228874a..adbc1709fb 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp @@ -53,16 +53,6 @@ using namespace TextEditor; namespace QmakeProjectManager { -Node *QmakeManager::contextNode() -{ - return ProjectTree::findCurrentNode(); -} - -Project *QmakeManager::contextProject() -{ - return ProjectTree::currentProject(); -} - static QmakeProFileNode *buildableFileProFile(Node *node) { if (node) { @@ -77,7 +67,7 @@ static QmakeProFileNode *buildableFileProFile(Node *node) FileNode *QmakeManager::contextBuildableFileNode() { - Node *node = contextNode(); + Node *node = ProjectTree::currentNode(); QmakeProFileNode *subProjectNode = buildableFileProFile(node); FileNode *fileNode = node ? node->asFileNode() : nullptr; @@ -97,7 +87,7 @@ void QmakeManager::addLibraryContextMenu() { QString projectPath; - Node *node = contextNode(); + Node *node = ProjectTree::currentNode(); if (ContainerNode *cn = node->asContainerNode()) projectPath = cn->project()->projectFilePath().toString(); else if (dynamic_cast<QmakeProFileNode *>(node)) @@ -142,7 +132,7 @@ void QmakeManager::runQMake() void QmakeManager::runQMakeContextMenu() { - runQMakeImpl(contextProject(), contextNode()); + runQMakeImpl(ProjectTree::currentProject(), ProjectTree::currentNode()); } void QmakeManager::runQMakeImpl(ProjectExplorer::Project *p, ProjectExplorer::Node *node) @@ -194,7 +184,7 @@ void QmakeManager::buildFileContextMenu() void QmakeManager::buildFile() { if (Core::IDocument *currentDocument= Core::EditorManager::currentDocument()) { - const Utils::FileName file = currentDocument->filePath(); + const Utils::FilePath file = currentDocument->filePath(); Node *n = ProjectTree::nodeForFile(file); FileNode *node = n ? n->asFileNode() : nullptr; Project *project = SessionManager::projectForFile(file); @@ -206,8 +196,11 @@ void QmakeManager::buildFile() void QmakeManager::handleSubDirContextMenu(QmakeManager::Action action, bool isFileBuild) { - handleSubDirContextMenu(action, isFileBuild, contextProject(), - buildableFileProFile(contextNode()), contextBuildableFileNode()); + handleSubDirContextMenu(action, + isFileBuild, + ProjectTree::currentProject(), + buildableFileProFile(ProjectTree::currentNode()), + contextBuildableFileNode()); } void QmakeManager::handleSubDirContextMenu(QmakeManager::Action action, bool isFileBuild, diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h index b7869f9374..ab163f1a76 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.h @@ -45,11 +45,9 @@ class QMAKEPROJECTMANAGER_EXPORT QmakeManager : public QObject Q_OBJECT public: - void notifyChanged(const Utils::FileName &name); + void notifyChanged(const Utils::FilePath &name); // Context information used in the slot implementations - static ProjectExplorer::Node *contextNode(); - static ProjectExplorer::Project *contextProject(); static ProjectExplorer::FileNode *contextBuildableFileNode(); enum Action { BUILD, REBUILD, CLEAN }; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro index b831a594d0..ccc64eda00 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.pro @@ -7,23 +7,18 @@ DEFINES += \ HEADERS += \ qmakebuildinfo.h \ qmakekitinformation.h \ - qmakekitconfigwidget.h \ qmakeparsernodes.h \ qmakeprojectimporter.h \ qmakeprojectmanagerplugin.h \ qmakeprojectmanager.h \ qmakeproject.h \ + qmakesettings.h \ qmakenodes.h \ qmakenodetreebuilder.h \ profileeditor.h \ profilehighlighter.h \ profilehoverhandler.h \ wizards/qtprojectparameters.h \ - wizards/guiappwizard.h \ - wizards/libraryparameters.h \ - wizards/librarywizard.h \ - wizards/librarywizarddialog.h \ - wizards/guiappwizarddialog.h \ wizards/modulespage.h \ wizards/filespage.h \ wizards/qtwizard.h \ @@ -46,7 +41,6 @@ HEADERS += \ qmakemakestep.h SOURCES += \ - qmakekitconfigwidget.cpp \ qmakekitinformation.cpp \ qmakeparsernodes.cpp \ qmakeprojectimporter.cpp \ @@ -54,16 +48,12 @@ SOURCES += \ qmakeprojectmanager.cpp \ qmakeproject.cpp \ qmakenodes.cpp \ + qmakesettings.cpp \ qmakenodetreebuilder.cpp \ profileeditor.cpp \ profilehighlighter.cpp \ profilehoverhandler.cpp \ wizards/qtprojectparameters.cpp \ - wizards/guiappwizard.cpp \ - wizards/libraryparameters.cpp \ - wizards/librarywizard.cpp \ - wizards/librarywizarddialog.cpp \ - wizards/guiappwizarddialog.cpp \ wizards/modulespage.cpp \ wizards/filespage.cpp \ wizards/qtwizard.cpp \ @@ -85,7 +75,6 @@ SOURCES += \ FORMS += \ qmakestep.ui \ - qmakeprojectconfigwidget.ui \ librarydetailswidget.ui RESOURCES += qmakeprojectmanager.qrc \ diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs index 2b0e99f353..e045f60663 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs @@ -36,18 +36,18 @@ Project { "profilehighlighter.cpp", "profilehighlighter.h", "profilehoverhandler.cpp", "profilehoverhandler.h", "qmakebuildinfo.h", - "qmakekitconfigwidget.cpp", "qmakekitconfigwidget.h", "qmakekitinformation.cpp", "qmakekitinformation.h", "qmakemakestep.cpp", "qmakemakestep.h", "qmakeparser.cpp", "qmakeparser.h", "qmakeparsernodes.cpp", "qmakeparsernodes.h", "qmakeprojectimporter.cpp", "qmakeprojectimporter.h", + "qmakesettings.cpp", "qmakesettings.h", "qmakestep.cpp", "qmakestep.h", "qmakestep.ui", "qmakebuildconfiguration.cpp", "qmakebuildconfiguration.h", "qmakenodes.cpp", "qmakenodes.h", "qmakenodetreebuilder.cpp", "qmakenodetreebuilder.h", "qmakeproject.cpp", "qmakeproject.h", - "qmakeprojectconfigwidget.cpp", "qmakeprojectconfigwidget.h", "qmakeprojectconfigwidget.ui", + "qmakeprojectconfigwidget.cpp", "qmakeprojectconfigwidget.h", "qmakeprojectmanager.cpp", "qmakeprojectmanager.h", "qmakeprojectmanager.qrc", "qmakeprojectmanager_global.h", @@ -78,11 +78,6 @@ Project { prefix: "wizards/" files: [ "filespage.cpp", "filespage.h", - "guiappwizard.cpp", "guiappwizard.h", - "guiappwizarddialog.cpp", "guiappwizarddialog.h", - "libraryparameters.cpp", "libraryparameters.h", - "librarywizard.cpp", "librarywizard.h", - "librarywizarddialog.cpp", "librarywizarddialog.h", "modulespage.cpp", "modulespage.h", "qtprojectparameters.cpp", "qtprojectparameters.h", "qtwizard.cpp", "qtwizard.h", diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index 46ffcec047..bf21949215 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -28,12 +28,11 @@ #include "profileeditor.h" #include "qmakeprojectmanager.h" #include "qmakenodes.h" +#include "qmakesettings.h" #include "qmakestep.h" #include "qmakemakestep.h" #include "qmakebuildconfiguration.h" #include "desktopqmakerunconfiguration.h" -#include "wizards/guiappwizard.h" -#include "wizards/librarywizard.h" #include "wizards/simpleprojectwizard.h" #include "wizards/subdirsprojectwizard.h" #include "customwidgetwizard/customwidgetwizard.h" @@ -54,6 +53,7 @@ #include <projectexplorer/buildmanager.h> #include <projectexplorer/projectmanager.h> #include <projectexplorer/projecttree.h> +#include <projectexplorer/runcontrol.h> #include <projectexplorer/session.h> #include <projectexplorer/target.h> @@ -86,7 +86,7 @@ public: void buildStateChanged(Project *pro); void updateBuildFileAction(); void disableBuildFileMenus(); - void enableBuildFileMenus(const Utils::FileName &file); + void enableBuildFileMenus(const Utils::FilePath &file); QmakeManager qmakeProjectManager; Core::Context projectContext; @@ -99,9 +99,13 @@ public: QmakeBuildConfigurationFactory buildConfigFactory; DesktopQmakeRunConfigurationFactory runConfigFactory; + SimpleRunWorkerFactory<SimpleTargetRunner, DesktopQmakeRunConfiguration> + runWorkerFactory; ProFileEditorFactory profileEditorFactory; + QmakeSettingsPage settingsPage; + ExternalQtEditor *m_designerEditor{ExternalQtEditor::createDesignerEditor()}; ExternalQtEditor *m_linguistEditor{ExternalQtEditor::createLinguistEditor()}; @@ -121,6 +125,8 @@ public: Utils::ParameterAction *m_buildFileAction = nullptr; QAction *m_addLibraryAction = nullptr; QAction *m_addLibraryActionContextMenu = nullptr; + + QmakeKitAspect qmakeKitAspect; }; QmakeProjectManagerPlugin::~QmakeProjectManagerPlugin() @@ -140,13 +146,9 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString //create and register objects ProjectManager::registerProjectType<QmakeProject>(QmakeProjectManager::Constants::PROFILE_MIMETYPE); - ProjectExplorer::KitManager::registerKitInformation<QmakeKitInformation>(); - IWizardFactory::registerFactoryCreator([] { return QList<IWizardFactory *> { new SubdirsProjectWizard, - new GuiAppWizard, - new LibraryWizard, new CustomWidgetWizard, new SimpleProjectWizard }; @@ -367,14 +369,14 @@ void QmakeProjectManagerPluginPrivate::updateRunQMakeAction() void QmakeProjectManagerPluginPrivate::updateContextActions() { - const Node *node = ProjectTree::findCurrentNode(); + const Node *node = ProjectTree::currentNode(); Project *project = ProjectTree::currentProject(); const ContainerNode *containerNode = node ? node->asContainerNode() : nullptr; const auto *proFileNode = dynamic_cast<const QmakeProFileNode *>(containerNode ? containerNode->rootProjectNode() : node); m_addLibraryActionContextMenu->setEnabled(proFileNode); - auto *qmakeProject = qobject_cast<QmakeProject *>(QmakeManager::contextProject()); + auto *qmakeProject = qobject_cast<QmakeProject *>(project); QmakeProFileNode *subProjectNode = nullptr; disableBuildFileMenus(); if (node) { @@ -450,7 +452,7 @@ void QmakeProjectManagerPluginPrivate::disableBuildFileMenus() m_buildFileContextMenu->setEnabled(false); } -void QmakeProjectManagerPluginPrivate::enableBuildFileMenus(const Utils::FileName &file) +void QmakeProjectManagerPluginPrivate::enableBuildFileMenus(const Utils::FilePath &file) { bool visible = false; bool enabled = false; diff --git a/src/plugins/qmakeprojectmanager/qmakesettings.cpp b/src/plugins/qmakeprojectmanager/qmakesettings.cpp new file mode 100644 index 0000000000..37c0a4ce39 --- /dev/null +++ b/src/plugins/qmakeprojectmanager/qmakesettings.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "qmakesettings.h" + +#include <coreplugin/icore.h> +#include <projectexplorer/projectexplorerconstants.h> +#include <utils/hostosinfo.h> + +#include <QCheckBox> +#include <QCoreApplication> +#include <QVBoxLayout> + +namespace QmakeProjectManager { +namespace Internal { + +const char BUILD_DIR_WARNING_KEY[] = "QmakeProjectManager/WarnAgainstUnalignedBuildDir"; +const char ALWAYS_RUN_QMAKE_KEY[] = "QmakeProjectManager/AlwaysRunQmake"; + +static bool operator==(const QmakeSettingsData &s1, const QmakeSettingsData &s2) +{ + return s1.warnAgainstUnalignedBuildDir == s2.warnAgainstUnalignedBuildDir + && s1.alwaysRunQmake == s2.alwaysRunQmake; +} +static bool operator!=(const QmakeSettingsData &s1, const QmakeSettingsData &s2) +{ + return !(s1 == s2); +} + +bool QmakeSettings::warnAgainstUnalignedBuildDir() +{ + return instance().m_settings.warnAgainstUnalignedBuildDir; +} + +bool QmakeSettings::alwaysRunQmake() +{ + return instance().m_settings.alwaysRunQmake; +} + +QmakeSettings &QmakeSettings::instance() +{ + static QmakeSettings theSettings; + return theSettings; +} + +void QmakeSettings::setSettingsData(const QmakeSettingsData &settings) +{ + if (instance().m_settings != settings) { + instance().m_settings = settings; + instance().storeSettings(); + emit instance().settingsChanged(); + } +} + +QmakeSettings::QmakeSettings() +{ + loadSettings(); +} + +void QmakeSettings::loadSettings() +{ + QSettings * const s = Core::ICore::settings(); + m_settings.warnAgainstUnalignedBuildDir = s->value( + BUILD_DIR_WARNING_KEY, Utils::HostOsInfo::isWindowsHost()).toBool(); + m_settings.alwaysRunQmake = s->value(ALWAYS_RUN_QMAKE_KEY, false).toBool(); +} + +void QmakeSettings::storeSettings() const +{ + QSettings * const s = Core::ICore::settings(); + s->setValue(BUILD_DIR_WARNING_KEY, warnAgainstUnalignedBuildDir()); + s->setValue(ALWAYS_RUN_QMAKE_KEY, alwaysRunQmake()); +} + +class QmakeSettingsPage::SettingsWidget : public QWidget +{ + Q_DECLARE_TR_FUNCTIONS(QmakeProjectManager::Internal::QmakeSettingsPage) +public: + SettingsWidget() + { + m_warnAgainstUnalignedBuildDirCheckbox.setText(tr("Warn if a project's source and " + "build directories are not at the same level")); + m_warnAgainstUnalignedBuildDirCheckbox.setToolTip(tr("Qmake has subtle bugs that " + "can be triggered if source and build directory are not at the same level.")); + m_warnAgainstUnalignedBuildDirCheckbox.setChecked( + QmakeSettings::warnAgainstUnalignedBuildDir()); + m_alwaysRunQmakeCheckbox.setText(tr("Run qmake on every build")); + m_alwaysRunQmakeCheckbox.setToolTip(tr("This option can help to prevent failures on " + "incremental builds, but might slow them down unnecessarily in the general case.")); + m_alwaysRunQmakeCheckbox.setChecked(QmakeSettings::alwaysRunQmake()); + const auto layout = new QVBoxLayout(this); + layout->addWidget(&m_warnAgainstUnalignedBuildDirCheckbox); + layout->addWidget(&m_alwaysRunQmakeCheckbox); + layout->addStretch(1); + } + + void apply() + { + QmakeSettingsData settings; + settings.warnAgainstUnalignedBuildDir = m_warnAgainstUnalignedBuildDirCheckbox.isChecked(); + settings.alwaysRunQmake = m_alwaysRunQmakeCheckbox.isChecked(); + QmakeSettings::setSettingsData(settings); + } + +private: + QCheckBox m_warnAgainstUnalignedBuildDirCheckbox; + QCheckBox m_alwaysRunQmakeCheckbox; +}; + +QmakeSettingsPage::QmakeSettingsPage() +{ + setId("K.QmakeProjectManager.QmakeSettings"); + setDisplayName(tr("Qmake")); + setCategory(ProjectExplorer::Constants::BUILD_AND_RUN_SETTINGS_CATEGORY); +} + +QWidget *QmakeSettingsPage::widget() +{ + if (!m_widget) + m_widget = new SettingsWidget; + return m_widget; + +} + +void QmakeSettingsPage::apply() +{ + if (m_widget) + m_widget->apply(); +} + +void QmakeSettingsPage::finish() +{ + delete m_widget; +} + +} // namespace Internal +} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.h b/src/plugins/qmakeprojectmanager/qmakesettings.h index 31eb5b7ce9..6918483595 100644 --- a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.h +++ b/src/plugins/qmakeprojectmanager/qmakesettings.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. @@ -25,29 +25,53 @@ #pragma once -#include "qtwizard.h" +#include <coreplugin/dialogs/ioptionspage.h> + +#include <QObject> +#include <QPointer> namespace QmakeProjectManager { namespace Internal { -struct GuiAppParameters; +class QmakeSettingsData { +public: + bool warnAgainstUnalignedBuildDir = false; + bool alwaysRunQmake = false; +}; -class GuiAppWizard : public QtWizard +class QmakeSettings : public QObject { Q_OBJECT - public: - GuiAppWizard(); + static QmakeSettings &instance(); + static bool warnAgainstUnalignedBuildDir(); + static bool alwaysRunQmake(); + static void setSettingsData(const QmakeSettingsData &settings); + +signals: + void settingsChanged(); private: - Core::BaseFileWizard *create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const override; + QmakeSettings(); + void loadSettings(); + void storeSettings() const; - Core::GeneratedFiles generateFiles(const QWizard *w, QString *errorMessage) const override; + QmakeSettingsData m_settings; +}; + +class QmakeSettingsPage : public Core::IOptionsPage +{ + Q_OBJECT +public: + QmakeSettingsPage(); private: - static bool parametrizeTemplate(const QString &templatePath, const QString &templateName, - const GuiAppParameters ¶ms, - QString *target, QString *errorMessage); + QWidget *widget() override; + void apply() override; + void finish() override; + + class SettingsWidget; + QPointer<SettingsWidget> m_widget; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 42f8a8fc00..104a093e4d 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -33,6 +33,7 @@ #include "qmakeparser.h" #include "qmakeproject.h" #include "qmakeprojectmanagerconstants.h" +#include "qmakesettings.h" #include <projectexplorer/buildmanager.h> #include <projectexplorer/buildsteplist.h> @@ -114,9 +115,9 @@ QString QMakeStep::allArguments(const BaseQtVersion *v, ArgumentFlags flags) con } } } - FileName specArg = mkspec(); + const QString specArg = mkspec(); if (!userProvidedMkspec && !specArg.isEmpty()) - arguments << "-spec" << specArg.toUserOutput(); + arguments << "-spec" << QDir::toNativeSeparators(specArg); // Find out what flags we pass on to qmake arguments << bc->configCommandLineArguments(); @@ -136,18 +137,18 @@ QMakeStepConfig QMakeStep::deducedArguments() const ProjectExplorer::Kit *kit = target()->kit(); QMakeStepConfig config; ProjectExplorer::ToolChain *tc - = ProjectExplorer::ToolChainKitInformation::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + = ProjectExplorer::ToolChainKitAspect::toolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); ProjectExplorer::Abi targetAbi; if (tc) { targetAbi = tc->targetAbi(); if (HostOsInfo::isWindowsHost() && tc->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) { - config.sysRoot = ProjectExplorer::SysRootKitInformation::sysRoot(kit).toString(); + config.sysRoot = ProjectExplorer::SysRootKitAspect::sysRoot(kit).toString(); config.targetTriple = tc->originalTargetTriple(); } } - BaseQtVersion *version = QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *version = QtKitAspect::qtVersion(target()->kit()); config.archConfig = QMakeStepConfig::targetArchFor(targetAbi, version); config.osType = QMakeStepConfig::osTypeFor(targetAbi, version); @@ -167,7 +168,7 @@ bool QMakeStep::init() { m_wasSuccess = true; QmakeBuildConfiguration *qmakeBc = qmakeBuildConfiguration(); - const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(target()->kit()); + const BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit()); if (!qtVersion) { emit addOutput(tr("No Qt version configured."), BuildStep::OutputFormat::ErrorMessage); @@ -181,7 +182,7 @@ bool QMakeStep::init() else workingDirectory = qmakeBc->buildDirectory().toString(); - m_qmakeExecutable = qtVersion->qmakeCommand().toString(); + m_qmakeExecutable = qtVersion->qmakeCommand(); m_qmakeArguments = allArguments(qtVersion); m_runMakeQmake = (qtVersion->qtVersion() >= QtVersionNumber(5, 0 ,0)); @@ -214,14 +215,15 @@ bool QMakeStep::init() } // Check whether we need to run qmake - bool makefileOutDated = (qmakeBc->compareToImportFrom(makefile) != QmakeBuildConfiguration::MakefileMatches); - if (m_forced || makefileOutDated) + if (m_forced || QmakeSettings::alwaysRunQmake() + || qmakeBc->compareToImportFrom(makefile) != QmakeBuildConfiguration::MakefileMatches) { m_needToRunQMake = true; + } m_forced = false; ProcessParameters *pp = processParameters(); pp->setMacroExpander(qmakeBc->macroExpander()); - pp->setWorkingDirectory(workingDirectory); + pp->setWorkingDirectory(Utils::FilePath::fromString(workingDirectory)); pp->setEnvironment(qmakeBc->environment()); setOutputParser(new QMakeParser); @@ -232,7 +234,7 @@ bool QMakeStep::init() QTC_ASSERT(node, return false); QString proFile = node->filePath().toString(); - QList<ProjectExplorer::Task> tasks = qtVersion->reportIssues(proFile, workingDirectory); + Tasks tasks = qtVersion->reportIssues(proFile, workingDirectory); Utils::sort(tasks); if (!tasks.isEmpty()) { @@ -309,7 +311,7 @@ void QMakeStep::finish(bool success) runNextCommand(); } -void QMakeStep::startOneCommand(const QString &command, const QString &args) +void QMakeStep::startOneCommand(const FilePath &command, const QString &args) { ProcessParameters *pp = processParameters(); pp->setCommand(command); @@ -341,7 +343,7 @@ void QMakeStep::runNextCommand() case State::RUN_MAKE_QMAKE_ALL: { auto *parser = new GnuMakeParser; - parser->setWorkingDirectory(processParameters()->workingDirectory()); + parser->setWorkingDirectory(processParameters()->workingDirectory().toString()); setOutputParser(parser); m_nextState = State::POST_PROCESS; startOneCommand(m_makeExecutable, m_makeArguments); @@ -434,10 +436,10 @@ void QMakeStep::setSeparateDebugInfo(bool enable) qmakeBuildConfiguration()->emitProFileEvaluateNeeded(); } -QString QMakeStep::makeCommand() const +FilePath QMakeStep::makeCommand() const { - auto *ms = qobject_cast<BuildStepList *>(parent())->firstOfType<MakeStep>(); - return ms ? ms->effectiveMakeCommand() : QString(); + auto ms = qobject_cast<BuildStepList *>(parent())->firstOfType<MakeStep>(); + return ms ? ms->effectiveMakeCommand() : FilePath(); } QString QMakeStep::makeArguments(const QString &makefile) const @@ -453,11 +455,11 @@ QString QMakeStep::makeArguments(const QString &makefile) const QString QMakeStep::effectiveQMakeCall() const { - BaseQtVersion *qtVersion = QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit()); QString qmake = qtVersion ? qtVersion->qmakeCommand().toUserOutput() : QString(); if (qmake.isEmpty()) qmake = tr("<no Qt version>"); - QString make = makeCommand(); + QString make = makeCommand().toString(); if (make.isEmpty()) make = tr("<no Make step found>"); @@ -475,7 +477,7 @@ QString QMakeStep::effectiveQMakeCall() const QStringList QMakeStep::parserArguments() { QStringList result; - BaseQtVersion *qt = QtKitInformation::qtVersion(target()->kit()); + BaseQtVersion *qt = QtKitAspect::qtVersion(target()->kit()); QTC_ASSERT(qt, return QStringList()); for (QtcProcess::ConstArgIterator ait(allArguments(qt, ArgumentFlag::Expand)); ait.next(); ) { if (ait.isSimple()) @@ -489,18 +491,18 @@ QString QMakeStep::userArguments() return m_userArgs; } -FileName QMakeStep::mkspec() const +QString QMakeStep::mkspec() const { QString additionalArguments = m_userArgs; QtcProcess::addArgs(&additionalArguments, m_extraArgs); for (QtcProcess::ArgIterator ait(&additionalArguments); ait.next(); ) { if (ait.value() == "-spec") { if (ait.next()) - return FileName::fromUserInput(ait.value()); + return FilePath::fromUserInput(ait.value()).toString(); } } - return QmakeProjectManager::QmakeKitInformation::effectiveMkspec(target()->kit()); + return QmakeKitAspect::effectiveMkspec(target()->kit()); } QVariantMap QMakeStep::toMap() const @@ -562,7 +564,7 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step) connect(m_ui->qmakeAdditonalArgumentsLineEdit, &QLineEdit::textEdited, this, &QMakeStepConfigWidget::qmakeArgumentsLineEdited); connect(m_ui->buildConfigurationComboBox, - static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), + QOverload<int>::of(&QComboBox::currentIndexChanged), this, &QMakeStepConfigWidget::buildConfigurationSelected); connect(m_ui->qmlDebuggingLibraryCheckBox, &QCheckBox::toggled, this, &QMakeStepConfigWidget::linkQmlDebuggingLibraryChecked); @@ -589,8 +591,6 @@ QMakeStepConfigWidget::QMakeStepConfigWidget(QMakeStep *step) connect(step->qmakeBuildConfiguration(), &QmakeBuildConfiguration::qmakeBuildConfigurationChanged, this, &QMakeStepConfigWidget::qmakeBuildConfigChanged); connect(step->target(), &Target::kitChanged, this, &QMakeStepConfigWidget::qtVersionChanged); - connect(QtVersionManager::instance(), &QtVersionManager::dumpUpdatedFor, - this, &QMakeStepConfigWidget::qtVersionChanged); auto chooser = new Core::VariableChooser(m_ui->qmakeAdditonalArgumentsLineEdit); chooser->addMacroExpanderProvider([step] { return step->macroExpander(); }); chooser->addSupportedWidget(m_ui->qmakeAdditonalArgumentsLineEdit); @@ -744,7 +744,7 @@ void QMakeStepConfigWidget::separateDebugInfoChecked(bool checked) void QMakeStepConfigWidget::updateSummaryLabel() { - BaseQtVersion *qtVersion = QtKitInformation::qtVersion(m_step->target()->kit()); + BaseQtVersion *qtVersion = QtKitAspect::qtVersion(m_step->target()->kit()); if (!qtVersion) { setSummaryText(tr("<b>qmake:</b> No Qt version set. Cannot run qmake.")); return; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.h b/src/plugins/qmakeprojectmanager/qmakestep.h index a0124dc9bb..90fef01d35 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.h +++ b/src/plugins/qmakeprojectmanager/qmakestep.h @@ -26,14 +26,13 @@ #pragma once #include "qmakeprojectmanager_global.h" + #include <projectexplorer/abstractprocessstep.h> -#include <QStringList> +#include <utils/fileutils.h> #include <memory> -namespace Utils { class FileName; } - namespace ProjectExplorer { class Abi; class BuildStep; @@ -137,7 +136,7 @@ public: // QMake extra arguments. Not user editable. QStringList extraArguments() const; void setExtraArguments(const QStringList &args); - Utils::FileName mkspec() const; + QString mkspec() const; bool linkQmlDebuggingLibrary() const; void setLinkQmlDebuggingLibrary(bool enable); bool useQtQuickCompiler() const; @@ -145,7 +144,7 @@ public: bool separateDebugInfo() const; void setSeparateDebugInfo(bool enable); - QString makeCommand() const; + Utils::FilePath makeCommand() const; QString makeArguments(const QString &makefile) const; QString effectiveQMakeCall() const; @@ -167,12 +166,12 @@ private: void doCancel() override; void finish(bool success) override; - void startOneCommand(const QString &command, const QString &args); + void startOneCommand(const Utils::FilePath &command, const QString &args); void runNextCommand(); - QString m_qmakeExecutable; + Utils::FilePath m_qmakeExecutable; QString m_qmakeArguments; - QString m_makeExecutable; + Utils::FilePath m_makeExecutable; QString m_makeArguments; QString m_userArgs; // Extra arguments for qmake. diff --git a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp deleted file mode 100644 index 08b7514a8e..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/guiappwizard.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "guiappwizard.h" - -#include "guiappwizarddialog.h" - -#include <projectexplorer/projectexplorerconstants.h> -#include <cpptools/abstracteditorsupport.h> -#include <designer/cpp/formclasswizardparameters.h> -#include <extensionsystem/pluginmanager.h> -#include <extensionsystem/invoker.h> -#include <qtsupport/qtsupportconstants.h> - -#include <utils/fileutils.h> - -#include <QCoreApplication> -#include <QDir> -#include <QTextStream> -#include <QSharedPointer> - -static const char mainSourceFileC[] = "main"; -static const char mainSourceShowC[] = " w.show();\n"; -static const char mainSourceMobilityShowC[] = " w.show();\n"; - -static const char mainWindowUiContentsC[] = -"\n <widget class=\"QMenuBar\" name=\"menuBar\" />" -"\n <widget class=\"QToolBar\" name=\"mainToolBar\" />" -"\n <widget class=\"QWidget\" name=\"centralWidget\" />" -"\n <widget class=\"QStatusBar\" name=\"statusBar\" />"; -static const char mainWindowMobileUiContentsC[] = -"\n <widget class=\"QWidget\" name=\"centralWidget\" />"; - -static const char *baseClassesC[] = {"QMainWindow", "QWidget", "QDialog"}; - -static inline QStringList baseClasses() -{ - QStringList rc; - for (auto baseClass : baseClassesC) - rc.push_back(QLatin1String(baseClass)); - return rc; -} - -namespace QmakeProjectManager { -namespace Internal { - -GuiAppWizard::GuiAppWizard() -{ - setId("C.Qt4Gui"); - setCategory(QLatin1String(ProjectExplorer::Constants::QT_APPLICATION_WIZARD_CATEGORY)); - setDisplayCategory(QCoreApplication::translate("ProjectExplorer", - ProjectExplorer::Constants::QT_APPLICATION_WIZARD_CATEGORY_DISPLAY)); - setDisplayName(tr("Qt Widgets Application")); - setDescription(tr("Creates a Qt application for the desktop. " - "Includes a Qt Designer-based main window.\n\n" - "Preselects a desktop Qt for building the application if available.")); - setIcon(QIcon(QLatin1String(":/wizards/images/gui.png"))); - setRequiredFeatures({QtSupport::Constants::FEATURE_QWIDGETS}); -} - -Core::BaseFileWizard *GuiAppWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const -{ - GuiAppWizardDialog *dialog = new GuiAppWizardDialog(this, displayName(), icon(), parent, parameters); - dialog->setProjectName(GuiAppWizardDialog::uniqueProjectName(parameters.defaultPath())); - // Order! suffixes first to generate files correctly - dialog->setLowerCaseFiles(QtWizard::lowerCaseFiles()); - dialog->setSuffixes(headerSuffix(), sourceSuffix(), formSuffix()); - dialog->setBaseClasses(baseClasses()); - return dialog; -} - -// Use the class generation utils provided by the designer plugin -static inline bool generateFormClass(const GuiAppParameters ¶ms, - const Core::GeneratedFile &uiFile, - Core::GeneratedFile *formSource, - Core::GeneratedFile *formHeader, - QString *errorMessage) -{ - // Retrieve parameters from settings - Designer::FormClassWizardParameters fp; - fp.uiTemplate = uiFile.contents(); - fp.uiFile = uiFile.path(); - fp.className = params.className; - fp.sourceFile = params.sourceFileName; - fp.headerFile = params.headerFileName; - fp.usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce(); - QString headerContents; - QString sourceContents; - // Invoke code generation service of Qt Designer plugin. - if (QObject *codeGenerator = ExtensionSystem::PluginManager::getObjectByName("QtDesignerFormClassCodeGenerator")) { - const QVariant code = ExtensionSystem::invoke<QVariant>(codeGenerator, "generateFormClassCode", fp); - if (code.type() == QVariant::List) { - const QVariantList vl = code.toList(); - if (vl.size() == 2) { - headerContents = vl.front().toString(); - sourceContents = vl.back().toString(); - } - } - } - if (headerContents.isEmpty() || sourceContents.isEmpty()) { - *errorMessage = QString::fromLatin1("Failed to obtain Designer plugin code generation service."); - return false; - } - - formHeader->setContents(headerContents); - formSource->setContents(sourceContents); - return true; -} - -Core::GeneratedFiles GuiAppWizard::generateFiles(const QWizard *w, - QString *errorMessage) const -{ - const auto *dialog = qobject_cast<const GuiAppWizardDialog *>(w); - const QtProjectParameters projectParams = dialog->projectParameters(); - const QString projectPath = projectParams.projectPath(); - const GuiAppParameters params = dialog->parameters(); - - // Generate file names. Note that the path for the project files is the - // newly generated project directory. - const QString templatePath = templateDir(); - // Create files: main source - QString contents; - const QString mainSourceFileName = buildFileName(projectPath, QLatin1String(mainSourceFileC), sourceSuffix()); - Core::GeneratedFile mainSource(mainSourceFileName); - if (!parametrizeTemplate(templatePath, QLatin1String("main.cpp"), params, &contents, errorMessage)) - return Core::GeneratedFiles(); - mainSource.setContents(CppTools::AbstractEditorSupport::licenseTemplate(mainSourceFileName) - + contents); - // Create files: form source with or without form - const QString formSourceFileName = buildFileName(projectPath, params.sourceFileName, sourceSuffix()); - const QString formHeaderName = buildFileName(projectPath, params.headerFileName, headerSuffix()); - Core::GeneratedFile formSource(formSourceFileName); - Core::GeneratedFile formHeader(formHeaderName); - formSource.setAttributes(Core::GeneratedFile::OpenEditorAttribute); - - QSharedPointer<Core::GeneratedFile> form; - if (params.designerForm) { - // Create files: form - const QString formName = buildFileName(projectPath, params.formFileName, formSuffix()); - form = QSharedPointer<Core::GeneratedFile>(new Core::GeneratedFile(formName)); - if (!parametrizeTemplate(templatePath, QLatin1String("widget.ui"), params, &contents, errorMessage)) - return Core::GeneratedFiles(); - form->setContents(contents); - if (!generateFormClass(params, *form, &formSource, &formHeader, errorMessage)) - return Core::GeneratedFiles(); - } else { - const QString formSourceTemplate = QLatin1String("mywidget.cpp"); - if (!parametrizeTemplate(templatePath, formSourceTemplate, params, &contents, errorMessage)) - return Core::GeneratedFiles(); - formSource.setContents(CppTools::AbstractEditorSupport::licenseTemplate(formSourceFileName) - + contents); - // Create files: form header - const QString formHeaderTemplate = QLatin1String("mywidget.h"); - if (!parametrizeTemplate(templatePath, formHeaderTemplate, params, &contents, errorMessage)) - return Core::GeneratedFiles(); - formHeader.setContents(CppTools::AbstractEditorSupport::licenseTemplate(formHeaderName) - + contents); - } - // Create files: profile - const QString profileName = buildFileName(projectPath, projectParams.fileName, profileSuffix()); - Core::GeneratedFile profile(profileName); - profile.setAttributes(Core::GeneratedFile::OpenProjectAttribute); - contents.clear(); - { - QTextStream proStr(&contents); - QtProjectParameters::writeProFileHeader(proStr); - projectParams.writeProFile(proStr); - proStr << "\nCONFIG += c++11"; // ensure all Qt5 versions can handle the source - proStr << "\n\nSOURCES +=" - << " \\\n " << Utils::FileName::fromString(mainSourceFileName).fileName() - << " \\\n " << Utils::FileName::fromString(formSource.path()).fileName() - << "\n\nHEADERS +=" - << " \\\n " << Utils::FileName::fromString(formHeader.path()).fileName(); - if (params.designerForm) - proStr << "\n\nFORMS +=" - << " \\\n " << Utils::FileName::fromString(form->path()).fileName(); - if (params.isMobileApplication) { - proStr << "\n\nCONFIG += mobility" - << "\nMOBILITY = " - << "\n"; - } - proStr << "\n\n# Default rules for deployment.\n" - "qnx: target.path = /tmp/$${TARGET}/bin\n" - "else: unix:!android: target.path = /opt/$${TARGET}/bin\n" - "!isEmpty(target.path): INSTALLS += target\n"; - } - profile.setContents(contents); - // List - Core::GeneratedFiles rc; - rc << mainSource << formSource << formHeader; - if (params.designerForm) - rc << *form; - rc << profile; - return rc; -} - -bool GuiAppWizard::parametrizeTemplate(const QString &templatePath, const QString &templateName, - const GuiAppParameters ¶ms, - QString *target, QString *errorMessage) -{ - const QString fileName = templatePath + QLatin1Char('/') + templateName; - Utils::FileReader reader; - if (!reader.fetch(fileName, QIODevice::Text, errorMessage)) - return false; - QString contents = QString::fromUtf8(reader.data()); - contents.replace(QLatin1String("%QAPP_INCLUDE%"), QLatin1String("QApplication")); - contents.replace(QLatin1String("%INCLUDE%"), params.headerFileName); - contents.replace(QLatin1String("%CLASS%"), params.className); - contents.replace(QLatin1String("%BASECLASS%"), params.baseClassName); - contents.replace(QLatin1String("%WIDGET_HEIGHT%"), QString::number(params.widgetHeight)); - contents.replace(QLatin1String("%WIDGET_WIDTH%"), QString::number(params.widgetWidth)); - if (params.isMobileApplication) - contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceMobilityShowC)); - else - contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceShowC)); - - // Replace include guards with pragma once - if (CppTools::AbstractEditorSupport::usePragmaOnce()) { - contents.replace(QLatin1String("#ifndef %PRE_DEF%\n#define %PRE_DEF%"), "#pragma once"); - contents.replace(QLatin1String("#endif // %PRE_DEF%\n"), QString()); - } - - const QChar dot = QLatin1Char('.'); - - QString preDef = params.headerFileName.toUpper(); - preDef.replace(dot, QLatin1Char('_')); - contents.replace(QLatin1String("%PRE_DEF%"), preDef); - - const QString uiFileName = params.formFileName; - QString uiHdr = QLatin1String("ui_"); - uiHdr += uiFileName.left(uiFileName.indexOf(dot)); - uiHdr += QLatin1String(".h"); - - contents.replace(QLatin1String("%UI_HDR%"), uiHdr); - if (params.baseClassName == QLatin1String("QMainWindow")) { - if (params.isMobileApplication) - contents.replace(QLatin1String("%CENTRAL_WIDGET%"), QLatin1String(mainWindowMobileUiContentsC)); - else - contents.replace(QLatin1String("%CENTRAL_WIDGET%"), QLatin1String(mainWindowUiContentsC)); - } else { - contents.remove(QLatin1String("%CENTRAL_WIDGET%")); - } - *target = contents; - return true; -} - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/guiappwizarddialog.cpp b/src/plugins/qmakeprojectmanager/wizards/guiappwizarddialog.cpp deleted file mode 100644 index 5f12fdc41a..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/guiappwizarddialog.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "guiappwizarddialog.h" - -#include "filespage.h" - -#include <projectexplorer/projectexplorerconstants.h> - -namespace QmakeProjectManager { -namespace Internal { - -GuiAppWizardDialog::GuiAppWizardDialog(const Core::BaseFileWizardFactory *factory, - const QString &templateName, - const QIcon &icon, QWidget *parent, - const Core::WizardDialogParameters ¶meters) : - BaseQmakeProjectWizardDialog(factory, false, parent, parameters), - m_filesPage(new FilesPage) -{ - setWindowIcon(icon); - setWindowTitle(templateName); - setSelectedModules(QLatin1String("core gui"), true); - - setIntroDescription(tr("This wizard generates a Qt Widgets Application " - "project. The application derives by default from QApplication " - "and includes an empty widget.")); - - addModulesPage(); - if (!parameters.extraValues().contains(QLatin1String(ProjectExplorer::Constants::PROJECT_KIT_IDS))) - addTargetSetupPage(); - - m_filesPage->setFormInputCheckable(true); - m_filesPage->setClassTypeComboVisible(false); - addPage(m_filesPage); - - addExtensionPages(extensionPages()); -} - -void GuiAppWizardDialog::setBaseClasses(const QStringList &baseClasses) -{ - m_filesPage->setBaseClassChoices(baseClasses); - if (!baseClasses.empty()) - m_filesPage->setBaseClassName(baseClasses.front()); -} - -void GuiAppWizardDialog::setSuffixes(const QString &header, const QString &source, const QString &form) -{ - m_filesPage->setSuffixes(header, source, form); -} - -void GuiAppWizardDialog::setLowerCaseFiles(bool l) -{ - m_filesPage->setLowerCaseFiles(l); -} - -QtProjectParameters GuiAppWizardDialog::projectParameters() const -{ - QtProjectParameters rc; - rc.type = QtProjectParameters::GuiApp; - rc.flags |= QtProjectParameters::WidgetsRequiredFlag; - rc.fileName = projectName(); - rc.path = path(); - rc.selectedModules = selectedModulesList(); - rc.deselectedModules = deselectedModulesList(); - return rc; -} - -GuiAppParameters GuiAppWizardDialog::parameters() const -{ - GuiAppParameters rc; - rc.className = m_filesPage->className(); - rc.baseClassName = m_filesPage->baseClassName(); - rc.sourceFileName = m_filesPage->sourceFileName(); - rc.headerFileName = m_filesPage->headerFileName(); - rc.formFileName = m_filesPage->formFileName(); - rc.designerForm = m_filesPage->formInputChecked(); - if (isQtPlatformSelected("Android.Device.Type")) { // FIXME: Is this really necessary? - rc.isMobileApplication = true; - rc.widgetWidth = 800; - rc.widgetHeight = 480; - } - return rc; -} - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/guiappwizarddialog.h b/src/plugins/qmakeprojectmanager/wizards/guiappwizarddialog.h deleted file mode 100644 index b12644e123..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/guiappwizarddialog.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "qtwizard.h" - -namespace QmakeProjectManager { -namespace Internal { - -struct QtProjectParameters; -class FilesPage; - -// Additional parameters required besides QtProjectParameters -struct GuiAppParameters -{ - QString className; - QString baseClassName; - QString sourceFileName; - QString headerFileName; - QString formFileName; - int widgetWidth = 400; - int widgetHeight = 300; - bool designerForm = true; - bool isMobileApplication = false; -}; - -class GuiAppWizardDialog : public BaseQmakeProjectWizardDialog -{ - Q_OBJECT - -public: - explicit GuiAppWizardDialog(const Core::BaseFileWizardFactory *factory, const QString &templateName, - const QIcon &icon, - QWidget *parent, - const Core::WizardDialogParameters ¶meters); - - void setBaseClasses(const QStringList &baseClasses); - void setSuffixes(const QString &header, const QString &source, const QString &form); - void setLowerCaseFiles(bool l); - - QtProjectParameters projectParameters() const; - GuiAppParameters parameters() const; - -private: - FilesPage *m_filesPage; -}; - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/libraryparameters.cpp b/src/plugins/qmakeprojectmanager/wizards/libraryparameters.cpp deleted file mode 100644 index 83217ce2bf..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/libraryparameters.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "libraryparameters.h" -#include "librarywizarddialog.h" - -#include <utils/codegeneration.h> -#include <utils/qtcassert.h> - -#include <QTextStream> -#include <QStringList> - -#include <cstring> - -namespace QmakeProjectManager { -namespace Internal { - -void LibraryParameters::generateCode(QtProjectParameters:: Type t, - const QString &headerName, - const QString &sharedHeader, - const QString &exportMacro, - const QString &pluginJsonFileName, - int indentation, - bool usePragmaOnce, - QString *header, - QString *source) const -{ - QTextStream headerStr(header); - - const QString indent = QString(indentation, QLatin1Char(' ')); - - // Do we have namespaces? - QStringList namespaceList = className.split(QLatin1String("::")); - if (namespaceList.empty()) // Paranoia! - return; - - const QString unqualifiedClassName = namespaceList.takeLast(); - - // 1) Header - const QString guard = Utils::headerGuard(headerFileName, namespaceList); - if (usePragmaOnce) - headerStr << "#pragma once\n\n"; - else - headerStr << "#ifndef " << guard << "\n#define " << guard << "\n\n"; - - if (!sharedHeader.isEmpty()) - Utils::writeIncludeFileDirective(sharedHeader, false, headerStr); - - // include base class header - if (!baseClassName.isEmpty()) { - Utils::writeIncludeFileDirective(baseClassName, true, headerStr); - headerStr << '\n'; - } - - const QString namespaceIndent = Utils::writeOpeningNameSpaces(namespaceList, indent, headerStr); - - // Class declaraction - if (!namespaceIndent.isEmpty()) - headerStr << '\n'; - headerStr << namespaceIndent << "class "; - if (t == QtProjectParameters::SharedLibrary && !exportMacro.isEmpty()) - headerStr << exportMacro << ' '; - - headerStr << unqualifiedClassName; - if (!baseClassName.isEmpty()) - headerStr << " : public " << baseClassName; - headerStr << "\n{\n"; - - // Is this a QObject (plugin) - const bool inheritsQObject = t == QtProjectParameters::QtPlugin; - if (inheritsQObject) - headerStr << namespaceIndent << indent << "Q_OBJECT\n"; - if (t == QtProjectParameters::QtPlugin) { // Write Qt plugin meta data. - const QString qt5InterfaceName = LibraryWizardDialog::pluginInterface(baseClassName); - QTC_CHECK(!qt5InterfaceName.isEmpty()); - headerStr << namespaceIndent << indent << "Q_PLUGIN_METADATA(IID \"" - << qt5InterfaceName << '"'; - QTC_CHECK(!pluginJsonFileName.isEmpty()); - headerStr << " FILE \"" << pluginJsonFileName << '"'; - headerStr << ")\n"; - } - - headerStr << namespaceIndent << "\npublic:\n"; - if (inheritsQObject) { - headerStr << namespaceIndent << indent << "explicit " << unqualifiedClassName - << "(QObject *parent = nullptr);\n"; - } else { - headerStr << namespaceIndent << indent << unqualifiedClassName << "();\n"; - } - if (!pureVirtualSignatures.empty()) { - headerStr << "\nprivate:\n"; - for (const QString &signature : pureVirtualSignatures) - headerStr << namespaceIndent << indent << signature << " override;\n"; - } - headerStr << namespaceIndent << "};\n"; - if (!namespaceIndent.isEmpty()) - headerStr << '\n'; - Utils::writeClosingNameSpaces(namespaceList, indent, headerStr); - if (!usePragmaOnce) - headerStr << "\n#endif // " << guard << '\n'; - - /// 2) Source - QTextStream sourceStr(source); - - Utils::writeIncludeFileDirective(headerName, false, sourceStr); - sourceStr << '\n'; - - Utils::writeOpeningNameSpaces(namespaceList, indent, sourceStr); - if (!namespaceIndent.isEmpty()) - sourceStr << '\n'; - - // Constructor - sourceStr << namespaceIndent << unqualifiedClassName << "::" << unqualifiedClassName; - if (inheritsQObject) { - sourceStr << "(QObject *parent) :\n" - << namespaceIndent << indent << baseClassName << "(parent)\n"; - } else { - sourceStr << "()\n"; - } - sourceStr << namespaceIndent << "{\n" << namespaceIndent << "}\n"; - for (const QString &signature : pureVirtualSignatures) { - const int parenIndex = signature.indexOf('('); - QTC_ASSERT(parenIndex != -1, continue); - int nameIndex = -1; - for (int i = parenIndex - 1; i > 0; --i) { - if (!signature.at(i).isLetterOrNumber()) { - nameIndex = i + 1; - break; - } - } - QTC_ASSERT(nameIndex != -1, continue); - sourceStr << '\n' << namespaceIndent << signature.left(nameIndex); - if (!std::strchr("&* ", signature.at(nameIndex - 1).toLatin1())) - sourceStr << ' '; - sourceStr << unqualifiedClassName << "::" << signature.mid(nameIndex) << '\n'; - sourceStr << namespaceIndent << "{\n" << indent - << "static_assert(false, \"You need to implement this function\");\n}\n"; - } - - Utils::writeClosingNameSpaces(namespaceList, indent, sourceStr); -} - -QString LibraryParameters::generateSharedHeader(const QString &globalHeaderFileName, - const QString &projectTarget, - const QString &exportMacro, - bool usePragmaOnce) -{ - QString contents; - if (usePragmaOnce) { - contents += "#pragma once\n"; - } else { - contents += "#ifndef " + Utils::headerGuard(globalHeaderFileName) + "\n"; - contents += "#define " + Utils::headerGuard(globalHeaderFileName) + "\n"; - } - contents += "\n"; - contents += "#include <QtCore/qglobal.h>\n"; - contents += "\n"; - contents += "#if defined(" + QtProjectParameters::libraryMacro(projectTarget) + ")\n"; - contents += "# define " + exportMacro + " Q_DECL_EXPORT\n"; - contents += "#else\n"; - contents += "# define " + exportMacro + " Q_DECL_IMPORT\n"; - contents += "#endif\n"; - contents += "\n"; - if (!usePragmaOnce) - contents += "#endif // " + Utils::headerGuard(globalHeaderFileName) + '\n'; - - return contents; -} - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/libraryparameters.h b/src/plugins/qmakeprojectmanager/wizards/libraryparameters.h deleted file mode 100644 index 4fe7d00dc1..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/libraryparameters.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "qtprojectparameters.h" - -#include <QStringList> - -namespace QmakeProjectManager { -namespace Internal { - -// Additional parameters required besides QtProjectParameters for creating -// libraries -struct LibraryParameters { - - // generate class - void generateCode(QtProjectParameters:: Type t, - const QString &headerName, - const QString &sharedHeader, - const QString &exportMacro, - const QString &pluginJsonFileName, - int indentation, - bool usePragmaOnce, - QString *header, - QString *source) const; - - // Generate the code of the shared header containing the export macro - static QString generateSharedHeader(const QString &globalHeaderFileName, - const QString &projectTarget, - const QString &exportMacro, - bool usePragmaOnce); - - QString className; - QString baseClassName; - QString sourceFileName; - QString headerFileName; - QStringList pureVirtualSignatures; -}; - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp b/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp deleted file mode 100644 index 239fec9c3f..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/librarywizard.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "librarywizard.h" -#include "librarywizarddialog.h" - -#include <cpptools/abstracteditorsupport.h> -#include <projectexplorer/projectexplorerconstants.h> -#include <qtsupport/qtsupportconstants.h> - -#include <utils/fileutils.h> - -#include <QTextStream> -#include <QCoreApplication> - -static const char sharedHeaderPostfixC[] = "_global"; - -namespace QmakeProjectManager { -namespace Internal { - -LibraryWizard::LibraryWizard() -{ - setId("H.Qt4Library"); - setCategory(QLatin1String(ProjectExplorer::Constants::LIBRARIES_WIZARD_CATEGORY)); - setDisplayCategory(QCoreApplication::translate("ProjectExplorer", - ProjectExplorer::Constants::LIBRARIES_WIZARD_CATEGORY_DISPLAY)); - setDisplayName(tr("C++ Library")); - setDescription(tr("Creates a C++ library based on qmake. This can be used to create:<ul>" - "<li>a shared C++ library for use with <tt>QPluginLoader</tt> and runtime (Plugins)</li>" - "<li>a shared or static C++ library for use with another project at linktime</li></ul>")); - setIcon(QIcon(QLatin1String(":/wizards/images/lib.png"))); - setRequiredFeatures({QtSupport::Constants::FEATURE_QT_PREFIX}); -} - -Core::BaseFileWizard *LibraryWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const -{ - LibraryWizardDialog *dialog = new LibraryWizardDialog(this, displayName(), icon(), parent, parameters); - dialog->setLowerCaseFiles(QtWizard::lowerCaseFiles()); - dialog->setProjectName(LibraryWizardDialog::uniqueProjectName(parameters.defaultPath())); - dialog->setSuffixes(headerSuffix(), sourceSuffix(), formSuffix()); - return dialog; -} - -static void writeLinuxProFile(QTextStream &str, const QtProjectParameters ¶ms) -{ - str << "\n" - "unix {\n"; - if (!params.targetDirectory.isEmpty()) - str << " target.path = " << params.targetDirectory << '\n'; - else - str << " target.path = /usr/lib\n"; - str << " INSTALLS += target\n" - "}\n"; -} - -Core::GeneratedFiles LibraryWizard::generateFiles(const QWizard *w, - QString *errorMessage) const -{ - Q_UNUSED(errorMessage) - const auto *dialog = qobject_cast<const LibraryWizardDialog *>(w); - const QtProjectParameters projectParams = dialog->parameters(); - const QString projectPath = projectParams.projectPath(); - const LibraryParameters params = dialog->libraryParameters(); - const bool usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce(); - - const QString sharedLibExportMacro = QtProjectParameters::exportMacro(projectParams.fileName); - - Core::GeneratedFiles rc; - // Class header + source - const QString sourceFileName = buildFileName(projectPath, params.sourceFileName, sourceSuffix()); - Core::GeneratedFile source(sourceFileName); - source.setAttributes(Core::GeneratedFile::OpenEditorAttribute); - - const QString headerFileFullName = buildFileName(projectPath, params.headerFileName, headerSuffix()); - const QString headerFileName = Utils::FileName::fromString(headerFileFullName).fileName(); - QString pluginJsonFileFullName; - QString pluginJsonFileName; - if (projectParams.type == QtProjectParameters::QtPlugin) { - pluginJsonFileFullName = buildFileName(projectPath, projectParams.fileName, QLatin1String("json")); - pluginJsonFileName = Utils::FileName::fromString(pluginJsonFileFullName).fileName(); - } - - Core::GeneratedFile header(headerFileFullName); - - // Create files: global header for shared libs - QString globalHeaderFileName; - if (projectParams.type == QtProjectParameters::SharedLibrary) { - const QString globalHeaderName = buildFileName(projectPath, projectParams.fileName.toLower() + QLatin1String(sharedHeaderPostfixC), headerSuffix()); - Core::GeneratedFile globalHeader(globalHeaderName); - globalHeaderFileName = Utils::FileName::fromString(globalHeader.path()).fileName(); - globalHeader.setContents(CppTools::AbstractEditorSupport::licenseTemplate(globalHeaderFileName) - + LibraryParameters::generateSharedHeader(globalHeaderFileName, projectParams.fileName, sharedLibExportMacro, usePragmaOnce)); - rc.push_back(globalHeader); - } - - // Generate code - QString headerContents, sourceContents; - params.generateCode(projectParams.type, headerFileName, - globalHeaderFileName, sharedLibExportMacro, pluginJsonFileName, - /* indentation*/ 4, usePragmaOnce, &headerContents, &sourceContents); - - source.setContents(CppTools::AbstractEditorSupport::licenseTemplate(sourceFileName, params.className) - + sourceContents); - header.setContents(CppTools::AbstractEditorSupport::licenseTemplate(headerFileFullName, params.className) - + headerContents); - rc.push_back(source); - rc.push_back(header); - // Create files: profile - const QString profileName = buildFileName(projectPath, projectParams.fileName, profileSuffix()); - Core::GeneratedFile profile(profileName); - profile.setAttributes(Core::GeneratedFile::OpenProjectAttribute); - QString profileContents; - { - QTextStream proStr(&profileContents); - QtProjectParameters::writeProFileHeader(proStr); - projectParams.writeProFile(proStr); - proStr << "\nSOURCES +=" - << " \\\n " << Utils::FileName::fromString(source.path()).fileName() - << "\n\nHEADERS +=" - << " \\\n " << headerFileName; - if (!globalHeaderFileName.isEmpty()) - proStr << " \\\n " << globalHeaderFileName << " \n"; - if (!pluginJsonFileName.isEmpty()) - proStr << "\nDISTFILES += " << pluginJsonFileName << " \n"; - writeLinuxProFile(proStr, projectParams); - } - profile.setContents(profileContents); - rc.push_back(profile); - - if (!pluginJsonFileName.isEmpty()) { - Core::GeneratedFile jsonFile(pluginJsonFileFullName); - jsonFile.setContents(QLatin1String("{\n \"Keys\" : [ ]\n}\n")); - rc.push_back(jsonFile); - } - return rc; -} - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/librarywizard.h b/src/plugins/qmakeprojectmanager/wizards/librarywizard.h deleted file mode 100644 index f7edeb5330..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/librarywizard.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "qtwizard.h" -#include "libraryparameters.h" - -namespace QmakeProjectManager { -namespace Internal { - -class LibraryWizard : public QtWizard -{ - Q_OBJECT - -public: - LibraryWizard(); - -protected: - Core::BaseFileWizard *create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const override; - - Core::GeneratedFiles generateFiles(const QWizard *w, QString *errorMessage) const override; -}; - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/librarywizarddialog.cpp b/src/plugins/qmakeprojectmanager/wizards/librarywizarddialog.cpp deleted file mode 100644 index 2aed6d43cd..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/librarywizarddialog.cpp +++ /dev/null @@ -1,347 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "librarywizarddialog.h" -#include "filespage.h" -#include "libraryparameters.h" -#include "modulespage.h" - -#include <utils/projectintropage.h> -#include <projectexplorer/projectexplorerconstants.h> - -#include <QDebug> - -#include <QComboBox> -#include <QLabel> - -enum { debugLibWizard = 0 }; - -namespace QmakeProjectManager { -namespace Internal { - -struct PluginBaseClasses { - const char *name; - const char *module; - QStringList pureVirtuals; - - // blank separated list or 0 - const char *dependentModules; - const char *targetDirectory; - const char *pluginInterface; -}; -using QSL = QStringList; - -static const PluginBaseClasses pluginBaseClasses[] = -{ - {"QAccessiblePlugin", "QtGui", - QSL{"QAccessibleInterface *create(const QString &key, QObject *object)"}, - "QtCore", "accessible", "QAccessibleFactoryInterface"}, - {"QGenericPlugin", "QtGui", QSL{"QObject *create(const QString &name, const QString &spec)"}, - "QtCore", "generic", "QGenericPluginFactoryInterface"}, - {"QIconEnginePlugin", "QtGui", QSL{"QIconEngine *create(const QString &filename)"}, - "QtCore", "imageformats", "QIconEngineFactoryInterface"}, - {"QImageIOPlugin", "QtGui", - QSL{"QImageIOPlugin::Capabilities capabilities(QIODevice *device, const QByteArray &format) const", - "QImageIOHandler *create(QIODevice *device, const QByteArray &format) const"}, - "QtCore", "imageformats", "QImageIOHandlerFactoryInterface"}, - {"QScriptExtensionPlugin", "QtScript", - QSL{"void initialize(const QString &key, QScriptEngine *engine)", "QStringList keys() const"}, - "QtCore", nullptr, "QScriptExtensionInterface"}, - {"QSqlDriverPlugin", "QtSql", QSL{"QSqlDriver *create(const QString &key)"}, - "QtCore", "sqldrivers", "QSqlDriverFactoryInterface"}, - {"QStylePlugin", "QtWidgets", QSL{"QStyle *create(const QString &key)"}, - "QtCore", "styles", "QStyleFactoryInterface"}, -}; - -enum { defaultPluginBaseClass = 1 }; - -static const PluginBaseClasses *findPluginBaseClass(const QString &name) -{ - const int pluginBaseClassCount = sizeof(pluginBaseClasses)/sizeof(PluginBaseClasses); - for (int i = 0; i < pluginBaseClassCount; i++) - if (name == QLatin1String(pluginBaseClasses[i].name)) - return pluginBaseClasses + i; - return nullptr; -} - -// return dependencies of a plugin as a line ready for the 'QT=' line in a pro -// file -static QStringList pluginDependencies(const PluginBaseClasses *plb) -{ - QStringList dependencies; - const QChar blank = QLatin1Char(' '); - // Find the module names and convert to ids - QStringList pluginModules= plb->dependentModules ? - QString::fromLatin1(plb->dependentModules).split(blank) : - QStringList(); - pluginModules.push_back(QLatin1String(plb->module)); - foreach (const QString &module, pluginModules) { - dependencies.append(ModulesPage::idOfModule(module)); - } - return dependencies; -} - -// A Project intro page with an additional type chooser. -class LibraryIntroPage : public Utils::ProjectIntroPage -{ -public: - explicit LibraryIntroPage(QWidget *parent = nullptr); - - QtProjectParameters::Type type() const; - -private: - QComboBox *m_typeCombo; -}; - -LibraryIntroPage::LibraryIntroPage(QWidget *parent) : - Utils::ProjectIntroPage(parent), - m_typeCombo(new QComboBox) -{ - m_typeCombo->setEditable(false); - m_typeCombo->addItem(LibraryWizardDialog::tr("Shared Library"), - QVariant(QtProjectParameters::SharedLibrary)); - m_typeCombo->addItem(LibraryWizardDialog::tr("Statically Linked Library"), - QVariant(QtProjectParameters::StaticLibrary)); - m_typeCombo->addItem(LibraryWizardDialog::tr("Qt Plugin"), - QVariant(QtProjectParameters::QtPlugin)); - insertControl(0, new QLabel(LibraryWizardDialog::tr("Type")), m_typeCombo); -} - -QtProjectParameters::Type LibraryIntroPage::type() const -{ - return static_cast<QtProjectParameters::Type>(m_typeCombo->itemData(m_typeCombo->currentIndex()).toInt()); -} - -// ------------------- LibraryWizardDialog -LibraryWizardDialog::LibraryWizardDialog(const Core::BaseFileWizardFactory *factory, - const QString &templateName, - const QIcon &icon, - QWidget *parent, - const Core::WizardDialogParameters ¶meters) : - BaseQmakeProjectWizardDialog(factory, true, new LibraryIntroPage, -1, parent, parameters), - m_filesPage(new FilesPage), - m_pluginBaseClassesInitialized(false), - m_filesPageId(-1), m_modulesPageId(-1), m_targetPageId(-1) -{ - setWindowIcon(icon); - setWindowTitle(templateName); - setSelectedModules(QLatin1String("core")); - - // Note that QWizard::currentIdChanged() is emitted at strange times. - // Use the intro page instead, set up initially - setIntroDescription(tr("This wizard generates a C++ Library project.")); - - if (!parameters.extraValues().contains(QLatin1String(ProjectExplorer::Constants::PROJECT_KIT_IDS))) - m_targetPageId = addTargetSetupPage(); - - m_modulesPageId = addModulesPage(); - - m_filesPage->setNamespacesEnabled(true); - m_filesPage->setFormFileInputVisible(false); - m_filesPage->setClassTypeComboVisible(false); - - m_filesPageId = addPage(m_filesPage); - - Utils::WizardProgressItem *introItem = wizardProgress()->item(startId()); - Utils::WizardProgressItem *targetItem = nullptr; - if (m_targetPageId != -1) - targetItem = wizardProgress()->item(m_targetPageId); - Utils::WizardProgressItem *modulesItem = wizardProgress()->item(m_modulesPageId); - Utils::WizardProgressItem *filesItem = wizardProgress()->item(m_filesPageId); - filesItem->setTitle(tr("Details")); - - if (targetItem) { - if (m_targetPageId != -1) { - targetItem->setNextItems(QList<Utils::WizardProgressItem *>() - << modulesItem << filesItem); - targetItem->setNextShownItem(nullptr); - } else { - introItem->setNextItems(QList<Utils::WizardProgressItem *>() - << modulesItem << filesItem); - introItem->setNextShownItem(nullptr); - } - } - - connect(this, &QWizard::currentIdChanged, this, &LibraryWizardDialog::slotCurrentIdChanged); - - addExtensionPages(extensionPages()); -} - -void LibraryWizardDialog::setSuffixes(const QString &header, const QString &source, const QString &form) -{ - m_filesPage->setSuffixes(header, source, form); -} - -void LibraryWizardDialog::setLowerCaseFiles(bool l) -{ - m_filesPage->setLowerCaseFiles(l); -} - -QtProjectParameters::Type LibraryWizardDialog::type() const -{ - return static_cast<const LibraryIntroPage*>(introPage())->type(); -} - -bool LibraryWizardDialog::isModulesPageSkipped() const -{ - // When leaving the intro or target page, the modules page is skipped - // in the case of a plugin since it knows its dependencies by itself. - return type() == QtProjectParameters::QtPlugin; -} - -int LibraryWizardDialog::skipModulesPageIfNeeded() const -{ - if (isModulesPageSkipped()) - return m_filesPageId; - return m_modulesPageId; -} - -int LibraryWizardDialog::nextId() const -{ - if (m_targetPageId != -1) { - if (currentId() == m_targetPageId) - return skipModulesPageIfNeeded(); - } else if (currentId() == startId()) { - return skipModulesPageIfNeeded(); - } - - return BaseQmakeProjectWizardDialog::nextId(); -} - -void LibraryWizardDialog::initializePage(int id) -{ - if (m_targetPageId != -1 && id == m_targetPageId) { - Utils::WizardProgressItem *targetsItem = wizardProgress()->item(m_targetPageId); - Utils::WizardProgressItem *modulesItem = wizardProgress()->item(m_modulesPageId); - Utils::WizardProgressItem *filesItem = wizardProgress()->item(m_filesPageId); - if (isModulesPageSkipped()) - targetsItem->setNextShownItem(filesItem); - else - targetsItem->setNextShownItem(modulesItem); - - } - BaseQmakeProjectWizardDialog::initializePage(id); -} - -void LibraryWizardDialog::cleanupPage(int id) -{ - if (m_targetPageId != -1 && id == m_targetPageId) { - Utils::WizardProgressItem *targetsItem = wizardProgress()->item(m_targetPageId); - targetsItem->setNextShownItem(nullptr); - } - BaseQmakeProjectWizardDialog::cleanupPage(id); -} - -QtProjectParameters LibraryWizardDialog::parameters() const -{ - QtProjectParameters rc; - rc.type = type(); - rc.fileName = projectName(); - rc.path = path(); - if (rc.type == QtProjectParameters::QtPlugin) { - // Plugin: Dependencies & Target directory - if (const PluginBaseClasses *plb = findPluginBaseClass(m_filesPage->baseClassName())) { - rc.selectedModules = pluginDependencies(plb); - if (plb->targetDirectory) { - rc.targetDirectory = QLatin1String("$$[QT_INSTALL_PLUGINS]/"); - rc.targetDirectory += QLatin1String(plb->targetDirectory); - } - } - } else { - // Modules from modules page - rc.selectedModules = selectedModulesList(); - rc.deselectedModules = deselectedModulesList(); - } - return rc; -} - -void LibraryWizardDialog::slotCurrentIdChanged(int id) -{ - if (debugLibWizard) - qDebug() << Q_FUNC_INFO << id; - if (id == m_filesPageId) - setupFilesPage();// Switching to files page: Set up base class accordingly (plugin) -} - -void LibraryWizardDialog::setupFilesPage() -{ - switch (type()) { - case QtProjectParameters::QtPlugin: - if (!m_pluginBaseClassesInitialized) { - if (debugLibWizard) - qDebug("initializing for plugins"); - QStringList baseClasses; - const int pluginBaseClassCount = sizeof(pluginBaseClasses)/sizeof(PluginBaseClasses); - Q_ASSERT(defaultPluginBaseClass < pluginBaseClassCount); - for (const PluginBaseClasses &pluginBaseClasse : pluginBaseClasses) - baseClasses.push_back(QLatin1String(pluginBaseClasse.name)); - m_filesPage->setBaseClassChoices(baseClasses); - m_filesPage->setBaseClassName(baseClasses.at(defaultPluginBaseClass)); - m_pluginBaseClassesInitialized = true; - } - m_filesPage->setBaseClassInputVisible(true); - break; - default: - if (!m_filesPage->isComplete()) { - // Urrm, figure out a good class name. Use project name this time - QString className = projectName(); - if (!className.isEmpty()) - className[0] = className.at(0).toUpper(); - m_filesPage->setClassName(className); - m_filesPage->setBaseClassInputVisible(false); - } - break; - } -} - -LibraryParameters LibraryWizardDialog::libraryParameters() const -{ - LibraryParameters rc; - rc.className = m_filesPage->className(); - if (type() == QtProjectParameters::QtPlugin) { - rc.baseClassName = m_filesPage->baseClassName(); - for (const PluginBaseClasses &c : pluginBaseClasses) { - if (QLatin1String(c.name) == rc.baseClassName) { - rc.pureVirtualSignatures = c.pureVirtuals; - break; - } - } - } - rc.sourceFileName = m_filesPage->sourceFileName(); - rc.headerFileName = m_filesPage->headerFileName(); - return rc; -} - -QString LibraryWizardDialog::pluginInterface(const QString &baseClass) -{ - if (const PluginBaseClasses *plb = findPluginBaseClass(baseClass)) - if (plb->pluginInterface) - return QLatin1String("org.qt-project.Qt.") + QLatin1String(plb->pluginInterface); - return QString(); -} - - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/librarywizarddialog.h b/src/plugins/qmakeprojectmanager/wizards/librarywizarddialog.h deleted file mode 100644 index 620ffe7cca..0000000000 --- a/src/plugins/qmakeprojectmanager/wizards/librarywizarddialog.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** 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 The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "qtwizard.h" - -namespace QmakeProjectManager { -namespace Internal { - -struct QtProjectParameters; -class FilesPage; -struct LibraryParameters; - -// Library wizard dialog. -class LibraryWizardDialog : public BaseQmakeProjectWizardDialog -{ - Q_OBJECT - -public: - LibraryWizardDialog(const Core::BaseFileWizardFactory *factory, const QString &templateName, - const QIcon &icon, - QWidget *parent, - const Core::WizardDialogParameters ¶meters); - - void setSuffixes(const QString &header, const QString &source, const QString &form= QString()); - void setLowerCaseFiles(bool); - - QtProjectParameters parameters() const; - LibraryParameters libraryParameters() const; - - static QString pluginInterface(const QString &baseClass); - - int nextId() const override; - -protected: - void initializePage(int id) override; - void cleanupPage(int id) override; - -private: - void slotCurrentIdChanged(int); - - QtProjectParameters::Type type() const; - void setupFilesPage(); - bool isModulesPageSkipped() const; - int skipModulesPageIfNeeded() const; - - FilesPage *m_filesPage; - bool m_pluginBaseClassesInitialized; - int m_filesPageId; - int m_modulesPageId; - int m_targetPageId; -}; - -} // namespace Internal -} // namespace QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp index 9a4b97a0b7..0e9cd877a5 100644 --- a/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp @@ -205,11 +205,11 @@ int BaseQmakeProjectWizardDialog::addTargetSetupPage(int id) const Core::Id platform = selectedPlatform(); QSet<Core::Id> features = {QtSupport::Constants::FEATURE_DESKTOP}; if (!platform.isValid()) - m_targetSetupPage->setPreferredKitPredicate(QtKitInformation::qtVersionPredicate(features)); + m_targetSetupPage->setPreferredKitPredicate(QtKitAspect::qtVersionPredicate(features)); else - m_targetSetupPage->setPreferredKitPredicate(QtKitInformation::platformPredicate(platform)); + m_targetSetupPage->setPreferredKitPredicate(QtKitAspect::platformPredicate(platform)); - m_targetSetupPage->setRequiredKitPredicate(QtKitInformation::qtVersionPredicate(requiredFeatures())); + m_targetSetupPage->setRequiredKitPredicate(QtKitAspect::qtVersionPredicate(requiredFeatures())); resize(900, 450); if (id >= 0) @@ -259,7 +259,7 @@ bool BaseQmakeProjectWizardDialog::writeUserFile(const QString &proFileName) con if (!m_targetSetupPage) return false; - QmakeProject *pro = new QmakeProject(Utils::FileName::fromString(proFileName)); + QmakeProject *pro = new QmakeProject(Utils::FilePath::fromString(proFileName)); bool success = m_targetSetupPage->setupProject(pro); if (success) pro->saveSettings(); @@ -271,7 +271,7 @@ bool BaseQmakeProjectWizardDialog::isQtPlatformSelected(Core::Id platform) const { QList<Core::Id> selectedKitList = selectedKits(); - return Utils::contains(KitManager::kits(QtKitInformation::platformPredicate(platform)), + return Utils::contains(KitManager::kits(QtKitAspect::platformPredicate(platform)), [selectedKitList](const Kit *k) { return selectedKitList.contains(k->id()); }); } diff --git a/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp index 2c1621fcb0..77c6fdd10f 100644 --- a/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/simpleprojectwizard.cpp @@ -70,8 +70,8 @@ public: bool isComplete() const override { return m_filesWidget->hasFilesSelected(); } void initializePage() override; void cleanupPage() override { m_filesWidget->cancelParsing(); } - FileNameList selectedFiles() const { return m_filesWidget->selectedFiles(); } - FileNameList selectedPaths() const { return m_filesWidget->selectedPaths(); } + FilePathList selectedFiles() const { return m_filesWidget->selectedFiles(); } + FilePathList selectedPaths() const { return m_filesWidget->selectedPaths(); } private: SimpleProjectWizardDialog *m_simpleProjectWizardDialog; @@ -117,8 +117,8 @@ public: QString path() const { return m_firstPage->path(); } void setPath(const QString &path) { m_firstPage->setPath(path); } - FileNameList selectedFiles() const { return m_secondPage->selectedFiles(); } - FileNameList selectedPaths() const { return m_secondPage->selectedPaths(); } + FilePathList selectedFiles() const { return m_secondPage->selectedFiles(); } + FilePathList selectedPaths() const { return m_secondPage->selectedPaths(); } QString projectName() const { return m_firstPage->fileName(); } FileWizardPage *m_firstPage; @@ -127,8 +127,8 @@ public: void FilesSelectionWizardPage::initializePage() { - m_filesWidget->resetModel(FileName::fromString(m_simpleProjectWizardDialog->path()), - FileNameList()); + m_filesWidget->resetModel(FilePath::fromString(m_simpleProjectWizardDialog->path()), + FilePathList()); } SimpleProjectWizard::SimpleProjectWizard() @@ -169,7 +169,7 @@ GeneratedFiles SimpleProjectWizard::generateFiles(const QWizard *w, const QDir dir(projectPath); const QString projectName = wizard->projectName(); const QString proFileName = QFileInfo(dir, projectName + ".pro").absoluteFilePath(); - const QStringList paths = Utils::transform(wizard->selectedPaths(), &FileName::toString); + const QStringList paths = Utils::transform(wizard->selectedPaths(), &FilePath::toString); MimeType headerType = Utils::mimeTypeForName("text/x-chdr"); @@ -189,7 +189,7 @@ GeneratedFiles SimpleProjectWizard::generateFiles(const QWizard *w, QString proSources = "SOURCES = \\\n"; QString proHeaders = "HEADERS = \\\n"; - for (const FileName &fileName : wizard->selectedFiles()) { + for (const FilePath &fileName : wizard->selectedFiles()) { QString source = dir.relativeFilePath(fileName.toString()); MimeType mimeType = Utils::mimeTypeForFile(fileName.toFileInfo()); if (mimeType.matchesName("text/x-chdr") || mimeType.matchesName("text/x-c++hdr")) |