Scanner (PluginListComponent& plc, AudioPluginFormat& format, PropertiesFile* properties, int threads) : 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), numThreads (threads), finished (false) { FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); if (path.getNumPaths() > 0) // if the path is empty, then paths aren't used for this format. { if (propertiesToUse != nullptr) path = getLastSearchPath (*propertiesToUse, formatToScan); 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(); } }
PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo, AudioPluginFormat& formatToLookFor, FileSearchPath directoriesToSearch, const bool recursive, const File& deadMansPedal) : list (listToAddTo), format (formatToLookFor), deadMansPedalFile (deadMansPedal), progress (0) { directoriesToSearch.removeRedundantPaths(); filesOrIdentifiersToScan = format.searchPathsForPlugins (directoriesToSearch, recursive); // 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.. const StringArray crashedPlugins (readDeadMansPedalFile (deadMansPedalFile)); for (int i = 0; i < crashedPlugins.size(); ++i) { const String f = crashedPlugins[i]; for (int j = filesOrIdentifiersToScan.size(); --j >= 0;) if (f == filesOrIdentifiersToScan[j]) filesOrIdentifiersToScan.move (j, -1); } applyBlacklistingsFromDeadMansPedal (listToAddTo, deadMansPedalFile); nextIndex.set (filesOrIdentifiersToScan.size()); }
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(); filesOrIdentifiersToScan = format.searchPathsForPlugins (directoriesToSearch, recursive, allowAsync); // 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 (listToAddTo, deadMansPedalFile); nextIndex.set (filesOrIdentifiersToScan.size()); }
//============================================================================== void FileSearchPathListComponent::setPath (const FileSearchPath& newPath) { if (newPath.toString() != path.toString()) { path = newPath; changed(); } }
Scanner (CabbagePluginListComponent& plc, AudioPluginFormat& format, const StringArray& filesOrIdentifiers, PropertiesFile* properties, bool allowPluginsWhichRequireAsynchronousInstantiation, int threads, const String& title, const String& text) : owner (plc), formatToScan (format), filesOrIdentifiersToScan (filesOrIdentifiers), propertiesToUse (properties), pathChooserWindow (TRANS("Select folders to scan..."), String(), AlertWindow::NoIcon), progressWindow (title, text, AlertWindow::NoIcon), progress (0.0), numThreads (threads), allowAsync (allowPluginsWhichRequireAsynchronousInstantiation), finished (false) { pathChooserWindow.setLookAndFeel(&owner.getLookAndFeel()); progressWindow.setLookAndFeel(&owner.getLookAndFeel()); FileSearchPath path (formatToScan.getDefaultLocationsToSearch()); // You need to use at least one thread when scanning plug-ins asynchronously jassert (! allowAsync || (numThreads > 0)); // If the filesOrIdentifiersToScan argumnent isn't empty, we should only scan these // If the path is empty, then paths aren't used for this format. if (filesOrIdentifiersToScan.isEmpty() && path.getNumPaths() > 0) { #if ! JUCE_IOS if (propertiesToUse != nullptr) path = getLastSearchPath (*propertiesToUse, formatToScan); #endif 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(); } }
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); } }
BEGIN_JUCE_NAMESPACE #include "juce_PluginDirectoryScanner.h" #include "juce_AudioPluginFormat.h" #include "../../io/files/juce_DirectoryIterator.h" //============================================================================== PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo, AudioPluginFormat& formatToLookFor, FileSearchPath directoriesToSearch, const bool recursive, const File& deadMansPedalFile_) : list (listToAddTo), format (formatToLookFor), deadMansPedalFile (deadMansPedalFile_), nextIndex (0), progress (0) { directoriesToSearch.removeRedundantPaths(); filesOrIdentifiersToScan = format.searchPathsForPlugins (directoriesToSearch, recursive); // 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.. const StringArray crashedPlugins (getDeadMansPedalFile()); for (int i = 0; i < crashedPlugins.size(); ++i) { const String f = crashedPlugins[i]; for (int j = filesOrIdentifiersToScan.size(); --j >= 0;) if (f == filesOrIdentifiersToScan[j]) filesOrIdentifiersToScan.move (j, -1); } }
void PluginListComponent::setLastSearchPath (PropertiesFile& properties, AudioPluginFormat& format, const FileSearchPath& newPath) { properties.setValue ("lastPluginScanPath_" + format.getName(), newPath.toString()); }
void PluginListComponent::scanFor (AudioPluginFormat* format) { #if JUCE_MODAL_LOOPS_PERMITTED if (format == nullptr) return; FileSearchPath path (format->getDefaultLocationsToSearch()); 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::returnKey); aw.addButton (TRANS("Cancel"), 0, KeyPress::escapeKey); if (aw.runModalLoop() == 0) return; path = pathList.getPath(); } if (propertiesToUse != nullptr) { propertiesToUse->setValue ("lastPluginScanPath_" + format->getName(), path.toString()); propertiesToUse->saveIfNeeded(); } double progress = 0.0; AlertWindow aw (TRANS("Scanning for plugins..."), TRANS("Searching for all possible plugin files..."), AlertWindow::NoIcon); aw.addButton (TRANS("Cancel"), 0, KeyPress::escapeKey); aw.addProgressBarComponent (progress); aw.enterModalState(); MessageManager::getInstance()->runDispatchLoopUntil (300); PluginDirectoryScanner scanner (list, *format, path, true, deadMansPedalFile); for (;;) { aw.setMessage (TRANS("Testing:\n\n") + scanner.getNextPluginFileThatWillBeScanned()); MessageManager::getInstance()->runDispatchLoopUntil (100); if (! scanner.scanNextFile (true)) break; if (! aw.isCurrentlyModal()) break; progress = scanner.getProgress(); } if (scanner.getFailedFiles().size() > 0) { StringArray shortNames; for (int i = 0; i < scanner.getFailedFiles().size(); ++i) shortNames.add (File (scanner.getFailedFiles()[i]).getFileName()); AlertWindow::showMessageBox (AlertWindow::InfoIcon, TRANS("Scan complete"), TRANS("Note that the following files appeared to be plugin files, but failed to load correctly:\n\n") + shortNames.joinIntoString (", ")); } #else jassertfalse; // this method needs refactoring to work without modal loops.. #endif }
void FileSearchPath::addPath (const FileSearchPath& other) { for (int i = 0; i < other.getNumPaths(); ++i) addIfNotAlreadyThere (other[i]); }