diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp index 2ea3c9824a..afbf23e5e8 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp @@ -202,6 +202,14 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& f } } } + + scanFinished(); +} + +void KnownPluginList::scanFinished() +{ + if (scanner != nullptr) + scanner->scanFinished(); } const StringArray& KnownPluginList::getBlacklistedFiles() const @@ -280,10 +288,16 @@ void KnownPluginList::sort (const SortMethod method, bool forwards) { if (method != defaultOrder) { + Array oldOrder, newOrder; + oldOrder.addArray (types); + PluginSorter sorter (method, forwards); types.sort (sorter, true); - sendChangeMessage(); + newOrder.addArray (types); + + if (oldOrder != newOrder) + sendChangeMessage(); } } @@ -523,3 +537,13 @@ int KnownPluginList::getIndexChosenByMenu (const int menuResultCode) const //============================================================================== KnownPluginList::CustomScanner::CustomScanner() {} KnownPluginList::CustomScanner::~CustomScanner() {} + +void KnownPluginList::CustomScanner::scanFinished() {} + +bool KnownPluginList::CustomScanner::shouldExit() const noexcept +{ + if (ThreadPoolJob* job = ThreadPoolJob::getCurrentThreadPoolJob()) + return job->shouldExit(); + + return false; +} diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h index 5f606437e4..3c8df25fdd 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h @@ -97,6 +97,9 @@ public: OwnedArray & 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. */ @@ -170,8 +173,8 @@ public: struct PluginTree { String folder; /**< The name of this folder in the tree */ - OwnedArray subFolders; - Array plugins; + OwnedArray subFolders; + Array plugins; }; /** Creates a PluginTree object containing all the known plugins. */ @@ -190,9 +193,21 @@ public: virtual bool findPluginTypesFor (AudioPluginFormat& format, OwnedArray & 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; }; - void setCustomScanner (CustomScanner* scanner); + /** Supplies a custom scanner to be used in future scans. + The KnownPluginList will take ownership of the object passed in. + */ + void setCustomScanner (CustomScanner*); private: //============================================================================== diff --git a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp index 5502f00a9e..a7beea7339 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp @@ -63,6 +63,7 @@ PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo, PluginDirectoryScanner::~PluginDirectoryScanner() { + list.scanFinished(); } //============================================================================== diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index 65cb60d188..a0c2388cfa 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -162,6 +162,7 @@ PluginListComponent::PluginListComponent (AudioPluginFormatManager& manager, Kno setSize (400, 600); list.addChangeListener (this); updateList(); + table.getHeader().reSortTable(); PluginDirectoryScanner::applyBlacklistingsFromDeadMansPedal (list, deadMansPedalFile); deadMansPedalFile.deleteFile(); @@ -196,6 +197,7 @@ void PluginListComponent::resized() void PluginListComponent::changeListenerCallback (ChangeBroadcaster*) { + table.getHeader().reSortTable(); updateList(); } diff --git a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp index 3c1c0d42ce..f20b1447ce 100644 --- a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp +++ b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp @@ -215,18 +215,18 @@ bool PropertiesFile::loadAsXml() bool PropertiesFile::saveAsXml() { XmlElement doc (PropertyFileConstants::fileTag); + const StringPairArray& props = getAllProperties(); - for (int i = 0; i < getAllProperties().size(); ++i) + for (int i = 0; i < props.size(); ++i) { XmlElement* const e = doc.createNewChildElement (PropertyFileConstants::valueTag); - e->setAttribute (PropertyFileConstants::nameAttribute, getAllProperties().getAllKeys() [i]); + e->setAttribute (PropertyFileConstants::nameAttribute, props.getAllKeys() [i]); // if the value seems to contain xml, store it as such.. - if (XmlElement* const childElement = XmlDocument::parse (getAllProperties().getAllValues() [i])) + if (XmlElement* const childElement = XmlDocument::parse (props.getAllValues() [i])) e->addChildElement (childElement); else - e->setAttribute (PropertyFileConstants::valueAttribute, - getAllProperties().getAllValues() [i]); + e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]); } ProcessScopedLock pl (createProcessLock()); @@ -311,14 +311,17 @@ bool PropertiesFile::saveAsBinary() out->writeInt (PropertyFileConstants::magicNumber); } - const int numProperties = getAllProperties().size(); + const StringPairArray& props = getAllProperties(); + const int numProperties = props.size(); + const StringArray& keys = props.getAllKeys(); + const StringArray& values = props.getAllValues(); out->writeInt (numProperties); for (int i = 0; i < numProperties; ++i) { - out->writeString (getAllProperties().getAllKeys() [i]); - out->writeString (getAllProperties().getAllValues() [i]); + out->writeString (keys[i]); + out->writeString (values[i]); } out = nullptr;