mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
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.
This commit is contained in:
parent
a28597c3c9
commit
543b001e9c
4 changed files with 94 additions and 19 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
for (int j = directories.size(); --j >= 0;)
|
||||
const auto checkedIsChildOf = [&] (const auto& a, const auto& b)
|
||||
{
|
||||
const File d2 (directories[j]);
|
||||
return File::isAbsolutePath (a) && File::isAbsolutePath (b) && File (a).isAChildOf (b);
|
||||
};
|
||||
|
||||
if (i != j && (d1.isAChildOf (d2) || d1 == d2))
|
||||
{
|
||||
directories.remove (i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto fContainsDirectory = [&] (const auto& f)
|
||||
{
|
||||
return f == directory || checkedIsChildOf (directory, f);
|
||||
};
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue