/* ============================================================================== This file is part of the JUCE library - "Jules' Utility Class Extensions" Copyright 2004-7 by Raw Material Software ltd. ------------------------------------------------------------------------------ JUCE can be redistributed and/or modified under the terms of the GNU General Public License, as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with JUCE; if not, visit www.gnu.org/licenses or write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------ If you'd like to release a closed-source product which uses JUCE, commercial licenses are also available: visit www.rawmaterialsoftware.com/juce for more information. ============================================================================== */ #include "../../../../juce.h" #include "juce_PluginListComponent.h" #include "juce_PluginDirectoryScanner.h" //============================================================================== PluginListComponent::PluginListComponent (KnownPluginList& listToEdit, const File& deadMansPedalFile_, PropertiesFile* const propertiesToUse_) : list (listToEdit), deadMansPedalFile (deadMansPedalFile_), propertiesToUse (propertiesToUse_) { addAndMakeVisible (listBox = new ListBox (String::empty, this)); addAndMakeVisible (optionsButton = new TextButton ("Options...")); optionsButton->addButtonListener (this); optionsButton->setTriggeredOnMouseDown (true); setSize (400, 600); list.addChangeListener (this); } PluginListComponent::~PluginListComponent() { list.removeChangeListener (this); deleteAllChildren(); } void PluginListComponent::resized() { listBox->setBounds (0, 0, getWidth(), getHeight() - 30); optionsButton->changeWidthToFitText (24); optionsButton->setTopLeftPosition (8, getHeight() - 28); } void PluginListComponent::changeListenerCallback (void*) { listBox->updateContent(); listBox->repaint(); } int PluginListComponent::getNumRows() { return list.getNumTypes(); } void PluginListComponent::paintListBoxItem (int row, Graphics& g, int width, int height, bool rowIsSelected) { if (rowIsSelected) g.fillAll (findColour (TextEditor::highlightColourId)); const PluginDescription* const pd = list.getType (row); if (pd != 0) { GlyphArrangement ga; ga.addCurtailedLineOfText (Font (height * 0.7f, Font::bold), pd->name, 8.0f, height * 0.8f, width - 10.0f, true); g.setColour (Colours::black); ga.draw (g); float x, y, r, b; ga.getBoundingBox (0, -1, x, y, r, b, false); String desc; desc << pd->pluginFormatName << (pd->isInstrument ? " instrument" : " effect") << " - " << pd->numInputChannels << (pd->numInputChannels == 1 ? " in" : " ins") << " / " << pd->numOutputChannels << (pd->numOutputChannels == 1 ? " out" : " outs"); if (pd->manufacturerName.isNotEmpty()) desc << " - " << pd->manufacturerName; if (pd->version.isNotEmpty()) desc << " - " << pd->version; if (pd->category.isNotEmpty()) desc << " - category: '" << pd->category << '\''; g.setColour (Colours::grey); ga.clear(); ga.addCurtailedLineOfText (Font (height * 0.6f), desc, r + 10.0f, height * 0.8f, width - r - 12.0f, true); ga.draw (g); } } void PluginListComponent::deleteKeyPressed (int lastRowSelected) { list.removeType (lastRowSelected); } void PluginListComponent::buttonClicked (Button* b) { if (optionsButton == b) { PopupMenu menu; menu.addItem (1, TRANS("Clear list")); menu.addItem (5, TRANS("Remove selected plugin from list"), listBox->getNumSelectedRows() > 0); menu.addItem (6, TRANS("Show folder containing selected plugin"), listBox->getNumSelectedRows() > 0); menu.addSeparator(); menu.addItem (2, TRANS("Sort alphabetically")); menu.addItem (3, TRANS("Sort by category")); menu.addItem (4, TRANS("Sort by manufacturer")); menu.addSeparator(); for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i) { AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i); if (format->getDefaultLocationsToSearch().getNumPaths() > 0) menu.addItem (10 + i, "Scan for new or updated " + format->getName() + " plugins..."); } const int r = menu.showAt (optionsButton); if (r == 1) { list.clear(); } else if (r == 2) { list.sort (KnownPluginList::sortAlphabetically); } else if (r == 3) { list.sort (KnownPluginList::sortByCategory); } else if (r == 4) { list.sort (KnownPluginList::sortByManufacturer); } else if (r == 5) { const SparseSet selected (listBox->getSelectedRows()); for (int i = list.getNumTypes(); --i >= 0;) if (selected.contains (i)) list.removeType (i); } else if (r == 6) { const PluginDescription* const desc = list.getType (listBox->getSelectedRow()); if (desc != 0) desc->file.getParentDirectory().startAsProcess(); } else if (r != 0) { scanFor (AudioPluginFormatManager::getInstance()->getFormat (r - 10)); } } } bool PluginListComponent::filesDropped (const StringArray& files, int, int) { OwnedArray typesFound; list.scanAndAddDragAndDroppedFiles (files, typesFound); return typesFound.size() > 0; } void PluginListComponent::scanFor (AudioPluginFormat* format) { if (format == 0) return; FileSearchPath path (format->getDefaultLocationsToSearch()); if (propertiesToUse != 0) 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 (KeyPress::escapeKey)); if (aw.runModalLoop() == 0) return; path = pathList.getPath(); } if (propertiesToUse != 0) { 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 (KeyPress::escapeKey)); aw.addProgressBarComponent (progress); aw.enterModalState(); MessageManager::getInstance()->dispatchPendingMessages(); PluginDirectoryScanner scanner (list, path, true, deadMansPedalFile); for (;;) { aw.setMessage (TRANS("Testing:\n\n") + scanner.getNextPluginFileThatWillBeScanned().getFileName()); MessageManager::getInstance()->dispatchPendingMessages (500); if (! scanner.scanNextFile (true)) break; if (! aw.isCurrentlyModal()) break; progress = scanner.getProgress(); } }