char *Sys_PathFromSaveMenu(void) { /* present a save file dialog and return the file's path */ OSStatus res; NavDialogCreationOptions options; NavDialogRef dialog; NavReplyRecord reply; NavUserAction action; AEKeyword keyword; DescType actualType; Size actualSize; FSRef outputDir; CFURLRef cfUrl; CFStringRef cfString; char filename[PATH_MAX]; int pathlen; NavGetDefaultDialogCreationOptions(&options); options.modality = kWindowModalityAppModal; /*options.modality = kWindowModalityWindowModal; *options.parentWindow = g_Window.window;*/ options.saveFileName = CFStringCreateWithCString(NULL, "Untitled.js", kCFStringEncodingASCII); res = NavCreatePutFileDialog(&options, FOURC_TO_INT("JSON"), FOURC_TO_INT("PLAT"), NULL, NULL, &dialog); NavDialogRun(dialog); action = NavDialogGetUserAction(dialog); if (action == kNavUserActionNone || action == kNavUserActionCancel) return NULL; res = NavDialogGetReply(dialog, &reply); if (res != noErr) return NULL; res = AEGetNthPtr(&reply.selection, 1, typeFSRef, &keyword, &actualType, &outputDir, sizeof(FSRef), &actualSize); cfUrl = CFURLCreateFromFSRef(kCFAllocatorDefault, &outputDir); cfString = NULL; if (cfUrl) { cfString = CFURLCopyFileSystemPath(cfUrl, kCFURLPOSIXPathStyle); CFRelease(cfUrl); } memset(g_SaveFileName, 0, PATH_MAX); CFStringGetCString(cfString, g_SaveFileName, PATH_MAX, kCFStringEncodingMacRoman); CFStringGetCString(reply.saveFileName, filename, PATH_MAX, kCFStringEncodingMacRoman); pathlen = strlen(g_SaveFileName); snprintf(g_SaveFileName+pathlen, PATH_MAX-pathlen, "/%s", filename); NavDialogDispose(dialog); return g_SaveFileName; }
// this code originates from the NavServices sample code in the CarbonLib SDK OSStatus DoSaveAsPDF(WindowRef w, void *ourDataP) { OSStatus err = noErr; static NavEventUPP gNavEventProc = NULL; // event proc for our Nav Dialogs NavDialogCreationOptions dialogOptions; if(!gNavEventProc){ gNavEventProc = NewNavEventUPP(NavEventProc); if(!gNavEventProc) err = memFullErr; } if(!err && (( err = NavGetDefaultDialogCreationOptions( &dialogOptions )) == noErr )) { OurSaveDialogData *dialogDataP = NULL; CFStringRef tempString; CopyWindowTitleAsCFString(w, &tempString); dialogOptions.saveFileName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, kFileTypePDFCFStr, tempString); CFRelease(tempString); // make the dialog modal to our parent doc, AKA sheets dialogOptions.parentWindow = w; dialogOptions.modality = kWindowModalityWindowModal; dialogDataP = (OurSaveDialogData *)malloc(sizeof(OurSaveDialogData)); if(dialogDataP){ dialogDataP->dialogRef = NULL; dialogDataP->parentWindow = w; dialogDataP->documentDataP = ourDataP; err = NavCreatePutFileDialog(&dialogOptions, kFileTypePDF, kFileCreator, gNavEventProc, dialogDataP, &dialogDataP->dialogRef); if (!err && dialogDataP->dialogRef != NULL) { err = NavDialogRun( dialogDataP->dialogRef ); if (err != noErr) { NavDialogDispose( dialogDataP->dialogRef ); dialogDataP->dialogRef = NULL; free(dialogDataP); } } }else err = memFullErr; if ( dialogOptions.saveFileName != NULL ) CFRelease( dialogOptions.saveFileName ); } return err; }
fileData* MacOSXDirScanner::saveFileDialog() { //XXX not finished yet. fprintf(stderr, "start OSX File Save Dialog\n"); OSStatus err; NavDialogRef saveDialog; NavDialogCreationOptions dialogAttributes; int n = 0; if ( savefD ) { delete savefD; savefD = NULL; } if( AudicleWindow::our_fullscreen ) { glutReshapeWindow( AudicleWindow::main()->m_w, AudicleWindow::main()->m_h ); glutPostRedisplay(); AudicleWindow::our_fullscreen = FALSE; return NULL; } err = NavGetDefaultDialogCreationOptions( &dialogAttributes ); dialogAttributes.modality = kWindowModalityAppModal; gNavEventHandlerPtr = NewNavEventUPP( dialogFileCallback ); err = NavCreatePutFileDialog( &dialogAttributes, 'ChuK', kNavGenericSignature, gNavEventHandlerPtr, NULL, &saveDialog ); if ( !AudicleGfx::cursor_on ) { ShowCursor(); AudicleGfx::cursor_on = true; } err = NavDialogRun( saveDialog ); if ( err != noErr ) { NavDialogDispose( saveDialog ); DisposeNavEventUPP( gNavEventHandlerPtr ); return NULL; } return savefD; }
OSFileRequest::OSFileRequest (const int reqType, const char *title, const char *fileType, const char *ext, const char *baseName, const char *path, const char *_baseDirType, int bufLen) : type(reqType), m_data(new Data) { m_data->status = NavGetDefaultDialogCreationOptions(&m_data->dialogOptions); m_data->dialogOptions.modality = kWindowModalityAppModal; m_data->dialogOptions.windowTitle = CFStringCreateWithCString(NULL, title, kCFStringEncodingMacRoman); m_data->dialogOptions.saveFileName = CFStringCreateWithCString(NULL, baseName, kCFStringEncodingMacRoman); if (type == FREQ_LOAD) { m_data->status = NavCreateGetFileDialog(&m_data->dialogOptions, NULL, NULL, NULL, NULL, NULL, &m_data->dialog); } else if (type == FREQ_SAVE) { m_data->status = NavCreatePutFileDialog(&m_data->dialogOptions, kUnknownType, kUnknownType, NULL, NULL, &m_data->dialog); } }
OSStatus SaveFileDialog( WindowRef parentWindow, CFStringRef documentName, OSType filetype, OSType fileCreator, void *inContextData, NavDialogRef *outDialog ) { NavDialogCreationOptions dialogOptions; OSStatus theErr = noErr; NavGetDefaultDialogCreationOptions( &dialogOptions ); dialogOptions.clientName = CFStringCreateWithPascalString( NULL, LMGetCurApName(), GetApplicationTextEncoding()); dialogOptions.saveFileName = documentName; dialogOptions.modality = ( parentWindow != NULL ) ? kWindowModalityWindowModal : kWindowModalityAppModal; dialogOptions.parentWindow = parentWindow; theErr = NavCreatePutFileDialog( &dialogOptions, filetype, fileCreator, GetEventUPP(), inContextData, outDialog ); if ( theErr == noErr ) { theErr = NavDialogRun( *outDialog ); if ( theErr != noErr ) { NavDialogDispose( *outDialog ); } if ( theErr != noErr || dialogOptions.modality == kWindowModalityAppModal ) { *outDialog = NULL; // The dialog has already been disposed. } } if ( dialogOptions.clientName != NULL ) { CFRelease( dialogOptions.clientName ); } return theErr; }
QString Q3FileDialog::macGetSaveFileName(const QString &start, const QString &filter, QString *, QWidget *parent, const char* /*name*/, const QString& caption, QString *selectedFilter) { OSErr err; QString retstr; NavDialogCreationOptions options; NavGetDefaultDialogCreationOptions(&options); static const int w = 450, h = 350; options.optionFlags |= kNavDontConfirmReplacement; options.modality = kWindowModalityAppModal; options.location.h = options.location.v = -1; QString workingDir; QString initialSelection; if (!start.isEmpty()) { Q3UrlOperator u(encodeFileName(start)); if (u.isLocalFile() && QFileInfo(u.path()).isDir()) { workingDir = start; } else { if (u.isLocalFile()) { QFileInfo fi(u.dirPath()); if (fi.exists()) { workingDir = u.dirPath(); initialSelection = u.fileName(); } } else { workingDir = u.toString(); } } if (!initialSelection.isEmpty()) options.saveFileName = CFStringCreateWithCharacters(0, (UniChar *)initialSelection.unicode(), initialSelection.length()); } if(!caption.isEmpty()) options.windowTitle = CFStringCreateWithCharacters(NULL, (UniChar *)caption.unicode(), caption.length()); if(parent && parent->isVisible()) { Qt::WindowType wt = parent->window()->windowType(); if (wt != Qt::Desktop && wt != Qt::Sheet && wt != Qt::Drawer) { options.modality = kWindowModalityWindowModal; options.parentWindow = qt_mac_window_for(parent); } else { parent = parent->window(); QString s = parent->windowTitle(); options.clientName = CFStringCreateWithCharacters(NULL, (UniChar *)s.unicode(), s.length()); options.location.h = (parent->x() + (parent->width() / 2)) - (w / 2); options.location.v = (parent->y() + (parent->height() / 2)) - (h / 2); QRect r = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber(parent)); if(options.location.h + w > r.right()) options.location.h -= (options.location.h + w) - r.right() + 10; if(options.location.v + h > r.bottom()) options.location.v -= (options.location.v + h) - r.bottom() + 10; } } else if(QWidget *p = qApp->mainWidget()) { static int last_screen = -1; int scr = QApplication::desktop()->screenNumber(p); if(last_screen != scr) { QRect r = QApplication::desktop()->screenGeometry(scr); options.location.h = (r.x() + (r.width() / 2)) - (w / 2); options.location.v = (r.y() + (r.height() / 2)) - (h / 2); } } QList<qt_mac_filter_name*> filts = makeFiltersList(filter); qt_mac_nav_filter_type t; t.index = 0; t.filts = &filts; if(filts.count() > 1) { int i = 0; CFStringRef *arr = (CFStringRef *)malloc(sizeof(CFStringRef) * filts.count()); for (QList<qt_mac_filter_name*>::Iterator it = filts.begin(); it != filts.end(); ++it) { QString rg = (*it)->description; arr[i++] = CFStringCreateWithCharacters(NULL, (UniChar *)rg.unicode(), rg.length()); } options.popupExtension = CFArrayCreate(NULL, (const void **)arr, filts.count(), NULL); } NavDialogRef dlg; if(NavCreatePutFileDialog(&options, 'cute', kNavGenericSignature, make_navProcUPP(), (void *) (filts.isEmpty() ? NULL : &t), &dlg)) { qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__); return retstr; } if (!workingDir.isEmpty()) { FSRef fsref; if (qt_mac_create_fsref(workingDir, &fsref) == noErr) { AEDesc desc; if (AECreateDesc(typeFSRef, &fsref, sizeof(FSRef), &desc) == noErr) NavCustomControl(dlg, kNavCtlSetLocation, (void*)&desc); } } NavDialogRun(dlg); if (selectedFilter) { NavMenuItemSpec navSpec; bzero(&navSpec, sizeof(NavMenuItemSpec)); qt_mac_filter_name *sel_filt_name = makeFiltersList(*selectedFilter).at(0); for (int i = 0; i < filts.count(); ++i) { const qt_mac_filter_name *filter = filts.at(i); if (sel_filt_name->description == filter->description && sel_filt_name->regxp == filter->regxp && sel_filt_name->filter == filter->filter) { navSpec.menuType = i; break; } } NavCustomControl(dlg, kNavCtlSelectCustomType, &navSpec); } if(options.modality == kWindowModalityWindowModal) { //simulate modality QWidget modal_widg(parent, __FILE__ "__modal_dlg", Qt::WType_TopLevel | Qt::WStyle_Customize | Qt::WStyle_DialogBorder); modal_widg.createWinId(); QApplicationPrivate::enterModal(&modal_widg); while(g_nav_blocking) qApp->processEvents(QEventLoop::WaitForMoreEvents); QApplicationPrivate::leaveModal(&modal_widg); } if(NavDialogGetUserAction(dlg) != kNavUserActionSaveAs) { NavDialogDispose(dlg); return retstr; } NavReplyRecord ret; NavDialogGetReply(dlg, &ret); NavDialogDispose(dlg); long count; err = AECountItems(&(ret.selection), &count); if(!ret.validRecord || err != noErr || !count) { NavDisposeReply(&ret); return retstr; } AEKeyword keyword; DescType type; Size size; FSRef ref; err = AEGetNthPtr(&(ret.selection), 1, typeFSRef, &keyword, &type, &ref, sizeof(ref), &size); if(err == noErr) { if(!str_buffer) { qAddPostRoutine(cleanup_str_buffer); str_buffer = (UInt8 *)malloc(1024); } FSRefMakePath(&ref, str_buffer, 1024); retstr = QString::fromUtf8((const char *)str_buffer); //now filename CFStringGetCString(ret.saveFileName, (char *)str_buffer, 1024, kCFStringEncodingUTF8); retstr += QLatin1Char('/') + QString::fromUtf8((const char *)str_buffer); } NavDisposeReply(&ret); if(selectedFilter) *selectedFilter = filts.at(t.index)->filter; while (!filts.isEmpty()) delete filts.takeFirst(); return retstr; }
CFURLRef GetSaveDialogForUser(char* title, char* message) { NavDialogCreationOptions dialogOptions; FSRef output_file; CFURLRef fileAsCFURLRef = NULL; OSStatus status; CFAllocatorRef alloc_default = kCFAllocatorDefault; AEKeyword keyword; DescType actual_type; Size actual_size; FSRef output_dir; NavReplyRecord reply; CFIndex len; // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions( &dialogOptions ); require_noerr( status, CantGetNavOptions ); dialogOptions.optionFlags = kNavNoTypePopup + kNavSupportPackages + kNavAllowOpenPackages; // = NULL; if (title != NULL) { CFStringRef cftitle = CFStringCreateWithCString(alloc_default,title,kCFStringEncodingMacRoman); dialogOptions.windowTitle = cftitle; } if (message != NULL) { CFStringRef cfmessage = CFStringCreateWithCString(alloc_default,message,kCFStringEncodingMacRoman); dialogOptions.message = cfmessage; } // Make the window app-wide modal dialogOptions.modality = kWindowModalityAppModal; NavDialogRef dialog; status = NavCreatePutFileDialog ( &dialogOptions, NULL, NULL, NULL, NULL, &dialog); require_noerr( status, CantCreateDialog ); status = NavDialogRun(dialog); require_noerr( status, CantRunDialog ); // get dialog reply status = NavDialogGetReply(dialog, &reply); require( ((status == noErr) || (status == userCanceledErr)), CantGetReply ); //get file directory status = AEGetNthPtr(&(reply.selection), 1, typeFSRef, &keyword, &actual_type, &output_dir, sizeof(output_file), &actual_size); require_noerr( status, CantExtractFSRef ); UInt8 output_dir_name[1024]; FSRefMakePath(&output_dir, output_dir_name, 1024 ); // now get filename len = CFStringGetLength(reply.saveFileName); if (len > 255) len = 255; UniChar output_filename[255]; CFStringGetCharacters(reply.saveFileName, CFRangeMake(0, len), output_filename); // need to unlink the old file if ( reply.replacing ) { FSRef oldfile; status = FSMakeFSRefUnicode(&output_dir, len, output_filename, kTextEncodingUnicodeDefault, &oldfile); if (status == noErr) status = FSDeleteObject(&oldfile); //overwrite failed! require_noerr( status, UserCanceled ); } //create fsref again to new file (NOTE: this actually makes a file...) status = FSCreateFileUnicode( &output_dir, len, output_filename, kFSCatInfoNone, NULL, &output_file, NULL ); require_noerr( status, CantExtractFSRef ); // Convert it to a CFURL fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &output_file); CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&reply) ); CantGetReply: CantRunDialog: // cleanup dialog NavDialogDispose(dialog); CantCreateDialog: CantGetNavOptions: return fileAsCFURLRef; }
OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename) { OSStatus error = noErr; NavDialogRef navRef = NULL; NavReplyRecord navReply; memset(&navReply, 0, sizeof(navReply)); // Setup the type, creator, and extension OSType type, creator; CFStringRef extension = NULL; switch (filter) { case FFSAVE_WAV: type = 'WAVE'; creator = 'TVOD'; extension = CFSTR(".wav"); break; case FFSAVE_TGA: type = 'TPIC'; creator = 'prvw'; extension = CFSTR(".tga"); break; case FFSAVE_BMP: type = 'BMPf'; creator = 'prvw'; extension = CFSTR(".bmp"); break; case FFSAVE_JPEG: type = 'JPEG'; creator = 'prvw'; extension = CFSTR(".jpeg"); break; case FFSAVE_PNG: type = 'PNG '; creator = 'prvw'; extension = CFSTR(".png"); break; case FFSAVE_AVI: type = '\?\?\?\?'; creator = '\?\?\?\?'; extension = CFSTR(".mov"); break; case FFSAVE_ANIM: type = '\?\?\?\?'; creator = '\?\?\?\?'; extension = CFSTR(".xaf"); break; #ifdef _CORY_TESTING case FFSAVE_GEOMETRY: type = '\?\?\?\?'; creator = '\?\?\?\?'; extension = CFSTR(".slg"); break; #endif case FFSAVE_RAW: type = '\?\?\?\?'; creator = '\?\?\?\?'; extension = CFSTR(".raw"); break; case FFSAVE_J2C: type = '\?\?\?\?'; creator = 'prvw'; extension = CFSTR(".j2c"); break; case FFSAVE_ALL: default: type = '\?\?\?\?'; creator = '\?\?\?\?'; extension = CFSTR(""); break; } // Create the dialog error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef); if (error == noErr) { CFStringRef nameString = NULL; bool hasExtension = true; // Create a CFString of the initial file name if (!filename.empty()) nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8); else nameString = CFSTR("Untitled"); // Add the extension if one was not provided if (nameString && !CFStringHasSuffix(nameString, extension)) { CFStringRef tempString = nameString; hasExtension = false; nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension); CFRelease(tempString); } // Set the name in the dialog if (nameString) { error = NavDialogSetSaveFileName(navRef, nameString); CFRelease(nameString); } else { error = paramErr; } } gViewerWindow->mWindow->beforeDialog(); // Run the dialog if (error == noErr) error = NavDialogRun(navRef); gViewerWindow->mWindow->afterDialog(); if (error == noErr) error = NavDialogGetReply(navRef, &navReply); if (navRef) NavDialogDispose(navRef); if (error == noErr && navReply.validRecord) { SInt32 count = 0; // AE indexes are 1 based... error = AECountItems(&navReply.selection, &count); if (count > 0) { // Get the FSRef to the containing folder FSRef fsRef; AEKeyword theAEKeyword; DescType typeCode; Size actualSize = 0; memset(&fsRef, 0, sizeof(fsRef)); error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize); if (error == noErr) { char path[PATH_MAX]; /*Flawfinder: ignore*/ char newFileName[SINGLE_FILENAME_BUFFER_SIZE]; /*Flawfinder: ignore*/ error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX); if (error == noErr) { if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8)) { mFiles.push_back(std::string(path) + "/" + std::string(newFileName)); } else { error = paramErr; } } else { error = paramErr; } } } } return error; }
QString qt_mac_get_save_file_name(const QFileDialogArgs &args, QString *pwd, QString *selectedFilter) { QWidget *parent = args.parent; OSErr err; QString retstr; NavDialogCreationOptions options; NavGetDefaultDialogCreationOptions(&options); static const int w = 450, h = 350; if (args.options & QFileDialog::DontConfirmOverwrite) options.optionFlags |= kNavDontConfirmReplacement; options.modality = kWindowModalityAppModal; options.location.h = options.location.v = -1; if (!args.directory.isEmpty()) options.saveFileName = QCFString::toCFStringRef(args.selection); if (!args.caption.isEmpty()) options.windowTitle = QCFString::toCFStringRef(args.caption); if (parent && parent->isVisible()) { WindowClass wclass; GetWindowClass(qt_mac_window_for(parent), &wclass); if (!(args.options & QFileDialog::DontUseSheet) && (wclass == kDocumentWindowClass || wclass == kFloatingWindowClass || wclass == kMovableModalWindowClass)) { options.modality = kWindowModalityWindowModal; options.parentWindow = qt_mac_window_for(parent); // The parent needs to be active for the sheet to get keyboard focus. if (!parent->isActiveWindow()) parent->activateWindow(); } else { parent = parent->window(); QString s = parent->windowTitle(); options.clientName = CFStringCreateWithCharacters(0, (UniChar *)s.unicode(), s.length()); options.location.h = (parent->x() + (parent->width() / 2)) - (w / 2); options.location.v = (parent->y() + (parent->height() / 2)) - (h / 2); QRect r = QApplication::desktop()->screenGeometry( QApplication::desktop()->screenNumber(parent)); if (options.location.h + w > r.right()) options.location.h -= (options.location.h + w) - r.right() + 10; if (options.location.v + h > r.bottom()) options.location.v -= (options.location.v + h) - r.bottom() + 10; } #if 0 } else if (QWidget *p = qApp->mainWidget()) { static int last_screen = -1; int scr = QApplication::desktop()->screenNumber(p); if (last_screen != scr) { QRect r = QApplication::desktop()->screenGeometry(scr); options.location.h = (r.x() + (r.width() / 2)) - (w / 2); options.location.v = (r.y() + (r.height() / 2)) - (h / 2); } #endif } QList<qt_mac_filter_name*> filts = qt_mac_make_filters_list(args.filter); qt_mac_nav_filter_type t; t.saveDialog = true; t.index = 0; t.filts = &filts; if (filts.count() > 1) { int i = 0; CFStringRef *arr = static_cast<CFStringRef *>(malloc(sizeof(CFStringRef) * filts.count())); for (QList<qt_mac_filter_name*>::const_iterator it = filts.constBegin(); it != filts.constEnd(); ++it) arr[i++] = QCFString::toCFStringRef((*it)->description); options.popupExtension = CFArrayCreate(0, reinterpret_cast<const void **>(arr), filts.count(), 0); } NavDialogRef dlg; if (NavCreatePutFileDialog(&options, 'cute', kNavGenericSignature, make_navProcUPP(), static_cast<void *>(filts.isEmpty() ? 0 : &t), &dlg)) { qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__); return retstr; } if (pwd && !pwd->isEmpty()) { FSRef fsref; if (qt_mac_create_fsref(*pwd, &fsref) == noErr) { AEDesc desc; if (AECreateDesc(typeFSRef, &fsref, sizeof(FSRef), &desc) == noErr) NavCustomControl(dlg, kNavCtlSetLocation, (void*)&desc); } } NavDialogRun(dlg); if (selectedFilter) { NavMenuItemSpec navSpec; bzero(&navSpec, sizeof(NavMenuItemSpec)); qt_mac_filter_name *sel_filt_name = qt_mac_make_filters_list(*selectedFilter).at(0); for (int i = 0; i < filts.count(); ++i) { const qt_mac_filter_name *filter = filts.at(i); if (sel_filt_name->description == filter->description && sel_filt_name->regxp == filter->regxp && sel_filt_name->filter == filter->filter) { navSpec.menuType = i; break; } } NavCustomControl(dlg, kNavCtlSelectCustomType, &navSpec); } if (options.modality == kWindowModalityWindowModal) { //simulate modality QWidget modal_widg(parent, Qt::Sheet); modal_widg.createWinId(); QApplicationPrivate::enterModal(&modal_widg); while (g_nav_blocking) qApp->processEvents(QEventLoop::WaitForMoreEvents); QApplicationPrivate::leaveModal(&modal_widg); } if (NavDialogGetUserAction(dlg) != kNavUserActionSaveAs) { NavDialogDispose(dlg); return retstr; } NavReplyRecord ret; NavDialogGetReply(dlg, &ret); NavDialogDispose(dlg); long count; err = AECountItems(&(ret.selection), &count); if (!ret.validRecord || err != noErr || !count) { NavDisposeReply(&ret); return retstr; } AEKeyword keyword; DescType type; Size size; FSRef ref; err = AEGetNthPtr(&(ret.selection), 1, typeFSRef, &keyword, &type, &ref, sizeof(ref), &size); if (err == noErr) { if (!str_buffer) { qAddPostRoutine(cleanup_str_buffer); str_buffer = (UInt8 *)malloc(1024); } FSRefMakePath(&ref, str_buffer, 1024); retstr = QString::fromUtf8((const char *)str_buffer); //now filename CFStringGetCString(ret.saveFileName, (char *)str_buffer, 1024, kCFStringEncodingUTF8); retstr += QLatin1String("/") + QString::fromUtf8((const char *)str_buffer); } NavDisposeReply(&ret); if (selectedFilter) *selectedFilter = filts.at(t.index)->filter; while (!filts.isEmpty()) delete filts.takeFirst(); return retstr; }
void GetSaveFileFromUser( char *title, char *path, char *okMsg, char *cancelMsg ) { // Allow the user to specify a name to save a file - the file need not already // exist. NavDialogCreationOptions dialogOptions; NavDialogRef dialog; NavReplyRecord replyRecord; CFURLRef fileAsCFURLRef = NULL; FSRef fileAsFSRef; OSStatus status; UInt8 output_dir_name[1024]; UniChar output_filename[255]; CFIndex len = 255; int i,pathlen; ZFileSpec fs( path ); //char *debug = fs.getFile(); // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions(&dialogOptions); require_noerr( status, CantGetNavOptions ); // Make the window app-wide modal dialogOptions.modality = kWindowModalityAppModal; dialogOptions.windowTitle = CFStringCreateWithCString( NULL, title, 0 ); dialogOptions.saveFileName = CFStringCreateWithCString( NULL, fs.getFile(), 0 ); //dialogOptions.optionFlags |= kNavPreserveSaveFileExtension; dialogOptions.optionFlags |= kNavNoTypePopup; // Create the dialog status = NavCreatePutFileDialog(&dialogOptions, NULL, NULL, NULL, NULL, &dialog); require_noerr( status, CantCreateDialog ); // Show it status = NavDialogRun(dialog); require_noerr( status, CantRunDialog ); // Get the reply status = NavDialogGetReply(dialog, &replyRecord); require( ((status == noErr) || (status == userCanceledErr)), CantGetReply ); // If the user clicked "Cancel", just bail if ( status == userCanceledErr ) { if( cancelMsg ) { zMsgQueue( cancelMsg ); NavDialogDispose( dialog ); return; } } // Get the file status = AEGetNthPtr(&(replyRecord.selection), 1, typeFSRef, NULL, NULL, &fileAsFSRef, sizeof(FSRef), NULL); require_noerr( status, CantExtractFSRef ); // Get folder name FSRefMakePath( &fileAsFSRef, output_dir_name, 1024 ); pathlen = strlen( (const char *)output_dir_name ); output_dir_name[ pathlen++ ] = '/'; // Get filename len = CFStringGetLength( replyRecord.saveFileName); for( i=0; i<len && pathlen < 1023; i++ ) { output_dir_name[ pathlen++ ] = CFStringGetCharacterAtIndex( replyRecord.saveFileName, i ); } output_dir_name[ pathlen ] = 0; if( okMsg ) { zMsgQueue( "%s overwriteExisting=1 osx=1 filespec='%s'", okMsg, escapeQuotes( (char*)output_dir_name ) ); // on OSX, the confirm to overwrite existing files happens as part of the native dialog } // Cleanup CantExtractFSRef: verify_noerr( NavDisposeReply(&replyRecord) ); CantGetReply: CantRunDialog: NavDialogDispose(dialog); CantCreateDialog: CantGetNavOptions: return; }
ofFileDialogResult ofFileSaveDialog(string defaultName, string messageName){ ofFileDialogResult results; //---------------------------------------------------------------------------------------- //------------------------------------------------------------------------------ OSX //---------------------------------------------------------------------------------------- #ifdef TARGET_OSX short fRefNumOut; FSRef output_file; OSStatus err; NavDialogCreationOptions options; NavGetDefaultDialogCreationOptions( &options ); options.optionFlags = kNavNoTypePopup + kNavSupportPackages + kNavAllowOpenPackages; options.modality = kWindowModalityAppModal; options.optionFlags = kNavDefaultNavDlogOptions; options.message = CFStringCreateWithCString(NULL, messageName.c_str(), kCFStringEncodingASCII);; options.saveFileName = CFStringCreateWithCString(NULL, defaultName.c_str(), kCFStringEncodingASCII); NavDialogRef dialog; err = NavCreatePutFileDialog(&options, '.mov', 'Moov', NULL, NULL, &dialog); //printf("NavCreatePutFileDialog returned %i\n", err ); err = NavDialogRun(dialog); //printf("NavDialogRun returned %i\n", err ); NavUserAction action; action = NavDialogGetUserAction( dialog ); //printf("got action %i\n", action); if (action == kNavUserActionNone || action == kNavUserActionCancel) { return results; } // get dialog reply NavReplyRecord reply; err = NavDialogGetReply(dialog, &reply); if ( err != noErr ) return results; if ( reply.replacing ) { printf("need to replace\n"); } AEKeyword keyword; DescType actual_type; Size actual_size; FSRef output_dir; err = AEGetNthPtr(&(reply.selection), 1, typeFSRef, &keyword, &actual_type, &output_dir, sizeof(output_file), &actual_size); //printf("AEGetNthPtr returned %i\n", err ); CFURLRef cfUrl = CFURLCreateFromFSRef( kCFAllocatorDefault, &output_dir ); CFStringRef cfString = NULL; if ( cfUrl != NULL ) { cfString = CFURLCopyFileSystemPath( cfUrl, kCFURLPOSIXPathStyle ); CFRelease( cfUrl ); } // copy from a CFString into a local c string (http://www.carbondev.com/site/?page=CStrings+) const int kBufferSize = 255; char folderURL[kBufferSize]; Boolean bool1 = CFStringGetCString(cfString,folderURL,kBufferSize,kCFStringEncodingMacRoman); char fileName[kBufferSize]; Boolean bool2 = CFStringGetCString(reply.saveFileName,fileName,kBufferSize,kCFStringEncodingMacRoman); // append strings together string url1 = folderURL; string url2 = fileName; string finalURL = url1 + "/" + url2; results.filePath = finalURL.c_str(); //printf("url %s\n", finalURL.c_str()); // cleanup dialog NavDialogDispose(dialog); #endif //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- //------------------------------------------------------------------------------ windoze //---------------------------------------------------------------------------------------- #ifdef TARGET_WIN32 wchar_t fileName[MAX_PATH] = L""; char * extension; OPENFILENAME ofn; memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); HWND hwnd = WindowFromDC(wglGetCurrentDC()); ofn.hwndOwner = hwnd; ofn.hInstance = GetModuleHandle(0); ofn.nMaxFileTitle = 31; ofn.lpstrFile = fileName; ofn.nMaxFile = MAX_PATH; ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0"); ofn.lpstrDefExt = _T(""); // we could do .rxml here? ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; ofn.lpstrTitle = _T("Select Output File"); if (GetSaveFileName(&ofn)){ results.filePath = convertWideToNarrow(fileName); } #endif //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- //------------------------------------------------------------------------------ linux //---------------------------------------------------------------------------------------- #if defined( TARGET_LINUX ) && defined (OF_USING_GTK) gtkFileDialog(GTK_FILE_CHOOSER_ACTION_SAVE, messageName,defaultName); #endif //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------- if( results.filePath.length() > 0 ){ results.bSuccess = true; results.fileName = ofFileUtils::getFilenameFromPath(results.filePath); } return results; }
std::string GetOpenFileFromUser(dialog_type d_type) { #ifdef UNDEFINED NavDialogCreationOptions dialogOptions; NavDialogRef dialog; NavReplyRecord replyRecord; //CFURLRef fileAsCFURLRef = NULL; FSRef fileAsFSRef; OSStatus status; CFIndex sz; CFRange r; std::string res; // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions(&dialogOptions); require_noerr( status, CantGetNavOptions ); // Make the window app-wide modal dialogOptions.modality = kWindowModalityAppModal; dialogOptions.optionFlags |= kNavDontConfirmReplacement; // Create the dialog status = (DO_LOAD == d_type)? NavCreateGetFileDialog(&dialogOptions, NULL, NULL, NULL, NULL, NULL, &dialog): NavCreatePutFileDialog(&dialogOptions, kNavGenericSignature, kNavGenericSignature, NULL, NULL, &dialog); require_noerr( status, CantCreateDialog ); // Show it status = NavDialogRun(dialog); require_noerr( status, CantRunDialog ); // Get the reply status = NavDialogGetReply(dialog, &replyRecord); require( ((status == noErr) || (status == userCanceledErr)), CantGetReply ); // If the user clicked "Cancel", just bail if ( status == userCanceledErr ) goto UserCanceled; // Get the file status = AEGetNthPtr(&(replyRecord.selection), 1, typeFSRef, NULL, NULL, &fileAsFSRef, sizeof(FSRef), NULL); require_noerr( status, CantExtractFSRef ); // Convert it to a CFURL // fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &fileAsFSRef); //success, lets extraxct info: // kdl; unsigned char buf[100]; buf[0]=0; //null terminated FSRefMakePath( &fileAsFSRef, (UInt8 *)buf, 100); res = std::string((char *)buf, strlen((char *)buf)); if(DO_SAVE == d_type){ //then add file name to the path. r.location = 0; r.length = CFStringGetLength(replyRecord.saveFileName); CFStringGetBytes( replyRecord.saveFileName, r, kCFStringEncodingUTF8, 0, //dont want to deal with uncovertable strings false, //internal representation buf, 100, &sz); res += "/"; res += std::string((char *)buf, sz); }; // Cleanup CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&replyRecord) ); CantGetReply: CantRunDialog: NavDialogDispose(dialog); CantCreateDialog: CantGetNavOptions: return res; #else return ""; #endif //UNDEFINED };
//--------------------------------------------------------------------- // Gets a file to save from the user. Caller must release the CFURLRef. // CFURLRef GetSaveFileFromUser(WindowRef window) { CFURLRef previousFile; CFStringRef saveFileName; UniChar *chars = NULL; CFIndex length; NavDialogCreationOptions dialogOptions; NavDialogRef dialog; NavReplyRecord replyRecord; CFURLRef fileAsCFURLRef = NULL; FSRef fileAsFSRef; FSRef parentDirectory; OSStatus status; if ( window == NULL ) return NULL; // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions(&dialogOptions); require_noerr( status, CantGetNavOptions ); // Change a few things (app-wide modal, show the extension) dialogOptions.modality = kWindowModalityAppModal; dialogOptions.parentWindow = window; dialogOptions.optionFlags = kNavDefaultNavDlogOptions | kNavPreserveSaveFileExtension; // Set up the default save name previousFile = GetWindowProxyFileCFURL(window); if (previousFile == NULL) dialogOptions.saveFileName = CFStringCreateWithCString(NULL, "Untitled.rtf", kCFStringEncodingASCII); else dialogOptions.saveFileName = CFURLCopyLastPathComponent(previousFile); // Create the dialog status = NavCreatePutFileDialog(&dialogOptions, kUnknownType, kUnknownType, NULL, NULL, &dialog); require_noerr( status, CantCreateDialog ); // Show it status = NavDialogRun(dialog); require_noerr( status, CantRunDialog ); // Get the reply status = NavDialogGetReply(dialog, &replyRecord); require( ((status == noErr) || (status == userCanceledErr)), CantGetReply ); // If the user clicked "Cancel", just bail if ( status == userCanceledErr ) goto UserCanceled; // Get the file's location and name status = AEGetNthPtr(&(replyRecord.selection), 1, typeFSRef, NULL, NULL, &parentDirectory, sizeof(FSRef), NULL); require_noerr( status, CantExtractFSRef ); saveFileName = replyRecord.saveFileName; length = CFStringGetLength(saveFileName); chars = malloc(length * sizeof(UniChar)); CFStringGetCharacters(saveFileName, CFRangeMake(0, length), chars); // If we are replacing a file, erase the previous one if ( replyRecord.replacing ) { status = FSMakeFSRefUnicode(&parentDirectory, length, chars, kTextEncodingUnknown, &fileAsFSRef); require_noerr( status, CantMakeFSRef ); status = FSDeleteObject(&fileAsFSRef); require_noerr( status, CantDeletePreviousFile ); } // Create the file status = FSCreateFileUnicode(&parentDirectory, length, chars, kFSCatInfoNone, NULL, &fileAsFSRef, NULL); require_noerr( status, CantCreateSaveFile ); // Convert the reference to the file to a CFURL fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &fileAsFSRef); // Cleanup CantCreateSaveFile: CantDeletePreviousFile: CantMakeFSRef: if ( chars != NULL ) free(chars); CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&replyRecord) ); CantGetReply: CantRunDialog: NavDialogDispose(dialog); CantCreateDialog: if (previousFile) CFRelease(previousFile); CFRelease(dialogOptions.saveFileName); CantGetNavOptions: return fileAsCFURLRef; }
bool showSaveFileDialog(std::string& result, const std::string& suggestedFileName, const std::string& path) { class Error : public std::exception { public: Error(OSStatus status) : std::exception(), _status(status) {} OSStatus getStatus() { return _status; } virtual const char* what() { return "Error while showing OpenFileDialog"; } static void checkForError(OSStatus status) { if (status != noErr) throw Error(status); } virtual ~Error() throw () {} private: OSStatus _status; }; OSStatus status; NavDialogRef dlg(NULL); NavObjectFilterUPP navFilterUPP = NULL; NavDialogCreationOptions myDialogOptions; NavReplyRecord navReply; bool success(false); try { status = NavGetDefaultDialogCreationOptions (&myDialogOptions); myDialogOptions.modality = kWindowModalityAppModal; DialogData data; data.defaultLocation = (path.empty()) ? "" : osgDB::findDataFile(path); myDialogOptions.saveFileName = CFStringCreateWithCString(kCFAllocatorDefault, suggestedFileName.c_str(), kCFStringEncodingUTF8); status = NavCreatePutFileDialog(&myDialogOptions, '????','????',sStandardNavEventFilter, &data, &dlg); Error::checkForError(status); status = NavDialogRun (dlg); Error::checkForError(status); NavUserAction userAction = NavDialogGetUserAction(dlg); if(userAction == kNavUserActionSaveAs) { const unsigned int max_path = 2048; FSRef fsRef; status = NavDialogGetReply( dlg, &navReply ); Error::checkForError(status); status = AEGetNthPtr(&(navReply.selection), 1, typeFSRef, NULL, NULL, &fsRef, sizeof(FSRef), NULL); char path[max_path]; status = FSRefMakePath ( &fsRef, (UInt8*)path, max_path ); result = std::string(path); if (CFStringGetCString(navReply.saveFileName, path, max_path, kCFStringEncodingUTF8)) { success = true; result += "/" + std::string(path); } NavDisposeReply ( &navReply ); } } catch (Error e) { log::error("showOpenFileDialog") <<"failed with " << e.getStatus() << std::endl; success = false; } if (navFilterUPP) ::DisposeNavObjectFilterUPP(navFilterUPP); if (dlg) NavDialogDispose (dlg); return success; }
Boolean AskUserForPutFileName(char* promptStr, char* defaultName, char* pathOfFileSelected, short maxPathLength, FSSpec *specPtr, MyCustomNavItemsData *myCustomItemsDataPtr) { OSStatus err = 0; NavDialogCreationOptions dialogOptions; OSType inFileType = 'TEXT'; // what will happen if we always just say TEXT and change our mind later ? (perhaps it will add .txt) ? OSType inFileCreator = kNavGenericSignature; NavEventUPP inEventProc = 0; Ptr inClientData = (Ptr)myCustomItemsDataPtr; NavDialogRef navDialogRef = 0; NavReplyRecord replyRecord; Boolean gotReply = false; FSSpec fsSpec; char pathName[256]=""; char theFileName[256]=""; CFStringRef windowTitleCFStrRef = 0; CFStringRef clientNameCFStrRef = 0; CFStringRef saveFileNameCFStrRef = 0; if(specPtr) memset(specPtr,0,sizeof(specPtr)); if(pathOfFileSelected && maxPathLength > 0) pathOfFileSelected[0] = 0; err = NavGetDefaultDialogCreationOptions(&dialogOptions); if(err) return false; // for now don't customize the dialogs, may want to do this later /*if(myCustomItemsDataPtr && myCustomItemsDataPtr->ditlResID) { inEventProc = GetMyNavEventHandlerUPP(); }*/ if(promptStr && promptStr[0]) { windowTitleCFStrRef = CFStringCreateWithCString(NULL, promptStr,kCFStringEncodingMacRoman); dialogOptions.windowTitle = windowTitleCFStrRef; } // set the client name so the system can remember the last place the user looked clientNameCFStrRef = CFStringCreateWithCString(NULL,"GNOME",kCFStringEncodingMacRoman); dialogOptions.clientName = clientNameCFStrRef; if(defaultName && defaultName[0]) { saveFileNameCFStrRef = CFStringCreateWithCString(NULL, defaultName,kCFStringEncodingMacRoman); dialogOptions.saveFileName = saveFileNameCFStrRef; } //err = NavCreatePutFileDialog(&dialogOptions,inFileType,inFileCreator,inEventProc,inClientData,&navDialogRef); err = NavCreatePutFileDialog(&dialogOptions,inFileType,inFileCreator,inEventProc,NULL,&navDialogRef); if(err) return false; InitCursor(); err = NavDialogRun(navDialogRef); SetWatchCursor(); if(err) goto done; err = NavDialogGetReply(navDialogRef,&replyRecord); if(err) goto done; gotReply = true; err = AEGetNthPtr(&(replyRecord.selection), 1, typeFSS, NULL, NULL, &fsSpec, sizeof(fsSpec), NULL); if(err) goto done; (void)PathNameFromDirID(fsSpec.parID,fsSpec.vRefNum,pathName); // GetPathWithDelimiterFromDirID mypstrcatJM((StringPtr)pathName,fsSpec.name); my_p2cstr(pathName); (void)CFStringGetCString(replyRecord.saveFileName,theFileName,256,kCFStringEncodingMacRoman); if( (strlen(pathName) + 1 + strlen(theFileName)) < maxPathLength){ strcpy(pathOfFileSelected,pathName); strcat(pathOfFileSelected,":"); strcat(pathOfFileSelected,theFileName); } else { err = -1; // path is too long to return } if(!err && specPtr) *specPtr = fsSpec; done: if(windowTitleCFStrRef) { CFRelease(windowTitleCFStrRef); windowTitleCFStrRef = 0;} if(clientNameCFStrRef) { CFRelease(clientNameCFStrRef); clientNameCFStrRef = 0;} if(saveFileNameCFStrRef) { CFRelease(saveFileNameCFStrRef); saveFileNameCFStrRef = 0;} if(gotReply) NavDisposeReply(&replyRecord); NavDialogDispose(navDialogRef); if(gotReply && !err) return true; return false; }