| @@ -132,7 +132,6 @@ | |||
| 84A06BE309CADB06006A43BD /* juce_mac_NamedPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A06BE209CADB06006A43BD /* juce_mac_NamedPipe.cpp */; }; | |||
| 84A4882908A22E2400752A2B /* juce_mac_CoreAudio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4881E08A22E2400752A2B /* juce_mac_CoreAudio.cpp */; }; | |||
| 84A4882A08A22E2400752A2B /* juce_mac_CoreMidi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4881F08A22E2400752A2B /* juce_mac_CoreMidi.cpp */; }; | |||
| 84A4882B08A22E2400752A2B /* juce_mac_FileChooser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882008A22E2400752A2B /* juce_mac_FileChooser.cpp */; }; | |||
| 84A4882C08A22E2400752A2B /* juce_mac_Files.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882108A22E2400752A2B /* juce_mac_Files.cpp */; }; | |||
| 84A4882D08A22E2400752A2B /* juce_mac_Fonts.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882208A22E2400752A2B /* juce_mac_Fonts.cpp */; }; | |||
| 84A4882E08A22E2400752A2B /* juce_mac_Messaging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84A4882308A22E2400752A2B /* juce_mac_Messaging.cpp */; }; | |||
| @@ -532,6 +531,7 @@ | |||
| 84F593B109855693008153BA /* juce_LassoComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F593B009855693008153BA /* juce_LassoComponent.h */; }; | |||
| 84F6B7540C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F6B7520C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.cpp */; }; | |||
| 84F6B7550C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F6B7530C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.h */; }; | |||
| 84F703230E1E56FB00EB338A /* juce_mac_FileChooser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84F703220E1E56FB00EB338A /* juce_mac_FileChooser.mm */; }; | |||
| 84F7A7AF0A8383A100D36246 /* juce_ToolbarButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F7A7AD0A8383A100D36246 /* juce_ToolbarButton.cpp */; }; | |||
| 84F7A7B00A8383A100D36246 /* juce_ToolbarButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F7A7AE0A8383A100D36246 /* juce_ToolbarButton.h */; }; | |||
| 84F7A7B80A8383C200D36246 /* juce_Toolbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F7A7B10A8383C200D36246 /* juce_Toolbar.cpp */; }; | |||
| @@ -709,7 +709,6 @@ | |||
| 84A06BE209CADB06006A43BD /* juce_mac_NamedPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_mac_NamedPipe.cpp; sourceTree = "<group>"; }; | |||
| 84A4881E08A22E2400752A2B /* juce_mac_CoreAudio.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_CoreAudio.cpp; path = platform_specific_code/juce_mac_CoreAudio.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4881F08A22E2400752A2B /* juce_mac_CoreMidi.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_CoreMidi.cpp; path = platform_specific_code/juce_mac_CoreMidi.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4882008A22E2400752A2B /* juce_mac_FileChooser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_FileChooser.cpp; path = platform_specific_code/juce_mac_FileChooser.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4882108A22E2400752A2B /* juce_mac_Files.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Files.cpp; path = platform_specific_code/juce_mac_Files.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4882208A22E2400752A2B /* juce_mac_Fonts.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Fonts.cpp; path = platform_specific_code/juce_mac_Fonts.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 84A4882308A22E2400752A2B /* juce_mac_Messaging.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_mac_Messaging.cpp; path = platform_specific_code/juce_mac_Messaging.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1109,6 +1108,7 @@ | |||
| 84F593B009855693008153BA /* juce_LassoComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_LassoComponent.h; sourceTree = "<group>"; }; | |||
| 84F6B7520C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_ChannelRemappingAudioSource.cpp; sourceTree = "<group>"; }; | |||
| 84F6B7530C06E29D00BB8791 /* juce_ChannelRemappingAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_ChannelRemappingAudioSource.h; sourceTree = "<group>"; }; | |||
| 84F703220E1E56FB00EB338A /* juce_mac_FileChooser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_FileChooser.mm; sourceTree = "<group>"; }; | |||
| 84F7A7AD0A8383A100D36246 /* juce_ToolbarButton.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_ToolbarButton.cpp; sourceTree = "<group>"; }; | |||
| 84F7A7AE0A8383A100D36246 /* juce_ToolbarButton.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_ToolbarButton.h; sourceTree = "<group>"; }; | |||
| 84F7A7B10A8383C200D36246 /* juce_Toolbar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_Toolbar.cpp; sourceTree = "<group>"; }; | |||
| @@ -1321,7 +1321,7 @@ | |||
| 84CE8A400DC5D7D600799A0E /* juce_mac_AudioCDBurner.mm */, | |||
| 84A4881E08A22E2400752A2B /* juce_mac_CoreAudio.cpp */, | |||
| 84A4881F08A22E2400752A2B /* juce_mac_CoreMidi.cpp */, | |||
| 84A4882008A22E2400752A2B /* juce_mac_FileChooser.cpp */, | |||
| 84F703220E1E56FB00EB338A /* juce_mac_FileChooser.mm */, | |||
| 84A4882108A22E2400752A2B /* juce_mac_Files.cpp */, | |||
| 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */, | |||
| 84A06BE209CADB06006A43BD /* juce_mac_NamedPipe.cpp */, | |||
| @@ -2558,7 +2558,6 @@ | |||
| files = ( | |||
| 84A4882908A22E2400752A2B /* juce_mac_CoreAudio.cpp in Sources */, | |||
| 84A4882A08A22E2400752A2B /* juce_mac_CoreMidi.cpp in Sources */, | |||
| 84A4882B08A22E2400752A2B /* juce_mac_FileChooser.cpp in Sources */, | |||
| 84A4882C08A22E2400752A2B /* juce_mac_Files.cpp in Sources */, | |||
| 84A4882D08A22E2400752A2B /* juce_mac_Fonts.cpp in Sources */, | |||
| 84A4882E08A22E2400752A2B /* juce_mac_Messaging.cpp in Sources */, | |||
| @@ -2821,6 +2820,7 @@ | |||
| 84BE9E1C0DE56DEB00AB8F23 /* juce_mac_SystemStats.mm in Sources */, | |||
| 84688AFB0DED58820077FDEA /* juce_AudioProcessorGraph.cpp in Sources */, | |||
| 84688AFD0DED58820077FDEA /* juce_AudioProcessorPlayer.cpp in Sources */, | |||
| 84F703230E1E56FB00EB338A /* juce_mac_FileChooser.mm in Sources */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| @@ -1,302 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| 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 <Carbon/Carbon.h> | |||
| #include <fnmatch.h> | |||
| #include "../../../src/juce_core/basics/juce_StandardHeader.h" | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h" | |||
| #include "../../../src/juce_appframework/gui/components/juce_Desktop.h" | |||
| #include "../../../src/juce_appframework/application/juce_Application.h" | |||
| #include "../../../src/juce_appframework/events/juce_MessageManager.h" | |||
| #include "../../../src/juce_core/misc/juce_PlatformUtilities.h" | |||
| #include "../../../src/juce_core/text/juce_LocalisedStrings.h" | |||
| //============================================================================== | |||
| struct JuceNavInfo | |||
| { | |||
| StringArray filters; | |||
| AEDesc defaultLocation; | |||
| bool defaultLocationValid; | |||
| }; | |||
| static void pascal juceNavEventProc (NavEventCallbackMessage callbackSelector, | |||
| NavCBRecPtr callbackParms, | |||
| void *callBackUD) | |||
| { | |||
| if (callbackSelector == kNavCBStart) | |||
| { | |||
| if (((JuceNavInfo*) callBackUD)->defaultLocationValid) | |||
| { | |||
| NavCustomControl (callbackParms->context, | |||
| kNavCtlSetLocation, | |||
| (void*) &((JuceNavInfo*) callBackUD)->defaultLocation); | |||
| } | |||
| for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;) | |||
| { | |||
| Component* const c = Desktop::getInstance().getComponent (i); | |||
| if (c != 0 && c->isAlwaysOnTop() && c->isVisible()) | |||
| { | |||
| SetWindowGroup (callbackParms->window, | |||
| GetWindowGroup ((WindowRef) c->getWindowHandle())); | |||
| break; | |||
| } | |||
| } | |||
| BringToFront (callbackParms->window); | |||
| SelectWindow (callbackParms->window); | |||
| SetUserFocusWindow (callbackParms->window); | |||
| } | |||
| } | |||
| static Boolean pascal juceNavFilterProc (AEDesc* theItem, | |||
| void*, | |||
| void* callBackUD, | |||
| NavFilterModes filterMode) | |||
| { | |||
| // must return true if we don't understand the object | |||
| bool result = true; | |||
| if (filterMode == kNavFilteringBrowserList) | |||
| { | |||
| AEDesc desc; | |||
| if (AECoerceDesc (theItem, typeFSRef, &desc) == noErr) | |||
| { | |||
| Size size = AEGetDescDataSize (&desc); | |||
| if (size > 0) | |||
| { | |||
| void* data = juce_calloc (size); | |||
| if (AEGetDescData (&desc, data, size) == noErr) | |||
| { | |||
| const String path (PlatformUtilities::makePathFromFSRef ((FSRef*) data)); | |||
| if (path.isNotEmpty()) | |||
| { | |||
| const File file (path); | |||
| if ((! file.isDirectory()) || PlatformUtilities::isBundle (path)) | |||
| { | |||
| const String filename (file.getFileName().toLowerCase()); | |||
| const char* const filenameUTF8 = filename.toUTF8(); | |||
| const JuceNavInfo* const info = (const JuceNavInfo*) callBackUD; | |||
| if (info != 0) | |||
| { | |||
| result = false; | |||
| for (int i = info->filters.size(); --i >= 0;) | |||
| { | |||
| const String wildcard (info->filters[i].toLowerCase()); | |||
| if (fnmatch (wildcard.toUTF8(), filenameUTF8, 0) == 0) | |||
| { | |||
| result = true; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| juce_free (data); | |||
| } | |||
| AEDisposeDesc (&desc); | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||
| const String& title, | |||
| const File& currentFileOrDirectory, | |||
| const String& filter, | |||
| bool selectsDirectory, | |||
| bool isSaveDialogue, | |||
| bool warnAboutOverwritingExistingFiles, | |||
| bool selectMultipleFiles, | |||
| FilePreviewComponent* extraInfoComponent) | |||
| { | |||
| JuceNavInfo userInfo; | |||
| userInfo.filters.addTokens (filter.replaceCharacters (T(",:"), T(";;")), T(";"), 0); | |||
| userInfo.filters.trim(); | |||
| userInfo.filters.removeEmptyStrings(); | |||
| userInfo.defaultLocationValid = false; | |||
| void* const userInfoPtr = (void*) &userInfo; | |||
| const int oldTimeBeforeWaitCursor = MessageManager::getInstance()->getTimeBeforeShowingWaitCursor(); | |||
| MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0); | |||
| NavEventUPP eventProc = NewNavEventUPP (juceNavEventProc); | |||
| NavObjectFilterUPP filterProc = NewNavObjectFilterUPP (juceNavFilterProc); | |||
| FSRef defaultRef; | |||
| if ((currentFileOrDirectory.isOnHardDisk() | |||
| && PlatformUtilities::makeFSRefFromPath (&defaultRef, | |||
| currentFileOrDirectory.getFullPathName())) | |||
| || (currentFileOrDirectory.getParentDirectory().isOnHardDisk() | |||
| && PlatformUtilities::makeFSRefFromPath (&defaultRef, | |||
| currentFileOrDirectory.getParentDirectory().getFullPathName()))) | |||
| { | |||
| if (AECreateDesc (typeFSRef, &defaultRef, sizeof (defaultRef), &userInfo.defaultLocation) == noErr) | |||
| { | |||
| userInfo.defaultLocationValid = true; | |||
| } | |||
| } | |||
| WindowRef lastFocused = GetUserFocusWindow(); | |||
| NavDialogCreationOptions options; | |||
| if (NavGetDefaultDialogCreationOptions (&options) == noErr) | |||
| { | |||
| options.optionFlags |= kNavSelectDefaultLocation | |||
| | kNavSupportPackages | |||
| | kNavAllowPreviews; | |||
| if (! warnAboutOverwritingExistingFiles) | |||
| options.optionFlags |= kNavDontConfirmReplacement; | |||
| if (selectMultipleFiles) | |||
| options.optionFlags |= kNavAllowMultipleFiles; | |||
| const String name (selectsDirectory ? TRANS("Choose folder") | |||
| : TRANS("Choose file")); | |||
| options.clientName = PlatformUtilities::juceStringToCFString (name); | |||
| CFStringRef message = PlatformUtilities::juceStringToCFString (title); | |||
| if (userInfo.defaultLocationValid) | |||
| options.saveFileName = PlatformUtilities::juceStringToCFString (currentFileOrDirectory.getFileName()); | |||
| // nasty layout bug if the message text is set for a directory browser.. | |||
| if (selectsDirectory) | |||
| options.windowTitle = message; | |||
| else | |||
| options.message = message; | |||
| NavDialogRef dialog = 0; | |||
| bool ok = false; | |||
| if (selectsDirectory) | |||
| { | |||
| ok = (NavCreateChooseFolderDialog (&options, eventProc, 0, userInfoPtr, &dialog) == noErr); | |||
| } | |||
| else if (isSaveDialogue) | |||
| { | |||
| ok = (NavCreatePutFileDialog (&options, 0, 0, eventProc, userInfoPtr, &dialog) == noErr); | |||
| } | |||
| else | |||
| { | |||
| ok = (NavCreateGetFileDialog (&options, 0, eventProc, 0, filterProc, userInfoPtr, &dialog) == noErr); | |||
| } | |||
| if (ok && (NavDialogRun (dialog) == noErr)) | |||
| { | |||
| NavReplyRecord reply; | |||
| if (NavDialogGetReply (dialog, &reply) == noErr) | |||
| { | |||
| if (reply.validRecord) | |||
| { | |||
| long count; | |||
| if (AECountItems (&(reply.selection), &count) == noErr | |||
| && count > 0) | |||
| { | |||
| AEKeyword theKeyword; | |||
| DescType actualType; | |||
| Size actualSize; | |||
| FSRef file; | |||
| for (int i = 1; i <= count; ++i) | |||
| { | |||
| // Get a pointer to selected file | |||
| if (AEGetNthPtr (&(reply.selection), | |||
| i, | |||
| typeFSRef, | |||
| &theKeyword, | |||
| &actualType, | |||
| &file, | |||
| sizeof (file), | |||
| &actualSize) == noErr) | |||
| { | |||
| String result (PlatformUtilities::makePathFromFSRef (&file)); | |||
| if (result.isNotEmpty() && isSaveDialogue && ! selectsDirectory) | |||
| { | |||
| CFStringRef saveName = NavDialogGetSaveFileName (dialog); | |||
| result = File (result) | |||
| .getChildFile (PlatformUtilities::convertToPrecomposedUnicode (PlatformUtilities::cfStringToJuceString (saveName))) | |||
| .getFullPathName(); | |||
| } | |||
| results.add (new File (result)); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| NavDisposeReply (&reply); | |||
| } | |||
| } | |||
| if (dialog != 0) | |||
| NavDialogDispose (dialog); | |||
| CFRelease (message); | |||
| CFRelease (options.clientName); | |||
| } | |||
| if (userInfo.defaultLocationValid) | |||
| AEDisposeDesc (&userInfo.defaultLocation); | |||
| DisposeNavEventUPP (eventProc); | |||
| DisposeNavObjectFilterUPP (filterProc); | |||
| MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (oldTimeBeforeWaitCursor); | |||
| SetUserFocusWindow (lastFocused); | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -0,0 +1,149 @@ | |||
| /* | |||
| ============================================================================== | |||
| 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 <Cocoa/Cocoa.h> | |||
| #include <fnmatch.h> | |||
| #include "../../../src/juce_core/basics/juce_StandardHeader.h" | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h" | |||
| END_JUCE_NAMESPACE | |||
| static const juce::String nsStringToJuce (NSString* s) | |||
| { | |||
| return juce::String::fromUTF8 ((juce::uint8*) [s UTF8String]); | |||
| } | |||
| static NSString* juceStringToNS (const juce::String& s) | |||
| { | |||
| return [NSString stringWithUTF8String: (const char*) s.toUTF8()]; | |||
| } | |||
| //============================================================================== | |||
| @interface JuceFileChooserDelegate : NSObject | |||
| { | |||
| juce::StringArray* filters; | |||
| } | |||
| - (JuceFileChooserDelegate*) initWithFilters: (juce::StringArray*) filters_; | |||
| - (void) dealloc; | |||
| - (BOOL) panel:(id) sender shouldShowFilename: (NSString*) filename; | |||
| @end | |||
| @implementation JuceFileChooserDelegate | |||
| - (JuceFileChooserDelegate*) initWithFilters: (juce::StringArray*) filters_ | |||
| { | |||
| [super init]; | |||
| filters = filters_; | |||
| return self; | |||
| } | |||
| - (void) dealloc | |||
| { | |||
| delete filters; | |||
| [super dealloc]; | |||
| } | |||
| - (BOOL) panel:(id) sender shouldShowFilename: (NSString*) filename | |||
| { | |||
| const char* filenameUTF8 = (const char*) [filename UTF8String]; | |||
| for (int i = filters->size(); --i >= 0;) | |||
| { | |||
| const juce::String wildcard ((*filters)[i].toLowerCase()); | |||
| if (fnmatch (wildcard.toUTF8(), filenameUTF8, 0) == 0) | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| @end | |||
| BEGIN_JUCE_NAMESPACE | |||
| void FileChooser::showPlatformDialog (OwnedArray<File>& results, | |||
| const String& title, | |||
| const File& currentFileOrDirectory, | |||
| const String& filter, | |||
| bool selectsDirectory, | |||
| bool isSaveDialogue, | |||
| bool warnAboutOverwritingExistingFiles, | |||
| bool selectMultipleFiles, | |||
| FilePreviewComponent* extraInfoComponent) | |||
| { | |||
| StringArray* filters = new StringArray(); | |||
| filters->addTokens (filter.replaceCharacters (T(",:"), T(";;")), T(";"), 0); | |||
| filters->trim(); | |||
| filters->removeEmptyStrings(); | |||
| JuceFileChooserDelegate* delegate = [[JuceFileChooserDelegate alloc] initWithFilters: filters]; | |||
| [delegate autorelease]; | |||
| NSSavePanel* panel = isSaveDialogue ? [NSSavePanel savePanel] | |||
| : [NSOpenPanel openPanel]; | |||
| [panel setTitle: juceStringToNS (title)]; | |||
| if (! isSaveDialogue) | |||
| { | |||
| NSOpenPanel* openPanel = (NSOpenPanel*) panel; | |||
| [openPanel setCanChooseDirectories: selectsDirectory]; | |||
| [openPanel setCanChooseFiles: ! selectsDirectory]; | |||
| [openPanel setAllowsMultipleSelection: selectMultipleFiles]; | |||
| } | |||
| [panel setDelegate: delegate]; | |||
| NSInteger result = [panel runModalForDirectory: juceStringToNS (currentFileOrDirectory.getParentDirectory().getFullPathName()) | |||
| file: juceStringToNS (currentFileOrDirectory.getFileName())]; | |||
| if (result == NSOKButton) | |||
| { | |||
| if (isSaveDialogue) | |||
| { | |||
| results.add (new File (nsStringToJuce ([panel filename]))); | |||
| } | |||
| else | |||
| { | |||
| NSOpenPanel* openPanel = (NSOpenPanel*) panel; | |||
| NSArray* urls = [openPanel filenames]; | |||
| for (int i = 0; i < [urls count]; ++i) | |||
| { | |||
| NSString* f = [urls objectAtIndex: i]; | |||
| results.add (new File (nsStringToJuce (f))); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -1,203 +1,202 @@ | |||
| /* | |||
| ============================================================================== | |||
| 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 "../../../src/juce_core/basics/juce_StandardHeader.h" | |||
| #include <pthread.h> | |||
| #include <sched.h> | |||
| #include <sys/file.h> | |||
| #include <sys/types.h> | |||
| #include <sys/sysctl.h> | |||
| #include <Carbon/Carbon.h> | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "../../../src/juce_core/threads/juce_CriticalSection.h" | |||
| #include "../../../src/juce_core/threads/juce_WaitableEvent.h" | |||
| #include "../../../src/juce_core/threads/juce_Thread.h" | |||
| #include "../../../src/juce_core/threads/juce_Process.h" | |||
| #include "../../../src/juce_core/misc/juce_PlatformUtilities.h" | |||
| #include "../../../src/juce_core/io/files/juce_File.h" | |||
| //============================================================================== | |||
| /* | |||
| Note that a lot of methods that you'd expect to find in this file actually | |||
| live in juce_posix_SharedCode.cpp! | |||
| */ | |||
| //============================================================================== | |||
| void JUCE_API juce_threadEntryPoint (void*); | |||
| void* threadEntryProc (void* userData) throw() | |||
| { | |||
| juce_threadEntryPoint (userData); | |||
| return 0; | |||
| } | |||
| void* juce_createThread (void* userData) throw() | |||
| { | |||
| pthread_t handle = 0; | |||
| if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||
| { | |||
| pthread_detach (handle); | |||
| return (void*) handle; | |||
| } | |||
| return 0; | |||
| } | |||
| void juce_killThread (void* handle) throw() | |||
| { | |||
| if (handle != 0) | |||
| pthread_cancel ((pthread_t) handle); | |||
| } | |||
| void juce_setCurrentThreadName (const String& /*name*/) throw() | |||
| { | |||
| } | |||
| int Thread::getCurrentThreadId() throw() | |||
| { | |||
| return (int) pthread_self(); | |||
| } | |||
| void juce_setThreadPriority (void* handle, int priority) throw() | |||
| { | |||
| if (handle == 0) | |||
| handle = (void*) pthread_self(); | |||
| struct sched_param param; | |||
| int policy; | |||
| pthread_getschedparam ((pthread_t) handle, &policy, ¶m); | |||
| param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11); | |||
| pthread_setschedparam ((pthread_t) handle, policy, ¶m); | |||
| } | |||
| void Thread::yield() throw() | |||
| { | |||
| sched_yield(); | |||
| } | |||
| void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw() | |||
| { | |||
| // xxx | |||
| jassertfalse | |||
| } | |||
| //============================================================================== | |||
| bool JUCE_CALLTYPE juce_isRunningUnderDebugger() throw() | |||
| { | |||
| static char testResult = 0; | |||
| if (testResult == 0) | |||
| { | |||
| struct kinfo_proc info; | |||
| int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; | |||
| size_t sz = sizeof (info); | |||
| sysctl (m, 4, &info, &sz, 0, 0); | |||
| testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1; | |||
| } | |||
| return testResult > 0; | |||
| } | |||
| bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw() | |||
| { | |||
| return juce_isRunningUnderDebugger(); | |||
| } | |||
| void Process::raisePrivilege() | |||
| { | |||
| jassertfalse | |||
| } | |||
| void Process::lowerPrivilege() | |||
| { | |||
| jassertfalse | |||
| } | |||
| void Process::terminate() | |||
| { | |||
| ExitToShell(); | |||
| } | |||
| void Process::setPriority (ProcessPriority p) | |||
| { | |||
| // xxx | |||
| } | |||
| void* Process::loadDynamicLibrary (const String& name) | |||
| { | |||
| // xxx needs to use bundles | |||
| FSSpec fs; | |||
| if (PlatformUtilities::makeFSSpecFromPath (&fs, name)) | |||
| { | |||
| CFragConnectionID connID; | |||
| Ptr mainPtr; | |||
| Str255 errorMessage; | |||
| Str63 nm; | |||
| PlatformUtilities::copyToStr63 (nm, name); | |||
| const OSErr err = GetDiskFragment (&fs, 0, kCFragGoesToEOF, nm, kReferenceCFrag, &connID, &mainPtr, errorMessage); | |||
| if (err == noErr) | |||
| return (void*)connID; | |||
| } | |||
| return 0; | |||
| } | |||
| void Process::freeDynamicLibrary (void* handle) | |||
| { | |||
| if (handle != 0) | |||
| CloseConnection ((CFragConnectionID*)&handle); | |||
| } | |||
| void* Process::getProcedureEntryPoint (void* h, const String& procedureName) | |||
| { | |||
| if (h != 0) | |||
| { | |||
| CFragSymbolClass cl; | |||
| Ptr ptr; | |||
| Str255 name; | |||
| PlatformUtilities::copyToStr255 (name, procedureName); | |||
| if (FindSymbol ((CFragConnectionID) h, name, &ptr, &cl) == noErr) | |||
| { | |||
| return ptr; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| /* | |||
| ============================================================================== | |||
| 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 "../../../src/juce_core/basics/juce_StandardHeader.h" | |||
| #include <pthread.h> | |||
| #include <sched.h> | |||
| #include <sys/file.h> | |||
| #include <sys/types.h> | |||
| #include <sys/sysctl.h> | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "../../../src/juce_core/threads/juce_CriticalSection.h" | |||
| #include "../../../src/juce_core/threads/juce_WaitableEvent.h" | |||
| #include "../../../src/juce_core/threads/juce_Thread.h" | |||
| #include "../../../src/juce_core/threads/juce_Process.h" | |||
| #include "../../../src/juce_core/misc/juce_PlatformUtilities.h" | |||
| #include "../../../src/juce_core/io/files/juce_File.h" | |||
| //============================================================================== | |||
| /* | |||
| Note that a lot of methods that you'd expect to find in this file actually | |||
| live in juce_posix_SharedCode.cpp! | |||
| */ | |||
| //============================================================================== | |||
| void JUCE_API juce_threadEntryPoint (void*); | |||
| void* threadEntryProc (void* userData) throw() | |||
| { | |||
| juce_threadEntryPoint (userData); | |||
| return 0; | |||
| } | |||
| void* juce_createThread (void* userData) throw() | |||
| { | |||
| pthread_t handle = 0; | |||
| if (pthread_create (&handle, 0, threadEntryProc, userData) == 0) | |||
| { | |||
| pthread_detach (handle); | |||
| return (void*) handle; | |||
| } | |||
| return 0; | |||
| } | |||
| void juce_killThread (void* handle) throw() | |||
| { | |||
| if (handle != 0) | |||
| pthread_cancel ((pthread_t) handle); | |||
| } | |||
| void juce_setCurrentThreadName (const String& /*name*/) throw() | |||
| { | |||
| } | |||
| int Thread::getCurrentThreadId() throw() | |||
| { | |||
| return (int) pthread_self(); | |||
| } | |||
| void juce_setThreadPriority (void* handle, int priority) throw() | |||
| { | |||
| if (handle == 0) | |||
| handle = (void*) pthread_self(); | |||
| struct sched_param param; | |||
| int policy; | |||
| pthread_getschedparam ((pthread_t) handle, &policy, ¶m); | |||
| param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11); | |||
| pthread_setschedparam ((pthread_t) handle, policy, ¶m); | |||
| } | |||
| void Thread::yield() throw() | |||
| { | |||
| sched_yield(); | |||
| } | |||
| void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask) throw() | |||
| { | |||
| // xxx | |||
| jassertfalse | |||
| } | |||
| //============================================================================== | |||
| bool JUCE_CALLTYPE juce_isRunningUnderDebugger() throw() | |||
| { | |||
| static char testResult = 0; | |||
| if (testResult == 0) | |||
| { | |||
| struct kinfo_proc info; | |||
| int m[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; | |||
| size_t sz = sizeof (info); | |||
| sysctl (m, 4, &info, &sz, 0, 0); | |||
| testResult = ((info.kp_proc.p_flag & P_TRACED) != 0) ? 1 : -1; | |||
| } | |||
| return testResult > 0; | |||
| } | |||
| bool JUCE_CALLTYPE Process::isRunningUnderDebugger() throw() | |||
| { | |||
| return juce_isRunningUnderDebugger(); | |||
| } | |||
| void Process::raisePrivilege() | |||
| { | |||
| jassertfalse | |||
| } | |||
| void Process::lowerPrivilege() | |||
| { | |||
| jassertfalse | |||
| } | |||
| void Process::terminate() | |||
| { | |||
| exit (0); | |||
| } | |||
| void Process::setPriority (ProcessPriority p) | |||
| { | |||
| // xxx | |||
| } | |||
| void* Process::loadDynamicLibrary (const String& name) | |||
| { | |||
| // xxx needs to use bundles | |||
| FSSpec fs; | |||
| if (PlatformUtilities::makeFSSpecFromPath (&fs, name)) | |||
| { | |||
| CFragConnectionID connID; | |||
| Ptr mainPtr; | |||
| Str255 errorMessage; | |||
| Str63 nm; | |||
| PlatformUtilities::copyToStr63 (nm, name); | |||
| const OSErr err = GetDiskFragment (&fs, 0, kCFragGoesToEOF, nm, kReferenceCFrag, &connID, &mainPtr, errorMessage); | |||
| if (err == noErr) | |||
| return (void*)connID; | |||
| } | |||
| return 0; | |||
| } | |||
| void Process::freeDynamicLibrary (void* handle) | |||
| { | |||
| if (handle != 0) | |||
| CloseConnection ((CFragConnectionID*)&handle); | |||
| } | |||
| void* Process::getProcedureEntryPoint (void* h, const String& procedureName) | |||
| { | |||
| if (h != 0) | |||
| { | |||
| CFragSymbolClass cl; | |||
| Ptr ptr; | |||
| Str255 name; | |||
| PlatformUtilities::copyToStr255 (name, procedureName); | |||
| if (FindSymbol ((CFragConnectionID) h, name, &ptr, &cl) == noErr) | |||
| { | |||
| return ptr; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -33740,7 +33740,7 @@ public: | |||
| /** | |||
| */ | |||
| const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes() const throw() { return availableDeviceTypes; } | |||
| const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes(); | |||
| /** Creates a list of available types. | |||
| @@ -44703,6 +44703,14 @@ public: | |||
| */ | |||
| void setScrollWheelEnabled (const bool enabled) throw(); | |||
| /** Returns a number to indicate which thumb is currently being dragged by the | |||
| mouse. | |||
| This will return 0 for the main thumb, 1 for the minimum-value thumb, 2 for | |||
| the maximum-value thumb, or -1 if none is currently down. | |||
| */ | |||
| int getThumbBeingDragged() const throw() { return sliderBeingDragged; } | |||
| /** Callback to indicate that the user is about to start dragging the slider. | |||
| @see SliderListener::sliderDragStarted | |||
| @@ -50477,11 +50485,6 @@ public: | |||
| /** @internal */ | |||
| void changeListenerCallback (void*); | |||
| /** Called by the device-specific displays to create a little level meter that | |||
| just displays the current total input levels from the given device manager. | |||
| */ | |||
| static Component* createSimpleLevelMeterComponent (AudioDeviceManager* managerToDisplay); | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| @@ -417,7 +417,7 @@ | |||
| #include "../build/macosx/platform_specific_code/juce_mac_AudioCDBurner.mm" | |||
| #include "../build/macosx/platform_specific_code/juce_mac_CoreAudio.cpp" | |||
| #include "../build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp" | |||
| #include "../build/macosx/platform_specific_code/juce_mac_FileChooser.cpp" | |||
| #include "../build/macosx/platform_specific_code/juce_mac_FileChooser.mm" | |||
| #include "../build/macosx/platform_specific_code/juce_mac_Fonts.cpp" | |||
| #include "../build/macosx/platform_specific_code/juce_mac_Messaging.cpp" | |||
| #include "../build/macosx/platform_specific_code/juce_mac_WebBrowserComponent.mm" | |||
| @@ -113,6 +113,7 @@ Slider::Slider (const String& name) | |||
| numDecimalPlaces (7), | |||
| sliderRegionStart (0), | |||
| sliderRegionSize (1), | |||
| sliderBeingDragged (-1), | |||
| pixelsForFullDragExtent (250), | |||
| style (LinearHorizontal), | |||
| textBoxPos (TextBoxLeft), | |||
| @@ -178,6 +179,8 @@ void Slider::sendDragEnd() | |||
| { | |||
| stoppedDragging(); | |||
| sliderBeingDragged = -1; | |||
| for (int i = listeners.size(); --i >= 0;) | |||
| { | |||
| ((SliderListener*) listeners.getUnchecked (i))->sliderDragEnded (this); | |||
| @@ -500,6 +500,14 @@ public: | |||
| */ | |||
| void setScrollWheelEnabled (const bool enabled) throw(); | |||
| /** Returns a number to indicate which thumb is currently being dragged by the | |||
| mouse. | |||
| This will return 0 for the main thumb, 1 for the minimum-value thumb, 2 for | |||
| the maximum-value thumb, or -1 if none is currently down. | |||
| */ | |||
| int getThumbBeingDragged() const throw() { return sliderBeingDragged; } | |||
| //============================================================================== | |||
| /** Callback to indicate that the user is about to start dragging the slider. | |||