| @@ -389,11 +389,7 @@ bool InternalPluginFormat::requiresUnblockedMessageThreadDuringCreation (const P | |||
| return false; | |||
| } | |||
| void InternalPluginFormat::getAllTypes (OwnedArray<PluginDescription>& results) | |||
| void InternalPluginFormat::getAllTypes (Array<PluginDescription>& results) | |||
| { | |||
| results.add (new PluginDescription (audioInDesc)); | |||
| results.add (new PluginDescription (audioOutDesc)); | |||
| results.add (new PluginDescription (midiInDesc)); | |||
| results.add (new PluginDescription (SineWaveSynth::getPluginDescription())); | |||
| results.add (new PluginDescription (ReverbFilter::getPluginDescription())); | |||
| results.add (audioInDesc, audioOutDesc, midiInDesc, SineWaveSynth::getPluginDescription(), ReverbFilter::getPluginDescription()); | |||
| } | |||
| @@ -42,8 +42,7 @@ public: | |||
| //============================================================================== | |||
| PluginDescription audioInDesc, audioOutDesc, midiInDesc; | |||
| void getAllTypes (OwnedArray<PluginDescription>&); | |||
| void getAllTypes (Array<PluginDescription>&); | |||
| //============================================================================== | |||
| String getName() const override { return "Internal"; } | |||
| @@ -844,9 +844,9 @@ void GraphEditorPanel::showPopupMenu (Point<int> mousePos) | |||
| menu->showMenuAsync ({}, | |||
| ModalCallbackFunction::create ([this, mousePos] (int r) | |||
| { | |||
| if (auto* mainWin = findParentComponentOfClass<MainHostWindow>()) | |||
| if (auto* desc = mainWin->getChosenType (r)) | |||
| createNewPlugin (*desc, mousePos); | |||
| if (r > 0) | |||
| if (auto* mainWin = findParentComponentOfClass<MainHostWindow>()) | |||
| createNewPlugin (mainWin->getChosenType (r), mousePos); | |||
| })); | |||
| } | |||
| } | |||
| @@ -1114,10 +1114,7 @@ struct GraphDocumentComponent::PluginListBoxModel : public ListBoxModel, | |||
| g.setColour (rowIsSelected ? Colours::black : Colours::white); | |||
| if (rowNumber < knownPlugins.getNumTypes()) | |||
| g.drawFittedText (knownPlugins.getType (rowNumber)->name, | |||
| { 0, 0, width, height - 2 }, | |||
| Justification::centred, | |||
| 1); | |||
| g.drawFittedText (knownPlugins.getTypes()[rowNumber].name, { 0, 0, width, height - 2 }, Justification::centred, 1); | |||
| g.setColour (Colours::black.withAlpha (0.4f)); | |||
| g.drawRect (0, height - 1, width, 1); | |||
| @@ -1283,7 +1280,7 @@ void GraphDocumentComponent::itemDropped (const SourceDetails& details) | |||
| // must be a valid index! | |||
| jassert (isPositiveAndBelow (pluginTypeIndex, pluginList.getNumTypes())); | |||
| createNewPlugin (*pluginList.getType (pluginTypeIndex), details.localPosition); | |||
| createNewPlugin (pluginList.getTypes()[pluginTypeIndex], details.localPosition); | |||
| } | |||
| void GraphDocumentComponent::showSidePanel (bool showSettingsPanel) | |||
| @@ -111,8 +111,8 @@ MainHostWindow::MainHostWindow() | |||
| if (auto savedPluginList = getAppProperties().getUserSettings()->getXmlValue ("pluginList")) | |||
| knownPluginList.recreateFromXml (*savedPluginList); | |||
| for (auto* t : internalTypes) | |||
| knownPluginList.addType (*t); | |||
| for (auto& t : internalTypes) | |||
| knownPluginList.addType (t); | |||
| pluginSortMethod = (KnownPluginList::SortMethod) getAppProperties().getUserSettings() | |||
| ->getIntValue ("pluginSortMethod", KnownPluginList::sortByManufacturer); | |||
| @@ -346,10 +346,9 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/ | |||
| } | |||
| else | |||
| { | |||
| if (auto* desc = getChosenType (menuItemID)) | |||
| createPlugin (*desc, | |||
| { proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f), | |||
| proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) }); | |||
| if (knownPluginList.getIndexChosenByMenu (menuItemID) >= 0) | |||
| createPlugin (getChosenType (menuItemID), { proportionOfWidth (0.3f + Random::getSystemRandom().nextFloat() * 0.6f), | |||
| proportionOfHeight (0.3f + Random::getSystemRandom().nextFloat() * 0.6f) }); | |||
| } | |||
| } | |||
| @@ -371,9 +370,9 @@ void MainHostWindow::addPluginsToMenu (PopupMenu& m) const | |||
| { | |||
| int i = 0; | |||
| for (auto* t : internalTypes) | |||
| m.addItem (++i, t->name + " (" + t->pluginFormatName + ")", | |||
| graphHolder->graph->getNodeForName (t->name) == nullptr); | |||
| for (auto& t : internalTypes) | |||
| m.addItem (++i, t.name + " (" + t.pluginFormatName + ")", | |||
| graphHolder->graph->getNodeForName (t.name) == nullptr); | |||
| } | |||
| m.addSeparator(); | |||
| @@ -381,12 +380,12 @@ void MainHostWindow::addPluginsToMenu (PopupMenu& m) const | |||
| knownPluginList.addToMenu (m, pluginSortMethod); | |||
| } | |||
| const PluginDescription* MainHostWindow::getChosenType (const int menuID) const | |||
| PluginDescription MainHostWindow::getChosenType (const int menuID) const | |||
| { | |||
| if (menuID >= 1 && menuID < 1 + internalTypes.size()) | |||
| return internalTypes [menuID - 1]; | |||
| return knownPluginList.getType (knownPluginList.getIndexChosenByMenu (menuID)); | |||
| return knownPluginList.getTypes()[knownPluginList.getIndexChosenByMenu (menuID)]; | |||
| } | |||
| //============================================================================== | |||
| @@ -87,7 +87,7 @@ public: | |||
| void createPlugin (const PluginDescription&, Point<int> pos); | |||
| void addPluginsToMenu (PopupMenu&) const; | |||
| const PluginDescription* getChosenType (int menuID) const; | |||
| PluginDescription getChosenType (int menuID) const; | |||
| bool isDoublePrecisionProcessing(); | |||
| void updatePrecisionMenuItem (ApplicationCommandInfo& info); | |||
| @@ -99,7 +99,7 @@ private: | |||
| AudioDeviceManager deviceManager; | |||
| AudioPluginFormatManager formatManager; | |||
| OwnedArray<PluginDescription> internalTypes; | |||
| Array<PluginDescription> internalTypes; | |||
| KnownPluginList knownPluginList; | |||
| KnownPluginList::SortMethod pluginSortMethod; | |||
| @@ -27,57 +27,6 @@ | |||
| namespace juce | |||
| { | |||
| PluginDescription::PluginDescription() | |||
| : uid (0), | |||
| isInstrument (false), | |||
| numInputChannels (0), | |||
| numOutputChannels (0), | |||
| hasSharedContainer (false) | |||
| { | |||
| } | |||
| PluginDescription::~PluginDescription() | |||
| { | |||
| } | |||
| PluginDescription::PluginDescription (const PluginDescription& other) | |||
| : name (other.name), | |||
| descriptiveName (other.descriptiveName), | |||
| pluginFormatName (other.pluginFormatName), | |||
| category (other.category), | |||
| manufacturerName (other.manufacturerName), | |||
| version (other.version), | |||
| fileOrIdentifier (other.fileOrIdentifier), | |||
| lastFileModTime (other.lastFileModTime), | |||
| lastInfoUpdateTime (other.lastInfoUpdateTime), | |||
| uid (other.uid), | |||
| isInstrument (other.isInstrument), | |||
| numInputChannels (other.numInputChannels), | |||
| numOutputChannels (other.numOutputChannels), | |||
| hasSharedContainer (other.hasSharedContainer) | |||
| { | |||
| } | |||
| PluginDescription& PluginDescription::operator= (const PluginDescription& other) | |||
| { | |||
| name = other.name; | |||
| descriptiveName = other.descriptiveName; | |||
| pluginFormatName = other.pluginFormatName; | |||
| category = other.category; | |||
| manufacturerName = other.manufacturerName; | |||
| version = other.version; | |||
| fileOrIdentifier = other.fileOrIdentifier; | |||
| uid = other.uid; | |||
| isInstrument = other.isInstrument; | |||
| lastFileModTime = other.lastFileModTime; | |||
| lastInfoUpdateTime = other.lastInfoUpdateTime; | |||
| numInputChannels = other.numInputChannels; | |||
| numOutputChannels = other.numOutputChannels; | |||
| hasSharedContainer = other.hasSharedContainer; | |||
| return *this; | |||
| } | |||
| bool PluginDescription::isDuplicateOf (const PluginDescription& other) const noexcept | |||
| { | |||
| return fileOrIdentifier == other.fileOrIdentifier | |||
| @@ -44,10 +44,10 @@ class JUCE_API PluginDescription | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| PluginDescription(); | |||
| PluginDescription (const PluginDescription& other); | |||
| PluginDescription& operator= (const PluginDescription& other); | |||
| ~PluginDescription(); | |||
| PluginDescription() = default; | |||
| PluginDescription (const PluginDescription& other) = default; | |||
| PluginDescription& operator= (const PluginDescription& other) = default; | |||
| //============================================================================== | |||
| /** The name of the plug-in. */ | |||
| @@ -96,19 +96,19 @@ public: | |||
| @see createIdentifierString | |||
| */ | |||
| int uid; | |||
| int uid = 0; | |||
| /** True if the plug-in identifies itself as a synthesiser. */ | |||
| bool isInstrument; | |||
| bool isInstrument = false; | |||
| /** The number of inputs. */ | |||
| int numInputChannels; | |||
| int numInputChannels = 0; | |||
| /** The number of outputs. */ | |||
| int numOutputChannels; | |||
| int numOutputChannels = 0; | |||
| /** True if the plug-in is part of a multi-type container, e.g. a VST Shell. */ | |||
| bool hasSharedContainer; | |||
| bool hasSharedContainer = false; | |||
| /** Returns true if the two descriptions refer to the same plug-in. | |||
| @@ -41,26 +41,38 @@ void KnownPluginList::clear() | |||
| } | |||
| } | |||
| PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const | |||
| int KnownPluginList::getNumTypes() const noexcept | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| return types.size(); | |||
| } | |||
| Array<PluginDescription> KnownPluginList::getTypes() const | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| return types; | |||
| } | |||
| for (auto* desc : types) | |||
| if (desc->fileOrIdentifier == fileOrIdentifier) | |||
| return desc; | |||
| std::unique_ptr<PluginDescription> KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| for (auto& desc : types) | |||
| if (desc.fileOrIdentifier == fileOrIdentifier) | |||
| return std::make_unique<PluginDescription> (desc); | |||
| return nullptr; | |||
| return {}; | |||
| } | |||
| PluginDescription* KnownPluginList::getTypeForIdentifierString (const String& identifierString) const | |||
| std::unique_ptr<PluginDescription> KnownPluginList::getTypeForIdentifierString (const String& identifierString) const | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| for (auto* desc : types) | |||
| if (desc->matchesIdentifierString (identifierString)) | |||
| return desc; | |||
| for (auto& desc : types) | |||
| if (desc.matchesIdentifierString (identifierString)) | |||
| return std::make_unique<PluginDescription> (desc); | |||
| return nullptr; | |||
| return {}; | |||
| } | |||
| bool KnownPluginList::addType (const PluginDescription& type) | |||
| @@ -68,31 +80,34 @@ bool KnownPluginList::addType (const PluginDescription& type) | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| for (auto* desc : types) | |||
| for (auto& desc : types) | |||
| { | |||
| if (desc->isDuplicateOf (type)) | |||
| if (desc.isDuplicateOf (type)) | |||
| { | |||
| // strange - found a duplicate plugin with different info.. | |||
| jassert (desc->name == type.name); | |||
| jassert (desc->isInstrument == type.isInstrument); | |||
| jassert (desc.name == type.name); | |||
| jassert (desc.isInstrument == type.isInstrument); | |||
| *desc = type; | |||
| desc = type; | |||
| return false; | |||
| } | |||
| } | |||
| types.insert (0, new PluginDescription (type)); | |||
| types.insert (0, type); | |||
| } | |||
| sendChangeMessage(); | |||
| return true; | |||
| } | |||
| void KnownPluginList::removeType (const int index) | |||
| void KnownPluginList::removeType (const PluginDescription& type) | |||
| { | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| types.remove (index); | |||
| for (auto& desc : types) | |||
| if (desc.isDuplicateOf (type)) | |||
| types.remove (&desc); | |||
| } | |||
| sendChangeMessage(); | |||
| @@ -106,16 +121,17 @@ bool KnownPluginList::isListingUpToDate (const String& fileOrIdentifier, | |||
| ScopedLock lock (typesArrayLock); | |||
| for (auto* d : types) | |||
| if (d->fileOrIdentifier == fileOrIdentifier && formatToUse.pluginNeedsRescanning (*d)) | |||
| for (auto& d : types) | |||
| if (d.fileOrIdentifier == fileOrIdentifier && formatToUse.pluginNeedsRescanning (d)) | |||
| return false; | |||
| return true; | |||
| } | |||
| void KnownPluginList::setCustomScanner (CustomScanner* newScanner) | |||
| void KnownPluginList::setCustomScanner (std::unique_ptr<CustomScanner> newScanner) | |||
| { | |||
| scanner.reset (newScanner); | |||
| if (scanner != newScanner) | |||
| scanner = std::move (newScanner); | |||
| } | |||
| bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, | |||
| @@ -132,14 +148,14 @@ bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier, | |||
| ScopedLock lock (typesArrayLock); | |||
| for (auto* d : types) | |||
| for (auto& d : types) | |||
| { | |||
| if (d->fileOrIdentifier == fileOrIdentifier && d->pluginFormatName == format.getName()) | |||
| if (d.fileOrIdentifier == fileOrIdentifier && d.pluginFormatName == format.getName()) | |||
| { | |||
| if (format.pluginNeedsRescanning (*d)) | |||
| if (format.pluginNeedsRescanning (d)) | |||
| needsRescanning = true; | |||
| else | |||
| typesFound.add (new PluginDescription (*d)); | |||
| typesFound.add (new PluginDescription (d)); | |||
| } | |||
| } | |||
| @@ -198,7 +214,7 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (AudioPluginFormatManager& f | |||
| if (! found) | |||
| { | |||
| const File f (filenameOrID); | |||
| File f (filenameOrID); | |||
| if (f.isDirectory()) | |||
| { | |||
| @@ -261,22 +277,22 @@ struct PluginSorter | |||
| PluginSorter (KnownPluginList::SortMethod sortMethod, bool forwards) noexcept | |||
| : method (sortMethod), direction (forwards ? 1 : -1) {} | |||
| bool operator() (const PluginDescription* first, const PluginDescription* second) const | |||
| bool operator() (const PluginDescription& first, const PluginDescription& second) const | |||
| { | |||
| int diff = 0; | |||
| switch (method) | |||
| { | |||
| case KnownPluginList::sortByCategory: diff = first->category.compareNatural (second->category, false); break; | |||
| case KnownPluginList::sortByManufacturer: diff = first->manufacturerName.compareNatural (second->manufacturerName, false); break; | |||
| case KnownPluginList::sortByFormat: diff = first->pluginFormatName.compare (second->pluginFormatName); break; | |||
| case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first->fileOrIdentifier).compare (lastPathPart (second->fileOrIdentifier)); break; | |||
| case KnownPluginList::sortByInfoUpdateTime: diff = compare (first->lastInfoUpdateTime, second->lastInfoUpdateTime); break; | |||
| case KnownPluginList::sortByCategory: diff = first.category.compareNatural (second.category, false); break; | |||
| case KnownPluginList::sortByManufacturer: diff = first.manufacturerName.compareNatural (second.manufacturerName, false); break; | |||
| case KnownPluginList::sortByFormat: diff = first.pluginFormatName.compare (second.pluginFormatName); break; | |||
| case KnownPluginList::sortByFileSystemLocation: diff = lastPathPart (first.fileOrIdentifier).compare (lastPathPart (second.fileOrIdentifier)); break; | |||
| case KnownPluginList::sortByInfoUpdateTime: diff = compare (first.lastInfoUpdateTime, second.lastInfoUpdateTime); break; | |||
| default: break; | |||
| } | |||
| if (diff == 0) | |||
| diff = first->name.compareNatural (second->name, false); | |||
| diff = first.name.compareNatural (second.name, false); | |||
| return diff * direction < 0; | |||
| } | |||
| @@ -303,7 +319,7 @@ void KnownPluginList::sort (const SortMethod method, bool forwards) | |||
| { | |||
| if (method != defaultOrder) | |||
| { | |||
| Array<PluginDescription*> oldOrder, newOrder; | |||
| Array<PluginDescription> oldOrder, newOrder; | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| @@ -313,7 +329,16 @@ void KnownPluginList::sort (const SortMethod method, bool forwards) | |||
| newOrder.addArray (types); | |||
| } | |||
| if (oldOrder != newOrder) | |||
| auto hasOrderChanged = [&] | |||
| { | |||
| for (int i = 0; i < oldOrder.size(); ++i) | |||
| if (! oldOrder[i].isDuplicateOf (newOrder[i])) | |||
| return true; | |||
| return false; | |||
| }(); | |||
| if (hasOrderChanged) | |||
| sendChangeMessage(); | |||
| } | |||
| } | |||
| @@ -327,7 +352,7 @@ std::unique_ptr<XmlElement> KnownPluginList::createXml() const | |||
| ScopedLock lock (typesArrayLock); | |||
| for (int i = types.size(); --i >= 0;) | |||
| e->prependChildElement (types.getUnchecked(i)->createXml().release()); | |||
| e->prependChildElement (types.getUnchecked (i).createXml().release()); | |||
| } | |||
| for (auto& b : blacklist) | |||
| @@ -360,12 +385,12 @@ struct PluginTreeUtils | |||
| { | |||
| enum { menuIdBase = 0x324503f4 }; | |||
| static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array<PluginDescription*>& allPlugins) | |||
| static void buildTreeByFolder (KnownPluginList::PluginTree& tree, const Array<PluginDescription>& allPlugins) | |||
| { | |||
| for (auto* pd : allPlugins) | |||
| for (auto& pd : allPlugins) | |||
| { | |||
| auto path = pd->fileOrIdentifier.replaceCharacter ('\\', '/') | |||
| .upToLastOccurrenceOf ("/", false, false); | |||
| auto path = pd.fileOrIdentifier.replaceCharacter ('\\', '/') | |||
| .upToLastOccurrenceOf ("/", false, false); | |||
| if (path.substring (1, 2) == ":") | |||
| path = path.substring (2); | |||
| @@ -400,16 +425,16 @@ struct PluginTreeUtils | |||
| } | |||
| static void buildTreeByCategory (KnownPluginList::PluginTree& tree, | |||
| const Array<PluginDescription*>& sorted, | |||
| const Array<PluginDescription>& sorted, | |||
| const KnownPluginList::SortMethod sortMethod) | |||
| { | |||
| String lastType; | |||
| std::unique_ptr<KnownPluginList::PluginTree> current (new KnownPluginList::PluginTree()); | |||
| auto current = std::make_unique<KnownPluginList::PluginTree>(); | |||
| for (auto* pd : sorted) | |||
| for (auto& pd : sorted) | |||
| { | |||
| auto thisType = (sortMethod == KnownPluginList::sortByCategory ? pd->category | |||
| : pd->manufacturerName); | |||
| auto thisType = (sortMethod == KnownPluginList::sortByCategory ? pd.category | |||
| : pd.manufacturerName); | |||
| if (! thisType.containsNonWhitespaceChars()) | |||
| thisType = "Other"; | |||
| @@ -420,7 +445,7 @@ struct PluginTreeUtils | |||
| { | |||
| current->folder = lastType; | |||
| tree.subFolders.add (std::move (current)); | |||
| current.reset (new KnownPluginList::PluginTree()); | |||
| current = std::make_unique<KnownPluginList::PluginTree>(); | |||
| } | |||
| lastType = thisType; | |||
| @@ -436,7 +461,7 @@ struct PluginTreeUtils | |||
| } | |||
| } | |||
| static void addPlugin (KnownPluginList::PluginTree& tree, PluginDescription* const pd, String path) | |||
| static void addPlugin (KnownPluginList::PluginTree& tree, PluginDescription pd, String path) | |||
| { | |||
| if (path.isEmpty()) | |||
| { | |||
| @@ -454,7 +479,7 @@ struct PluginTreeUtils | |||
| for (int i = tree.subFolders.size(); --i >= 0;) | |||
| { | |||
| KnownPluginList::PluginTree& subFolder = *tree.subFolders.getUnchecked(i); | |||
| auto& subFolder = *tree.subFolders.getUnchecked (i); | |||
| if (subFolder.folder.equalsIgnoreCase (firstSubFolder)) | |||
| { | |||
| @@ -463,27 +488,26 @@ struct PluginTreeUtils | |||
| } | |||
| } | |||
| auto newFolder = new KnownPluginList::PluginTree(); | |||
| auto* newFolder = new KnownPluginList::PluginTree(); | |||
| newFolder->folder = firstSubFolder; | |||
| tree.subFolders.add (newFolder); | |||
| addPlugin (*newFolder, pd, remainingPath); | |||
| } | |||
| } | |||
| static bool containsDuplicateNames (const Array<const PluginDescription*>& plugins, const String& name) | |||
| static bool containsDuplicateNames (const Array<PluginDescription>& plugins, const String& name) | |||
| { | |||
| int matches = 0; | |||
| for (int i = 0; i < plugins.size(); ++i) | |||
| if (plugins.getUnchecked(i)->name == name) | |||
| if (++matches > 1) | |||
| return true; | |||
| for (auto& p : plugins) | |||
| if (p.name == name && ++matches > 1) | |||
| return true; | |||
| return false; | |||
| } | |||
| static bool addToMenu (const KnownPluginList::PluginTree& tree, PopupMenu& m, | |||
| const OwnedArray<PluginDescription>& allPlugins, | |||
| const Array<PluginDescription>& allPlugins, | |||
| const String& currentlyTickedPluginID) | |||
| { | |||
| bool isTicked = false; | |||
| @@ -491,32 +515,47 @@ struct PluginTreeUtils | |||
| for (auto* sub : tree.subFolders) | |||
| { | |||
| PopupMenu subMenu; | |||
| const bool isItemTicked = addToMenu (*sub, subMenu, allPlugins, currentlyTickedPluginID); | |||
| auto isItemTicked = addToMenu (*sub, subMenu, allPlugins, currentlyTickedPluginID); | |||
| isTicked = isTicked || isItemTicked; | |||
| m.addSubMenu (sub->folder, subMenu, true, nullptr, isItemTicked, 0); | |||
| } | |||
| for (auto* plugin : tree.plugins) | |||
| auto getPluginMenuIndex = [&] (const PluginDescription& d) | |||
| { | |||
| int i = 0; | |||
| for (auto& p : allPlugins) | |||
| { | |||
| if (p.isDuplicateOf (d)) | |||
| return i + menuIdBase; | |||
| ++i; | |||
| } | |||
| return 0; | |||
| }; | |||
| for (auto& plugin : tree.plugins) | |||
| { | |||
| auto name = plugin->name; | |||
| auto name = plugin.name; | |||
| if (containsDuplicateNames (tree.plugins, name)) | |||
| name << " (" << plugin->pluginFormatName << ')'; | |||
| name << " (" << plugin.pluginFormatName << ')'; | |||
| const bool isItemTicked = plugin->matchesIdentifierString (currentlyTickedPluginID); | |||
| auto isItemTicked = plugin.matchesIdentifierString (currentlyTickedPluginID); | |||
| isTicked = isTicked || isItemTicked; | |||
| m.addItem (allPlugins.indexOf (plugin) + menuIdBase, name, true, isItemTicked); | |||
| m.addItem (getPluginMenuIndex (plugin), name, true, isItemTicked); | |||
| } | |||
| return isTicked; | |||
| } | |||
| }; | |||
| KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortMethod) const | |||
| std::unique_ptr<KnownPluginList::PluginTree> KnownPluginList::createTree (const SortMethod sortMethod) const | |||
| { | |||
| Array<PluginDescription*> sorted; | |||
| Array<PluginDescription> sorted; | |||
| { | |||
| ScopedLock lock (typesArrayLock); | |||
| @@ -525,7 +564,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM | |||
| std::stable_sort (sorted.begin(), sorted.end(), PluginSorter (sortMethod, true)); | |||
| auto* tree = new PluginTree(); | |||
| auto tree = std::make_unique<PluginTree>(); | |||
| if (sortMethod == sortByCategory || sortMethod == sortByManufacturer || sortMethod == sortByFormat) | |||
| { | |||
| @@ -537,7 +576,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM | |||
| } | |||
| else | |||
| { | |||
| for (auto* p : sorted) | |||
| for (auto& p : sorted) | |||
| tree->plugins.add (p); | |||
| } | |||
| @@ -548,7 +587,7 @@ KnownPluginList::PluginTree* KnownPluginList::createTree (const SortMethod sortM | |||
| void KnownPluginList::addToMenu (PopupMenu& menu, const SortMethod sortMethod, | |||
| const String& currentlyTickedPluginID) const | |||
| { | |||
| std::unique_ptr<PluginTree> tree (createTree (sortMethod)); | |||
| auto tree = createTree (sortMethod); | |||
| PluginTreeUtils::addToMenu (*tree, menu, types, currentlyTickedPluginID); | |||
| } | |||
| @@ -52,37 +52,27 @@ public: | |||
| /** Clears the list. */ | |||
| void clear(); | |||
| /** Returns the number of types currently in the list. | |||
| @see getType | |||
| */ | |||
| int getNumTypes() const noexcept { return types.size(); } | |||
| /** Adds a type manually from its description. */ | |||
| bool addType (const PluginDescription& type); | |||
| /** Returns one of the types. | |||
| @see getNumTypes | |||
| */ | |||
| PluginDescription* getType (int index) const noexcept { return types [index]; } | |||
| /** Removes a type. */ | |||
| void removeType (const PluginDescription& type); | |||
| /** Type iteration. */ | |||
| PluginDescription** begin() const noexcept { return types.begin(); } | |||
| /** Returns the number of types currently in the list. */ | |||
| int getNumTypes() const noexcept; | |||
| /** Type iteration. */ | |||
| PluginDescription** end() const noexcept { return types.end(); } | |||
| /** Returns a copy of the current list. */ | |||
| Array<PluginDescription> getTypes() const; | |||
| /** Looks for a type in the list which comes from this file. */ | |||
| PluginDescription* getTypeForFile (const String& fileOrIdentifier) const; | |||
| 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(). | |||
| */ | |||
| PluginDescription* getTypeForIdentifierString (const String& identifierString) const; | |||
| /** Adds a type manually from its description. */ | |||
| bool addType (const PluginDescription& type); | |||
| /** Removes a type. */ | |||
| void removeType (int index); | |||
| 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. | |||
| @@ -153,7 +143,7 @@ public: | |||
| Use getIndexChosenByMenu() to find out the type that was chosen. | |||
| */ | |||
| void addToMenu (PopupMenu& menu, SortMethod sortMethod, | |||
| const String& currentlyTickedPluginID = String()) const; | |||
| const String& currentlyTickedPluginID = {}) const; | |||
| /** Converts a menu item index that has been chosen into its index in this list. | |||
| Returns -1 if it's not an ID that was used. | |||
| @@ -180,11 +170,11 @@ public: | |||
| { | |||
| String folder; /**< The name of this folder in the tree */ | |||
| OwnedArray<PluginTree> subFolders; | |||
| Array<const PluginDescription*> plugins; | |||
| Array<PluginDescription> plugins; | |||
| }; | |||
| /** Creates a PluginTree object containing all the known plugins. */ | |||
| PluginTree* createTree (const SortMethod sortMethod) const; | |||
| std::unique_ptr<PluginTree> createTree (const SortMethod sortMethod) const; | |||
| //============================================================================== | |||
| /** Class to define a custom plugin scanner */ | |||
| @@ -214,11 +204,19 @@ public: | |||
| /** Supplies a custom scanner to be used in future scans. | |||
| The KnownPluginList will take ownership of the object passed in. | |||
| */ | |||
| void setCustomScanner (CustomScanner*); | |||
| void setCustomScanner (std::unique_ptr<CustomScanner> newScanner); | |||
| //============================================================================== | |||
| // 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. | |||
| JUCE_DEPRECATED_WITH_BODY (PluginDescription* getType (int index) const noexcept, { return &types.getReference (index); }) | |||
| JUCE_DEPRECATED_WITH_BODY (PluginDescription** begin() const noexcept, { jassertfalse; return nullptr; }) | |||
| JUCE_DEPRECATED_WITH_BODY (PluginDescription** end() const noexcept, { jassertfalse; return nullptr; }) | |||
| private: | |||
| //============================================================================== | |||
| OwnedArray<PluginDescription> types; | |||
| Array<PluginDescription> types; | |||
| StringArray blacklist; | |||
| std::unique_ptr<CustomScanner> scanner; | |||
| CriticalSection scanLock, typesArrayLock; | |||
| @@ -67,15 +67,17 @@ public: | |||
| else if (columnId == descCol) | |||
| text = TRANS("Deactivated after failing to initialise correctly"); | |||
| } | |||
| else if (const PluginDescription* const desc = list.getType (row)) | |||
| else | |||
| { | |||
| auto desc = list.getTypes()[row]; | |||
| switch (columnId) | |||
| { | |||
| case nameCol: text = desc->name; break; | |||
| case typeCol: text = desc->pluginFormatName; break; | |||
| case categoryCol: text = desc->category.isNotEmpty() ? desc->category : "-"; break; | |||
| case manufacturerCol: text = desc->manufacturerName; break; | |||
| case descCol: text = getPluginDescription (*desc); break; | |||
| case nameCol: text = desc.name; break; | |||
| case typeCol: text = desc.pluginFormatName; break; | |||
| case categoryCol: text = desc.category.isNotEmpty() ? desc.category : "-"; break; | |||
| case manufacturerCol: text = desc.manufacturerName; break; | |||
| case descCol: text = getPluginDescription (desc); break; | |||
| default: jassertfalse; break; | |||
| } | |||
| @@ -238,30 +240,32 @@ void PluginListComponent::setTableModel (TableListBoxModel* model) | |||
| bool PluginListComponent::canShowSelectedFolder() const | |||
| { | |||
| if (const PluginDescription* const desc = list.getType (table.getSelectedRow())) | |||
| return File::createFileWithoutCheckingPath (desc->fileOrIdentifier).exists(); | |||
| return false; | |||
| return File::createFileWithoutCheckingPath (list.getTypes()[table.getSelectedRow()].fileOrIdentifier).exists(); | |||
| } | |||
| void PluginListComponent::showSelectedFolder() | |||
| { | |||
| if (canShowSelectedFolder()) | |||
| if (const PluginDescription* const desc = list.getType (table.getSelectedRow())) | |||
| File (desc->fileOrIdentifier).getParentDirectory().startAsProcess(); | |||
| File (list.getTypes()[table.getSelectedRow()].fileOrIdentifier).getParentDirectory().startAsProcess(); | |||
| } | |||
| void PluginListComponent::removeMissingPlugins() | |||
| { | |||
| for (int i = list.getNumTypes(); --i >= 0;) | |||
| if (! formatManager.doesPluginStillExist (*list.getType (i))) | |||
| list.removeType (i); | |||
| auto types = list.getTypes(); | |||
| for (int i = types.size(); --i >= 0;) | |||
| { | |||
| auto type = types.getUnchecked (i); | |||
| if (! formatManager.doesPluginStillExist (type)) | |||
| list.removeType (type); | |||
| } | |||
| } | |||
| void PluginListComponent::removePluginItem (int index) | |||
| { | |||
| if (index < list.getNumTypes()) | |||
| list.removeType (index); | |||
| list.removeType (list.getTypes()[index]); | |||
| else | |||
| list.removeFromBlacklist (list.getBlacklistedFiles() [index - list.getNumTypes()]); | |||
| } | |||