The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
4.7KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. //==============================================================================
  21. /** Manipulates a cross-platform partial file path. (Needed because File is designed
  22. for absolute paths on the active OS)
  23. */
  24. class RelativePath
  25. {
  26. public:
  27. //==============================================================================
  28. enum RootFolder
  29. {
  30. unknown,
  31. projectFolder,
  32. buildTargetFolder
  33. };
  34. //==============================================================================
  35. RelativePath()
  36. : root (unknown)
  37. {}
  38. RelativePath (const String& relPath, const RootFolder rootType)
  39. : path (FileHelpers::unixStylePath (relPath)), root (rootType)
  40. {
  41. }
  42. RelativePath (const File& file, const File& rootFolder, const RootFolder rootType)
  43. : path (FileHelpers::unixStylePath (FileHelpers::getRelativePathFrom (file, rootFolder))), root (rootType)
  44. {
  45. }
  46. RootFolder getRoot() const { return root; }
  47. String toUnixStyle() const { return FileHelpers::unixStylePath (path); }
  48. String toWindowsStyle() const { return FileHelpers::windowsStylePath (path); }
  49. String getFileName() const { return getFakeFile().getFileName(); }
  50. String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); }
  51. String getFileExtension() const { return getFakeFile().getFileExtension(); }
  52. bool hasFileExtension (juce::StringRef extension) const { return getFakeFile().hasFileExtension (extension); }
  53. bool isAbsolute() const { return FileHelpers::isAbsolutePath (path); }
  54. RelativePath withFileExtension (const String& extension) const
  55. {
  56. return RelativePath (path.upToLastOccurrenceOf (".", ! extension.startsWithChar ('.'), false) + extension, root);
  57. }
  58. RelativePath getParentDirectory() const
  59. {
  60. String p (path);
  61. if (path.endsWithChar ('/'))
  62. p = p.dropLastCharacters (1);
  63. return RelativePath (p.upToLastOccurrenceOf ("/", false, false), root);
  64. }
  65. RelativePath getChildFile (const String& subpath) const
  66. {
  67. if (FileHelpers::isAbsolutePath (subpath))
  68. return RelativePath (subpath, root);
  69. String p (toUnixStyle());
  70. if (! p.endsWithChar ('/'))
  71. p << '/';
  72. return RelativePath (p + subpath, root);
  73. }
  74. RelativePath rebased (const File& originalRoot, const File& newRoot, const RootFolder newRootType) const
  75. {
  76. if (isAbsolute())
  77. return RelativePath (path, newRootType);
  78. return RelativePath (FileHelpers::getRelativePathFrom (originalRoot.getChildFile (toUnixStyle()), newRoot), newRootType);
  79. }
  80. private:
  81. //==============================================================================
  82. String path;
  83. RootFolder root;
  84. File getFakeFile() const
  85. {
  86. #if JUCE_WINDOWS
  87. if (FileHelpers::isAbsolutePath (path))
  88. {
  89. // This is a hack to convert unix-style absolute paths into valid absolute Windows paths to avoid hitting
  90. // an assertion in File::parseAbsolutePath().
  91. if (path.startsWithChar (L'/') || path.startsWithChar (L'$') || path.startsWithChar (L'~'))
  92. return File (String ("C:\\") + FileHelpers::windowsStylePath (path.substring (1)));
  93. return File (path);
  94. }
  95. #endif
  96. // This method gets called very often, so we'll cache this directory.
  97. static const File currentWorkingDirectory (File::getCurrentWorkingDirectory());
  98. return currentWorkingDirectory.getChildFile (path);
  99. }
  100. };