diff options
| author | pepper <peppersclothescult@gmail.com> | 2015-01-10 21:37:24 -0800 |
|---|---|---|
| committer | pepper <peppersclothescult@gmail.com> | 2015-01-10 21:37:24 -0800 |
| commit | 58f8437f4b8b741ddc8e7bcde21bf983cc618430 (patch) | |
| tree | bfd0a9d601274fe56de15a4eaeb0998f9481419d /vendor/vstsdk2.4/vstgui.sf/vstgui/cfileselector.cpp | |
| parent | 36773a28ece1641a2d827a29869cdd4c38e87925 (diff) | |
Diffstat (limited to 'vendor/vstsdk2.4/vstgui.sf/vstgui/cfileselector.cpp')
| -rw-r--r-- | vendor/vstsdk2.4/vstgui.sf/vstgui/cfileselector.cpp | 1156 |
1 files changed, 1156 insertions, 0 deletions
diff --git a/vendor/vstsdk2.4/vstgui.sf/vstgui/cfileselector.cpp b/vendor/vstsdk2.4/vstgui.sf/vstgui/cfileselector.cpp new file mode 100644 index 0000000..0a715ea --- /dev/null +++ b/vendor/vstsdk2.4/vstgui.sf/vstgui/cfileselector.cpp @@ -0,0 +1,1156 @@ +//----------------------------------------------------------------------------- +// VST Plug-Ins SDK +// VSTGUI: Graphical User Interface Framework for VST plugins : +// +// Version 3.0 $Date: 2006/01/31 10:03:38 $ +// +//----------------------------------------------------------------------------- +// VSTGUI LICENSE +// © 2004, Steinberg Media Technologies, All Rights Reserved +//----------------------------------------------------------------------------- +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the Steinberg Media Technologies nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +//----------------------------------------------------------------------------- + +#if !PLUGGUI +#include "AudioEffectX.h" +#endif + +#ifndef __cfileselector__ +#include "cfileselector.h" +#endif + +//----------------------------------------------------------------------------- +// CFileSelector Implementation +//----------------------------------------------------------------------------- +#define stringAnyType "Any Type (*.*)" +#define stringAllTypes "All Types: (" +#define stringSelect "Select" +#define stringCancel "Cancel" +#define stringLookIn "Look in" +#define kPathMax 1024 + +#if WINDOWS +#include <stdio.h> + +static UINT_PTR APIENTRY SelectDirectoryHook (HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK SelectDirectoryButtonProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +WNDPROC fpOldSelectDirectoryButtonProc; +static UINT_PTR APIENTRY WinSaveHook (HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam); +static bool bFolderSelected; +static bool bDidCancel; +static char selDirPath[kPathMax]; +#if PLUGGUI + extern HINSTANCE ghInst; + inline HINSTANCE GetInstance () { return ghInst; } +#else + extern void* hInstance; + inline HINSTANCE GetInstance () { return (HINSTANCE)hInstance; } +#endif +#endif + +BEGIN_NAMESPACE_VSTGUI + +//----------------------------------------------------------------------------- +CFileSelector::CFileSelector (void* ptr) +: ptr (ptr) +, vstFileSelect (0) +{} + +//----------------------------------------------------------------------------- +CFileSelector::~CFileSelector () +{ + if (vstFileSelect) + { + #if VST + if (ptr && ((AudioEffectX*)ptr)->canHostDo ("closeFileSelector")) + ((AudioEffectX*)ptr)->closeFileSelector (vstFileSelect); + else + #endif + { + if (vstFileSelect->reserved == 1 && vstFileSelect->returnPath) + { + delete []vstFileSelect->returnPath; + vstFileSelect->returnPath = 0; + vstFileSelect->sizeReturnPath = 0; + } + if (vstFileSelect->returnMultiplePaths) + { + for (long i = 0; i < vstFileSelect->nbReturnPath; i++) + { + delete []vstFileSelect->returnMultiplePaths[i]; + vstFileSelect->returnMultiplePaths[i] = 0; + } + delete[] vstFileSelect->returnMultiplePaths; + vstFileSelect->returnMultiplePaths = 0; + } + } + } +} + +//----------------------------------------------------------------------------- +long CFileSelector::run (VstFileSelect *vstFileSelect) +{ + this->vstFileSelect = vstFileSelect; + vstFileSelect->nbReturnPath = 0; + if (vstFileSelect->returnPath) + vstFileSelect->returnPath[0] = 0; + + #if !PLUGGUI + if (ptr + #if MACX + && vstFileSelect->command != kVstFileSave + #endif + && ((AudioEffectX*)ptr)->canHostDo ("openFileSelector") && ((AudioEffectX*)ptr)->canHostDo ("closeFileSelector")) + { + if (((AudioEffectX*)ptr)->openFileSelector (vstFileSelect)) + return vstFileSelect->nbReturnPath; + } + else + #endif + { +#if WINDOWS + char filter[512]; + char filePathBuffer[kPathMax]; + strcpy (filePathBuffer, ""); + char* filePath = filePathBuffer; + char fileName[kPathMax]; + strcpy (fileName, ""); + filter[0] = 0; + filePath[0] = 0; + fileName[0] = 0; + + //----------------------------------------- + if (vstFileSelect->command == kVstFileLoad || + vstFileSelect->command == kVstMultipleFilesLoad || + vstFileSelect->command == kVstDirectorySelect) + { + char* multiBuffer = 0; + if (vstFileSelect->command == kVstMultipleFilesLoad) + { + multiBuffer = new char [kPathMax * 100]; + strcpy (multiBuffer, ""); + filePath = multiBuffer; + } + + if (vstFileSelect->command != kVstDirectorySelect) + { + char allBuffer [kPathMax] = {0}; + char* p = filter; + char* p2 = allBuffer; + + const char* ext; + const char* extensions [100]; + long i, j, extCount = 0; + char string[24]; + + for (long ty = 0; ty < vstFileSelect->nbFileTypes; ty++) + { + for (i = 0; i < 2 ; i++) + { + if (i == 0) + { + ext = vstFileSelect->fileTypes[ty].dosType; + + strcpy (p, vstFileSelect->fileTypes[ty].name); + strcat (p, " (."); + strcat (p, ext); + strcat (p, ")"); + p += strlen (p) + 1; + + strcpy (string, "*."); + strcat (string, ext); + strcpy (p, string); + p += strlen (p); + } + else + { + if (!strcmp (vstFileSelect->fileTypes[ty].dosType, vstFileSelect->fileTypes[ty].unixType) || !strcmp (vstFileSelect->fileTypes[ty].unixType, "")) + break; // for + ext = vstFileSelect->fileTypes[ty].unixType; + strcpy (string, ";*."); + strcat (string, ext); + strcpy (p, string); + p += strlen (p); + } + bool found = false; + for (j = 0; j < extCount;j ++) + { + if (strcmp (ext, extensions [j]) == 0) + { + found = true; + break; + } + } + if (!found && extCount < 100) + extensions [extCount++] = ext; + } + p ++; + } // end for filetype + + if (extCount > 1) + { + for (i = 0; i < extCount ;i ++) + { + ext = extensions [i]; + strcpy (string, "*."); + strcat (string, ext); + + if (p2 != allBuffer) + { + strcpy (p2, ";"); + p2++; + } + strcpy (p2, string); + p2 += strlen (p2); + } + + // add the : All types + strcpy (p, stringAllTypes); + strcat (p, allBuffer); + strcat (p, ")"); + p += strlen (p) + 1; + strcpy (p, allBuffer); + p += strlen (p) + 1; + } + + strcpy (p, stringAnyType); + p += strlen (p) + 1; + strcpy (p, "*.*"); + p += strlen (p) + 1; + + *p++ = 0; + *p++ = 0; + } + + OPENFILENAME ofn = {0}; + ofn.lStructSize = sizeof (OPENFILENAME); + HWND owner = 0; + #if !PLUGGUI + if (ptr && ((AudioEffectX*)ptr)->getEditor () && ((AEffGUIEditor*)((AudioEffectX*)ptr)->getEditor ())->getFrame ()) + owner = (HWND)((AEffGUIEditor*)((AudioEffectX*)ptr)->getEditor ())->getFrame ()->getSystemWindow (); + #endif + ofn.hwndOwner = owner; + + if (vstFileSelect->command == kVstDirectorySelect) + ofn.lpstrFilter = "HideFileFilter\0*.___\0\0"; // to hide files + else + ofn.lpstrFilter = filter[0] ? filter : 0; + ofn.nFilterIndex = 1; + ofn.lpstrCustomFilter = NULL; + ofn.lpstrFile = filePath; + if (vstFileSelect->command == kVstMultipleFilesLoad) + ofn.nMaxFile = 100 * kPathMax - 1; + else + ofn.nMaxFile = sizeof (filePathBuffer) - 1; + + ofn.lpstrFileTitle = fileName; + ofn.nMaxFileTitle = 64; + ofn.lpstrInitialDir = vstFileSelect->initialPath; + ofn.lpstrTitle = vstFileSelect->title; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING | OFN_ENABLEHOOK; + if (vstFileSelect->command == kVstDirectorySelect) + { + ofn.Flags &= ~OFN_FILEMUSTEXIST; + ofn.lpfnHook = SelectDirectoryHook; + } + + if (vstFileSelect->command == kVstMultipleFilesLoad) + ofn.Flags |= OFN_ALLOWMULTISELECT; + + vstFileSelect->nbReturnPath = 0; + bDidCancel = true; + + if (GetOpenFileName (&ofn) || + ((vstFileSelect->command == kVstDirectorySelect) && !bDidCancel && strlen (selDirPath) != 0)) + { + switch (vstFileSelect->command) + { + case kVstFileLoad: + vstFileSelect->nbReturnPath = 1; + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char[strlen (ofn.lpstrFile) + 1]; + vstFileSelect->sizeReturnPath = (long)strlen (ofn.lpstrFile) + 1; + } + strcpy (vstFileSelect->returnPath, ofn.lpstrFile); + break; + + case kVstMultipleFilesLoad: + { + char string[kPathMax], directory[kPathMax]; + char *previous = ofn.lpstrFile; + size_t len; + bool dirFound = false; + bool first = true; + directory[0] = 0; // !! + vstFileSelect->returnMultiplePaths = new char*[kPathMax]; + long i = 0; + while (1) + { + if (*previous != 0) + { // something found + if (!dirFound) + { + dirFound = true; + strcpy (directory, previous); + len = strlen (previous) + 1; // including 0 + previous += len; + + if (*previous == 0) + { // 1 selected file only + vstFileSelect->returnMultiplePaths[i] = new char [strlen (directory) + 1]; + strcpy (vstFileSelect->returnMultiplePaths[i++], directory); + } + else + { + if (directory[strlen (directory) - 1] != '\\') + strcat (directory, "\\"); + } + } + else + { + sprintf (string, "%s%s", directory, previous); + len = strlen (previous) + 1; // including 0 + previous += len; + + vstFileSelect->returnMultiplePaths[i] = new char [strlen (string) + 1]; + strcpy (vstFileSelect->returnMultiplePaths[i++], string); + } + } + else + break; + } + vstFileSelect->nbReturnPath = i; + } break; + + case kVstDirectorySelect: + vstFileSelect->nbReturnPath = 1; + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char[strlen (selDirPath) + 1]; + vstFileSelect->sizeReturnPath = (long)strlen (selDirPath) + 1; + } + strcpy (vstFileSelect->returnPath, selDirPath); + } + if (multiBuffer) + delete []multiBuffer; + return vstFileSelect->nbReturnPath; + } + if (multiBuffer) + delete []multiBuffer; + } + + //----------------------------------------- + else if (vstFileSelect->command == kVstFileSave) + { + char* p = filter; + for (long ty = 0; ty < vstFileSelect->nbFileTypes; ty++) + { + const char* ext = vstFileSelect->fileTypes[ty].dosType; + if (ext) + { + strcpy (p, vstFileSelect->fileTypes[ty].name); + strcat (p, " (."); + strcat (p, ext); + strcat (p, ")"); + p += strlen (p) + 1; + + char string[24]; + strcpy (string, "*."); + strcat (string, ext); + strcpy (p, string); + p += strlen (p) + 1; + } + } + *p++ = 0; + *p++ = 0; + + OPENFILENAME ofn = {0}; + ofn.lStructSize = sizeof (OPENFILENAME); + HWND owner = 0; + #if !PLUGGUI + if (((AudioEffectX*)ptr)->getEditor () && ((AEffGUIEditor*)((AudioEffectX*)ptr)->getEditor ())->getFrame ()) + owner = (HWND)((AEffGUIEditor*)((AudioEffectX*)ptr)->getEditor ())->getFrame ()->getSystemWindow (); + #endif + ofn.hwndOwner = owner; + ofn.hInstance = GetInstance (); + ofn.lpstrFilter = filter[0] ? filter : 0; + ofn.nFilterIndex = 1; + ofn.lpstrFile = filePath; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxFile = sizeof (filePathBuffer) - 1; + ofn.lpstrFileTitle = fileName; + ofn.nMaxFileTitle = 64; + ofn.lpstrInitialDir = vstFileSelect->initialPath; + ofn.lpstrTitle = vstFileSelect->title; + ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_ENABLEHOOK; + + if (vstFileSelect->nbFileTypes >= 1) + ofn.lpstrDefExt = vstFileSelect->fileTypes[0].dosType; + + // add a template view + ofn.lCustData = (DWORD)0; + ofn.lpfnHook = WinSaveHook; + + if (GetSaveFileName (&ofn)) + { + vstFileSelect->nbReturnPath = 1; + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char[strlen (ofn.lpstrFile) + 1]; + vstFileSelect->sizeReturnPath = (long)strlen (ofn.lpstrFile) + 1; + } + strcpy (vstFileSelect->returnPath, ofn.lpstrFile); + + return vstFileSelect->nbReturnPath; + } + #if _DEBUG + else + { + DWORD err = CommDlgExtendedError (); // for breakpoint + } + #endif + } + +#elif MAC +#if TARGET_API_MAC_CARBON + #if MACX + // new approach for supporting long filenames on mac os x is to use unix path mode + // if vstFileSelect->future[0] is 1 on entry and 0 on exit the resulting paths are UTF8 encoded paths + bool unixPathMode = (vstFileSelect->future[0] == 1); + #endif + NavEventUPP eventUPP = NewNavEventUPP (CFileSelector::navEventProc); + if (vstFileSelect->command == kVstFileSave) + { + NavDialogCreationOptions dialogOptions; + NavGetDefaultDialogCreationOptions (&dialogOptions); + dialogOptions.windowTitle = CFStringCreateWithCString (NULL, vstFileSelect->title[0] ? vstFileSelect->title : "Select a Destination", kCFStringEncodingUTF8); + CFStringRef defSaveName = 0; + #if MACX + if (unixPathMode && vstFileSelect->initialPath) + { + char* name = strrchr (vstFileSelect->initialPath, '/'); + if (name && name[1] != 0) + { + defSaveName = dialogOptions.saveFileName = CFStringCreateWithCString (NULL, name+1, kCFStringEncodingUTF8); + name[0] = 0; + dialogOptions.optionFlags |= kNavPreserveSaveFileExtension; + } + else if (name == 0) + { + defSaveName = dialogOptions.saveFileName = CFStringCreateWithCString (NULL, vstFileSelect->initialPath, kCFStringEncodingUTF8); + dialogOptions.optionFlags |= kNavPreserveSaveFileExtension; + vstFileSelect->initialPath = 0; + } + } + else + #endif + if (vstFileSelect->initialPath && ((FSSpec*)vstFileSelect->initialPath)->name) + { + FSSpec* defaultSpec = (FSSpec*)vstFileSelect->initialPath; + defSaveName = CFStringCreateWithPascalString (NULL, defaultSpec->name, kCFStringEncodingASCII); + if (defSaveName) + { + dialogOptions.saveFileName = defSaveName; + dialogOptions.optionFlags |= kNavPreserveSaveFileExtension; + } + *defaultSpec->name = 0; + } + NavDialogRef dialogRef; + if (NavCreatePutFileDialog (&dialogOptions, NULL, kNavGenericSignature, eventUPP, this, &dialogRef) == noErr) + { + AEDesc defaultLocation; + AEDesc* defLocPtr = 0; + if (vstFileSelect->initialPath) + { + #if MACX + if (unixPathMode) + { + FSRef fsRef; + if (FSPathMakeRef ((const unsigned char*)vstFileSelect->initialPath, &fsRef, NULL) == noErr) + { + if (AECreateDesc (typeFSRef, &fsRef, sizeof(FSRef), &defaultLocation) == noErr) + defLocPtr = &defaultLocation; + } + } + else + #endif + { + FSSpec* defaultSpec = (FSSpec*)vstFileSelect->initialPath; + if (defaultSpec->parID && defaultSpec->vRefNum) + { + if (AECreateDesc (typeFSS, defaultSpec, sizeof(FSSpec), &defaultLocation) == noErr) + defLocPtr = &defaultLocation; + } + } + } + if (defLocPtr) + NavCustomControl (dialogRef, kNavCtlSetLocation, (void*)defLocPtr); + NavDialogRun (dialogRef); + + if (defLocPtr) + AEDisposeDesc (defLocPtr); + + NavReplyRecord navReply; + if (NavDialogGetReply (dialogRef, &navReply) == noErr) + { + FSRef parentFSRef; + AEKeyword theAEKeyword; + DescType typeCode; + Size actualSize; + // get the FSRef referring to the parent directory + if (AEGetNthPtr(&navReply.selection, 1, typeFSRef, + &theAEKeyword, &typeCode, &parentFSRef, sizeof(FSRef), &actualSize) == noErr) + { + #if MACX + if (unixPathMode) + { + bool success = true; + vstFileSelect->nbReturnPath = 1; + if (vstFileSelect->returnPath == 0) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [PATH_MAX]; + } + if (FSRefMakePath (&parentFSRef, (unsigned char*)vstFileSelect->returnPath, PATH_MAX) == noErr) + { + char saveFileName [PATH_MAX]; + if (CFStringGetCString (navReply.saveFileName, saveFileName, PATH_MAX, kCFStringEncodingUTF8)) + { + strcat (vstFileSelect->returnPath, "/"); + strcat (vstFileSelect->returnPath, saveFileName); + vstFileSelect->future[0] = 0; + } + else + success = false; + } + else + success = false; + if (!success && vstFileSelect->reserved) + { + vstFileSelect->nbReturnPath = 0; + delete [] vstFileSelect->returnPath; + } + } + else + #endif + { + FSSpec spec; + FSCatalogInfoBitmap infoBitmap = kFSCatInfoNone; + FSGetCatalogInfo (&parentFSRef, infoBitmap, NULL, NULL, &spec, NULL); + CInfoPBRec pbRec = {0}; + pbRec.dirInfo.ioDrDirID = spec.parID; + pbRec.dirInfo.ioVRefNum = spec.vRefNum; + pbRec.dirInfo.ioNamePtr = spec.name; + if (PBGetCatInfoSync (&pbRec) == noErr) + { + spec.parID = pbRec.dirInfo.ioDrDirID; + // the cfstring -> pascalstring can fail if the filename length > 63 (FSSpec sucks) + if (CFStringGetPascalString (navReply.saveFileName, (unsigned char*)&spec.name, sizeof (spec.name), kCFStringEncodingASCII)) + { + vstFileSelect->nbReturnPath = 1; + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [sizeof (FSSpec)]; + } + memcpy (vstFileSelect->returnPath, &spec, sizeof (FSSpec)); + } + } + } + } + NavDisposeReply (&navReply); + } + if (defSaveName) + CFRelease (defSaveName); + NavDialogDispose (dialogRef); + DisposeNavEventUPP (eventUPP); + return vstFileSelect->nbReturnPath; + } + if (defSaveName) + CFRelease (defSaveName); + } + else if (vstFileSelect->command == kVstDirectorySelect) + { + NavDialogCreationOptions dialogOptions; + NavGetDefaultDialogCreationOptions (&dialogOptions); + dialogOptions.windowTitle = CFStringCreateWithCString (NULL, vstFileSelect->title[0] ? vstFileSelect->title : "Select Directory", kCFStringEncodingUTF8); + NavDialogRef dialogRef; + if (NavCreateChooseFolderDialog (&dialogOptions, eventUPP, NULL, this, &dialogRef) == noErr) + { + AEDesc defaultLocation; + AEDesc* defLocPtr = 0; + if (vstFileSelect->initialPath) + { + #if MACX + if (unixPathMode) + { + FSRef fsRef; + if (FSPathMakeRef ((const unsigned char*)vstFileSelect->initialPath, &fsRef, NULL) == noErr) + { + if (AECreateDesc (typeFSRef, &fsRef, sizeof(FSRef), &defaultLocation) == noErr) + defLocPtr = &defaultLocation; + } + } + else + #endif + { + FSSpec* defaultSpec = (FSSpec*)vstFileSelect->initialPath; + if (defaultSpec->parID && defaultSpec->vRefNum) + if (AECreateDesc (typeFSS, defaultSpec, sizeof(FSSpec), &defaultLocation) == noErr) + defLocPtr = &defaultLocation; + } + } + if (defLocPtr) + NavCustomControl (dialogRef, kNavCtlSetLocation, (void*)defLocPtr); + NavDialogRun (dialogRef); + if (defLocPtr) + AEDisposeDesc (defLocPtr); + NavReplyRecord navReply; + if (NavDialogGetReply (dialogRef, &navReply) == noErr) + { + FSRef parentFSRef; + AEKeyword theAEKeyword; + DescType typeCode; + Size actualSize; + if (AEGetNthPtr(&navReply.selection, 1, typeFSRef, + &theAEKeyword, &typeCode, &parentFSRef, sizeof(FSRef), &actualSize) == noErr) + { + #if MACX + if (unixPathMode) + { + vstFileSelect->nbReturnPath = 1; + if (vstFileSelect->returnPath == 0) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [PATH_MAX]; + } + if (FSRefMakePath (&parentFSRef, (unsigned char*)vstFileSelect->returnPath, PATH_MAX) != noErr) + { + vstFileSelect->nbReturnPath = 0; + if (vstFileSelect->reserved) + delete [] vstFileSelect->returnPath; + } + else + vstFileSelect->future[0] = 0; + } + else + #endif + { + FSSpec spec; + FSCatalogInfoBitmap infoBitmap = kFSCatInfoNone; + FSGetCatalogInfo (&parentFSRef, infoBitmap, NULL, NULL, &spec, NULL); + vstFileSelect->nbReturnPath = 1; + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [sizeof (FSSpec)]; + } + memcpy (vstFileSelect->returnPath, &spec, sizeof (FSSpec)); + } + } + + NavDisposeReply (&navReply); + } + NavDialogDispose (dialogRef); + DisposeNavEventUPP (eventUPP); + return vstFileSelect->nbReturnPath; + } + } + else // FileLoad + { + NavDialogCreationOptions dialogOptions; + NavGetDefaultDialogCreationOptions (&dialogOptions); + if (vstFileSelect->command == kVstFileLoad) + { + dialogOptions.windowTitle = CFStringCreateWithCString (NULL, vstFileSelect->title[0] ? vstFileSelect->title : "Select a File to Open", kCFStringEncodingUTF8); + dialogOptions.optionFlags &= ~kNavAllowMultipleFiles; + } + else + { + dialogOptions.windowTitle = CFStringCreateWithCString (NULL, vstFileSelect->title[0] ? vstFileSelect->title : "Select Files to Open", kCFStringEncodingUTF8); + dialogOptions.optionFlags |= kNavAllowMultipleFiles; + } + NavObjectFilterUPP objectFilterUPP = NewNavObjectFilterUPP (CFileSelector::navObjectFilterProc); + NavDialogRef dialogRef; + if (NavCreateGetFileDialog (&dialogOptions, NULL, eventUPP, NULL, objectFilterUPP, this, &dialogRef) == noErr) + { + AEDesc defaultLocation; + AEDesc* defLocPtr = 0; + if (vstFileSelect->initialPath) + { + #if MACX + if (unixPathMode) + { + FSRef fsRef; + if (FSPathMakeRef ((const unsigned char*)vstFileSelect->initialPath, &fsRef, NULL) == noErr) + { + if (AECreateDesc (typeFSRef, &fsRef, sizeof(FSRef), &defaultLocation) == noErr) + defLocPtr = &defaultLocation; + } + } + else + #endif + { + FSSpec* defaultSpec = (FSSpec*)vstFileSelect->initialPath; + if (defaultSpec->parID && defaultSpec->vRefNum) + if (AECreateDesc (typeFSS, defaultSpec, sizeof(FSSpec), &defaultLocation) == noErr) + defLocPtr = &defaultLocation; + } + } + if (defLocPtr) + NavCustomControl (dialogRef, kNavCtlSetLocation, (void*)defLocPtr); + + NavDialogRun (dialogRef); + + if (defLocPtr) + AEDisposeDesc (defLocPtr); + + NavReplyRecord navReply; + if (NavDialogGetReply (dialogRef, &navReply) == noErr) + { + FSRef parentFSRef; + AEKeyword theAEKeyword; + DescType typeCode; + Size actualSize; + if (vstFileSelect->command == kVstFileLoad) + { + if (AEGetNthPtr(&navReply.selection, 1, typeFSRef, + &theAEKeyword, &typeCode, &parentFSRef, sizeof(FSRef), &actualSize) == noErr) + { + #if MACX + if (unixPathMode) + { + vstFileSelect->nbReturnPath = 1; + if (vstFileSelect->returnPath == 0) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [PATH_MAX]; + } + if (FSRefMakePath (&parentFSRef, (unsigned char*)vstFileSelect->returnPath, PATH_MAX) != noErr) + { + vstFileSelect->nbReturnPath = 0; + if (vstFileSelect->reserved) + delete [] vstFileSelect->returnPath; + } + else + vstFileSelect->future[0] = 0; + } + else + #endif + { + FSSpec spec; + FSCatalogInfoBitmap infoBitmap = kFSCatInfoNone; + FSGetCatalogInfo (&parentFSRef, infoBitmap, NULL, NULL, &spec, NULL); + vstFileSelect->nbReturnPath = 1; + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [sizeof (FSSpec)]; + } + memcpy (vstFileSelect->returnPath, &spec, sizeof (FSSpec)); + } + } + } + else + { + long nbReturnPath; + AECountItems (&navReply.selection, &nbReturnPath); + vstFileSelect->nbReturnPath = nbReturnPath; + vstFileSelect->returnMultiplePaths = new char* [vstFileSelect->nbReturnPath]; + int index = 1; + while (AEGetNthPtr(&navReply.selection, index++, typeFSRef, + &theAEKeyword, &typeCode, &parentFSRef, sizeof(FSRef), &actualSize) == noErr) + { + #if MACX + if (unixPathMode) + { + vstFileSelect->returnMultiplePaths[index-2] = new char[PATH_MAX]; + FSRefMakePath (&parentFSRef, (unsigned char*)vstFileSelect->returnMultiplePaths[index-2], PATH_MAX); + vstFileSelect->future[0] = 0; + } + else + #endif + { + FSSpec spec; + FSCatalogInfoBitmap infoBitmap = kFSCatInfoNone; + FSGetCatalogInfo (&parentFSRef, infoBitmap, NULL, NULL, &spec, NULL); + vstFileSelect->returnMultiplePaths[index-2] = new char[sizeof (FSSpec)]; + memcpy (vstFileSelect->returnMultiplePaths[index-2], &spec, sizeof (FSSpec)); + } + } + } + } + DisposeNavObjectFilterUPP (objectFilterUPP); + DisposeNavEventUPP (eventUPP); + NavDialogDispose (dialogRef); + return vstFileSelect->nbReturnPath; + } + DisposeNavObjectFilterUPP (objectFilterUPP); + } + DisposeNavEventUPP (eventUPP); +#else + StandardFileReply reply; + if (vstFileSelect->command == kVstFileSave) + { + unsigned char defName[64]; + defName[0] = 0; + StandardPutFile ("\pSelect a Destination", defName, &reply); + if (reply.sfGood && reply.sfFile.name[0] != 0) + { + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [301]; + } + memcpy (vstFileSelect->returnPath, &reply.sfFile, 300); + vstFileSelect->nbReturnPath = 1; + return 1; + } + } + + else if (vstFileSelect->command == kVstDirectorySelect) + { + #if USENAVSERVICES + if (NavServicesAvailable ()) + { + NavReplyRecord navReply; + NavDialogOptions dialogOptions; + short ret = false; + AEDesc defLoc; + defLoc.descriptorType = typeFSS; + defLoc.dataHandle = NewHandle (sizeof (FSSpec)); + FSSpec finalFSSpec; + finalFSSpec.parID = 0; // *dirID; + finalFSSpec.vRefNum = 0; // *volume; + finalFSSpec.name[0] = 0; + + NavGetDefaultDialogOptions (&dialogOptions); + dialogOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles; + dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation; + strcpy ((char* )dialogOptions.message, "Select Directory"); + c2pstr ((char* )dialogOptions.message); + NavChooseFolder (&defLoc, &navReply, &dialogOptions, 0 /* eventUPP */, 0, 0); + DisposeHandle (defLoc.dataHandle); + + AEDesc resultDesc; + AEKeyword keyword; + resultDesc.dataHandle = 0L; + + if (navReply.validRecord && AEGetNthDesc (&navReply.selection, 1, typeFSS, &keyword, &resultDesc) == noErr) + { + ret = true; + vstFileSelect->nbReturnPath = 1; + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [sizeof (FSSpec)]; + } + memcpy (vstFileSelect->returnPath, *resultDesc.dataHandle, sizeof (FSSpec)); + } + NavDisposeReply (&navReply); + return vstFileSelect->nbReturnPath; + } + else + #endif + { + // Can't select a Folder; the Application does not support it, and Navigational Services are not available... + return 0; + } + } + + else + { + SFTypeList typelist; + long numFileTypes = vstFileSelect->nbFileTypes; + //seem not to work... if (numFileTypes <= 0) + { + numFileTypes = -1; // all files + typelist[0] = 'AIFF'; + } + /*else + { + if (numFileTypes > 4) + numFileTypes = 4; + for (long i = 0; i < numFileTypes; i++) + memcpy (&typelist[i], vstFileSelect->fileTypes[i].macType, 4); + }*/ + StandardGetFile (0L, numFileTypes, typelist, &reply); + if (reply.sfGood) + { + if (!vstFileSelect->returnPath) + { + vstFileSelect->reserved = 1; + vstFileSelect->returnPath = new char [301]; + } + memcpy (vstFileSelect->returnPath, &reply.sfFile, 300); + vstFileSelect->nbReturnPath = 1; + return 1; + } + } +#endif // TARGET_API_MAC_CARBON +#else + //CAlert::alert ("The current Host application doesn't support FileSelector !", "Warning"); +#endif + } + return 0; +} + +#if MAC && TARGET_API_MAC_CARBON +//----------------------------------------------------------------------------- +pascal void CFileSelector::navEventProc (const NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, NavCallBackUserData callBackUD) +{ + CFileSelector* fs = (CFileSelector*)callBackUD; + switch (callBackSelector) + { + case kNavCBEvent: + { + #if !PLUGGUI + AudioEffectX* effect = (AudioEffectX*)fs->ptr; + if (effect && callBackParms->eventData.eventDataParms.event->what == nullEvent) + effect->masterIdle (); + #endif + break; + } + } +} + +//----------------------------------------------------------------------------- +pascal Boolean CFileSelector::navObjectFilterProc (AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) +{ + Boolean result = false; + CFileSelector* fs = (CFileSelector*)callBackUD; + NavFileOrFolderInfo *theInfo = (NavFileOrFolderInfo*)info; + + if (theInfo->isFolder || fs->vstFileSelect->nbFileTypes == 0) + result = true; + else + { + FSRef ref; + AECoerceDesc (theItem, typeFSRef, theItem); + if (AEGetDescData (theItem, &ref, sizeof (FSRef)) == noErr) + { + LSItemInfoRecord infoRecord; + if (LSCopyItemInfoForRef (&ref, kLSRequestExtension | kLSRequestTypeCreator, &infoRecord) == noErr) + { + char extension [128]; + extension[0] = 0; + if (infoRecord.extension) + CFStringGetCString (infoRecord.extension, extension, 128, kCFStringEncodingUTF8); + for (long i = 0; i < fs->vstFileSelect->nbFileTypes; i++) + { + VstFileType* ft = &fs->vstFileSelect->fileTypes[i]; + if ((OSType)ft->macType == infoRecord.filetype) + { + result = true; + break; + } + else if (infoRecord.extension) + { + if (!strcasecmp (extension, ft->unixType) || !strcasecmp (extension, ft->dosType)) + { + result = true; + break; + } + } + } + if (infoRecord.extension) + CFRelease (infoRecord.extension); + } + } + } + return result; +} +#endif + +END_NAMESPACE_VSTGUI + +#if WINDOWS +#include <dlgs.h> +//----------------------------------------------------------------------------- +UINT_PTR APIENTRY SelectDirectoryHook (HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_NOTIFY: + { + OFNOTIFY *lpon = (OFNOTIFY *)lParam; + + switch (lpon->hdr.code) + { + case CDN_FILEOK: + CommDlg_OpenSave_GetFolderPath (GetParent (hdlg), selDirPath, kPathMax); + bDidCancel = false; + break; + + case CDN_INITDONE: { + #define HIDE_ITEMS 4 + int i; + UINT hide_items[HIDE_ITEMS] = {edt1, stc3, cmb1, stc2}; + + for (i = 0; i < HIDE_ITEMS; i++) + CommDlg_OpenSave_HideControl (GetParent (hdlg), hide_items[i]); + + CommDlg_OpenSave_SetControlText (GetParent (hdlg), stc4, (char*)(const char*)stringLookIn); + CommDlg_OpenSave_SetControlText (GetParent (hdlg), IDOK, (char*)(const char*)stringSelect); + CommDlg_OpenSave_SetControlText (GetParent (hdlg), IDCANCEL, (char*)(const char*)stringCancel); + } break; + } + } break; + + case WM_INITDIALOG: + fpOldSelectDirectoryButtonProc = /*(FARPROC)*/(WNDPROC)SetWindowLongPtr ( + GetDlgItem (GetParent (hdlg), IDOK), + GWLP_WNDPROC, (LONG_PTR)SelectDirectoryButtonProc); + break; + + case WM_DESTROY: + SetWindowLongPtr (GetDlgItem (GetParent (hdlg), IDOK), + GWLP_WNDPROC, (LONG_PTR)fpOldSelectDirectoryButtonProc); + } + return false; +} + +//----------------------------------------------------------------------------- +LRESULT CALLBACK SelectDirectoryButtonProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_SETTEXT: + if (! (strcmp ((char *)lParam, stringSelect) == 0)) + return false; + break; + + case WM_LBUTTONUP: + case WM_RBUTTONUP: { + char mode[256]; + GetWindowText (hwnd, mode, 256); + if (!strcmp (mode, stringSelect)) + { + bFolderSelected = true; + char oldDirPath[kPathMax]; + CommDlg_OpenSave_GetFolderPath (GetParent (hwnd), oldDirPath, kPathMax); + // you need a lot of tricks to get name of currently selected folder: + // the following call of the original windows procedure causes the + // selected folder to open and after that you can retrieve its name + // by calling ..._GetFolderPath (...) + CallWindowProc ((WNDPROC)fpOldSelectDirectoryButtonProc, hwnd, message, wParam, lParam); + CommDlg_OpenSave_GetFolderPath (GetParent (hwnd), selDirPath, kPathMax); + + if (1) // consumers like it like this + { + if (strcmp (oldDirPath, selDirPath) == 0 || selDirPath [0] == 0) + { + // the same folder as the old one, means nothing selected: close + bFolderSelected = true; + bDidCancel = false; + PostMessage (GetParent (hwnd), WM_CLOSE, 0, 0); + return false; + } + else + { + // another folder is selected: browse into it + bFolderSelected = false; + return true; + } + } + else // original code + { + if (strcmp (oldDirPath, selDirPath) == 0 || selDirPath [0] == 0) + { + // the same folder as the old one, means nothing selected: stay open + bFolderSelected = false; + return true; + } + } + } + + bDidCancel = false; + PostMessage (GetParent (hwnd), WM_CLOSE, 0, 0); + return false; + } break; + } // end switch + + return CallWindowProc ((WNDPROC)fpOldSelectDirectoryButtonProc, hwnd, message, wParam, lParam); +} + +//----------------------------------------------------------------------------- +static void showPathInWindowTitle (HWND hParent, LPOFNOTIFY lpon) +{ + #define WINDOWTEXTSIZE 260 + 64 + OPENFILENAME *ofn = lpon->lpOFN; + char text[WINDOWTEXTSIZE]; + char *p; + size_t len; + + // Put the path into the Window Title + if (lpon->lpOFN->lpstrTitle) + strcpy (text, lpon->lpOFN->lpstrTitle); + else + { + char *pp; + + GetWindowText (hParent, text, WINDOWTEXTSIZE); + pp = strchr (text, '-'); + if (pp) + *--pp = 0; + } + + p = strcat (text, " - ["); + p = text; + len = strlen (text); + p += len; + len = WINDOWTEXTSIZE - len - 2; + CommDlg_OpenSave_GetFolderPath (hParent, p, len); + strcat (text, "]"); + SetWindowText (hParent, text); +} + +//------------------------------------------------------------------------ +UINT_PTR APIENTRY WinSaveHook (HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_NOTIFY: { + LPOFNOTIFY lpon = (LPOFNOTIFY)lParam; + if (!lpon) + break; + + switch (lpon->hdr.code) + { + case CDN_FOLDERCHANGE: + showPathInWindowTitle (GetParent (hdlg), lpon); + break; + } + } break; + } // end switch + + return 0; +} +#endif + +//----------------------------------------------------------------------------- |
