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; }
bool OSFileRequest::Post(void) { m_data->status = NavDialogRun(m_data->dialog); NavUserAction action = NavDialogGetUserAction(m_data->dialog); if (( action != kNavUserActionOpen ) && (action != kNavUserActionSaveAs)) return false; m_data->status = NavDialogGetReply(m_data->dialog, &m_data->replyRecord); return true; }
static int manually_locate_product(const char *name, char *buf, size_t bufsize, const char *title) { NavDialogCreationOptions dlgopt; NavDialogRef dlg; NavReplyRecord reply; NavUserAction action; AEKeyword keyword; AEDesc desc; FSRef fsref; OSStatus rc; int retval = 0; const char *promptfmt = _("We can't find your \"%s\" installation." " Would you like to show us where it is?"); char *promptstr = alloca(strlen(name) + strlen(promptfmt) + 1); if (promptstr == NULL) { log_fatal(_("Out of memory.")); return(0); } /* if */ sprintf(promptstr, promptfmt, name); if (!ui_prompt_yn(promptstr, title)) return(0); NavGetDefaultDialogCreationOptions(&dlgopt); dlgopt.optionFlags |= kNavSupportPackages; dlgopt.optionFlags |= kNavAllowOpenPackages; dlgopt.optionFlags &= ~kNavAllowMultipleFiles; dlgopt.windowTitle = CFSTR("Please select the product's icon and click 'OK'."); /* !!! FIXME! */ dlgopt.actionButtonLabel = CFSTR("OK"); NavCreateChooseFolderDialog(&dlgopt, NULL, NULL, NULL, &dlg); NavDialogRun(dlg); action = NavDialogGetUserAction(dlg); if (action != kNavUserActionCancel) { NavDialogGetReply(dlg, &reply); rc = AEGetNthDesc(&reply.selection, 1, typeFSRef, &keyword, &desc); if (rc != noErr) log_fatal("Unexpected error in AEGetNthDesc: %d", (int) rc); else { /* !!! FIXME: Check return values here! */ BlockMoveData(*desc.dataHandle, &fsref, sizeof (fsref)); FSRefMakePath(&fsref, BAD_CAST buf, bufsize - 1); buf[bufsize - 1] = '\0'; AEDisposeDesc(&desc); retval = 1; } /* if */ NavDisposeReply(&reply); } /* else */ NavDialogDispose(dlg); return(retval); } /* manually_locate_product */
pascal void CNavOpenDialog::NavModernEventProc( NavEventCallbackMessage msg, NavCBRecPtr params, void* userData ) { OSStatus status = noErr; CNavOpenDialog* openDialog = (CNavOpenDialog*)userData; switch( msg ) { case kNavCBStart: // any initial set up like custom control state is set here break; case kNavCBCustomize: // add custom controls to the Nav dialog here break; case kNavCBUserAction: { NavReplyRecord reply; NavUserAction userAction = 0; status = NavDialogGetReply( params->context, &reply ); if( status == noErr ) { userAction = NavDialogGetUserAction( params->context ); switch( userAction ) { case kNavUserActionOpen: { if( userData != NULL ) openDialog->OpenFile( reply ); } break; } status = NavDisposeReply( &reply ); } break; } case kNavCBPopupMenuSelect: { NavMenuItemSpecPtr pNavMenuItem = NULL; pNavMenuItem = (NavMenuItemSpec *)params->eventData.eventDataParms.param; if (pNavMenuItem!= NULL) openDialog->SetCurrentFormatMenuSelection( pNavMenuItem->menuType ); } break; case kNavCBTerminate: { // We must make a new NavDialogRef on every run of the NavDialog // so dispose of the current one on terminate openDialog->ReleaseNavDialogRef(); } break; } }
char *Sys_PathFromOpenMenu(void) { /* present an open file dialog and return the file's path */ OSStatus res; NavDialogCreationOptions options; NavDialogRef dialog; NavReplyRecord reply; NavUserAction action; FSRef fileRef; CFURLRef cfUrl; CFStringRef cfString; res = NavGetDefaultDialogCreationOptions(&options); options.modality = kWindowModalityAppModal; res = NavCreateGetFileDialog(&options, NULL, NULL, NULL, 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, NULL, NULL, &fileRef, sizeof(FSRef), NULL); cfUrl = CFURLCreateFromFSRef(NULL, &fileRef); cfString = NULL; if (cfUrl) { cfString = CFURLCopyFileSystemPath(cfUrl, kCFURLPOSIXPathStyle); CFRelease(cfUrl); } memset(g_OpenFileName, 0, PATH_MAX); CFStringGetCString(cfString, g_OpenFileName, PATH_MAX, kCFStringEncodingMacRoman); return g_OpenFileName; }
void userActionCallback ( NavCBRecPtr callBackParms ) { OSStatus err; long int n; NavReplyRecord * nReply = new NavReplyRecord; err = NavDialogGetReply ( callBackParms->context, nReply ); if ( err != noErr ) { NavDisposeReply( nReply ); return; } NavUserAction userAction; userAction = NavDialogGetUserAction( callBackParms->context ); switch ( userAction ) { case kNavUserActionOpen: AECountItems( &(nReply->selection), &n ) ; if ( n != 0 ) { AEKeyword aeKey; AEDesc record; FSRef fref; char newfilename[512]; openfD = new fileData(); fileData * newfD = openfD; for ( int i = 0; i < n ; i++ ) { if ( i != 0 ) { newfD->next = new fileData(); newfD = newfD->next; } AEGetNthDesc (&(nReply->selection), i+1, typeFSRef, &aeKey, &record ); err = AEGetDescData( &record, ( void * )( &fref ), sizeof( FSRef ) ); FSRefMakePath( &fref, (UInt8*)newfilename, 512); fprintf(stderr, "open: %s\n", newfilename ); newfD->fileName = newfilename; newfD->isDir = false; } } break; case kNavUserActionSaveAs: AECountItems( &(nReply->selection), &n ) ; if ( n != 0 ) { AEKeyword aeKey; AEDesc record; FSRef fref; char newfilename[512]; char fileSaveName[512]; savefD = new fileData(); for ( int i = 0; i < n ; i++ ) { AEGetNthDesc (&(nReply->selection), i+1, typeFSRef, &aeKey, &record ); err = AEGetDescData( &record, ( void * )( &fref ), sizeof( FSRef ) ); FSRefMakePath( &fref, (UInt8*)newfilename, 512); fprintf(stderr, "save: %s\n", newfilename ); savefD->fileName = newfilename; savefD->isDir = false; const char * fname = CFStringGetCStringPtr( nReply->saveFileName, kCFStringEncodingASCII ); if ( fname ) { fprintf(stderr, "file is %s\n", fname); savefD->fileName += "/"; savefD->fileName += fname; } else { CFStringGetCString ( nReply->saveFileName, (char*)fileSaveName, 512, kCFStringEncodingASCII ); savefD->fileName += "/"; savefD->fileName += fileSaveName; fprintf(stderr, "no filename given\n"); } } } break; } NavDisposeReply( nReply ); }
static pascal void AddNavEvent( NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void * callBackUD ) // Called by Navigation Services when interesting things happen // in our Nav dialog (which is displayed when the user clicks // the "Add" button). In this case we're primarily interested // in two events: the user action of the user clicking the Choose // button of the Nav dialog, and the dialog being torn down. { #pragma unused(callBackUD) OSStatus err; OSStatus junk; NavDialogRef navDialog; navDialog = callBackParms->context; assert(navDialog != NULL); switch (callBackSelector) { case kNavCBUserAction: switch ( NavDialogGetUserAction(navDialog) ) { case kNavUserActionChoose: { NavReplyRecord reply; AEKeyword junkKeyword; DescType junkType; Size junkSize; err = NavDialogGetReply(navDialog, &reply); if (err == noErr) { FSRef chosenItem; // In the debug build, verify that only one items is // selected. #if ! defined(NDEBUG) { long selectionCount; assert( (AECountItems( &reply.selection, &selectionCount) == noErr) && (selectionCount == 1) ); } #endif // Get the selected item. err = AEGetNthPtr( &reply.selection, 1, typeFSRef, &junkKeyword, &junkType, &chosenItem, sizeof(chosenItem), &junkSize ); // Use LoginItemsAE to add it to the list. if (err == noErr) { err = LIAEAddRefAtEnd( &chosenItem, GetControlValue(gAddHiddenControl) != 0 ); } junk = NavDisposeReply(&reply); assert(junk == noErr); if (err == noErr) { DoRefresh(); } else { DisplayError(err); } } } break; default: // do nothing break; } break; case kNavCBTerminate: NavDialogDispose(navDialog); break; default: // do nothing break; } }
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; }
QStringList qt_mac_get_open_file_names(const QFileDialogArgs &args, QString *pwd, QString *selectedFilter) { QWidget *parent = args.parent; OSErr err; QStringList retstrl; NavDialogCreationOptions options; NavGetDefaultDialogCreationOptions(&options); options.modality = kWindowModalityAppModal; options.optionFlags |= kNavSupportPackages; if (args.options & QFileDialog::DontConfirmOverwrite) options.optionFlags |= kNavDontConfirmReplacement; if (args.mode != QFileDialog::ExistingFiles) options.optionFlags &= ~kNavAllowMultipleFiles; if (!args.caption.isEmpty()) options.windowTitle = QCFString::toCFStringRef(args.caption); static const int w = 450, h = 350; options.location.h = options.location.v = -1; 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); } else { parent = parent->window(); QString s = parent->windowTitle(); options.clientName = QCFString::toCFStringRef(s); 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)); const int border = 10; if (options.location.h + w > r.right()) options.location.h -= (options.location.h + w) - r.right() + border; if (options.location.v + h > r.bottom()) options.location.v -= (options.location.v + h) - r.bottom() + border; if (options.location.h < r.left()) options.location.h = r.left() + border; if (options.location.v < r.top()) options.location.v = r.top() + border; } #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 = false; 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 (args.mode == QFileDialog::DirectoryOnly || args.mode == QFileDialog::Directory) { if (NavCreateChooseFolderDialog(&options, make_navProcUPP(), 0, 0, &dlg)) { qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__); return retstrl; } } else { if (NavCreateGetFileDialog(&options, 0, make_navProcUPP(), 0, make_navFilterUPP(), (void *) (filts.isEmpty() ? 0 : &t), &dlg)) { qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__); return retstrl; } } 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) & (kNavUserActionOpen | kNavUserActionChoose | kNavUserActionNewFolder))) { NavDialogDispose(dlg); return retstrl; } NavReplyRecord ret; NavDialogGetReply(dlg, &ret); NavDialogDispose(dlg); long count; err = AECountItems(&(ret.selection), &count); if (!ret.validRecord || err != noErr || !count) { NavDisposeReply(&ret); return retstrl; } for (long index = 1; index <= count; index++) { FSRef ref; err = AEGetNthPtr(&(ret.selection), index, typeFSRef, 0, 0, &ref, sizeof(ref), 0); if (err != noErr) break; if (!str_buffer) { qAddPostRoutine(cleanup_str_buffer); str_buffer = (UInt8 *)malloc(1024); } FSRefMakePath(&ref, str_buffer, 1024); retstrl.append(QString::fromUtf8((const char *)str_buffer)); } NavDisposeReply(&ret); if (selectedFilter) *selectedFilter = filts.at(t.index)->filter; while (!filts.isEmpty()) delete filts.takeFirst(); return retstrl; }
pascal void NavEventProc( NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void* callBackUD ) { OurSaveDialogData *dialogDataP = (OurSaveDialogData*)callBackUD; OSStatus err = noErr; switch( callBackSelector ) { case kNavCBUserAction: { NavReplyRecord reply; NavUserAction userAction = 0; if ((err = NavDialogGetReply( callBackParms->context, &reply )) == noErr ) { OSStatus tempErr; userAction = NavDialogGetUserAction( callBackParms->context ); switch( userAction ) { case kNavUserActionSaveAs: { if ( dialogDataP != NULL ){ AEDesc actualDesc; if ( (err = AECoerceDesc( &reply.selection, typeFSRef, &actualDesc )) == noErr ) { // the coercion succeeded as an FSRef, // so use HFS+ APIs to save the file: err = DoFSRefSave( dialogDataP, &reply, &actualDesc); AEDisposeDesc( &actualDesc ); }else{ // the coercion failed as an FSRef, so get the FSSpec and // save the file /* FSRef's don't exist on systems prior to MacOS 9 so there it is necessary to have a different approach as shown in the Nav Services sample in the CarbonSDK. Since this code is used on MacOS X only, this is not an issue. */ // assert(...) } } break; } case kNavUserActionCancel: //.. break; case kNavUserActionNewFolder: //.. break; } tempErr = NavDisposeReply( &reply ); if(!err) err = tempErr; } break; } case kNavCBTerminate: { if( dialogDataP != NULL ) { if(dialogDataP->dialogRef) NavDialogDispose(dialogDataP->dialogRef ); dialogDataP->dialogRef = NULL; free(dialogDataP); } } break; } }
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; }
bool showOpenFileDialog(std::string& result, const std::string& path, const std::string& filetypes) { 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); if (!filetypes.empty()) { navFilterUPP = NewNavObjectFilterUPP(CrossPlatformFilterCallback); std::vector<std::string> exts; cefix::strTokenize(filetypes,exts,","); data.allowedExtensions.insert(exts.begin(), exts.end()); } status = NavCreateChooseFileDialog(&myDialogOptions, NULL, sStandardNavEventFilter, NULL, navFilterUPP, &data, &dlg); Error::checkForError(status); status = NavDialogRun (dlg); Error::checkForError(status); NavUserAction userAction = NavDialogGetUserAction(dlg); if(userAction == kNavUserActionChoose) { 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 ); NavDisposeReply ( &navReply ); result = std::string(path); success = true; } } catch (Error e) { log::error("showOpenFileDialog") << "failed with " << e.getStatus() << std::endl; success = false; } if (navFilterUPP) ::DisposeNavObjectFilterUPP(navFilterUPP); if (dlg) NavDialogDispose (dlg); return success; }
static pascal void NavEventProc( NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void* callBackUD ) { OurDialogData *dialogDataP = (OurDialogData*)callBackUD; OSStatus err = noErr; switch( callBackSelector ) { case kNavCBUserAction: { NavReplyRecord reply; NavUserAction userAction = 0; if ((err = NavDialogGetReply( callBackParms->context, &reply )) == noErr ) { OSStatus tempErr; userAction = NavDialogGetUserAction( callBackParms->context ); switch( userAction ) { case kNavUserActionOpen: { long count = 0; short index; err = AECountItems( &reply.selection, &count ); for ( index = 1; index <= count; index++ ) { AEKeyword keyWord; AEDesc theDesc; if (( err = AEGetNthDesc( &reply.selection, index, typeWildCard, &keyWord, &theDesc )) == noErr ) { FSRef fileRef; GetFSRefFromAEDesc(&theDesc, &fileRef); (void)doTheFile( fileRef ); AEDisposeDesc( &theDesc ); } } EnableMenuCommand(NULL, kHICommandOpen); } break; case kNavUserActionCancel: //.. break; case kNavUserActionNewFolder: //.. break; } tempErr = NavDisposeReply( &reply ); if(!err) err = tempErr; } break; } case kNavCBTerminate: if( dialogDataP != NULL ) { if(dialogDataP->dialogRef) NavDialogDispose(dialogDataP->dialogRef ); dialogDataP->dialogRef = NULL; free(dialogDataP); } break; } }
static OSStatus UniversalConfirmSaveDialog( WindowRef parentWindow, CFStringRef documentName, Boolean quitting, void* inContextData, NavDialogRef *outDialog, NavUserAction *outUserAction ) { OSStatus theErr = noErr; NavAskSaveChangesAction action = 0; NavDialogRef dialog = NULL; NavUserAction userAction = kNavUserActionNone; NavDialogCreationOptions dialogOptions; NavEventUPP eventUPP; Boolean disposeAfterRun; NavGetDefaultDialogCreationOptions( &dialogOptions ); action = quitting ? kNavSaveChangesQuittingApplication : kNavSaveChangesClosingDocument; dialogOptions.modality = ( parentWindow != NULL ) ? kWindowModalityWindowModal : kWindowModalityAppModal; dialogOptions.parentWindow = parentWindow; dialogOptions.clientName = CFStringCreateWithPascalString( NULL, LMGetCurApName(), GetApplicationTextEncoding()); if ( documentName != NULL ) { dialogOptions.saveFileName = documentName; } eventUPP = ( inContextData == NULL ) ? GetPrivateEventUPP() : GetEventUPP(); disposeAfterRun = ( dialogOptions.modality == kWindowModalityAppModal && inContextData == NULL ); theErr = NavCreateAskSaveChangesDialog( &dialogOptions, action, eventUPP, inContextData, &dialog ); if ( theErr == noErr ) { theErr = NavDialogRun( dialog ); if ( theErr != noErr || disposeAfterRun ) { userAction = NavDialogGetUserAction( dialog ); NavDialogDispose( dialog ); dialog = NULL; } } if ( dialogOptions.clientName != NULL ) { CFRelease( dialogOptions.clientName ); } if ( outDialog != NULL ) { *outDialog = dialog; } if ( outUserAction != NULL ) { *outUserAction = userAction; } return theErr; }
QStringList Q3FileDialog::macGetOpenFileNames(const QString &filter, QString *pwd, QWidget *parent, const char* /*name*/, const QString& caption, QString *selectedFilter, bool multi, bool directory) { OSErr err; QStringList retstrl; NavDialogCreationOptions options; NavGetDefaultDialogCreationOptions(&options); options.modality = kWindowModalityAppModal; options.optionFlags |= kNavDontConfirmReplacement | kNavSupportPackages; if (!multi) options.optionFlags &= ~kNavAllowMultipleFiles; if(!caption.isEmpty()) options.windowTitle = CFStringCreateWithCharacters(NULL, (UniChar *)caption.unicode(), caption.length()); static const int w = 450, h = 350; options.location.h = options.location.v = -1; 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(directory) { if(NavCreateChooseFolderDialog(&options, make_navProcUPP(), NULL, NULL, &dlg)) { qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__); return retstrl; } } else { if(NavCreateGetFileDialog(&options, NULL, make_navProcUPP(), NULL, make_navFilterUPP(), (void *) (filts.isEmpty() ? NULL : &t), &dlg)) { qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__); return retstrl; } } 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 = 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) & (kNavUserActionOpen | kNavUserActionChoose | kNavUserActionNewFolder))) { NavDialogDispose(dlg); return retstrl; } NavReplyRecord ret; NavDialogGetReply(dlg, &ret); NavDialogDispose(dlg); long count; err = AECountItems(&(ret.selection), &count); if(!ret.validRecord || err != noErr || !count) { NavDisposeReply(&ret); return retstrl; } for(long index = 1; index <= count; index++) { FSRef ref; err = AEGetNthPtr(&(ret.selection), index, typeFSRef, 0, 0, &ref, sizeof(ref), 0); if(err != noErr) break; if(!str_buffer) { qAddPostRoutine(cleanup_str_buffer); str_buffer = (UInt8 *)malloc(1024); } FSRefMakePath(&ref, str_buffer, 1024); retstrl.append(QString::fromUtf8((const char *)str_buffer)); } NavDisposeReply(&ret); if(selectedFilter) *selectedFilter = filts.at(t.index)->filter; while (!filts.isEmpty()) delete filts.takeFirst(); return retstrl; }
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; }
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; }