migrating to the latest JUCE version
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -1,240 +1,240 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Manages a list of plugin types.
|
||||
|
||||
This can be easily edited, saved and loaded, and used to create instances of
|
||||
the plugin types in it.
|
||||
|
||||
@see PluginListComponent
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API KnownPluginList : public ChangeBroadcaster
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty list. */
|
||||
KnownPluginList();
|
||||
|
||||
/** Destructor. */
|
||||
~KnownPluginList() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Clears the list. */
|
||||
void clear();
|
||||
|
||||
/** Adds a type manually from its description. */
|
||||
bool addType (const PluginDescription& type);
|
||||
|
||||
/** Removes a type. */
|
||||
void removeType (const PluginDescription& type);
|
||||
|
||||
/** Returns the number of types currently in the list. */
|
||||
int getNumTypes() const noexcept;
|
||||
|
||||
/** Returns a copy of the current list. */
|
||||
Array<PluginDescription> getTypes() const;
|
||||
|
||||
/** Returns the subset of plugin types for a given format. */
|
||||
Array<PluginDescription> getTypesForFormat (AudioPluginFormat&) const;
|
||||
|
||||
/** Looks for a type in the list which comes from this file. */
|
||||
std::unique_ptr<PluginDescription> getTypeForFile (const String& fileOrIdentifier) const;
|
||||
|
||||
/** Looks for a type in the list which matches a plugin type ID.
|
||||
|
||||
The identifierString parameter must have been created by
|
||||
PluginDescription::createIdentifierString().
|
||||
*/
|
||||
std::unique_ptr<PluginDescription> getTypeForIdentifierString (const String& identifierString) const;
|
||||
|
||||
/** Looks for all types that can be loaded from a given file, and adds them
|
||||
to the list.
|
||||
|
||||
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
|
||||
re-tested if it's not already in the list, or if the file's modification
|
||||
time has changed since the list was created. If dontRescanIfAlreadyInList is
|
||||
false, the file will always be reloaded and tested.
|
||||
|
||||
Returns true if any new types were added, and all the types found in this
|
||||
file (even if it was already known and hasn't been re-scanned) get returned
|
||||
in the array.
|
||||
*/
|
||||
bool scanAndAddFile (const String& possiblePluginFileOrIdentifier,
|
||||
bool dontRescanIfAlreadyInList,
|
||||
OwnedArray<PluginDescription>& typesFound,
|
||||
AudioPluginFormat& formatToUse);
|
||||
|
||||
/** Tells a custom scanner that a scan has finished, and it can release any resources. */
|
||||
void scanFinished();
|
||||
|
||||
/** Returns true if the specified file is already known about and if it
|
||||
hasn't been modified since our entry was created.
|
||||
*/
|
||||
bool isListingUpToDate (const String& possiblePluginFileOrIdentifier,
|
||||
AudioPluginFormat& formatToUse) const;
|
||||
|
||||
/** Scans and adds a bunch of files that might have been dragged-and-dropped.
|
||||
If any types are found in the files, their descriptions are returned in the array.
|
||||
*/
|
||||
void scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& formatManager,
|
||||
const StringArray& filenames,
|
||||
OwnedArray<PluginDescription>& typesFound);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the list of blacklisted files. */
|
||||
const StringArray& getBlacklistedFiles() const;
|
||||
|
||||
/** Adds a plugin ID to the black-list. */
|
||||
void addToBlacklist (const String& pluginID);
|
||||
|
||||
/** Removes a plugin ID from the black-list. */
|
||||
void removeFromBlacklist (const String& pluginID);
|
||||
|
||||
/** Clears all the blacklisted files. */
|
||||
void clearBlacklistedFiles();
|
||||
|
||||
//==============================================================================
|
||||
/** Sort methods used to change the order of the plugins in the list.
|
||||
*/
|
||||
enum SortMethod
|
||||
{
|
||||
defaultOrder = 0,
|
||||
sortAlphabetically,
|
||||
sortByCategory,
|
||||
sortByManufacturer,
|
||||
sortByFormat,
|
||||
sortByFileSystemLocation,
|
||||
sortByInfoUpdateTime
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Adds the plug-in types to a popup menu so that the user can select one.
|
||||
|
||||
Depending on the sort method, it may add sub-menus for categories,
|
||||
manufacturers, etc.
|
||||
|
||||
Use getIndexChosenByMenu() to find out the type that was chosen.
|
||||
*/
|
||||
static void addToMenu (PopupMenu& menu, const Array<PluginDescription>& types,
|
||||
SortMethod sortMethod, const String& currentlyTickedPluginID = {});
|
||||
|
||||
/** Converts a menu item index that has been chosen into its index in the list.
|
||||
Returns -1 if it's not an ID that was used.
|
||||
@see addToMenu
|
||||
*/
|
||||
static int getIndexChosenByMenu (const Array<PluginDescription>& types, int menuResultCode);
|
||||
|
||||
//==============================================================================
|
||||
/** Sorts the list. */
|
||||
void sort (SortMethod method, bool forwards);
|
||||
|
||||
//==============================================================================
|
||||
/** Creates some XML that can be used to store the state of this list. */
|
||||
std::unique_ptr<XmlElement> createXml() const;
|
||||
|
||||
/** Recreates the state of this list from its stored XML format. */
|
||||
void recreateFromXml (const XmlElement& xml);
|
||||
|
||||
//==============================================================================
|
||||
/** A structure that recursively holds a tree of plugins.
|
||||
@see KnownPluginList::createTree()
|
||||
*/
|
||||
struct PluginTree
|
||||
{
|
||||
String folder; /**< The name of this folder in the tree */
|
||||
OwnedArray<PluginTree> subFolders;
|
||||
Array<PluginDescription> plugins;
|
||||
};
|
||||
|
||||
/** Creates a PluginTree object representing the list of plug-ins. */
|
||||
static std::unique_ptr<PluginTree> createTree (const Array<PluginDescription>& types, SortMethod sortMethod);
|
||||
|
||||
//==============================================================================
|
||||
/** Class to define a custom plugin scanner */
|
||||
class CustomScanner
|
||||
{
|
||||
public:
|
||||
CustomScanner();
|
||||
virtual ~CustomScanner();
|
||||
|
||||
/** Attempts to load the given file and find a list of plugins in it.
|
||||
@returns true if the plugin loaded, false if it crashed
|
||||
*/
|
||||
virtual bool findPluginTypesFor (AudioPluginFormat& format,
|
||||
OwnedArray<PluginDescription>& result,
|
||||
const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Called when a scan has finished, to allow clean-up of resources. */
|
||||
virtual void scanFinished();
|
||||
|
||||
/** Returns true if the current scan should be abandoned.
|
||||
Any blocking methods should check this value repeatedly and return if
|
||||
if becomes true.
|
||||
*/
|
||||
bool shouldExit() const noexcept;
|
||||
};
|
||||
|
||||
/** Supplies a custom scanner to be used in future scans.
|
||||
The KnownPluginList will take ownership of the object passed in.
|
||||
*/
|
||||
void setCustomScanner (std::unique_ptr<CustomScanner> newScanner);
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
// These methods have been deprecated! When getting the list of plugin types you should instead use
|
||||
// the getTypes() method which returns a copy of the internal PluginDescription array and can be accessed
|
||||
// in a thread-safe way.
|
||||
[[deprecated]] PluginDescription* getType (int index) noexcept { return &types.getReference (index); }
|
||||
[[deprecated]] const PluginDescription* getType (int index) const noexcept { return &types.getReference (index); }
|
||||
[[deprecated]] PluginDescription** begin() noexcept { jassertfalse; return nullptr; }
|
||||
[[deprecated]] PluginDescription* const* begin() const noexcept { jassertfalse; return nullptr; }
|
||||
[[deprecated]] PluginDescription** end() noexcept { jassertfalse; return nullptr; }
|
||||
[[deprecated]] PluginDescription* const* end() const noexcept { jassertfalse; return nullptr; }
|
||||
|
||||
// These methods have been deprecated in favour of their static counterparts. You should call getTypes()
|
||||
// to store the plug-in list at a point in time and use it when calling these methods.
|
||||
[[deprecated]] void addToMenu (PopupMenu& menu, SortMethod sortMethod, const String& currentlyTickedPluginID = {}) const;
|
||||
[[deprecated]] int getIndexChosenByMenu (int menuResultCode) const;
|
||||
[[deprecated]] std::unique_ptr<PluginTree> createTree (const SortMethod sortMethod) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Array<PluginDescription> types;
|
||||
StringArray blacklist;
|
||||
std::unique_ptr<CustomScanner> scanner;
|
||||
CriticalSection scanLock, typesArrayLock;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnownPluginList)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Manages a list of plugin types.
|
||||
|
||||
This can be easily edited, saved and loaded, and used to create instances of
|
||||
the plugin types in it.
|
||||
|
||||
@see PluginListComponent
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API KnownPluginList : public ChangeBroadcaster
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/** Creates an empty list. */
|
||||
KnownPluginList();
|
||||
|
||||
/** Destructor. */
|
||||
~KnownPluginList() override;
|
||||
|
||||
//==============================================================================
|
||||
/** Clears the list. */
|
||||
void clear();
|
||||
|
||||
/** Adds a type manually from its description. */
|
||||
bool addType (const PluginDescription& type);
|
||||
|
||||
/** Removes a type. */
|
||||
void removeType (const PluginDescription& type);
|
||||
|
||||
/** Returns the number of types currently in the list. */
|
||||
int getNumTypes() const noexcept;
|
||||
|
||||
/** Returns a copy of the current list. */
|
||||
Array<PluginDescription> getTypes() const;
|
||||
|
||||
/** Returns the subset of plugin types for a given format. */
|
||||
Array<PluginDescription> getTypesForFormat (AudioPluginFormat&) const;
|
||||
|
||||
/** Looks for a type in the list which comes from this file. */
|
||||
std::unique_ptr<PluginDescription> getTypeForFile (const String& fileOrIdentifier) const;
|
||||
|
||||
/** Looks for a type in the list which matches a plugin type ID.
|
||||
|
||||
The identifierString parameter must have been created by
|
||||
PluginDescription::createIdentifierString().
|
||||
*/
|
||||
std::unique_ptr<PluginDescription> getTypeForIdentifierString (const String& identifierString) const;
|
||||
|
||||
/** Looks for all types that can be loaded from a given file, and adds them
|
||||
to the list.
|
||||
|
||||
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
|
||||
re-tested if it's not already in the list, or if the file's modification
|
||||
time has changed since the list was created. If dontRescanIfAlreadyInList is
|
||||
false, the file will always be reloaded and tested.
|
||||
|
||||
Returns true if any new types were added, and all the types found in this
|
||||
file (even if it was already known and hasn't been re-scanned) get returned
|
||||
in the array.
|
||||
*/
|
||||
bool scanAndAddFile (const String& possiblePluginFileOrIdentifier,
|
||||
bool dontRescanIfAlreadyInList,
|
||||
OwnedArray<PluginDescription>& typesFound,
|
||||
AudioPluginFormat& formatToUse);
|
||||
|
||||
/** Tells a custom scanner that a scan has finished, and it can release any resources. */
|
||||
void scanFinished();
|
||||
|
||||
/** Returns true if the specified file is already known about and if it
|
||||
hasn't been modified since our entry was created.
|
||||
*/
|
||||
bool isListingUpToDate (const String& possiblePluginFileOrIdentifier,
|
||||
AudioPluginFormat& formatToUse) const;
|
||||
|
||||
/** Scans and adds a bunch of files that might have been dragged-and-dropped.
|
||||
If any types are found in the files, their descriptions are returned in the array.
|
||||
*/
|
||||
void scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& formatManager,
|
||||
const StringArray& filenames,
|
||||
OwnedArray<PluginDescription>& typesFound);
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the list of blacklisted files. */
|
||||
const StringArray& getBlacklistedFiles() const;
|
||||
|
||||
/** Adds a plugin ID to the black-list. */
|
||||
void addToBlacklist (const String& pluginID);
|
||||
|
||||
/** Removes a plugin ID from the black-list. */
|
||||
void removeFromBlacklist (const String& pluginID);
|
||||
|
||||
/** Clears all the blacklisted files. */
|
||||
void clearBlacklistedFiles();
|
||||
|
||||
//==============================================================================
|
||||
/** Sort methods used to change the order of the plugins in the list.
|
||||
*/
|
||||
enum SortMethod
|
||||
{
|
||||
defaultOrder = 0,
|
||||
sortAlphabetically,
|
||||
sortByCategory,
|
||||
sortByManufacturer,
|
||||
sortByFormat,
|
||||
sortByFileSystemLocation,
|
||||
sortByInfoUpdateTime
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
/** Adds the plug-in types to a popup menu so that the user can select one.
|
||||
|
||||
Depending on the sort method, it may add sub-menus for categories,
|
||||
manufacturers, etc.
|
||||
|
||||
Use getIndexChosenByMenu() to find out the type that was chosen.
|
||||
*/
|
||||
static void addToMenu (PopupMenu& menu, const Array<PluginDescription>& types,
|
||||
SortMethod sortMethod, const String& currentlyTickedPluginID = {});
|
||||
|
||||
/** Converts a menu item index that has been chosen into its index in the list.
|
||||
Returns -1 if it's not an ID that was used.
|
||||
@see addToMenu
|
||||
*/
|
||||
static int getIndexChosenByMenu (const Array<PluginDescription>& types, int menuResultCode);
|
||||
|
||||
//==============================================================================
|
||||
/** Sorts the list. */
|
||||
void sort (SortMethod method, bool forwards);
|
||||
|
||||
//==============================================================================
|
||||
/** Creates some XML that can be used to store the state of this list. */
|
||||
std::unique_ptr<XmlElement> createXml() const;
|
||||
|
||||
/** Recreates the state of this list from its stored XML format. */
|
||||
void recreateFromXml (const XmlElement& xml);
|
||||
|
||||
//==============================================================================
|
||||
/** A structure that recursively holds a tree of plugins.
|
||||
@see KnownPluginList::createTree()
|
||||
*/
|
||||
struct PluginTree
|
||||
{
|
||||
String folder; /**< The name of this folder in the tree */
|
||||
OwnedArray<PluginTree> subFolders;
|
||||
Array<PluginDescription> plugins;
|
||||
};
|
||||
|
||||
/** Creates a PluginTree object representing the list of plug-ins. */
|
||||
static std::unique_ptr<PluginTree> createTree (const Array<PluginDescription>& types, SortMethod sortMethod);
|
||||
|
||||
//==============================================================================
|
||||
/** Class to define a custom plugin scanner */
|
||||
class CustomScanner
|
||||
{
|
||||
public:
|
||||
CustomScanner();
|
||||
virtual ~CustomScanner();
|
||||
|
||||
/** Attempts to load the given file and find a list of plugins in it.
|
||||
@returns true if the plugin loaded, false if it crashed
|
||||
*/
|
||||
virtual bool findPluginTypesFor (AudioPluginFormat& format,
|
||||
OwnedArray<PluginDescription>& result,
|
||||
const String& fileOrIdentifier) = 0;
|
||||
|
||||
/** Called when a scan has finished, to allow clean-up of resources. */
|
||||
virtual void scanFinished();
|
||||
|
||||
/** Returns true if the current scan should be abandoned.
|
||||
Any blocking methods should check this value repeatedly and return if
|
||||
if becomes true.
|
||||
*/
|
||||
bool shouldExit() const noexcept;
|
||||
};
|
||||
|
||||
/** Supplies a custom scanner to be used in future scans.
|
||||
The KnownPluginList will take ownership of the object passed in.
|
||||
*/
|
||||
void setCustomScanner (std::unique_ptr<CustomScanner> newScanner);
|
||||
|
||||
//==============================================================================
|
||||
#ifndef DOXYGEN
|
||||
// These methods have been deprecated! When getting the list of plugin types you should instead use
|
||||
// the getTypes() method which returns a copy of the internal PluginDescription array and can be accessed
|
||||
// in a thread-safe way.
|
||||
[[deprecated]] PluginDescription* getType (int index) noexcept { return &types.getReference (index); }
|
||||
[[deprecated]] const PluginDescription* getType (int index) const noexcept { return &types.getReference (index); }
|
||||
[[deprecated]] PluginDescription** begin() noexcept { jassertfalse; return nullptr; }
|
||||
[[deprecated]] PluginDescription* const* begin() const noexcept { jassertfalse; return nullptr; }
|
||||
[[deprecated]] PluginDescription** end() noexcept { jassertfalse; return nullptr; }
|
||||
[[deprecated]] PluginDescription* const* end() const noexcept { jassertfalse; return nullptr; }
|
||||
|
||||
// These methods have been deprecated in favour of their static counterparts. You should call getTypes()
|
||||
// to store the plug-in list at a point in time and use it when calling these methods.
|
||||
[[deprecated]] void addToMenu (PopupMenu& menu, SortMethod sortMethod, const String& currentlyTickedPluginID = {}) const;
|
||||
[[deprecated]] int getIndexChosenByMenu (int menuResultCode) const;
|
||||
[[deprecated]] std::unique_ptr<PluginTree> createTree (const SortMethod sortMethod) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
Array<PluginDescription> types;
|
||||
StringArray blacklist;
|
||||
std::unique_ptr<CustomScanner> scanner;
|
||||
CriticalSection scanLock, typesArrayLock;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (KnownPluginList)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,139 +1,139 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
static StringArray readDeadMansPedalFile (const File& file)
|
||||
{
|
||||
StringArray lines;
|
||||
file.readLines (lines);
|
||||
lines.removeEmptyStrings();
|
||||
return lines;
|
||||
}
|
||||
|
||||
PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo,
|
||||
AudioPluginFormat& formatToLookFor,
|
||||
FileSearchPath directoriesToSearch,
|
||||
const bool recursive,
|
||||
const File& deadMansPedal,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation)
|
||||
: list (listToAddTo),
|
||||
format (formatToLookFor),
|
||||
deadMansPedalFile (deadMansPedal),
|
||||
allowAsync (allowPluginsWhichRequireAsynchronousInstantiation)
|
||||
{
|
||||
directoriesToSearch.removeRedundantPaths();
|
||||
setFilesOrIdentifiersToScan (format.searchPathsForPlugins (directoriesToSearch, recursive, allowAsync));
|
||||
}
|
||||
|
||||
PluginDirectoryScanner::~PluginDirectoryScanner()
|
||||
{
|
||||
list.scanFinished();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void PluginDirectoryScanner::setFilesOrIdentifiersToScan (const StringArray& filesOrIdentifiers)
|
||||
{
|
||||
filesOrIdentifiersToScan = filesOrIdentifiers;
|
||||
|
||||
// If any plugins have crashed recently when being loaded, move them to the
|
||||
// end of the list to give the others a chance to load correctly..
|
||||
for (auto& crashed : readDeadMansPedalFile (deadMansPedalFile))
|
||||
for (int j = filesOrIdentifiersToScan.size(); --j >= 0;)
|
||||
if (crashed == filesOrIdentifiersToScan[j])
|
||||
filesOrIdentifiersToScan.move (j, -1);
|
||||
|
||||
applyBlacklistingsFromDeadMansPedal (list, deadMansPedalFile);
|
||||
nextIndex.set (filesOrIdentifiersToScan.size());
|
||||
}
|
||||
|
||||
String PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const
|
||||
{
|
||||
return format.getNameOfPluginFromIdentifier (filesOrIdentifiersToScan [nextIndex.get() - 1]);
|
||||
}
|
||||
|
||||
void PluginDirectoryScanner::updateProgress()
|
||||
{
|
||||
progress = (1.0f - (float) nextIndex.get() / (float) filesOrIdentifiersToScan.size());
|
||||
}
|
||||
|
||||
bool PluginDirectoryScanner::scanNextFile (bool dontRescanIfAlreadyInList,
|
||||
String& nameOfPluginBeingScanned)
|
||||
{
|
||||
const int index = --nextIndex;
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
auto file = filesOrIdentifiersToScan [index];
|
||||
|
||||
if (file.isNotEmpty() && ! (dontRescanIfAlreadyInList && list.isListingUpToDate (file, format)))
|
||||
{
|
||||
nameOfPluginBeingScanned = format.getNameOfPluginFromIdentifier (file);
|
||||
|
||||
OwnedArray<PluginDescription> typesFound;
|
||||
|
||||
// Add this plugin to the end of the dead-man's pedal list in case it crashes...
|
||||
auto crashedPlugins = readDeadMansPedalFile (deadMansPedalFile);
|
||||
crashedPlugins.removeString (file);
|
||||
crashedPlugins.add (file);
|
||||
setDeadMansPedalFile (crashedPlugins);
|
||||
|
||||
list.scanAndAddFile (file, dontRescanIfAlreadyInList, typesFound, format);
|
||||
|
||||
// Managed to load without crashing, so remove it from the dead-man's-pedal..
|
||||
crashedPlugins.removeString (file);
|
||||
setDeadMansPedalFile (crashedPlugins);
|
||||
|
||||
if (typesFound.size() == 0 && ! list.getBlacklistedFiles().contains (file))
|
||||
failedFiles.add (file);
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress();
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
bool PluginDirectoryScanner::skipNextFile()
|
||||
{
|
||||
updateProgress();
|
||||
return --nextIndex > 0;
|
||||
}
|
||||
|
||||
void PluginDirectoryScanner::setDeadMansPedalFile (const StringArray& newContents)
|
||||
{
|
||||
if (deadMansPedalFile.getFullPathName().isNotEmpty())
|
||||
deadMansPedalFile.replaceWithText (newContents.joinIntoString ("\n"), true, true);
|
||||
}
|
||||
|
||||
void PluginDirectoryScanner::applyBlacklistingsFromDeadMansPedal (KnownPluginList& list, const File& file)
|
||||
{
|
||||
// If any plugins have crashed recently when being loaded, move them to the
|
||||
// end of the list to give the others a chance to load correctly..
|
||||
for (auto& crashedPlugin : readDeadMansPedalFile (file))
|
||||
list.addToBlacklist (crashedPlugin);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
static StringArray readDeadMansPedalFile (const File& file)
|
||||
{
|
||||
StringArray lines;
|
||||
file.readLines (lines);
|
||||
lines.removeEmptyStrings();
|
||||
return lines;
|
||||
}
|
||||
|
||||
PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo,
|
||||
AudioPluginFormat& formatToLookFor,
|
||||
FileSearchPath directoriesToSearch,
|
||||
const bool recursive,
|
||||
const File& deadMansPedal,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation)
|
||||
: list (listToAddTo),
|
||||
format (formatToLookFor),
|
||||
deadMansPedalFile (deadMansPedal),
|
||||
allowAsync (allowPluginsWhichRequireAsynchronousInstantiation)
|
||||
{
|
||||
directoriesToSearch.removeRedundantPaths();
|
||||
setFilesOrIdentifiersToScan (format.searchPathsForPlugins (directoriesToSearch, recursive, allowAsync));
|
||||
}
|
||||
|
||||
PluginDirectoryScanner::~PluginDirectoryScanner()
|
||||
{
|
||||
list.scanFinished();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void PluginDirectoryScanner::setFilesOrIdentifiersToScan (const StringArray& filesOrIdentifiers)
|
||||
{
|
||||
filesOrIdentifiersToScan = filesOrIdentifiers;
|
||||
|
||||
// If any plugins have crashed recently when being loaded, move them to the
|
||||
// end of the list to give the others a chance to load correctly..
|
||||
for (auto& crashed : readDeadMansPedalFile (deadMansPedalFile))
|
||||
for (int j = filesOrIdentifiersToScan.size(); --j >= 0;)
|
||||
if (crashed == filesOrIdentifiersToScan[j])
|
||||
filesOrIdentifiersToScan.move (j, -1);
|
||||
|
||||
applyBlacklistingsFromDeadMansPedal (list, deadMansPedalFile);
|
||||
nextIndex.set (filesOrIdentifiersToScan.size());
|
||||
}
|
||||
|
||||
String PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const
|
||||
{
|
||||
return format.getNameOfPluginFromIdentifier (filesOrIdentifiersToScan [nextIndex.get() - 1]);
|
||||
}
|
||||
|
||||
void PluginDirectoryScanner::updateProgress()
|
||||
{
|
||||
progress = (1.0f - (float) nextIndex.get() / (float) filesOrIdentifiersToScan.size());
|
||||
}
|
||||
|
||||
bool PluginDirectoryScanner::scanNextFile (bool dontRescanIfAlreadyInList,
|
||||
String& nameOfPluginBeingScanned)
|
||||
{
|
||||
const int index = --nextIndex;
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
auto file = filesOrIdentifiersToScan [index];
|
||||
|
||||
if (file.isNotEmpty() && ! (dontRescanIfAlreadyInList && list.isListingUpToDate (file, format)))
|
||||
{
|
||||
nameOfPluginBeingScanned = format.getNameOfPluginFromIdentifier (file);
|
||||
|
||||
OwnedArray<PluginDescription> typesFound;
|
||||
|
||||
// Add this plugin to the end of the dead-man's pedal list in case it crashes...
|
||||
auto crashedPlugins = readDeadMansPedalFile (deadMansPedalFile);
|
||||
crashedPlugins.removeString (file);
|
||||
crashedPlugins.add (file);
|
||||
setDeadMansPedalFile (crashedPlugins);
|
||||
|
||||
list.scanAndAddFile (file, dontRescanIfAlreadyInList, typesFound, format);
|
||||
|
||||
// Managed to load without crashing, so remove it from the dead-man's-pedal..
|
||||
crashedPlugins.removeString (file);
|
||||
setDeadMansPedalFile (crashedPlugins);
|
||||
|
||||
if (typesFound.size() == 0 && ! list.getBlacklistedFiles().contains (file))
|
||||
failedFiles.add (file);
|
||||
}
|
||||
}
|
||||
|
||||
updateProgress();
|
||||
return index > 0;
|
||||
}
|
||||
|
||||
bool PluginDirectoryScanner::skipNextFile()
|
||||
{
|
||||
updateProgress();
|
||||
return --nextIndex > 0;
|
||||
}
|
||||
|
||||
void PluginDirectoryScanner::setDeadMansPedalFile (const StringArray& newContents)
|
||||
{
|
||||
if (deadMansPedalFile.getFullPathName().isNotEmpty())
|
||||
deadMansPedalFile.replaceWithText (newContents.joinIntoString ("\n"), true, true);
|
||||
}
|
||||
|
||||
void PluginDirectoryScanner::applyBlacklistingsFromDeadMansPedal (KnownPluginList& list, const File& file)
|
||||
{
|
||||
// If any plugins have crashed recently when being loaded, move them to the
|
||||
// end of the list to give the others a chance to load correctly..
|
||||
for (auto& crashedPlugin : readDeadMansPedalFile (file))
|
||||
list.addToBlacklist (crashedPlugin);
|
||||
}
|
||||
|
||||
} // namespace juce
|
||||
|
@ -1,138 +1,138 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Scans a directory for plugins, and adds them to a KnownPluginList.
|
||||
|
||||
To use one of these, create it and call scanNextFile() repeatedly, until
|
||||
it returns false.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API PluginDirectoryScanner
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creates a scanner.
|
||||
|
||||
@param listToAddResultsTo this will get the new types added to it.
|
||||
@param formatToLookFor this is the type of format that you want to look for
|
||||
@param directoriesToSearch the path to search
|
||||
@param searchRecursively true to search recursively
|
||||
@param deadMansPedalFile if this isn't File(), then it will be used as a file
|
||||
to store the names of any plugins that crash during
|
||||
initialisation. If there are any plugins listed in it,
|
||||
then these will always be scanned after all other possible
|
||||
files have been tried - in this way, even if there's a few
|
||||
dodgy plugins in your path, then a couple of rescans
|
||||
will still manage to find all the proper plugins.
|
||||
It's probably best to choose a file in the user's
|
||||
application data directory (alongside your app's
|
||||
settings file) for this. The file format it uses
|
||||
is just a list of filenames of the modules that
|
||||
failed.
|
||||
@param allowPluginsWhichRequireAsynchronousInstantiation
|
||||
If this is false then the scanner will exclude plug-ins
|
||||
asynchronous creation - such as AUv3 plug-ins.
|
||||
*/
|
||||
PluginDirectoryScanner (KnownPluginList& listToAddResultsTo,
|
||||
AudioPluginFormat& formatToLookFor,
|
||||
FileSearchPath directoriesToSearch,
|
||||
bool searchRecursively,
|
||||
const File& deadMansPedalFile,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation = false);
|
||||
|
||||
/** Destructor. */
|
||||
~PluginDirectoryScanner();
|
||||
|
||||
//==============================================================================
|
||||
/** Sets a specific list of filesOrIdentifiersToScan to scan.
|
||||
N.B. This list must match the format passed to the constructor.
|
||||
@see AudioPluginFormat::searchPathsForPlugins
|
||||
*/
|
||||
void setFilesOrIdentifiersToScan (const StringArray& filesOrIdentifiersToScan);
|
||||
|
||||
/** Tries the next likely-looking file.
|
||||
|
||||
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
|
||||
re-tested if it's not already in the list, or if the file's modification
|
||||
time has changed since the list was created. If dontRescanIfAlreadyInList is
|
||||
false, the file will always be reloaded and tested.
|
||||
The nameOfPluginBeingScanned will be updated to the name of the plugin being
|
||||
scanned before the scan starts.
|
||||
|
||||
Returns false when there are no more files to try.
|
||||
*/
|
||||
bool scanNextFile (bool dontRescanIfAlreadyInList,
|
||||
String& nameOfPluginBeingScanned);
|
||||
|
||||
/** Skips over the next file without scanning it.
|
||||
Returns false when there are no more files to try.
|
||||
*/
|
||||
bool skipNextFile();
|
||||
|
||||
/** Returns the description of the plugin that will be scanned during the next
|
||||
call to scanNextFile().
|
||||
|
||||
This is handy if you want to show the user which file is currently getting
|
||||
scanned.
|
||||
*/
|
||||
String getNextPluginFileThatWillBeScanned() const;
|
||||
|
||||
/** Returns the estimated progress, between 0 and 1. */
|
||||
float getProgress() const { return progress; }
|
||||
|
||||
/** This returns a list of all the filenames of things that looked like being
|
||||
a plugin file, but which failed to open for some reason.
|
||||
*/
|
||||
const StringArray& getFailedFiles() const noexcept { return failedFiles; }
|
||||
|
||||
/** Reads the given dead-mans-pedal file and applies its contents to the list. */
|
||||
static void applyBlacklistingsFromDeadMansPedal (KnownPluginList& listToApplyTo,
|
||||
const File& deadMansPedalFile);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
KnownPluginList& list;
|
||||
AudioPluginFormat& format;
|
||||
StringArray filesOrIdentifiersToScan;
|
||||
File deadMansPedalFile;
|
||||
StringArray failedFiles;
|
||||
Atomic<int> nextIndex;
|
||||
float progress = 0;
|
||||
const bool allowAsync;
|
||||
|
||||
void updateProgress();
|
||||
void setDeadMansPedalFile (const StringArray& newContents);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginDirectoryScanner)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
Scans a directory for plugins, and adds them to a KnownPluginList.
|
||||
|
||||
To use one of these, create it and call scanNextFile() repeatedly, until
|
||||
it returns false.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API PluginDirectoryScanner
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creates a scanner.
|
||||
|
||||
@param listToAddResultsTo this will get the new types added to it.
|
||||
@param formatToLookFor this is the type of format that you want to look for
|
||||
@param directoriesToSearch the path to search
|
||||
@param searchRecursively true to search recursively
|
||||
@param deadMansPedalFile if this isn't File(), then it will be used as a file
|
||||
to store the names of any plugins that crash during
|
||||
initialisation. If there are any plugins listed in it,
|
||||
then these will always be scanned after all other possible
|
||||
files have been tried - in this way, even if there's a few
|
||||
dodgy plugins in your path, then a couple of rescans
|
||||
will still manage to find all the proper plugins.
|
||||
It's probably best to choose a file in the user's
|
||||
application data directory (alongside your app's
|
||||
settings file) for this. The file format it uses
|
||||
is just a list of filenames of the modules that
|
||||
failed.
|
||||
@param allowPluginsWhichRequireAsynchronousInstantiation
|
||||
If this is false then the scanner will exclude plug-ins
|
||||
asynchronous creation - such as AUv3 plug-ins.
|
||||
*/
|
||||
PluginDirectoryScanner (KnownPluginList& listToAddResultsTo,
|
||||
AudioPluginFormat& formatToLookFor,
|
||||
FileSearchPath directoriesToSearch,
|
||||
bool searchRecursively,
|
||||
const File& deadMansPedalFile,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation = false);
|
||||
|
||||
/** Destructor. */
|
||||
~PluginDirectoryScanner();
|
||||
|
||||
//==============================================================================
|
||||
/** Sets a specific list of filesOrIdentifiersToScan to scan.
|
||||
N.B. This list must match the format passed to the constructor.
|
||||
@see AudioPluginFormat::searchPathsForPlugins
|
||||
*/
|
||||
void setFilesOrIdentifiersToScan (const StringArray& filesOrIdentifiersToScan);
|
||||
|
||||
/** Tries the next likely-looking file.
|
||||
|
||||
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
|
||||
re-tested if it's not already in the list, or if the file's modification
|
||||
time has changed since the list was created. If dontRescanIfAlreadyInList is
|
||||
false, the file will always be reloaded and tested.
|
||||
The nameOfPluginBeingScanned will be updated to the name of the plugin being
|
||||
scanned before the scan starts.
|
||||
|
||||
Returns false when there are no more files to try.
|
||||
*/
|
||||
bool scanNextFile (bool dontRescanIfAlreadyInList,
|
||||
String& nameOfPluginBeingScanned);
|
||||
|
||||
/** Skips over the next file without scanning it.
|
||||
Returns false when there are no more files to try.
|
||||
*/
|
||||
bool skipNextFile();
|
||||
|
||||
/** Returns the description of the plugin that will be scanned during the next
|
||||
call to scanNextFile().
|
||||
|
||||
This is handy if you want to show the user which file is currently getting
|
||||
scanned.
|
||||
*/
|
||||
String getNextPluginFileThatWillBeScanned() const;
|
||||
|
||||
/** Returns the estimated progress, between 0 and 1. */
|
||||
float getProgress() const { return progress; }
|
||||
|
||||
/** This returns a list of all the filenames of things that looked like being
|
||||
a plugin file, but which failed to open for some reason.
|
||||
*/
|
||||
const StringArray& getFailedFiles() const noexcept { return failedFiles; }
|
||||
|
||||
/** Reads the given dead-mans-pedal file and applies its contents to the list. */
|
||||
static void applyBlacklistingsFromDeadMansPedal (KnownPluginList& listToApplyTo,
|
||||
const File& deadMansPedalFile);
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
KnownPluginList& list;
|
||||
AudioPluginFormat& format;
|
||||
StringArray filesOrIdentifiersToScan;
|
||||
File deadMansPedalFile;
|
||||
StringArray failedFiles;
|
||||
Atomic<int> nextIndex;
|
||||
std::atomic<float> progress { 0.0f };
|
||||
const bool allowAsync;
|
||||
|
||||
void updateProgress();
|
||||
void setDeadMansPedalFile (const StringArray& newContents);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginDirectoryScanner)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,143 +1,145 @@
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2020 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
|
||||
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
|
||||
|
||||
End User License Agreement: www.juce.com/juce-6-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component displaying a list of plugins, with options to scan for them,
|
||||
add, remove and sort them.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API PluginListComponent : public Component,
|
||||
public FileDragAndDropTarget,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creates the list component.
|
||||
|
||||
For info about the deadMansPedalFile, see the PluginDirectoryScanner constructor.
|
||||
The properties file, if supplied, is used to store the user's last search paths.
|
||||
*/
|
||||
PluginListComponent (AudioPluginFormatManager& formatManager,
|
||||
KnownPluginList& listToRepresent,
|
||||
const File& deadMansPedalFile,
|
||||
PropertiesFile* propertiesToUse,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation = false);
|
||||
|
||||
/** Destructor. */
|
||||
~PluginListComponent() override;
|
||||
|
||||
/** Changes the text in the panel's options button. */
|
||||
void setOptionsButtonText (const String& newText);
|
||||
|
||||
/** Returns a pop-up menu that contains all the options for scanning and updating the list. */
|
||||
PopupMenu createOptionsMenu();
|
||||
|
||||
/** Returns a menu that can be shown if a row is right-clicked, containing actions
|
||||
like "remove plugin" or "show folder" etc.
|
||||
*/
|
||||
PopupMenu createMenuForRow (int rowNumber);
|
||||
|
||||
/** Changes the text in the progress dialog box that is shown when scanning. */
|
||||
void setScanDialogText (const String& textForProgressWindowTitle,
|
||||
const String& textForProgressWindowDescription);
|
||||
|
||||
/** Sets how many threads to simultaneously scan for plugins.
|
||||
If this is 0, then all scanning happens on the message thread (this is the default when
|
||||
allowPluginsWhichRequireAsynchronousInstantiation is false). If
|
||||
allowPluginsWhichRequireAsynchronousInstantiation is true then numThreads must not
|
||||
be zero (it is one by default). */
|
||||
void setNumberOfThreadsForScanning (int numThreads);
|
||||
|
||||
/** Returns the last search path stored in a given properties file for the specified format. */
|
||||
static FileSearchPath getLastSearchPath (PropertiesFile&, AudioPluginFormat&);
|
||||
|
||||
/** Stores a search path in a properties file for the given format. */
|
||||
static void setLastSearchPath (PropertiesFile&, AudioPluginFormat&, const FileSearchPath&);
|
||||
|
||||
/** Triggers an asynchronous scan for the given format. */
|
||||
void scanFor (AudioPluginFormat&);
|
||||
|
||||
/** Triggers an asynchronous scan for the given format and scans only the given files or identifiers.
|
||||
@see AudioPluginFormat::searchPathsForPlugins
|
||||
*/
|
||||
void scanFor (AudioPluginFormat&, const StringArray& filesOrIdentifiersToScan);
|
||||
|
||||
/** Returns true if there's currently a scan in progress. */
|
||||
bool isScanning() const noexcept;
|
||||
|
||||
/** Removes the plugins currently selected in the table. */
|
||||
void removeSelectedPlugins();
|
||||
|
||||
/** Sets a custom table model to be used.
|
||||
This will take ownership of the model and delete it when no longer needed.
|
||||
*/
|
||||
void setTableModel (TableListBoxModel*);
|
||||
|
||||
/** Returns the table used to display the plugin list. */
|
||||
TableListBox& getTableListBox() noexcept { return table; }
|
||||
|
||||
/** Returns the button used to display the options menu - you can make this invisible
|
||||
if you want to hide it and use some other method for showing the menu.
|
||||
*/
|
||||
TextButton& getOptionsButton() { return optionsButton; }
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioPluginFormatManager& formatManager;
|
||||
KnownPluginList& list;
|
||||
File deadMansPedalFile;
|
||||
TableListBox table;
|
||||
TextButton optionsButton;
|
||||
PropertiesFile* propertiesToUse;
|
||||
String dialogTitle, dialogText;
|
||||
bool allowAsync;
|
||||
int numThreads;
|
||||
|
||||
class TableModel;
|
||||
std::unique_ptr<TableListBoxModel> tableModel;
|
||||
|
||||
class Scanner;
|
||||
std::unique_ptr<Scanner> currentScanner;
|
||||
|
||||
void scanFinished (const StringArray&);
|
||||
void updateList();
|
||||
void removeMissingPlugins();
|
||||
void removePluginItem (int index);
|
||||
|
||||
void resized() override;
|
||||
bool isInterestedInFileDrag (const StringArray&) override;
|
||||
void filesDropped (const StringArray&, int, int) override;
|
||||
void changeListenerCallback (ChangeBroadcaster*) override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library.
|
||||
Copyright (c) 2022 - Raw Material Software Limited
|
||||
|
||||
JUCE is an open source library subject to commercial or open-source
|
||||
licensing.
|
||||
|
||||
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
|
||||
Agreement and JUCE Privacy Policy.
|
||||
|
||||
End User License Agreement: www.juce.com/juce-7-licence
|
||||
Privacy Policy: www.juce.com/juce-privacy-policy
|
||||
|
||||
Or: You may also use this code under the terms of the GPL v3 (see
|
||||
www.gnu.org/licenses).
|
||||
|
||||
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
||||
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
||||
DISCLAIMED.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
namespace juce
|
||||
{
|
||||
|
||||
//==============================================================================
|
||||
/**
|
||||
A component displaying a list of plugins, with options to scan for them,
|
||||
add, remove and sort them.
|
||||
|
||||
@tags{Audio}
|
||||
*/
|
||||
class JUCE_API PluginListComponent : public Component,
|
||||
public FileDragAndDropTarget,
|
||||
private ChangeListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
/**
|
||||
Creates the list component.
|
||||
|
||||
For info about the deadMansPedalFile, see the PluginDirectoryScanner constructor.
|
||||
The properties file, if supplied, is used to store the user's last search paths.
|
||||
*/
|
||||
PluginListComponent (AudioPluginFormatManager& formatManager,
|
||||
KnownPluginList& listToRepresent,
|
||||
const File& deadMansPedalFile,
|
||||
PropertiesFile* propertiesToUse,
|
||||
bool allowPluginsWhichRequireAsynchronousInstantiation = false);
|
||||
|
||||
/** Destructor. */
|
||||
~PluginListComponent() override;
|
||||
|
||||
/** Changes the text in the panel's options button. */
|
||||
void setOptionsButtonText (const String& newText);
|
||||
|
||||
/** Returns a pop-up menu that contains all the options for scanning and updating the list. */
|
||||
PopupMenu createOptionsMenu();
|
||||
|
||||
/** Returns a menu that can be shown if a row is right-clicked, containing actions
|
||||
like "remove plugin" or "show folder" etc.
|
||||
*/
|
||||
PopupMenu createMenuForRow (int rowNumber);
|
||||
|
||||
/** Changes the text in the progress dialog box that is shown when scanning. */
|
||||
void setScanDialogText (const String& textForProgressWindowTitle,
|
||||
const String& textForProgressWindowDescription);
|
||||
|
||||
/** Sets how many threads to simultaneously scan for plugins.
|
||||
If this is 0, then all scanning happens on the message thread (this is the default when
|
||||
allowPluginsWhichRequireAsynchronousInstantiation is false). If
|
||||
allowPluginsWhichRequireAsynchronousInstantiation is true then numThreads must not
|
||||
be zero (it is one by default). */
|
||||
void setNumberOfThreadsForScanning (int numThreads);
|
||||
|
||||
/** Returns the last search path stored in a given properties file for the specified format. */
|
||||
static FileSearchPath getLastSearchPath (PropertiesFile&, AudioPluginFormat&);
|
||||
|
||||
/** Stores a search path in a properties file for the given format. */
|
||||
static void setLastSearchPath (PropertiesFile&, AudioPluginFormat&, const FileSearchPath&);
|
||||
|
||||
/** Triggers an asynchronous scan for the given format. */
|
||||
void scanFor (AudioPluginFormat&);
|
||||
|
||||
/** Triggers an asynchronous scan for the given format and scans only the given files or identifiers.
|
||||
@see AudioPluginFormat::searchPathsForPlugins
|
||||
*/
|
||||
void scanFor (AudioPluginFormat&, const StringArray& filesOrIdentifiersToScan);
|
||||
|
||||
/** Returns true if there's currently a scan in progress. */
|
||||
bool isScanning() const noexcept;
|
||||
|
||||
/** Removes the plugins currently selected in the table. */
|
||||
void removeSelectedPlugins();
|
||||
|
||||
/** Sets a custom table model to be used.
|
||||
This will take ownership of the model and delete it when no longer needed.
|
||||
*/
|
||||
void setTableModel (TableListBoxModel*);
|
||||
|
||||
/** Returns the table used to display the plugin list. */
|
||||
TableListBox& getTableListBox() noexcept { return table; }
|
||||
|
||||
/** Returns the button used to display the options menu - you can make this invisible
|
||||
if you want to hide it and use some other method for showing the menu.
|
||||
*/
|
||||
TextButton& getOptionsButton() { return optionsButton; }
|
||||
|
||||
/** @internal */
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
AudioPluginFormatManager& formatManager;
|
||||
KnownPluginList& list;
|
||||
File deadMansPedalFile;
|
||||
TableListBox table;
|
||||
TextButton optionsButton;
|
||||
PropertiesFile* propertiesToUse;
|
||||
String dialogTitle, dialogText;
|
||||
bool allowAsync;
|
||||
int numThreads;
|
||||
|
||||
class TableModel;
|
||||
std::unique_ptr<TableListBoxModel> tableModel;
|
||||
|
||||
class Scanner;
|
||||
std::unique_ptr<Scanner> currentScanner;
|
||||
|
||||
void scanFinished (const StringArray&, const std::vector<String>&);
|
||||
void updateList();
|
||||
void removeMissingPlugins();
|
||||
void removePluginItem (int index);
|
||||
|
||||
bool isInterestedInFileDrag (const StringArray&) override;
|
||||
void filesDropped (const StringArray&, int, int) override;
|
||||
void changeListenerCallback (ChangeBroadcaster*) override;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent)
|
||||
};
|
||||
|
||||
} // namespace juce
|
||||
|
Reference in New Issue
Block a user