Browse Source

Projucer: Make the source code editor respect line endings when loading and saving a file and add an option to set the preferred line feed for a project

tags/2021-05-28
ed 7 years ago
parent
commit
b8a4e00cb4
11 changed files with 96 additions and 56 deletions
  1. +6
    -6
      extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h
  2. +31
    -29
      extras/Projucer/Source/Application/jucer_CommandLine.cpp
  3. +17
    -1
      extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp
  4. +8
    -6
      extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp
  5. +6
    -0
      extras/Projucer/Source/Project/jucer_Project.cpp
  6. +4
    -2
      extras/Projucer/Source/Project/jucer_Project.h
  7. +1
    -1
      extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp
  8. +2
    -2
      extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp
  9. +1
    -1
      extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h
  10. +1
    -0
      extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h
  11. +19
    -8
      extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp

+ 6
- 6
extras/Projucer/Source/Application/Windows/jucer_PIPCreatorWindowComponent.h View File

@@ -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)


+ 31
- 29
extras/Projucer/Source/Application/jucer_CommandLine.cpp View File

@@ -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];


+ 17
- 1
extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp View File

@@ -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();
}


+ 8
- 6
extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp View File

@@ -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<SourceCodeDocument*> (odm.openFile (nullptr, cppFile)))
if (auto* cpp = dynamic_cast<SourceCodeDocument*> (odm.openFile (&project, cppFile)))
{
if (auto* header = dynamic_cast<SourceCodeDocument*> (odm.openFile (nullptr, headerFile)))
if (auto* header = dynamic_cast<SourceCodeDocument*> (odm.openFile (&project, headerFile)))
{
std::unique_ptr<JucerDocument> jucerDoc (new ComponentDocument (cpp));


+ 6
- 0
extras/Projucer/Source/Project/jucer_Project.cpp View File

@@ -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");


+ 4
- 2
extras/Projucer/Source/Project/jucer_Project.h View File

@@ -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,


+ 1
- 1
extras/Projucer/Source/Utility/Helpers/jucer_CodeHelpers.cpp View File

@@ -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);
}


+ 2
- 2
extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.cpp View File

@@ -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)


+ 1
- 1
extras/Projucer/Source/Utility/Helpers/jucer_MiscUtilities.h View File

@@ -28,7 +28,7 @@
//==============================================================================
const char* getPreferredLinefeed();
const char* getPreferredLineFeed();
String joinLinesIntoSourceFile (StringArray& lines);
var parseJUCEHeaderMetadata (const File&);


+ 1
- 0
extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h View File

@@ -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");


+ 19
- 8
extras/Projucer/Source/Wizards/jucer_NewFileWizard.cpp View File

@@ -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))
{


Loading…
Cancel
Save