diff --git a/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h index 2a3fc65e68..ff38d44ab8 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h @@ -223,7 +223,7 @@ private: if (descriptionValue.get().toString().isNotEmpty()) section.add (" description: " + descriptionValue.get().toString()); if (! section.isEmpty()) - metadata.add (section.joinIntoString (getPreferredLinefeed())); + metadata.add (section.joinIntoString (getPreferredLineFeed())); } { @@ -236,7 +236,7 @@ private: if (exportersString.isNotEmpty()) section.add (" exporters: " + exportersString); if (! section.isEmpty()) - metadata.add (section.joinIntoString (getPreferredLinefeed())); + metadata.add (section.joinIntoString (getPreferredLineFeed())); } { @@ -246,7 +246,7 @@ private: if (definesValue.get().toString().isNotEmpty()) section.add (" defines: " + definesValue.get().toString()); if (! section.isEmpty()) - metadata.add (section.joinIntoString (getPreferredLinefeed())); + metadata.add (section.joinIntoString (getPreferredLineFeed())); } { @@ -256,7 +256,7 @@ private: if (mainClassValue.get().toString().isNotEmpty()) section.add (" mainClass: " + mainClassValue.get().toString()); if (! section.isEmpty()) - metadata.add (section.joinIntoString (getPreferredLinefeed())); + metadata.add (section.joinIntoString (getPreferredLineFeed())); } { @@ -265,10 +265,10 @@ private: if (useLocalCopyValue.get()) section.add (" useLocalCopy: " + useLocalCopyValue.get().toString()); if (! section.isEmpty()) - metadata.add (section.joinIntoString (getPreferredLinefeed())); + metadata.add (section.joinIntoString (getPreferredLineFeed())); } - return metadata.joinIntoString (String (getPreferredLinefeed()) + getPreferredLinefeed()); + return metadata.joinIntoString (String (getPreferredLineFeed()) + getPreferredLineFeed()); } void createPIPFile (File fileToSave) diff --git a/extras/Projucer/Source/Application/jucer_CommandLine.cpp b/extras/Projucer/Source/Application/jucer_CommandLine.cpp index a97de85799..39de68fb09 100644 --- a/extras/Projucer/Source/Application/jucer_CommandLine.cpp +++ b/extras/Projucer/Source/Application/jucer_CommandLine.cpp @@ -31,8 +31,8 @@ #include "jucer_CommandLine.h" //============================================================================== -const char* preferredLinefeed = "\r\n"; -const char* getPreferredLinefeed() { return preferredLinefeed; } +const char* preferredLineFeed = "\r\n"; +const char* getPreferredLineFeed() { return preferredLineFeed; } //============================================================================== namespace @@ -87,6 +87,8 @@ namespace project.reset(); ConsoleApplication::fail ("Failed to load the project file: " + projectFile.getFullPathName()); } + + preferredLineFeed = project->getProjectLineFeed().toRawUTF8(); } void save (bool justSaveResources) @@ -398,7 +400,7 @@ namespace auto newText = joinLinesIntoSourceFile (lines); - if (newText != content && newText != content + getPreferredLinefeed()) + if (newText != content && newText != content + getPreferredLineFeed()) replaceFile (file, newText, options.removeTabs ? "Removing tabs in: " : "Cleaning file: "); } @@ -494,7 +496,7 @@ namespace { auto newText = joinLinesIntoSourceFile (lines); - if (newText != content && newText != content + getPreferredLinefeed()) + if (newText != content && newText != content + getPreferredLineFeed()) replaceFile (file, newText, "Fixing includes in: "); } } @@ -542,7 +544,7 @@ namespace for (int i = 0; i < text.length(); ++i) out << " << '" << String::charToString (text[i]) << "'"; - out << ";" << preferredLinefeed; + out << ";" << preferredLineFeed; } }; @@ -566,18 +568,18 @@ namespace MemoryOutputStream out; - out << "String createString()" << preferredLinefeed - << "{" << preferredLinefeed; + out << "String createString()" << preferredLineFeed + << "{" << preferredLineFeed; for (int i = 0; i < sections.size(); ++i) sections.getReference(i).writeGenerator (out); - out << preferredLinefeed - << " String result = " << getStringConcatenationExpression (rng, 0, sections.size()) << ";" << preferredLinefeed - << preferredLinefeed - << " jassert (result == " << originalText.quoted() << ");" << preferredLinefeed - << " return result;" << preferredLinefeed - << "}" << preferredLinefeed; + out << preferredLineFeed + << " String result = " << getStringConcatenationExpression (rng, 0, sections.size()) << ";" << preferredLineFeed + << preferredLineFeed + << " jassert (result == " << originalText.quoted() << ");" << preferredLineFeed + << " return result;" << preferredLineFeed + << "}" << preferredLineFeed; std::cout << out.toString() << std::endl; } @@ -635,32 +637,32 @@ namespace MemoryOutputStream header, cpp; - header << "// Auto-generated binary data by the Projucer" << preferredLinefeed - << "// Source file: " << source.getRelativePathFrom (target.getParentDirectory()) << preferredLinefeed - << preferredLinefeed; + header << "// Auto-generated binary data by the Projucer" << preferredLineFeed + << "// Source file: " << source.getRelativePathFrom (target.getParentDirectory()) << preferredLineFeed + << preferredLineFeed; cpp << header.toString(); if (target.hasFileExtension (headerFileExtensions)) { - header << "static constexpr unsigned char " << variableName << "[] =" << preferredLinefeed - << literal.toString() << preferredLinefeed - << preferredLinefeed; + header << "static constexpr unsigned char " << variableName << "[] =" << preferredLineFeed + << literal.toString() << preferredLineFeed + << preferredLineFeed; replaceFile (target, header.toString(), "Writing: "); } else if (target.hasFileExtension (cppFileExtensions)) { - header << "extern const char* " << variableName << ";" << preferredLinefeed - << "const unsigned int " << variableName << "Size = " << (int) dataSize << ";" << preferredLinefeed - << preferredLinefeed; + header << "extern const char* " << variableName << ";" << preferredLineFeed + << "const unsigned int " << variableName << "Size = " << (int) dataSize << ";" << preferredLineFeed + << preferredLineFeed; - cpp << CodeHelpers::createIncludeStatement (target.withFileExtension (".h").getFileName()) << preferredLinefeed - << preferredLinefeed - << "static constexpr unsigned char " << variableName << "_local[] =" << preferredLinefeed - << literal.toString() << preferredLinefeed - << preferredLinefeed - << "const char* " << variableName << " = (const char*) " << variableName << "_local;" << preferredLinefeed; + cpp << CodeHelpers::createIncludeStatement (target.withFileExtension (".h").getFileName()) << preferredLineFeed + << preferredLineFeed + << "static constexpr unsigned char " << variableName << "_local[] =" << preferredLineFeed + << literal.toString() << preferredLineFeed + << preferredLineFeed + << "const char* " << variableName << " = (const char*) " << variableName << "_local;" << preferredLineFeed; replaceFile (target, cpp.toString(), "Writing: "); replaceFile (target.withFileExtension (".h"), header.toString(), "Writing: "); @@ -889,7 +891,7 @@ int performCommandLine (const ArgumentList& args) return ConsoleApplication::invokeCatchingFailures ([&] () -> int { if (args.containsOption ("--lf")) - preferredLinefeed = "\n"; + preferredLineFeed = "\n"; auto command = args[0]; diff --git a/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp b/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp index 4ec4e4eebb..1777411b3a 100644 --- a/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp +++ b/extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp @@ -63,7 +63,23 @@ void SourceCodeDocument::reloadInternal() { jassert (codeDoc != nullptr); modDetector.updateHash(); - codeDoc->applyChanges (getFile().loadFileAsString()); + + auto fileContent = getFile().loadFileAsString(); + + auto lineFeed = [&]() -> const char* + { + if (fileContent.contains ("\r\n")) + return "\r\n"; + + if (fileContent.contains ("\n")) + return "\n"; + + return project->getProjectLineFeed().toRawUTF8(); + }(); + + codeDoc->setNewLineCharacters (lineFeed); + + codeDoc->applyChanges (fileContent); codeDoc->setSavePoint(); } diff --git a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp index 0c3c09f308..c5b0568e26 100644 --- a/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp +++ b/extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp @@ -513,7 +513,7 @@ bool JucerDocument::findTemplateFiles (String& headerContent, String& cppContent return true; } -static String fixLineEndings (const String& s) +static String fixLineEndings (const String& s, const char* lineFeed) { StringArray lines; lines.addLines (s); @@ -526,7 +526,7 @@ static String fixLineEndings (const String& s) lines.add (String()); - return lines.joinIntoString ("\r\n"); + return lines.joinIntoString (lineFeed); } bool JucerDocument::flushChangesToDocuments (Project* project) @@ -554,8 +554,10 @@ bool JucerDocument::flushChangesToDocuments (Project* project) generated.applyToCode (cppTemplate, headerFile.withFileExtension (".cpp"), existingCpp, project); - headerTemplate = fixLineEndings (headerTemplate); - cppTemplate = fixLineEndings (cppTemplate); + auto* lineFeed = project->getProjectLineFeed().toRawUTF8(); + + headerTemplate = fixLineEndings (headerTemplate, lineFeed); + cppTemplate = fixLineEndings (cppTemplate, lineFeed); if (header->getCodeDocument().getAllContent() != headerTemplate) header->getCodeDocument().replaceAllContent (headerTemplate); @@ -768,9 +770,9 @@ struct NewGUIComponentWizard : public NewFileWizard::Type auto& odm = ProjucerApplication::getApp().openDocumentManager; - if (auto* cpp = dynamic_cast (odm.openFile (nullptr, cppFile))) + if (auto* cpp = dynamic_cast (odm.openFile (&project, cppFile))) { - if (auto* header = dynamic_cast (odm.openFile (nullptr, headerFile))) + if (auto* header = dynamic_cast (odm.openFile (&project, headerFile))) { std::unique_ptr jucerDoc (new ComponentDocument (cpp)); diff --git a/extras/Projucer/Source/Project/jucer_Project.cpp b/extras/Projucer/Source/Project/jucer_Project.cpp index f738024fc1..51edb19db9 100644 --- a/extras/Projucer/Source/Project/jucer_Project.cpp +++ b/extras/Projucer/Source/Project/jucer_Project.cpp @@ -200,6 +200,8 @@ void Project::initialiseProjectValues() if (projectUIDValue.isUsingDefault()) projectUIDValue = projectUIDValue.getDefault(); + projectLineFeedValue.referTo (projectRoot, Ids::projectLineFeed, getUndoManager(), "\r\n"); + companyNameValue.referTo (projectRoot, Ids::companyName, getUndoManager()); companyCopyrightValue.referTo (projectRoot, Ids::companyCopyright, getUndoManager()); companyWebsiteValue.referTo (projectRoot, Ids::companyWebsite, getUndoManager()); @@ -928,6 +930,10 @@ void Project::createPropertyEditors (PropertyListBuilder& props) "The project's version number. This should be in the format major.minor.point[.point] where you should omit the final " "(optional) [.point] if you are targeting AU and AUv3 plug-ins as they only support three number versions."); + props.add (new ChoicePropertyComponent (projectLineFeedValue, "Project Line Feed", { "\\r\\n", "\\n", }, { "\r\n", "\n" }), + "Use this to set the line feed which will be used when creating new source files for this project " + "(this won't affect any existing files)."); + props.add (new TextPropertyComponent (companyNameValue, "Company Name", 256, false), "Your company name, which will be added to the properties of the binary where possible"); diff --git a/extras/Projucer/Source/Project/jucer_Project.h b/extras/Projucer/Source/Project/jucer_Project.h index b9414d449f..a9b3ed2676 100644 --- a/extras/Projucer/Source/Project/jucer_Project.h +++ b/extras/Projucer/Source/Project/jucer_Project.h @@ -98,6 +98,8 @@ public: String getProjectFilenameRootString() { return File::createLegalFileName (getDocumentTitle()); } String getProjectUIDString() const { return projectUIDValue.get(); } + String getProjectLineFeed() const { return projectLineFeedValue.get(); } + String getVersionString() const { return versionValue.get(); } String getVersionAsHex() const; int getVersionAsHexInteger() const; @@ -409,8 +411,8 @@ public: private: ValueTree projectRoot { Ids::JUCERPROJECT }; - ValueWithDefault projectNameValue, projectUIDValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, companyCopyrightValue, - companyWebsiteValue, companyEmailValue, displaySplashScreenValue, reportAppUsageValue, splashScreenColourValue, cppStandardValue, + ValueWithDefault projectNameValue, projectUIDValue, projectLineFeedValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, + companyCopyrightValue, companyWebsiteValue, companyEmailValue, displaySplashScreenValue, reportAppUsageValue, splashScreenColourValue, cppStandardValue, headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInJuceHeaderValue, binaryDataNamespaceValue; ValueWithDefault pluginFormatsValue, pluginNameValue, pluginDescriptionValue, pluginManufacturerValue, pluginManufacturerCodeValue, diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp b/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp index deb7c1f7a7..bf7af246f3 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp +++ b/extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp @@ -433,7 +433,7 @@ namespace CodeHelpers String getLeadingWhitespace (String line) { - line = line.removeCharacters ("\r\n"); + line = line.removeCharacters (line.endsWith ("\r\n") ? "\r\n" : "\n"); auto endOfLeadingWS = line.getCharPointer().findEndOfWhitespace(); return String (line.getCharPointer(), endOfLeadingWS); } diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp index cd145b64e0..8312884aba 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp +++ b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp @@ -27,7 +27,7 @@ #include "../../Application/jucer_Headers.h" #ifdef BUILDING_JUCE_COMPILEENGINE - const char* getPreferredLinefeed() { return "\r\n"; } + const char* getPreferredLineFeed() { return "\r\n"; } #endif //============================================================================== @@ -36,7 +36,7 @@ String joinLinesIntoSourceFile (StringArray& lines) while (lines.size() > 10 && lines [lines.size() - 1].isEmpty()) lines.remove (lines.size() - 1); - return lines.joinIntoString (getPreferredLinefeed()) + getPreferredLinefeed(); + return lines.joinIntoString (getPreferredLineFeed()) + getPreferredLineFeed(); } String trimCommentCharsFromStartOfLine (const String& line) diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h index 0584dc41da..9f7f471014 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h @@ -28,7 +28,7 @@ //============================================================================== -const char* getPreferredLinefeed(); +const char* getPreferredLineFeed(); String joinLinesIntoSourceFile (StringArray& lines); var parseJUCEHeaderMetadata (const File&); diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h index ad354744f6..5930a9d8e5 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h @@ -343,6 +343,7 @@ namespace Ids DECLARE_ID (buildEnabled); DECLARE_ID (continuousRebuildEnabled); DECLARE_ID (warningsEnabled); + DECLARE_ID (projectLineFeed); const Identifier ID ("id"); const Identifier ID_uppercase ("ID"); diff --git a/extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp b/extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp index 19e2c61725..6701246916 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp +++ b/extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp @@ -32,13 +32,22 @@ NewFileWizard::Type* createGUIComponentWizard(); //============================================================================== namespace { + String addPreferredProjectLineFeed (const String& content, const String& lineFeed) + { + if (lineFeed != "\r\n") + return content.replace ("\r\n", lineFeed); + + return content; + } + static String fillInBasicTemplateFields (const File& file, const Project::Item& item, const char* templateName) { - return item.project.getFileTemplate (templateName) - .replace ("%%filename%%", file.getFileName(), false) - .replace ("%%date%%", Time::getCurrentTime().toString (true, true, true), false) - .replace ("%%author%%", SystemStats::getFullUserName(), false) - .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (file.withFileExtension (".h"), file)); + return addPreferredProjectLineFeed (item.project.getFileTemplate (templateName) + .replace ("%%filename%%", file.getFileName(), false) + .replace ("%%date%%", Time::getCurrentTime().toString (true, true, true), false) + .replace ("%%author%%", SystemStats::getFullUserName(), false) + .replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (file.withFileExtension (".h"), file)), + item.project.getProjectLineFeed()); } static bool fillInNewCppFileTemplate (const File& file, const Project::Item& item, const char* templateName) @@ -167,9 +176,11 @@ public: static bool create (const String& className, Project::Item parent, const File& newFile, const char* templateName) { - String content = fillInBasicTemplateFields (newFile, parent, templateName) - .replace ("%%component_class%%", className) - .replace ("%%include_juce%%", CodeHelpers::createIncludeStatement (parent.project.getAppIncludeFile(), newFile)); + auto content = fillInBasicTemplateFields (newFile, parent, templateName) + .replace ("%%component_class%%", className) + .replace ("%%include_juce%%", CodeHelpers::createIncludeStatement (parent.project.getAppIncludeFile(), newFile)); + + addPreferredProjectLineFeed (content, parent.project.getProjectLineFeed()); if (FileHelpers::overwriteFileWithNewDataIfDifferent (newFile, content)) {