From 2f3dd2261aca114ed889aadca85cdf86f4f24632 Mon Sep 17 00:00:00 2001 From: jules Date: Thu, 31 Jan 2013 14:55:24 +0000 Subject: [PATCH] Clean-ups to the plugin scanning code. --- .../scanning/juce_KnownPluginList.cpp | 7 +- .../scanning/juce_KnownPluginList.h | 5 +- .../scanning/juce_PluginDirectoryScanner.cpp | 2 +- .../scanning/juce_PluginDirectoryScanner.h | 5 +- .../scanning/juce_PluginListComponent.cpp | 138 ++++++++++-------- 5 files changed, 94 insertions(+), 63 deletions(-) diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp index 7c0c5c2cea..3b02cb39cd 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp @@ -154,9 +154,14 @@ bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, OwnedArray found; if (scanner != nullptr) - scanner->findPluginTypesFor (format, found, fileOrIdentifier); + { + if (! scanner->findPluginTypesFor (format, found, fileOrIdentifier)) + addToBlacklist (fileOrIdentifier); + } else + { format.findAllTypesForFile (found, fileOrIdentifier); + } for (int i = 0; i < found.size(); ++i) { diff --git a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h index 41bcc16d4e..c861b9721f 100644 --- a/modules/juce_audio_processors/scanning/juce_KnownPluginList.h +++ b/modules/juce_audio_processors/scanning/juce_KnownPluginList.h @@ -186,7 +186,10 @@ public: CustomScanner(); virtual ~CustomScanner(); - virtual void findPluginTypesFor (AudioPluginFormat& format, + /** 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 & result, const String& fileOrIdentifier) = 0; }; diff --git a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp index d5f939a4be..02036ba059 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.cpp @@ -67,7 +67,7 @@ PluginDirectoryScanner::~PluginDirectoryScanner() } //============================================================================== -const String PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const +String PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const { return format.getNameOfPluginFromIdentifier (filesOrIdentifiersToScan [nextIndex]); } diff --git a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h index 391c5f6598..1f6651e5c6 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h +++ b/modules/juce_audio_processors/scanning/juce_PluginDirectoryScanner.h @@ -94,10 +94,9 @@ public: This is handy if you want to show the user which file is currently getting scanned. */ - const String getNextPluginFileThatWillBeScanned() const; + String getNextPluginFileThatWillBeScanned() const; - /** Returns the estimated progress, between 0 and 1. - */ + /** 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 diff --git a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp index dc70e0a167..32e95049b3 100644 --- a/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp +++ b/modules/juce_audio_processors/scanning/juce_PluginListComponent.cpp @@ -119,7 +119,8 @@ void PluginListComponent::paintListBoxItem (int row, Graphics& g, int width, int if (name.isNotEmpty()) { GlyphArrangement ga; - ga.addCurtailedLineOfText (Font (height * 0.7f, Font::bold), name, 8.0f, height * 0.8f, width - 10.0f, true); + ga.addCurtailedLineOfText (Font (height * 0.7f, Font::bold), + name, 8.0f, height * 0.8f, width - 10.0f, true); g.setColour (isBlacklisted ? Colours::red : Colours::black); ga.draw (g); @@ -249,23 +250,37 @@ class PluginListComponent::Scanner : private Timer, public: Scanner (PluginListComponent& plc, AudioPluginFormat& format, - const FileSearchPath& path, + PropertiesFile* properties, bool useThread) : Thread ("plugin_scan"), - owner (plc), - aw (TRANS("Scanning for plug-ins..."), - TRANS("Searching for all possible plug-in files..."), AlertWindow::NoIcon), - progress (0.0), finished (false), - scanner (owner.list, format, path, true, owner.deadMansPedalFile) + owner (plc), formatToScan (format), propertiesToUse (properties), + pathChooserWindow (TRANS("Select folders to scan..."), String::empty, AlertWindow::NoIcon), + progressWindow (TRANS("Scanning for plug-ins..."), + TRANS("Searching for all possible plug-in files..."), AlertWindow::NoIcon), + progress (0.0), shouldUseThread (useThread), finished (false) { - aw.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey)); - aw.addProgressBarComponent (progress); - aw.enterModalState(); + FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); - if (useThread) - startThread(); + if (path.getNumPaths() > 0) // if the path is empty, then paths aren't used for this format. + { + if (propertiesToUse != nullptr) + path = propertiesToUse->getValue ("lastPluginScanPath_" + formatToScan.getName(), path.toString()); - startTimer (20); + pathList.setSize (500, 300); + pathList.setPath (path); + + pathChooserWindow.addCustomComponent (&pathList); + pathChooserWindow.addButton (TRANS("Scan"), 1, KeyPress (KeyPress::returnKey)); + pathChooserWindow.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey)); + + pathChooserWindow.enterModalState (true, + ModalCallbackFunction::forComponent (startScanCallback, &pathChooserWindow, this), + false); + } + else + { + startScan(); + } } ~Scanner() @@ -274,6 +289,46 @@ public: } private: + static void startScanCallback (int result, AlertWindow* alert, Scanner* scanner) + { + if (alert != nullptr && scanner != nullptr) + { + if (result != 0) + scanner->startScan(); + else + scanner->finishedScan(); + } + } + + void startScan() + { + pathChooserWindow.setVisible (false); + + scanner = new PluginDirectoryScanner (owner.list, formatToScan, pathList.getPath(), + true, owner.deadMansPedalFile); + + if (propertiesToUse != nullptr) + { + propertiesToUse->setValue ("lastPluginScanPath_" + formatToScan.getName(), pathList.getPath().toString()); + propertiesToUse->saveIfNeeded(); + } + + progressWindow.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey)); + progressWindow.addProgressBarComponent (progress); + progressWindow.enterModalState(); + + if (shouldUseThread) + startThread(); + + startTimer (20); + } + + void finishedScan() + { + owner.scanFinished (scanner != nullptr ? scanner->getFailedFiles() + : StringArray()); + } + void timerCallback() { if (! isThreadRunning()) @@ -282,13 +337,13 @@ private: startTimer (20); } - if (! aw.isCurrentlyModal()) + if (! progressWindow.isCurrentlyModal()) finished = true; if (finished) - owner.scanFinished (scanner.getFailedFiles()); + finishedScan(); else - aw.setMessage (progressMessage); + progressWindow.setMessage (progressMessage); } void run() @@ -299,11 +354,11 @@ private: bool doNextScan() { - progressMessage = TRANS("Testing:\n\n") + scanner.getNextPluginFileThatWillBeScanned(); + progressMessage = TRANS("Testing:\n\n") + scanner->getNextPluginFileThatWillBeScanned(); - if (scanner.scanNextFile (true)) + if (scanner->scanNextFile (true)) { - progress = scanner.getProgress(); + progress = scanner->getProgress(); return true; } @@ -311,12 +366,15 @@ private: return false; } + ScopedPointer scanner; + AlertWindow pathChooserWindow, progressWindow; + FileSearchPathListComponent pathList; PluginListComponent& owner; - AlertWindow aw; + AudioPluginFormat& formatToScan; + PropertiesFile* propertiesToUse; String progressMessage; double progress; - bool finished; - PluginDirectoryScanner scanner; + bool shouldUseThread, finished; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Scanner) }; @@ -324,41 +382,7 @@ private: void PluginListComponent::scanFor (AudioPluginFormat* format) { if (format != nullptr) - { - FileSearchPath path (format->getDefaultLocationsToSearch()); - - if (path.getNumPaths() > 0) // if the path is empty, then paths aren't used for this format. - { - #if JUCE_MODAL_LOOPS_PERMITTED - if (propertiesToUse != nullptr) - path = propertiesToUse->getValue ("lastPluginScanPath_" + format->getName(), path.toString()); - - AlertWindow aw (TRANS("Select folders to scan..."), String::empty, AlertWindow::NoIcon); - FileSearchPathListComponent pathList; - pathList.setSize (500, 300); - pathList.setPath (path); - - aw.addCustomComponent (&pathList); - aw.addButton (TRANS("Scan"), 1, KeyPress (KeyPress::returnKey)); - aw.addButton (TRANS("Cancel"), 0, KeyPress (KeyPress::escapeKey)); - - if (aw.runModalLoop() == 0) - return; - - path = pathList.getPath(); - #else - jassertfalse; // XXX this method needs refactoring to work without modal loops.. - #endif - } - - if (propertiesToUse != nullptr) - { - propertiesToUse->setValue ("lastPluginScanPath_" + format->getName(), path.toString()); - propertiesToUse->saveIfNeeded(); - } - - currentScanner = new Scanner (*this, *format, path, scanOnBackgroundThread); - } + currentScanner = new Scanner (*this, *format, propertiesToUse, scanOnBackgroundThread); } void PluginListComponent::scanFinished (const StringArray& failedFiles)