Browse Source

tags/2021-05-28
jules 17 years ago
parent
commit
e1772515b4
26 changed files with 1232 additions and 1973 deletions
  1. +19
    -1
      build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h
  2. +7
    -4
      build/macosx/platform_specific_code/juce_mac_MainMenu.mm
  3. +2
    -2
      build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm
  4. +4
    -2
      extras/audio plugin host/src/host/InternalFilters.h
  5. +11
    -3
      extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.mm
  6. +752
    -484
      juce_amalgamated.cpp
  7. +41
    -20
      juce_amalgamated.h
  8. +1
    -1
      src/juce_appframework/audio/audio_file_formats/juce_AudioThumbnail.cpp
  9. +0
    -1320
      src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp
  10. +4
    -2
      src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h
  11. +218
    -20
      src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.mm
  12. +3
    -2
      src/juce_appframework/audio/plugins/formats/juce_DirectXPluginFormat.h
  13. +3
    -2
      src/juce_appframework/audio/plugins/formats/juce_LADSPAPluginFormat.h
  14. +47
    -7
      src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp
  15. +6
    -2
      src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h
  16. +13
    -2
      src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h
  17. +4
    -4
      src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp
  18. +55
    -27
      src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp
  19. +5
    -4
      src/juce_appframework/audio/plugins/juce_KnownPluginList.h
  20. +4
    -4
      src/juce_appframework/audio/plugins/juce_PluginDescription.h
  21. +19
    -46
      src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.cpp
  22. +4
    -4
      src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.h
  23. +1
    -1
      src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp
  24. +2
    -2
      src/juce_appframework/gui/components/juce_Desktop.h
  25. +3
    -3
      src/juce_appframework/gui/components/menus/juce_MenuBarModel.h
  26. +4
    -4
      src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.cpp

+ 19
- 1
build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h View File

@@ -29,7 +29,13 @@
============================================================================== ==============================================================================
*/ */
/** Creates a floating carbon window that can be used to hold a carbon UI.
#ifndef __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
#define __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__
//==============================================================================
/**
Creates a floating carbon window that can be used to hold a carbon UI.
This is a handy class that's designed to be inlined where needed, e.g. This is a handy class that's designed to be inlined where needed, e.g.
in the audio plugin hosting code. in the audio plugin hosting code.
@@ -106,6 +112,8 @@ public:
setOurSizeToEmbeddedViewSize(); setOurSizeToEmbeddedViewSize();
setEmbeddedWindowToOurSize(); setEmbeddedWindowToOurSize();
creationTime = Time::getCurrentTime();
} }
} }
@@ -203,6 +211,11 @@ public:
void timerCallback() void timerCallback()
{ {
setOurSizeToEmbeddedViewSize(); setOurSizeToEmbeddedViewSize();
// To avoid strange overpainting problems when the UI is first opened, we'll
// repaint it a few times during the first second that it's on-screen..
if ((Time::getCurrentTime() - creationTime).inMilliseconds() < 1000)
HIViewSetNeedsDisplay (embeddedView, true);
} }
OSStatus carbonEventHandler (EventHandlerCallRef nextHandlerRef, OSStatus carbonEventHandler (EventHandlerCallRef nextHandlerRef,
@@ -222,6 +235,8 @@ public:
SetEventParameter (event, kEventParamClickActivation, typeClickActivationResult, SetEventParameter (event, kEventParamClickActivation, typeClickActivationResult,
sizeof (ClickActivationResult), &howToHandleClick); sizeof (ClickActivationResult), &howToHandleClick);
HIViewSetNeedsDisplay (embeddedView, true);
} }
break; break;
} }
@@ -239,6 +254,9 @@ protected:
WindowRef wrapperWindow; WindowRef wrapperWindow;
HIViewRef embeddedView; HIViewRef embeddedView;
bool recursiveResize; bool recursiveResize;
Time creationTime;
EventHandlerRef eventHandlerRef; EventHandlerRef eventHandlerRef;
}; };
#endif // __JUCE_MAC_CARBONVIEWWRAPPERCOMPONENT_JUCEHEADER__

+ 7
- 4
build/macosx/platform_specific_code/juce_mac_MainMenu.mm View File

@@ -181,11 +181,14 @@ public:
MenuBarModel* currentModel; MenuBarModel* currentModel;
void addMenuItem (PopupMenu::MenuItemIterator& iter, NSMenu* menuToAddTo,
void addMenuItem (PopupMenu::MenuItemIterator& iter, NSMenu* menuToAddTo,
const int topLevelMenuId, const int topLevelIndex) const int topLevelMenuId, const int topLevelIndex)
{ {
NSString* text = juceStringToNS (iter.itemName.upToFirstOccurrenceOf (T("<end>"), false, true)); NSString* text = juceStringToNS (iter.itemName.upToFirstOccurrenceOf (T("<end>"), false, true));
if (text == 0)
text = @"";
if (iter.isSeparator) if (iter.isSeparator)
{ {
[menuToAddTo addItem: [NSMenuItem separatorItem]]; [menuToAddTo addItem: [NSMenuItem separatorItem]];
@@ -320,7 +323,7 @@ END_JUCE_NAMESPACE
BEGIN_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE
//============================================================================== //==============================================================================
static NSMenu* createStandardAppMenu (NSMenu* menu, const String& appName,
static NSMenu* createStandardAppMenu (NSMenu* menu, const String& appName,
const PopupMenu* extraItems) const PopupMenu* extraItems)
{ {
if (extraItems != 0 && JuceMainMenuHandler::instance != 0 && extraItems->getNumItems() > 0) if (extraItems != 0 && JuceMainMenuHandler::instance != 0 && extraItems->getNumItems() > 0)
@@ -329,7 +332,7 @@ static NSMenu* createStandardAppMenu (NSMenu* menu, const String& appName,
while (iter.next()) while (iter.next())
JuceMainMenuHandler::instance->addMenuItem (iter, menu, 0, -1); JuceMainMenuHandler::instance->addMenuItem (iter, menu, 0, -1);
[menu addItem: [NSMenuItem separatorItem]]; [menu addItem: [NSMenuItem separatorItem]];
} }
@@ -415,7 +418,7 @@ void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel,
delete JuceMainMenuHandler::instance; delete JuceMainMenuHandler::instance;
jassert (JuceMainMenuHandler::instance == 0); // should be zeroed in the destructor jassert (JuceMainMenuHandler::instance == 0); // should be zeroed in the destructor
jassert (extraAppleMenuItems == 0); // you can't specify some extra items without also supplying a model jassert (extraAppleMenuItems == 0); // you can't specify some extra items without also supplying a model
extraAppleMenuItems = 0; extraAppleMenuItems = 0;
} }
else else


+ 2
- 2
build/macosx/platform_specific_code/juce_mac_NSViewComponentPeer.mm View File

@@ -1347,8 +1347,8 @@ void NSViewComponentPeer::redirectMovedOrResized()
//============================================================================== //==============================================================================
void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable) void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable)
{ {
// Very annoyingly, this function has to use the old SetSystemUIMode function,
// which is in Carbon.framework. But, because there's no Cocoa equivalent, it
// Very annoyingly, this function has to use the old SetSystemUIMode function,
// which is in Carbon.framework. But, because there's no Cocoa equivalent, it
// is apparently still available in 64-bit apps.. // is apparently still available in 64-bit apps..
if (enableOrDisable) if (enableOrDisable)
{ {


+ 4
- 2
extras/audio plugin host/src/host/InternalFilters.h View File

@@ -62,10 +62,12 @@ public:
//============================================================================== //==============================================================================
const String getName() const { return "Internal"; } const String getName() const { return "Internal"; }
bool fileMightContainThisPluginType (const File&) { return false; }
bool fileMightContainThisPluginType (const String&) { return false; }
const FileSearchPath getDefaultLocationsToSearch() { return FileSearchPath(); } const FileSearchPath getDefaultLocationsToSearch() { return FileSearchPath(); }
void findAllTypesForFile (OwnedArray <PluginDescription>&, const File&) {}
void findAllTypesForFile (OwnedArray <PluginDescription>&, const String&) {}
bool doesPluginStillExist (const PluginDescription&) { return true; } bool doesPluginStillExist (const PluginDescription&) { return true; }
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; }
const StringArray searchPathsForPlugins (const FileSearchPath&, const bool) { return StringArray(); }
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
//============================================================================== //==============================================================================


+ 11
- 3
extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.mm View File

@@ -779,8 +779,8 @@ protected:
UInt8 inData1, UInt8 inData1,
UInt8 inData2, UInt8 inData2,
#if defined(MAC_OS_X_VERSION_10_5) #if defined(MAC_OS_X_VERSION_10_5)
UInt32 inStartFrame
#else
UInt32 inStartFrame)
#else
long inStartFrame) long inStartFrame)
#endif #endif
{ {
@@ -796,6 +796,14 @@ protected:
return noErr; return noErr;
} }
OSStatus HandleSysEx (const UInt8* inData, UInt32 inLength)
{
#if JucePlugin_WantsMidiInput
midiEvents.addEvent (inData, inLength, 0);
#endif
return noErr;
}
//============================================================================== //==============================================================================
ComponentResult GetPresets (CFArrayRef* outData) const ComponentResult GetPresets (CFArrayRef* outData) const
{ {
@@ -952,7 +960,7 @@ private:
- (NSString*) description - (NSString*) description
{ {
return [NSString stringWithString: @JucePlugin_Name];
return [NSString stringWithString: @JucePlugin_Name];
} }
- (NSView*) uiViewForAudioUnit: (AudioUnit) inAudioUnit - (NSView*) uiViewForAudioUnit: (AudioUnit) inAudioUnit


+ 752
- 484
juce_amalgamated.cpp
File diff suppressed because it is too large
View File


+ 41
- 20
juce_amalgamated.h View File

@@ -27836,8 +27836,8 @@ public:
/** Either the file containing the plugin module, or some other unique way /** Either the file containing the plugin module, or some other unique way
of identifying it. of identifying it.


E.g. for an AU, this would be the component ID, because not all AUs actually
live in a file...
E.g. for an AU, this would be an ID string that the component manager
could use to retrieve the plugin. For a VST, it's the file path.
*/ */
String fileOrIdentifier; String fileOrIdentifier;


@@ -27965,7 +27965,7 @@ public:
subtypes, so in that case, each subtype is returned as a separate object. subtypes, so in that case, each subtype is returned as a separate object.
*/ */
virtual void findAllTypesForFile (OwnedArray <PluginDescription>& results, virtual void findAllTypesForFile (OwnedArray <PluginDescription>& results,
const File& file) = 0;
const String& fileOrIdentifier) = 0;


/** Tries to recreate a type from a previously generated PluginDescription. /** Tries to recreate a type from a previously generated PluginDescription.


@@ -27979,7 +27979,11 @@ public:
This is for searching for potential files, so it shouldn't actually try to This is for searching for potential files, so it shouldn't actually try to
load the plugin or do anything time-consuming. load the plugin or do anything time-consuming.
*/ */
virtual bool fileMightContainThisPluginType (const File& file) = 0;
virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0;

/** Returns a readable version of the name of the plugin that this identifier refers to.
*/
virtual const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0;


/** Checks whether this plugin could possibly be loaded. /** Checks whether this plugin could possibly be loaded.


@@ -27988,6 +27992,14 @@ public:
*/ */
virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; virtual bool doesPluginStillExist (const PluginDescription& desc) = 0;


/** Searches a suggested set of directories for any plugins in this format.

The path might be ignored, e.g. by AUs, which are found by the OS rather
than manually.
*/
virtual const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch,
const bool recursive) = 0;

/** Returns the typical places to look for this kind of plugin. /** Returns the typical places to look for this kind of plugin.


Note that if this returns no paths, it means that the format can't be scanned-for Note that if this returns no paths, it means that the format can't be scanned-for
@@ -28541,7 +28553,7 @@ public:


/** Looks for a type in the list which comes from this file. /** Looks for a type in the list which comes from this file.
*/ */
PluginDescription* getTypeForFile (const File& file) const throw();
PluginDescription* getTypeForFile (const String& fileOrIdentifier) const throw();


/** Looks for a type in the list which matches a plugin type ID. /** Looks for a type in the list which matches a plugin type ID.


@@ -28568,14 +28580,15 @@ public:
file (even if it was already known and hasn't been re-scanned) get returned file (even if it was already known and hasn't been re-scanned) get returned
in the array. in the array.
*/ */
bool scanAndAddFile (const File& possiblePluginFile,
bool scanAndAddFile (const String& possiblePluginFileOrIdentifier,
const bool dontRescanIfAlreadyInList, const bool dontRescanIfAlreadyInList,
OwnedArray <PluginDescription>& typesFound);
OwnedArray <PluginDescription>& typesFound,
AudioPluginFormat& formatToUse);


/** Returns true if the specified file is already known about and if it /** Returns true if the specified file is already known about and if it
hasn't been modified since our entry was created. hasn't been modified since our entry was created.
*/ */
bool isListingUpToDate (const File& possiblePluginFile) const throw();
bool isListingUpToDate (const String& possiblePluginFileOrIdentifier) const throw();


/** Scans and adds a bunch of files that might have been dragged-and-dropped. /** Scans and adds a bunch of files that might have been dragged-and-dropped.


@@ -34678,9 +34691,11 @@ public:
~AudioUnitPluginFormat(); ~AudioUnitPluginFormat();


const String getName() const { return "AudioUnit"; } const String getName() const { return "AudioUnit"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
bool doesPluginStillExist (const PluginDescription& desc); bool doesPluginStillExist (const PluginDescription& desc);
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();


@@ -34718,9 +34733,10 @@ public:
~DirectXPluginFormat(); ~DirectXPluginFormat();


const String getName() const { return "DirectX"; } const String getName() const { return "DirectX"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; }
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();


juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
@@ -34757,9 +34773,10 @@ public:
~LADSPAPluginFormat(); ~LADSPAPluginFormat();


const String getName() const { return "LADSPA"; } const String getName() const { return "LADSPA"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; }
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();


juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
@@ -34794,9 +34811,11 @@ public:
~VSTPluginFormat(); ~VSTPluginFormat();


const String getName() const { return "VST"; } const String getName() const { return "VST"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
bool doesPluginStillExist (const PluginDescription& desc); bool doesPluginStillExist (const PluginDescription& desc);
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();


@@ -34805,6 +34824,8 @@ public:
private: private:
VSTPluginFormat (const VSTPluginFormat&); VSTPluginFormat (const VSTPluginFormat&);
const VSTPluginFormat& operator= (const VSTPluginFormat&); const VSTPluginFormat& operator= (const VSTPluginFormat&);

void recursiveFileSearch (StringArray& results, const File& dir, const bool recursive);
}; };


#endif #endif
@@ -34884,12 +34905,13 @@ public:
*/ */
bool scanNextFile (const bool dontRescanIfAlreadyInList); bool scanNextFile (const bool dontRescanIfAlreadyInList);


/** Returns the file that will be scanned during the next call to scanNextFile().
/** Returns the description of the plugin that will be scanned during the next
call to scanNextFile().


This is handy if you want to show the user which file is currently getting This is handy if you want to show the user which file is currently getting
scanned. scanned.
*/ */
const File getNextPluginFileThatWillBeScanned() const throw();
const String getNextPluginFileThatWillBeScanned() const throw();


/** Returns the estimated progress, between 0 and 1. /** Returns the estimated progress, between 0 and 1.
*/ */
@@ -34905,13 +34927,12 @@ public:
private: private:
KnownPluginList& list; KnownPluginList& list;
AudioPluginFormat& format; AudioPluginFormat& format;
OwnedArray <File> filesToScan;
StringArray filesOrIdentifiersToScan;
File deadMansPedalFile; File deadMansPedalFile;
StringArray failedFiles; StringArray failedFiles;
int nextIndex; int nextIndex;
float progress; float progress;


void recursiveFileSearch (const File& dir, const bool recursive);
const StringArray getDeadMansPedalFile() throw(); const StringArray getDeadMansPedalFile() throw();
void setDeadMansPedalFile (const StringArray& newContents) throw(); void setDeadMansPedalFile (const StringArray& newContents) throw();




+ 1
- 1
src/juce_appframework/audio/audio_file_formats/juce_AudioThumbnail.cpp View File

@@ -510,7 +510,7 @@ void AudioThumbnail::drawChannel (Graphics& g,
const float vscale = verticalZoomFactor * h / 256.0f; const float vscale = verticalZoomFactor * h / 256.0f;
const Rectangle clip (g.getClipBounds()); const Rectangle clip (g.getClipBounds());
const int skipLeft = clip.getX() - x;
const int skipLeft = jlimit (0, w, clip.getX() - x);
w -= skipLeft; w -= skipLeft;
x += skipLeft; x += skipLeft;


+ 0
- 1320
src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.cpp
File diff suppressed because it is too large
View File


+ 4
- 2
src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.h View File

@@ -49,9 +49,11 @@ public:
//============================================================================== //==============================================================================
const String getName() const { return "AudioUnit"; } const String getName() const { return "AudioUnit"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
bool doesPluginStillExist (const PluginDescription& desc); bool doesPluginStillExist (const PluginDescription& desc);
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();


+ 218
- 20
src/juce_appframework/audio/plugins/formats/juce_AudioUnitPluginFormat.mm View File

@@ -81,6 +81,129 @@ BEGIN_JUCE_NAMESPACE
static int insideCallback = 0; static int insideCallback = 0;
//==============================================================================
static const String osTypeToString (OSType type) throw()
{
char s[4];
s[0] = (char) (((uint32) type) >> 24);
s[1] = (char) (((uint32) type) >> 16);
s[2] = (char) (((uint32) type) >> 8);
s[3] = (char) ((uint32) type);
return String (s, 4);
}
static OSType stringToOSType (const String& s1) throw()
{
const String s (s1 + " ");
return (((OSType) (unsigned char) s[0]) << 24)
| (((OSType) (unsigned char) s[1]) << 16)
| (((OSType) (unsigned char) s[2]) << 8)
| ((OSType) (unsigned char) s[3]);
}
static const tchar* auIdentifierPrefix = T("AudioUnit:");
static const String createAUPluginIdentifier (const ComponentDescription& desc)
{
jassert (osTypeToString ('abcd') == T("abcd")); // agh, must have got the endianness wrong..
jassert (stringToOSType ("abcd") == (OSType) 'abcd'); // ditto
String s (auIdentifierPrefix);
if (desc.componentType == kAudioUnitType_MusicDevice)
s << "Synths/";
else if (desc.componentType == kAudioUnitType_MusicEffect
|| desc.componentType == kAudioUnitType_Effect)
s << "Effects/";
else if (desc.componentType == kAudioUnitType_Generator)
s << "Generators/";
else if (desc.componentType == kAudioUnitType_Panner)
s << "Panners/";
s << osTypeToString (desc.componentType)
<< T(",")
<< osTypeToString (desc.componentSubType)
<< T(",")
<< osTypeToString (desc.componentManufacturer);
return s;
}
static void getAUDetails (ComponentRecord* comp, String& name, String& manufacturer)
{
Handle componentNameHandle = NewHandle (sizeof (void*));
Handle componentInfoHandle = NewHandle (sizeof (void*));
if (componentNameHandle != 0 && componentInfoHandle != 0)
{
ComponentDescription desc;
if (GetComponentInfo (comp, &desc, componentNameHandle, componentInfoHandle, 0) == noErr)
{
ConstStr255Param nameString = (ConstStr255Param) (*componentNameHandle);
ConstStr255Param infoString = (ConstStr255Param) (*componentInfoHandle);
if (nameString != 0 && nameString[0] != 0)
{
const String all ((const char*) nameString + 1, nameString[0]);
DBG ("name: "+ all);
manufacturer = all.upToFirstOccurrenceOf (T(":"), false, false).trim();
name = all.fromFirstOccurrenceOf (T(":"), false, false).trim();
}
if (infoString != 0 && infoString[0] != 0)
{
const String all ((const char*) infoString + 1, infoString[0]);
DBG ("info: " + all);
}
if (name.isEmpty())
name = "<Unknown>";
}
DisposeHandle (componentNameHandle);
DisposeHandle (componentInfoHandle);
}
}
static bool getComponentDescFromIdentifier (const String& fileOrIdentifier, ComponentDescription& desc,
String& name, String& version, String& manufacturer)
{
zerostruct (desc);
if (fileOrIdentifier.startsWithIgnoreCase (auIdentifierPrefix))
{
String s (fileOrIdentifier.substring (jmax (fileOrIdentifier.lastIndexOfChar (T(':')),
fileOrIdentifier.lastIndexOfChar (T('/'))) + 1));
StringArray tokens;
tokens.addTokens (s, T(","), 0);
tokens.trim();
tokens.removeEmptyStrings();
if (tokens.size() == 3)
{
desc.componentType = stringToOSType (tokens[0]);
desc.componentSubType = stringToOSType (tokens[1]);
desc.componentManufacturer = stringToOSType (tokens[2]);
ComponentRecord* comp = FindNextComponent (0, &desc);
if (comp != 0)
{
getAUDetails (comp, name, manufacturer);
return true;
}
}
}
return false;
}
//============================================================================== //==============================================================================
class AudioUnitPluginWindowCarbon; class AudioUnitPluginWindowCarbon;
class AudioUnitPluginWindowCocoa; class AudioUnitPluginWindowCocoa;
@@ -98,11 +221,11 @@ public:
void fillInPluginDescription (PluginDescription& desc) const void fillInPluginDescription (PluginDescription& desc) const
{ {
desc.name = pluginName; desc.name = pluginName;
desc.file = file;
desc.fileOrIdentifier = createAUPluginIdentifier (componentDesc);
desc.uid = ((int) componentDesc.componentType) desc.uid = ((int) componentDesc.componentType)
^ ((int) componentDesc.componentSubType) ^ ((int) componentDesc.componentSubType)
^ ((int) componentDesc.componentManufacturer); ^ ((int) componentDesc.componentManufacturer);
desc.lastFileModTime = file.getLastModificationTime();
desc.lastFileModTime = 0;
desc.pluginFormatName = "AudioUnit"; desc.pluginFormatName = "AudioUnit";
desc.category = getCategory(); desc.category = getCategory();
desc.manufacturerName = manufacturer; desc.manufacturerName = manufacturer;
@@ -163,7 +286,7 @@ private:
ComponentDescription componentDesc; ComponentDescription componentDesc;
String pluginName, manufacturer, version; String pluginName, manufacturer, version;
File file;
String fileOrIdentifier;
CriticalSection lock; CriticalSection lock;
bool initialised, wantsMidiMessages, wasPlaying; bool initialised, wantsMidiMessages, wasPlaying;
@@ -175,7 +298,7 @@ private:
Array <int> parameterIds; Array <int> parameterIds;
//============================================================================== //==============================================================================
bool getComponentDescFromFile (const File& file);
bool getComponentDescFromFile (const String& fileOrIdentifier);
void initialise(); void initialise();
//============================================================================== //==============================================================================
@@ -257,12 +380,12 @@ private:
const String getCategory() const; const String getCategory() const;
//============================================================================== //==============================================================================
AudioUnitPluginInstance (const File& file);
AudioUnitPluginInstance (const String& fileOrIdentifier);
}; };
//============================================================================== //==============================================================================
AudioUnitPluginInstance::AudioUnitPluginInstance (const File& file_)
: file (file_),
AudioUnitPluginInstance::AudioUnitPluginInstance (const String& fileOrIdentifier)
: fileOrIdentifier (fileOrIdentifier),
initialised (false), initialised (false),
wantsMidiMessages (false), wantsMidiMessages (false),
audioUnit (0), audioUnit (0),
@@ -273,9 +396,9 @@ AudioUnitPluginInstance::AudioUnitPluginInstance (const File& file_)
{ {
++insideCallback; ++insideCallback;
log (T("Opening AU: ") + file.getFullPathName());
log (T("Opening AU: ") + fileOrIdentifier);
if (getComponentDescFromFile (file))
if (getComponentDescFromFile (fileOrIdentifier))
{ {
ComponentRecord* const comp = FindNextComponent (0, &componentDesc); ComponentRecord* const comp = FindNextComponent (0, &componentDesc);
@@ -314,15 +437,18 @@ AudioUnitPluginInstance::~AudioUnitPluginInstance()
juce_free (outputBufferList); juce_free (outputBufferList);
} }
bool AudioUnitPluginInstance::getComponentDescFromFile (const File& file)
bool AudioUnitPluginInstance::getComponentDescFromFile (const String& fileOrIdentifier)
{ {
zerostruct (componentDesc); zerostruct (componentDesc);
if (getComponentDescFromIdentifier (fileOrIdentifier, componentDesc, pluginName, version, manufacturer))
return true;
const File file (fileOrIdentifier);
if (! file.hasFileExtension (T(".component"))) if (! file.hasFileExtension (T(".component")))
return false; return false;
const String filename (file.getFullPathName());
const char* const utf8 = filename.toUTF8();
const char* const utf8 = fileOrIdentifier.toUTF8();
CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8, CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*) utf8,
strlen (utf8), file.isDirectory()); strlen (utf8), file.isDirectory());
if (url != 0) if (url != 0)
@@ -730,15 +856,24 @@ public:
~AudioUnitPluginWindowCocoa() ~AudioUnitPluginWindowCocoa()
{ {
const bool wasValid = isValid();
wrapper->setView (0); wrapper->setView (0);
activeWindows.removeValue (this); activeWindows.removeValue (this);
if (isValid())
if (wasValid)
plugin.editorBeingDeleted (this); plugin.editorBeingDeleted (this);
delete wrapper; delete wrapper;
} }
bool isValid() const { return wrapper->getView() != 0; } bool isValid() const { return wrapper->getView() != 0; }
void paint (Graphics& g)
{
g.fillAll (Colours::white);
}
void resized() void resized()
{ {
wrapper->setSize (getWidth(), getHeight()); wrapper->setSize (getWidth(), getHeight());
@@ -794,6 +929,11 @@ private:
juce_free (info); juce_free (info);
wrapper->setView (pluginView); wrapper->setView (pluginView);
if (pluginView != 0)
setSize ([pluginView frame].size.width,
[pluginView frame].size.height);
return pluginView != 0; return pluginView != 0;
} }
}; };
@@ -1264,13 +1404,13 @@ AudioUnitPluginFormat::~AudioUnitPluginFormat()
} }
void AudioUnitPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& results, void AudioUnitPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& results,
const File& file)
const String& fileOrIdentifier)
{ {
if (! fileMightContainThisPluginType (file))
if (! fileMightContainThisPluginType (fileOrIdentifier))
return; return;
PluginDescription desc; PluginDescription desc;
desc.file = file;
desc.fileOrIdentifier = fileOrIdentifier;
desc.uid = 0; desc.uid = 0;
AudioUnitPluginInstance* instance = dynamic_cast <AudioUnitPluginInstance*> (createInstanceFromDescription (desc)); AudioUnitPluginInstance* instance = dynamic_cast <AudioUnitPluginInstance*> (createInstanceFromDescription (desc));
@@ -1295,9 +1435,9 @@ AudioPluginInstance* AudioUnitPluginFormat::createInstanceFromDescription (const
{ {
AudioUnitPluginInstance* result = 0; AudioUnitPluginInstance* result = 0;
if (fileMightContainThisPluginType (desc.file))
if (fileMightContainThisPluginType (desc.fileOrIdentifier))
{ {
result = new AudioUnitPluginInstance (desc.file);
result = new AudioUnitPluginInstance (desc.fileOrIdentifier);
if (result->audioUnit != 0) if (result->audioUnit != 0)
{ {
@@ -1312,15 +1452,73 @@ AudioPluginInstance* AudioUnitPluginFormat::createInstanceFromDescription (const
return result; return result;
} }
bool AudioUnitPluginFormat::fileMightContainThisPluginType (const File& f)
const StringArray AudioUnitPluginFormat::searchPathsForPlugins (const FileSearchPath& /*directoriesToSearch*/,
const bool /*recursive*/)
{ {
StringArray result;
ComponentRecord* comp = 0;
ComponentDescription desc;
zerostruct (desc);
for (;;)
{
zerostruct (desc);
comp = FindNextComponent (comp, &desc);
if (comp == 0)
break;
GetComponentInfo (comp, &desc, 0, 0, 0);
if (desc.componentType == kAudioUnitType_MusicDevice
|| desc.componentType == kAudioUnitType_MusicEffect
|| desc.componentType == kAudioUnitType_Effect
|| desc.componentType == kAudioUnitType_Generator
|| desc.componentType == kAudioUnitType_Panner)
{
const String s (createAUPluginIdentifier (desc));
DBG (s);
result.add (s);
}
}
return result;
}
bool AudioUnitPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier)
{
ComponentDescription desc;
String name, version, manufacturer;
if (getComponentDescFromIdentifier (fileOrIdentifier, desc, name, version, manufacturer))
return FindNextComponent (0, &desc) != 0;
const File f (fileOrIdentifier);
return f.hasFileExtension (T(".component")) return f.hasFileExtension (T(".component"))
&& f.isDirectory(); && f.isDirectory();
} }
const String AudioUnitPluginFormat::getNameOfPluginFromIdentifier (const String& fileOrIdentifier)
{
ComponentDescription desc;
String name, version, manufacturer;
getComponentDescFromIdentifier (fileOrIdentifier, desc, name, version, manufacturer);
if (name.isEmpty())
name = fileOrIdentifier;
return name;
}
bool AudioUnitPluginFormat::doesPluginStillExist (const PluginDescription& desc)
{
return File (desc.fileOrIdentifier).exists();
}
const FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch() const FileSearchPath AudioUnitPluginFormat::getDefaultLocationsToSearch()
{ {
return FileSearchPath ("~/Library/Audio/Plug-Ins/Components;/Library/Audio/Plug-Ins/Components");
return FileSearchPath ("(Default AudioUnit locations)");
} }
#endif #endif


+ 3
- 2
src/juce_appframework/audio/plugins/formats/juce_DirectXPluginFormat.h View File

@@ -53,9 +53,10 @@ public:
//============================================================================== //==============================================================================
const String getName() const { return "DirectX"; } const String getName() const { return "DirectX"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; }
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();
//============================================================================== //==============================================================================


+ 3
- 2
src/juce_appframework/audio/plugins/formats/juce_LADSPAPluginFormat.h View File

@@ -53,9 +53,10 @@ public:
//============================================================================== //==============================================================================
const String getName() const { return "LADSPA"; } const String getName() const { return "LADSPA"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; }
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();
//============================================================================== //==============================================================================


+ 47
- 7
src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.cpp View File

@@ -2892,13 +2892,13 @@ VSTPluginFormat::~VSTPluginFormat()
} }
void VSTPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& results, void VSTPluginFormat::findAllTypesForFile (OwnedArray <PluginDescription>& results,
const File& file)
const String& fileOrIdentifier)
{ {
if (! fileMightContainThisPluginType (file))
if (! fileMightContainThisPluginType (fileOrIdentifier))
return; return;
PluginDescription desc; PluginDescription desc;
desc.fileOrIdentifier = file.getFullPathName();
desc.fileOrIdentifier = fileOrIdentifier;
desc.uid = 0; desc.uid = 0;
VSTPluginInstance* instance = dynamic_cast <VSTPluginInstance*> (createInstanceFromDescription (desc)); VSTPluginInstance* instance = dynamic_cast <VSTPluginInstance*> (createInstanceFromDescription (desc));
@@ -2976,10 +2976,10 @@ AudioPluginInstance* VSTPluginFormat::createInstanceFromDescription (const Plugi
{ {
VSTPluginInstance* result = 0; VSTPluginInstance* result = 0;
File file (desc.fileOrIdentifier);
if (fileMightContainThisPluginType (file))
if (fileMightContainThisPluginType (desc.fileOrIdentifier))
{ {
File file (desc.fileOrIdentifier);
const File previousWorkingDirectory (File::getCurrentWorkingDirectory()); const File previousWorkingDirectory (File::getCurrentWorkingDirectory());
file.getParentDirectory().setAsCurrentWorkingDirectory(); file.getParentDirectory().setAsCurrentWorkingDirectory();
@@ -3008,8 +3008,10 @@ AudioPluginInstance* VSTPluginFormat::createInstanceFromDescription (const Plugi
return result; return result;
} }
bool VSTPluginFormat::fileMightContainThisPluginType (const File& f)
bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdentifier)
{ {
const File f (fileOrIdentifier);
#if JUCE_MAC #if JUCE_MAC
if (f.isDirectory() && f.hasFileExtension (T(".vst"))) if (f.isDirectory() && f.hasFileExtension (T(".vst")))
return true; return true;
@@ -3041,11 +3043,48 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const File& f)
#endif #endif
} }
const String VSTPluginFormat::getNameOfPluginFromIdentifier (const String& fileOrIdentifier)
{
return fileOrIdentifier;
}
bool VSTPluginFormat::doesPluginStillExist (const PluginDescription& desc) bool VSTPluginFormat::doesPluginStillExist (const PluginDescription& desc)
{ {
return File (desc.fileOrIdentifier).exists(); return File (desc.fileOrIdentifier).exists();
} }
const StringArray VSTPluginFormat::searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive)
{
StringArray results;
for (int j = 0; j < directoriesToSearch.getNumPaths(); ++j)
recursiveFileSearch (results, directoriesToSearch [j], recursive);
return results;
}
void VSTPluginFormat::recursiveFileSearch (StringArray& results, const File& dir, const bool recursive)
{
// avoid allowing the dir iterator to be recursive, because we want to avoid letting it delve inside
// .component or .vst directories.
DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories);
while (iter.next())
{
const File f (iter.getFile());
bool isPlugin = false;
if (fileMightContainThisPluginType (f.getFullPathName()))
{
isPlugin = true;
results.add (f.getFullPathName());
}
if (recursive && (! isPlugin) && f.isDirectory())
recursiveFileSearch (results, f, true);
}
}
const FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch() const FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch()
{ {
#if JUCE_MAC #if JUCE_MAC
@@ -3059,6 +3098,7 @@ const FileSearchPath VSTPluginFormat::getDefaultLocationsToSearch()
#endif #endif
} }
END_JUCE_NAMESPACE END_JUCE_NAMESPACE
#endif #endif


+ 6
- 2
src/juce_appframework/audio/plugins/formats/juce_VSTPluginFormat.h View File

@@ -50,9 +50,11 @@ public:
//============================================================================== //==============================================================================
const String getName() const { return "VST"; } const String getName() const { return "VST"; }
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const File& file);
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc); AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
bool fileMightContainThisPluginType (const File& file);
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
bool doesPluginStillExist (const PluginDescription& desc); bool doesPluginStillExist (const PluginDescription& desc);
const FileSearchPath getDefaultLocationsToSearch(); const FileSearchPath getDefaultLocationsToSearch();
@@ -62,6 +64,8 @@ public:
private: private:
VSTPluginFormat (const VSTPluginFormat&); VSTPluginFormat (const VSTPluginFormat&);
const VSTPluginFormat& operator= (const VSTPluginFormat&); const VSTPluginFormat& operator= (const VSTPluginFormat&);
void recursiveFileSearch (StringArray& results, const File& dir, const bool recursive);
}; };


+ 13
- 2
src/juce_appframework/audio/plugins/juce_AudioPluginFormat.h View File

@@ -68,7 +68,7 @@ public:
subtypes, so in that case, each subtype is returned as a separate object. subtypes, so in that case, each subtype is returned as a separate object.
*/ */
virtual void findAllTypesForFile (OwnedArray <PluginDescription>& results, virtual void findAllTypesForFile (OwnedArray <PluginDescription>& results,
const File& file) = 0;
const String& fileOrIdentifier) = 0;
/** Tries to recreate a type from a previously generated PluginDescription. /** Tries to recreate a type from a previously generated PluginDescription.
@@ -82,7 +82,11 @@ public:
This is for searching for potential files, so it shouldn't actually try to This is for searching for potential files, so it shouldn't actually try to
load the plugin or do anything time-consuming. load the plugin or do anything time-consuming.
*/ */
virtual bool fileMightContainThisPluginType (const File& file) = 0;
virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0;
/** Returns a readable version of the name of the plugin that this identifier refers to.
*/
virtual const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0;
/** Checks whether this plugin could possibly be loaded. /** Checks whether this plugin could possibly be loaded.
@@ -91,6 +95,13 @@ public:
*/ */
virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; virtual bool doesPluginStillExist (const PluginDescription& desc) = 0;
/** Searches a suggested set of directories for any plugins in this format.
The path might be ignored, e.g. by AUs, which are found by the OS rather
than manually.
*/
virtual const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch,
const bool recursive) = 0;
/** Returns the typical places to look for this kind of plugin. /** Returns the typical places to look for this kind of plugin.


+ 4
- 4
src/juce_appframework/audio/plugins/juce_AudioPluginFormatManager.cpp View File

@@ -79,14 +79,14 @@ void AudioPluginFormatManager::addDefaultFormats()
} }
#endif #endif
#if JUCE_PLUGINHOST_VST
formats.add (new VSTPluginFormat());
#endif
#if JUCE_PLUGINHOST_AU && JUCE_MAC #if JUCE_PLUGINHOST_AU && JUCE_MAC
formats.add (new AudioUnitPluginFormat()); formats.add (new AudioUnitPluginFormat());
#endif #endif
#if JUCE_PLUGINHOST_VST
formats.add (new VSTPluginFormat());
#endif
#if JUCE_PLUGINHOST_DX && JUCE_WIN32 #if JUCE_PLUGINHOST_DX && JUCE_WIN32
formats.add (new DirectXPluginFormat()); formats.add (new DirectXPluginFormat());
#endif #endif


+ 55
- 27
src/juce_appframework/audio/plugins/juce_KnownPluginList.cpp View File

@@ -55,10 +55,10 @@ void KnownPluginList::clear()
} }
} }
PluginDescription* KnownPluginList::getTypeForFile (const File& file) const throw()
PluginDescription* KnownPluginList::getTypeForFile (const String& fileOrIdentifier) const throw()
{ {
for (int i = 0; i < types.size(); ++i) for (int i = 0; i < types.size(); ++i)
if (types.getUnchecked(i)->fileOrIdentifier == file.getFullPathName())
if (types.getUnchecked(i)->fileOrIdentifier == fileOrIdentifier)
return types.getUnchecked(i); return types.getUnchecked(i);
return 0; return 0;
@@ -99,17 +99,33 @@ void KnownPluginList::removeType (const int index) throw()
sendChangeMessage (this); sendChangeMessage (this);
} }
bool KnownPluginList::isListingUpToDate (const File& possiblePluginFile) const throw()
static Time getFileModTime (const String& fileOrIdentifier) throw()
{ {
if (getTypeForFile (possiblePluginFile) == 0)
if (fileOrIdentifier.startsWithChar (T('/'))
|| fileOrIdentifier[1] == T(':'))
{
return File (fileOrIdentifier).getLastModificationTime();
}
return Time (0);
}
static bool timesAreDifferent (const Time& t1, const Time& t2) throw()
{
return t1 != t2 || t1 == Time (0);
}
bool KnownPluginList::isListingUpToDate (const String& fileOrIdentifier) const throw()
{
if (getTypeForFile (fileOrIdentifier) == 0)
return false; return false;
for (int i = types.size(); --i >= 0;) for (int i = types.size(); --i >= 0;)
{ {
const PluginDescription* const d = types.getUnchecked(i); const PluginDescription* const d = types.getUnchecked(i);
if (d->fileOrIdentifier == possiblePluginFile.getFullPathName()
&& d->lastFileModTime != possiblePluginFile.getLastModificationTime())
if (d->fileOrIdentifier == fileOrIdentifier
&& timesAreDifferent (d->lastFileModTime, getFileModTime (fileOrIdentifier)))
{ {
return false; return false;
} }
@@ -118,14 +134,15 @@ bool KnownPluginList::isListingUpToDate (const File& possiblePluginFile) const t
return true; return true;
} }
bool KnownPluginList::scanAndAddFile (const File& possiblePluginFile,
bool KnownPluginList::scanAndAddFile (const String& fileOrIdentifier,
const bool dontRescanIfAlreadyInList, const bool dontRescanIfAlreadyInList,
OwnedArray <PluginDescription>& typesFound)
OwnedArray <PluginDescription>& typesFound,
AudioPluginFormat& format)
{ {
bool addedOne = false; bool addedOne = false;
if (dontRescanIfAlreadyInList if (dontRescanIfAlreadyInList
&& getTypeForFile (possiblePluginFile) != 0)
&& getTypeForFile (fileOrIdentifier) != 0)
{ {
bool needsRescanning = false; bool needsRescanning = false;
@@ -133,9 +150,9 @@ bool KnownPluginList::scanAndAddFile (const File& possiblePluginFile,
{ {
const PluginDescription* const d = types.getUnchecked(i); const PluginDescription* const d = types.getUnchecked(i);
if (d->fileOrIdentifier == possiblePluginFile.getFullPathName())
if (d->fileOrIdentifier == fileOrIdentifier)
{ {
if (d->lastFileModTime != possiblePluginFile.getLastModificationTime())
if (timesAreDifferent (d->lastFileModTime, getFileModTime (fileOrIdentifier)))
needsRescanning = true; needsRescanning = true;
else else
typesFound.add (new PluginDescription (*d)); typesFound.add (new PluginDescription (*d));
@@ -146,23 +163,18 @@ bool KnownPluginList::scanAndAddFile (const File& possiblePluginFile,
return false; return false;
} }
for (int i = 0; i < AudioPluginFormatManager::getInstance()->getNumFormats(); ++i)
{
AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (i);
OwnedArray <PluginDescription> found;
format->findAllTypesForFile (found, possiblePluginFile);
OwnedArray <PluginDescription> found;
format.findAllTypesForFile (found, fileOrIdentifier);
for (int i = 0; i < found.size(); ++i)
{
PluginDescription* const desc = found.getUnchecked(i);
jassert (desc != 0);
for (int i = 0; i < found.size(); ++i)
{
PluginDescription* const desc = found.getUnchecked(i);
jassert (desc != 0);
if (addType (*desc))
addedOne = true;
if (addType (*desc))
addedOne = true;
typesFound.add (new PluginDescription (*desc));
}
typesFound.add (new PluginDescription (*desc));
} }
return addedOne; return addedOne;
@@ -173,10 +185,20 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (const StringArray& files,
{ {
for (int i = 0; i < files.size(); ++i) for (int i = 0; i < files.size(); ++i)
{ {
const File f (files [i]);
bool loaded = false;
for (int j = 0; j < AudioPluginFormatManager::getInstance()->getNumFormats(); ++j)
{
AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (j);
if (scanAndAddFile (files[i], true, typesFound, *format))
loaded = true;
}
if (! scanAndAddFile (f, true, typesFound))
if (! loaded)
{ {
const File f (files[i]);
if (f.isDirectory()) if (f.isDirectory())
{ {
StringArray s; StringArray s;
@@ -350,7 +372,13 @@ public:
PopupMenu subMenu; PopupMenu subMenu;
sub->addToMenu (subMenu, allPlugins); sub->addToMenu (subMenu, allPlugins);
#if JUCE_MAC
// avoid the special AU formatting nonsense on Mac..
m.addSubMenu (sub->folder.fromFirstOccurrenceOf (T(":"), false, false), subMenu);
#else
m.addSubMenu (sub->folder, subMenu); m.addSubMenu (sub->folder, subMenu);
#endif
} }
for (i = 0; i < plugins.size(); ++i) for (i = 0; i < plugins.size(); ++i)


+ 5
- 4
src/juce_appframework/audio/plugins/juce_KnownPluginList.h View File

@@ -74,7 +74,7 @@ public:
/** Looks for a type in the list which comes from this file. /** Looks for a type in the list which comes from this file.
*/ */
PluginDescription* getTypeForFile (const File& file) const throw();
PluginDescription* getTypeForFile (const String& fileOrIdentifier) const throw();
/** Looks for a type in the list which matches a plugin type ID. /** Looks for a type in the list which matches a plugin type ID.
@@ -101,14 +101,15 @@ public:
file (even if it was already known and hasn't been re-scanned) get returned file (even if it was already known and hasn't been re-scanned) get returned
in the array. in the array.
*/ */
bool scanAndAddFile (const File& possiblePluginFile,
bool scanAndAddFile (const String& possiblePluginFileOrIdentifier,
const bool dontRescanIfAlreadyInList, const bool dontRescanIfAlreadyInList,
OwnedArray <PluginDescription>& typesFound);
OwnedArray <PluginDescription>& typesFound,
AudioPluginFormat& formatToUse);
/** Returns true if the specified file is already known about and if it /** Returns true if the specified file is already known about and if it
hasn't been modified since our entry was created. hasn't been modified since our entry was created.
*/ */
bool isListingUpToDate (const File& possiblePluginFile) const throw();
bool isListingUpToDate (const String& possiblePluginFileOrIdentifier) const throw();
/** Scans and adds a bunch of files that might have been dragged-and-dropped. /** Scans and adds a bunch of files that might have been dragged-and-dropped.


+ 4
- 4
src/juce_appframework/audio/plugins/juce_PluginDescription.h View File

@@ -75,10 +75,10 @@ public:
String version; String version;
/** Either the file containing the plugin module, or some other unique way /** Either the file containing the plugin module, or some other unique way
of identifying it.
E.g. for an AU, this would be the component ID, because not all AUs actually
live in a file...
of identifying it.
E.g. for an AU, this would be an ID string that the component manager
could use to retrieve the plugin. For a VST, it's the file path.
*/ */
String fileOrIdentifier; String fileOrIdentifier;


+ 19
- 46
src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.cpp View File

@@ -52,8 +52,7 @@ PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo,
{ {
directoriesToSearch.removeRedundantPaths(); directoriesToSearch.removeRedundantPaths();
for (int j = 0; j < directoriesToSearch.getNumPaths(); ++j)
recursiveFileSearch (directoriesToSearch [j], recursive);
filesOrIdentifiersToScan = format.searchPathsForPlugins (directoriesToSearch, recursive);
// If any plugins have crashed recently when being loaded, move them to the // 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.. // end of the list to give the others a chance to load correctly..
@@ -61,33 +60,11 @@ PluginDirectoryScanner::PluginDirectoryScanner (KnownPluginList& listToAddTo,
for (int i = 0; i < crashedPlugins.size(); ++i) for (int i = 0; i < crashedPlugins.size(); ++i)
{ {
const File f (crashedPlugins[i]);
const String f = crashedPlugins[i];
for (int j = filesToScan.size(); --j >= 0;)
if (f == *filesToScan.getUnchecked (j))
filesToScan.move (j, -1);
}
}
void PluginDirectoryScanner::recursiveFileSearch (const File& dir, const bool recursive)
{
// avoid allowing the dir iterator to be recursive, because we want to avoid letting it delve inside
// .component or .vst directories.
DirectoryIterator iter (dir, false, "*", File::findFilesAndDirectories);
while (iter.next())
{
const File f (iter.getFile());
bool isPlugin = false;
if (format.fileMightContainThisPluginType (f))
{
isPlugin = true;
filesToScan.add (new File (f));
}
if (recursive && (! isPlugin) && f.isDirectory())
recursiveFileSearch (f, true);
for (int j = filesOrIdentifiersToScan.size(); --j >= 0;)
if (f == filesOrIdentifiersToScan[j])
filesOrIdentifiersToScan.move (j, -1);
} }
} }
@@ -96,49 +73,45 @@ PluginDirectoryScanner::~PluginDirectoryScanner()
} }
//============================================================================== //==============================================================================
const File PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const throw()
const String PluginDirectoryScanner::getNextPluginFileThatWillBeScanned() const throw()
{ {
File* const file = filesToScan [nextIndex];
if (file != 0)
return *file;
return File::nonexistent;
return format.getNameOfPluginFromIdentifier (filesOrIdentifiersToScan [nextIndex]);
} }
bool PluginDirectoryScanner::scanNextFile (const bool dontRescanIfAlreadyInList) bool PluginDirectoryScanner::scanNextFile (const bool dontRescanIfAlreadyInList)
{ {
File* const file = filesToScan [nextIndex];
String file (filesOrIdentifiersToScan [nextIndex]);
if (file != 0)
if (file.isNotEmpty())
{ {
if (! list.isListingUpToDate (*file))
if (! list.isListingUpToDate (file))
{ {
OwnedArray <PluginDescription> typesFound; OwnedArray <PluginDescription> typesFound;
// Add this plugin to the end of the dead-man's pedal list in case it crashes... // Add this plugin to the end of the dead-man's pedal list in case it crashes...
StringArray crashedPlugins (getDeadMansPedalFile()); StringArray crashedPlugins (getDeadMansPedalFile());
crashedPlugins.removeString (file->getFullPathName());
crashedPlugins.add (file->getFullPathName());
crashedPlugins.removeString (file);
crashedPlugins.add (file);
setDeadMansPedalFile (crashedPlugins); setDeadMansPedalFile (crashedPlugins);
list.scanAndAddFile (*file,
list.scanAndAddFile (file,
dontRescanIfAlreadyInList, dontRescanIfAlreadyInList,
typesFound);
typesFound,
format);
// Managed to load without crashing, so remove it from the dead-man's-pedal.. // Managed to load without crashing, so remove it from the dead-man's-pedal..
crashedPlugins.removeString (file->getFullPathName());
crashedPlugins.removeString (file);
setDeadMansPedalFile (crashedPlugins); setDeadMansPedalFile (crashedPlugins);
if (typesFound.size() == 0) if (typesFound.size() == 0)
failedFiles.add (file->getFullPathName());
failedFiles.add (file);
} }
++nextIndex; ++nextIndex;
progress = nextIndex / (float) filesToScan.size();
progress = nextIndex / (float) filesOrIdentifiersToScan.size();
} }
return nextIndex < filesToScan.size();
return nextIndex < filesOrIdentifiersToScan.size();
} }
const StringArray PluginDirectoryScanner::getDeadMansPedalFile() throw() const StringArray PluginDirectoryScanner::getDeadMansPedalFile() throw()


+ 4
- 4
src/juce_appframework/audio/plugins/juce_PluginDirectoryScanner.h View File

@@ -89,12 +89,13 @@ public:
*/ */
bool scanNextFile (const bool dontRescanIfAlreadyInList); bool scanNextFile (const bool dontRescanIfAlreadyInList);
/** Returns the file that will be scanned during the next call to scanNextFile().
/** Returns the description of the plugin that will be scanned during the next
call to scanNextFile().
This is handy if you want to show the user which file is currently getting This is handy if you want to show the user which file is currently getting
scanned. scanned.
*/ */
const File getNextPluginFileThatWillBeScanned() const throw();
const String getNextPluginFileThatWillBeScanned() const throw();
/** Returns the estimated progress, between 0 and 1. /** Returns the estimated progress, between 0 and 1.
*/ */
@@ -111,13 +112,12 @@ public:
private: private:
KnownPluginList& list; KnownPluginList& list;
AudioPluginFormat& format; AudioPluginFormat& format;
OwnedArray <File> filesToScan;
StringArray filesOrIdentifiersToScan;
File deadMansPedalFile; File deadMansPedalFile;
StringArray failedFiles; StringArray failedFiles;
int nextIndex; int nextIndex;
float progress; float progress;
void recursiveFileSearch (const File& dir, const bool recursive);
const StringArray getDeadMansPedalFile() throw(); const StringArray getDeadMansPedalFile() throw();
void setDeadMansPedalFile (const StringArray& newContents) throw(); void setDeadMansPedalFile (const StringArray& newContents) throw();


+ 1
- 1
src/juce_appframework/audio/plugins/juce_PluginListComponent.cpp View File

@@ -279,7 +279,7 @@ void PluginListComponent::scanFor (AudioPluginFormat* format)
for (;;) for (;;)
{ {
aw.setMessage (TRANS("Testing:\n\n") aw.setMessage (TRANS("Testing:\n\n")
+ scanner.getNextPluginFileThatWillBeScanned().getFileName());
+ scanner.getNextPluginFileThatWillBeScanned());
MessageManager::getInstance()->runDispatchLoopUntil (20); MessageManager::getInstance()->runDispatchLoopUntil (20);


+ 2
- 2
src/juce_appframework/gui/components/juce_Desktop.h View File

@@ -181,8 +181,8 @@ public:
The component must already be on the desktop for this method to work. It will The component must already be on the desktop for this method to work. It will
be resized to completely fill the screen and any extraneous taskbars, menu bars, be resized to completely fill the screen and any extraneous taskbars, menu bars,
etc will be hidden. etc will be hidden.
To exit kiosk mode, just call setKioskModeComponent (0). When this is called,
To exit kiosk mode, just call setKioskModeComponent (0). When this is called,
the component that's currently being used will be resized back to the size the component that's currently being used will be resized back to the size
and position it was in before being put into this mode. and position it was in before being put into this mode.
*/ */


+ 3
- 3
src/juce_appframework/gui/components/menus/juce_MenuBarModel.h View File

@@ -149,9 +149,9 @@ public:
not to delete a model while it is being used. not to delete a model while it is being used.
An optional extra menu can be specified, containing items to add to the top of An optional extra menu can be specified, containing items to add to the top of
the apple menu. (Confusingly, the 'apple' menu isn't the one with a picture of
an apple, it's the one next to it, with your application's name at the top
and the services menu etc on it). When one of these items is selected, the
the apple menu. (Confusingly, the 'apple' menu isn't the one with a picture of
an apple, it's the one next to it, with your application's name at the top
and the services menu etc on it). When one of these items is selected, the
menu bar model will be used to invoke it, and in the menuItemSelected() callback menu bar model will be used to invoke it, and in the menuItemSelected() callback
the topLevelMenuIndex parameter will be -1. If you pass in an extraAppleMenuItems the topLevelMenuIndex parameter will be -1. If you pass in an extraAppleMenuItems
object then newMenuBarModel must be non-null. object then newMenuBarModel must be non-null.


+ 4
- 4
src/juce_appframework/gui/components/mouse/juce_DragAndDropContainer.cpp View File

@@ -113,7 +113,7 @@ public:
{ {
Component* const over = dynamic_cast <Component*> (currentlyOver); Component* const over = dynamic_cast <Component*> (currentlyOver);
// (note: use a local copy of the dragDesc member in case the callback runs
// (note: use a local copy of the dragDesc member in case the callback runs
// a modal loop and deletes this object before the method completes) // a modal loop and deletes this object before the method completes)
const String dragDescLocal (dragDesc); const String dragDescLocal (dragDesc);
@@ -163,7 +163,7 @@ public:
hit = hit->getComponentAt (rx, ry); hit = hit->getComponentAt (rx, ry);
} }
// (note: use a local copy of the dragDesc member in case the callback runs
// (note: use a local copy of the dragDesc member in case the callback runs
// a modal loop and deletes this object before the method completes) // a modal loop and deletes this object before the method completes)
const String dragDescLocal (dragDesc); const String dragDescLocal (dragDesc);
@@ -234,7 +234,7 @@ public:
if (dropAccepted && ddt != 0) if (dropAccepted && ddt != 0)
{ {
// (note: use a local copy of the dragDesc member in case the callback runs
// (note: use a local copy of the dragDesc member in case the callback runs
// a modal loop and deletes this object before the method completes) // a modal loop and deletes this object before the method completes)
const String dragDescLocal (dragDesc); const String dragDescLocal (dragDesc);
@@ -247,7 +247,7 @@ public:
void updateLocation (const bool canDoExternalDrag, int x, int y) void updateLocation (const bool canDoExternalDrag, int x, int y)
{ {
// (note: use a local copy of the dragDesc member in case the callback runs
// (note: use a local copy of the dragDesc member in case the callback runs
// a modal loop and deletes this object before it returns) // a modal loop and deletes this object before it returns)
const String dragDescLocal (dragDesc); const String dragDescLocal (dragDesc);


Loading…
Cancel
Save