Browse Source

FileSearchPath: Allow working with paths that are not necessarily absolute

This allows paths that are prefixed with environment variables to behave
as expected. This is useful when scanning the default LV2 locations in
the AudioPluginHost on Windows.
v7.0.9
reuk 2 years ago
parent
commit
543b001e9c
4 changed files with 93 additions and 18 deletions
  1. +3
    -3
      modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp
  2. +75
    -11
      modules/juce_core/files/juce_FileSearchPath.cpp
  3. +12
    -1
      modules/juce_core/files/juce_FileSearchPath.h
  4. +3
    -3
      modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp

+ 3
- 3
modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp View File

@@ -472,9 +472,9 @@ private:
{
for (int i = 0; i < pathList.getPath().getNumPaths(); ++i)
{
auto f = pathList.getPath()[i];
auto f = pathList.getPath().getRawString (i);
if (isStupidPath (f))
if (File::isAbsolutePath (f) && isStupidPath (File (f)))
{
AlertWindow::showOkCancelBox (MessageBoxIconType::WarningIcon,
TRANS("Plugin Scanning"),
@@ -483,7 +483,7 @@ private:
"attempting to load unsuitable files.")
+ newLine
+ TRANS ("Are you sure you want to scan the folder \"XYZ\"?")
.replace ("XYZ", f.getFullPathName()),
.replace ("XYZ", f),
TRANS ("Scan"),
String(),
nullptr,


+ 75
- 11
modules/juce_core/files/juce_FileSearchPath.cpp View File

@@ -63,7 +63,12 @@ int FileSearchPath::getNumPaths() const
File FileSearchPath::operator[] (int index) const
{
return File (directories[index]);
return File (getRawString (index));
}
String FileSearchPath::getRawString (int index) const
{
return directories[index];
}
String FileSearchPath::toString() const
@@ -110,21 +115,30 @@ void FileSearchPath::addPath (const FileSearchPath& other)
void FileSearchPath::removeRedundantPaths()
{
for (int i = directories.size(); --i >= 0;)
std::vector<String> reduced;
for (const auto& directory : directories)
{
const File d1 (directories[i]);
const auto checkedIsChildOf = [&] (const auto& a, const auto& b)
{
return File::isAbsolutePath (a) && File::isAbsolutePath (b) && File (a).isAChildOf (b);
};
for (int j = directories.size(); --j >= 0;)
const auto fContainsDirectory = [&] (const auto& f)
{
const File d2 (directories[j]);
return f == directory || checkedIsChildOf (directory, f);
};
if (i != j && (d1.isAChildOf (d2) || d1 == d2))
{
directories.remove (i);
break;
}
}
if (std::find_if (reduced.begin(), reduced.end(), fContainsDirectory) != reduced.end())
continue;
const auto directoryContainsF = [&] (const auto& f) { return checkedIsChildOf (f, directory); };
reduced.erase (std::remove_if (reduced.begin(), reduced.end(), directoryContainsF), reduced.end());
reduced.push_back (directory);
}
directories = StringArray (reduced.data(), (int) reduced.size());
}
void FileSearchPath::removeNonExistentPaths()
@@ -172,4 +186,54 @@ bool FileSearchPath::isFileInPath (const File& fileToCheck,
return false;
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class FileSearchPathTests : public UnitTest
{
public:
FileSearchPathTests() : UnitTest ("FileSearchPath", UnitTestCategories::files) {}
void runTest() override
{
beginTest ("removeRedundantPaths");
{
#if JUCE_WINDOWS
const String prefix = "C:";
#else
const String prefix = "";
#endif
{
FileSearchPath fsp { prefix + "/a/b/c/d;" + prefix + "/a/b/c/e;" + prefix + "/a/b/c" };
fsp.removeRedundantPaths();
expectEquals (fsp.toString(), prefix + "/a/b/c");
}
{
FileSearchPath fsp { prefix + "/a/b/c;" + prefix + "/a/b/c/d;" + prefix + "/a/b/c/e" };
fsp.removeRedundantPaths();
expectEquals (fsp.toString(), prefix + "/a/b/c");
}
{
FileSearchPath fsp { prefix + "/a/b/c/d;" + prefix + "/a/b/c;" + prefix + "/a/b/c/e" };
fsp.removeRedundantPaths();
expectEquals (fsp.toString(), prefix + "/a/b/c");
}
{
FileSearchPath fsp { "%FOO%;" + prefix + "/a/b/c;%FOO%;" + prefix + "/a/b/c/d" };
fsp.removeRedundantPaths();
expectEquals (fsp.toString(), "%FOO%;" + prefix + "/a/b/c");
}
}
}
};
static FileSearchPathTests fileSearchPathTests;
#endif
} // namespace juce

+ 12
- 1
modules/juce_core/files/juce_FileSearchPath.h View File

@@ -71,10 +71,21 @@ public:
/** Returns one of the folders in this search path.
The file returned isn't guaranteed to actually be a valid directory.
@see getNumPaths
@see getNumPaths, getRawString
*/
File operator[] (int index) const;
/** Returns the unaltered text of the folder at the specified index.
Unlike operator[], this function returns the exact text that was entered. It does not
attempt to convert the path into an absolute path.
This may be useful if the directory string is expected to understand environment variables
or other placeholders that the File constructor doesn't necessarily understand.
@see operator[]
*/
String getRawString (int index) const;
/** Returns the search path as a semicolon-separated list of directories. */
String toString() const;


+ 3
- 3
modules/juce_gui_basics/filebrowser/juce_FileSearchPathListComponent.cpp View File

@@ -129,7 +129,7 @@ void FileSearchPathListComponent::paintListBoxItem (int rowNumber, Graphics& g,
f.setHorizontalScale (0.9f);
g.setFont (f);
g.drawText (path[rowNumber].getFullPathName(),
g.drawText (path.getRawString (rowNumber),
4, 0, width - 6, height,
Justification::centredLeft, true);
}
@@ -145,7 +145,7 @@ void FileSearchPathListComponent::deleteKeyPressed (int row)
void FileSearchPathListComponent::returnKeyPressed (int row)
{
chooser = std::make_unique<FileChooser> (TRANS("Change folder..."), path[row], "*");
chooser = std::make_unique<FileChooser> (TRANS("Change folder..."), path.getRawString (row), "*");
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;
chooser->launchAsync (chooserFlags, [this, row] (const FileChooser& fc)
@@ -258,7 +258,7 @@ void FileSearchPathListComponent::moveSelection (int delta)
if (currentRow != newRow)
{
auto f = path[currentRow];
const auto f = File::createFileWithoutCheckingPath (path.getRawString (currentRow));
path.remove (currentRow);
path.add (f, newRow);
listBox.selectRow (newRow);


Loading…
Cancel
Save