OSErr squeakFindImage(char* pathName) { NavDialogCreationOptions dialogOptions; NavObjectFilterUPP filterProc = NewNavObjectFilterUPP(findImageFilterProc); OSErr anErr = noErr; NavDialogRef navDialog; FSRef fileAsFSRef; // Specify default options for dialog box anErr = NavGetDefaultDialogCreationOptions(&dialogOptions); if (anErr != noErr) return anErr; // Adjust the options to fit our needs // Set default location option dialogOptions.optionFlags |= kNavSelectDefaultLocation; dialogOptions.optionFlags |= kNavAllFilesInPopup; dialogOptions.optionFlags |= kNavSelectAllReadableItem; // Clear preview option dialogOptions.optionFlags ^= kNavAllowPreviews; // Call NavGetFile() with specified options and // declare our app-defined functions and type list NavCreateChooseFileDialog ( &dialogOptions, nil, nil, nil, filterProc, nil, &navDialog); anErr = NavDialogRun (navDialog); if (anErr != noErr ) return anErr; NavReplyRecord outReply; anErr = NavDialogGetReply (navDialog,&outReply); DisposeNavObjectFilterUPP(filterProc); NavDialogDispose(navDialog); if (anErr != noErr) return anErr; if (!outReply.validRecord) { anErr = NavDisposeReply(&outReply); return -1; } // Get the file anErr = AEGetNthPtr(&(outReply.selection), 1, typeFSRef, NULL, NULL, &fileAsFSRef, sizeof(FSRef), NULL); PathToFileViaFSRef(pathName,DOCUMENT_NAME_SIZE, &fileAsFSRef, gCurrentVMEncoding); // Dispose of NavReplyRecord, resources, descriptors anErr = NavDisposeReply(&outReply); return 0; }
char * ReadDataFile (long * pBufferSize, FSSpec * pfsspecData) { NavReplyRecord replyNav; NavTypeListHandle hTypeList = (NavTypeListHandle) NewHandleClear (sizeof (NavTypeList) + sizeof (OSType) * 1); AEKeyword theKeyword; DescType actualType; Size actualSize; OSStatus err = noErr; short fileRef; char * pFileBuffer; HLock ((Handle) hTypeList); (**hTypeList).osTypeCount = 2; (**hTypeList).osType[0] = 'TEXT'; (**hTypeList).osType[1] = '????'; // select sprite file err = NavChooseFile (NULL, &replyNav, NULL, NULL, NULL, NULL, hTypeList, NULL); if ((err == noErr) && (replyNav.validRecord)) err = AEGetNthPtr (&(replyNav.selection), 1, typeFSS, &theKeyword, &actualType, pfsspecData, sizeof (FSSpec), &actualSize); NavDisposeReply (&replyNav); if (err != noErr) return false; FSpOpenDF(pfsspecData, fsRdPerm, &fileRef); GetEOF(fileRef, pBufferSize); pFileBuffer = (char *) NewPtrClear (*pBufferSize); FSRead (fileRef, pBufferSize, pFileBuffer); FSClose (fileRef); return pFileBuffer; }
// select a file to play, and play it BOOL PlayFile() { BOOL ret=FALSE; NavDialogRef fileDialog; NavDialogCreationOptions fo; NavGetDefaultDialogCreationOptions(&fo); fo.optionFlags=0; fo.parentWindow=win; NavCreateChooseFileDialog(&fo,NULL,NULL,NULL,NULL,NULL,&fileDialog); if (!NavDialogRun(fileDialog)) { NavReplyRecord r; if (!NavDialogGetReply(fileDialog,&r)) { AEKeyword k; FSRef fr; if (!AEGetNthPtr(&r.selection,1,typeFSRef,&k,NULL,&fr,sizeof(fr),NULL)) { char file[256]; FSRefMakePath(&fr,(BYTE*)file,sizeof(file)); if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_LOOP)) && !(chan=BASS_MusicLoad(FALSE,file,0,0,BASS_MUSIC_RAMP|BASS_SAMPLE_LOOP,1))) { Error("Can't play file"); } else { BASS_ChannelPlay(chan,FALSE); ret=TRUE; } } NavDisposeReply(&r); } } NavDialogDispose(fileDialog); return ret; }
int prFile_PutFile(struct VMGlobals *g, int numArgsPushed) { PyrSlot *a = g->sp - 2; PyrSlot *b = g->sp - 1; PyrSlot *c = g->sp; NavDialogOptions options; int err = NavGetDefaultDialogOptions(&options); if (err) return errFailed; options.dialogOptionFlags |= kNavNoTypePopup; options.dialogOptionFlags |= kNavDontAutoTranslate; options.dialogOptionFlags |= kNavDontAddTranslateItems; options.dialogOptionFlags |= kNavSelectDefaultLocation; options.dialogOptionFlags &= ~kNavAllowPreviews; options.dialogOptionFlags &= ~kNavAllowMultipleFiles; if (isKindOfSlot(b, class_string)) { pstringFromPyrString((PyrString*)slotRawObject(b), options.message, 256); } if (isKindOfSlot(c, class_string)) { pstringFromPyrString((PyrString*)slotRawObject(c), options.savedFileName, 256); } else { //pstrncpy(options.savedFileName, "\pUntitled", 255); } NavReplyRecord reply; err = NavPutFile(0, &reply, &options, 0, 'TEXT', 'SCjm', 0); if (err == noErr && reply.validRecord) { AEKeyword keyword; DescType actualType; Size actualSize; FSSpec fsspec; err = AEGetNthPtr(&reply.selection, 1, typeFSS, &keyword, &actualType, &fsspec, sizeof(FSSpec), &actualSize); if (err == noErr) { Str255 pathname; GetFullPathname(&fsspec, pathname); p2cstr(pathname); PyrString *string = newPyrString(g->gc, (char*)pathname, 0, true); SetObject(a, string); err = NavCompleteSave(&reply, kNavTranslateInPlace); } else { SetNil(a); } err = NavDisposeReply(&reply); } else { SetNil(a); } return errNone; }
//--------------------------------------------------------------------- // Gets a file to open from the user. Caller must release the CFURLRef. CFURLRef GetOpenFileFromUser(bool bFolder) { NavDialogCreationOptions dialogOptions; NavDialogRef dialog; NavReplyRecord replyRecord; CFURLRef fileAsCFURLRef = NULL; FSRef fileAsFSRef; OSStatus status; // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions(&dialogOptions); require_noerr( status, CantGetNavOptions ); // Make the window app-wide modal dialogOptions.modality = kWindowModalityAppModal; dialogOptions.optionFlags != kNavAllowOpenPackages; // Create the dialog if( bFolder ){ status = NavCreateChooseFolderDialog(&dialogOptions, NULL, NULL, NULL, &dialog); }else{ status = NavCreateGetFileDialog(&dialogOptions, NULL, 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 ) goto UserCanceled; // Get the file //TODO: for multiple files - 1 specifies index 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); // Cleanup CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&replyRecord) ); CantGetReply: CantRunDialog: NavDialogDispose(dialog); CantCreateDialog: CantGetNavOptions: return fileAsCFURLRef; }
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 OSStatus OpenEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void *inUserData) { NavDialogRef fileDialog; NavDialogCreationOptions fo; NavGetDefaultDialogCreationOptions(&fo); fo.optionFlags=0; fo.parentWindow=win; NavCreateChooseFileDialog(&fo,NULL,NULL,NULL,NULL,NULL,&fileDialog); // if someone wants to somehow get the file selector to filter like in the Windows example, that'd be nice ;) if (!NavDialogRun(fileDialog)) { NavReplyRecord r; if (!NavDialogGetReply(fileDialog,&r)) { AEKeyword k; FSRef fr; if (!AEGetNthPtr(&r.selection,1,typeFSRef,&k,NULL,&fr,sizeof(fr),NULL)) { char file[256]; FSRefMakePath(&fr,(BYTE*)file,sizeof(file)); BASS_StreamFree(chan); // free old stream before opening new if (!(chan=BASS_StreamCreateFile(FALSE,file,0,0,BASS_SAMPLE_LOOP|BASS_SAMPLE_FLOAT))) { SetControlTitleWithCFString(inUserData,CFSTR("click here to open a file...")); { ControlRef cref=GetControl(11); SetControlData(cref,kControlNoPart,kControlStaticTextTextTag,0,""); DrawOneControl(cref); } SetControl32BitMaximum(GetControl(12),0); Error("Can't play the file"); } else { CFStringRef cs=CFStringCreateWithCString(0,file,kCFStringEncodingUTF8); SetControlTitleWithCFString(inUserData,cs); CFRelease(cs); { // display the file type and length QWORD bytes=BASS_ChannelGetLength(chan,BASS_POS_BYTE); DWORD time=BASS_ChannelBytes2Seconds(chan,bytes); BASS_CHANNELINFO info; BASS_ChannelGetInfo(chan,&info); sprintf(file,"channel type = %x (%s)\nlength = %llu (%u:%02u)", info.ctype,GetCTypeString(info.ctype,info.plugin),bytes,time/60,time%60); { ControlRef cref=GetControl(11); SetControlData(cref,kControlNoPart,kControlStaticTextTextTag,strlen(file),file); DrawOneControl(cref); } SetControl32BitMaximum(GetControl(12),time); // update scroller range } BASS_ChannelPlay(chan,FALSE); } } NavDisposeReply(&r); } } NavDialogDispose(fileDialog); return noErr; }
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; } }
bool nav_open_file(char *filetype,char *path) { NavDialogCreationOptions navoption; NavReplyRecord navreply; NavEventUPP navevent; NavObjectFilterUPP navfilter; AEKeyword keyword; DescType typecode; Size sz; NavDialogRef diagref; FSRef fsref; strcpy(nav_filetype,filetype); NavGetDefaultDialogCreationOptions(&navoption); navoption.optionFlags-=kNavDontAddTranslateItems; navoption.optionFlags-=kNavAllowPreviews; navevent=NewNavEventUPP(nav_event_proc); navfilter=NewNavObjectFilterUPP(nav_file_filter); NavCreateGetFileDialog(&navoption,NULL,navevent,NULL,navfilter,NULL,&diagref); NavDialogRun(diagref); NavDialogGetReply(diagref,&navreply); NavDialogDispose(diagref); DisposeNavEventUPP(navevent); DisposeNavObjectFilterUPP(navfilter); if (!navreply.validRecord) { NavDisposeReply(&navreply); return(FALSE); } AEGetNthPtr(&(navreply.selection),1,typeFSRef,&keyword,&typecode,(void*)&fsref,sizeof(FSRef),&sz); NavDisposeReply(&navreply); FSRefMakePath(&fsref,(unsigned char*)path,1024); return(TRUE); }
static pascal void MyPrivateEventProc( const NavEventCallbackMessage callbackSelector, NavCBRecPtr callbackParms, NavCallBackUserData callbackUD ) { switch ( callbackSelector ) { case kNavCBEvent: { switch (callbackParms->eventData.eventDataParms.event->what) { case updateEvt: case activateEvt: HandleEvent(callbackParms->eventData.eventDataParms.event); break; } } break; case kNavCBUserAction: { if ( callbackParms->userAction == kNavUserActionOpen ) { // This is an open files action, send an AppleEvent NavReplyRecord reply; OSStatus status; status = NavDialogGetReply( callbackParms->context, &reply ); if ( status == noErr ) { SendOpenAE( reply.selection ); NavDisposeReply( &reply ); } } } break; case kNavCBTerminate: { if ( callbackParms->context == gOpenFileDialog ) { NavDialogDispose( gOpenFileDialog ); gOpenFileDialog = NULL; } // if after dismissing the dialog SimpleText has no windows open (so Activate event will not be sent) - // call AdjustMenus ourselves to have at right menus enabled if (FrontWindow() == nil) AdjustMenus(nil, true, false); } break; } }
OSErr PutFile (ConstStr255Param thePrompt, ConstStr255Param theFileName, FSSpecPtr theFSSpecPtr, Boolean *theIsSelected, Boolean *theIsReplacing) { NavReplyRecord myReply; NavDialogOptions myDialogOptions; NavEventUPP myEventUPP = NewNavEventUPP(HandleNavEvent); OSErr myErr = noErr; if ((theFSSpecPtr == NULL) || (theIsSelected == NULL) || (theIsReplacing == NULL)) return(paramErr); // assume we are not replacing an existing file *theIsReplacing = false; *theIsSelected = false; // specify the options for the dialog box NavGetDefaultDialogOptions(&myDialogOptions); myDialogOptions.dialogOptionFlags += kNavNoTypePopup; myDialogOptions.dialogOptionFlags += kNavDontAutoTranslate; BlockMoveData(theFileName, myDialogOptions.savedFileName, theFileName[0] + 1); BlockMoveData(thePrompt, myDialogOptions.message, thePrompt[0] + 1); // prompt the user for a file myErr = NavPutFile(NULL, &myReply, &myDialogOptions, myEventUPP, MovieFileType, sigMoviePlayer, NULL); if ((myErr == noErr) && myReply.validRecord) { AEKeyword myKeyword; DescType myActualType; Size myActualSize = 0; // get the FSSpec for the selected file if (theFSSpecPtr != NULL) myErr = AEGetNthPtr(&(myReply.selection), 1, typeFSS, &myKeyword, &myActualType, theFSSpecPtr, sizeof(FSSpec), &myActualSize); *theIsSelected = myReply.validRecord; if (myReply.validRecord) { *theIsReplacing = myReply.replacing; } NavDisposeReply(&myReply); } DisposeNavEventUPP(myEventUPP); return(myErr); }
void mac_opensession(void) { if (mac_gestalts.navsvers > 0) { NavReplyRecord navr; NavDialogOptions navopts; NavTypeListHandle navtypes; AEDesc defaultloc = { 'null', NULL }; AEDesc *navdefault = NULL; short vol; long dirid; FSSpec fss; if (NavGetDefaultDialogOptions(&navopts) != noErr) return; /* XXX should we create sessions dir? */ if (get_session_dir(FALSE, &vol, &dirid) == noErr && FSMakeFSSpec(vol, dirid, NULL, &fss) == noErr && AECreateDesc(typeFSS, &fss, sizeof(fss), &defaultloc) == noErr) navdefault = &defaultloc; /* Can't meaningfully preview a saved session yet */ navopts.dialogOptionFlags &= ~kNavAllowPreviews; navtypes = (NavTypeListHandle)GetResource('open', open_pTTY); if (NavGetFile(navdefault, &navr, &navopts, NULL, NULL, NULL, navtypes, NULL) == noErr && navr.validRecord) mac_openlist(navr.selection); NavDisposeReply(&navr); if (navtypes != NULL) ReleaseResource((Handle)navtypes); } #if !TARGET_API_MAC_CARBON /* XXX Navigation Services */ else { StandardFileReply sfr; static const OSType sftypes[] = { 'Sess', 0, 0, 0 }; StandardGetFile(NULL, 1, sftypes, &sfr); if (!sfr.sfGood) return; mac_opensessionfrom(&sfr.sfFile); /* XXX handle error */ } #endif }
OSStatus CompleteSave( NavReplyRecord* inReply, FSRef* inFileRef, Boolean inDidWriteFile ) { OSStatus theErr; if ( inReply->validRecord ) { if ( inDidWriteFile ) { theErr = NavCompleteSave( inReply, kNavTranslateInPlace ); } else if ( !inReply->replacing ) { // Write failed, not replacing, so delete the file // that was created in BeginSave. FSDeleteObject( inFileRef ); } theErr = NavDisposeReply( inReply ); } return theErr; }
static OSErr ChooseObject( FSRef *objectRef, Boolean getDir) { NavDialogOptions options; NavReplyRecord reply; OSErr osErr; if( objectRef == NULL ) return paramErr; osErr = (! NavServicesAvailable()) ? -1 : noErr; if( osErr == noErr ) osErr = NavGetDefaultDialogOptions(&options); else printf( "Navigation Services is required\n" ); if (osErr == noErr) { /* only select one object at a time */ options.dialogOptionFlags &= ~kNavAllowMultipleFiles; /* if an alias or symfile is selected, return the symfile/alias itself */ /* also support packages */ options.dialogOptionFlags |= kNavDontResolveAliases | kNavSupportPackages; if( getDir ) /* caller wants a directory */ osErr = NavChooseFolder(NULL, &reply, &options, NULL, NULL, NULL); else /* caller wants an object */ osErr = NavChooseObject(NULL, &reply, &options, NULL, NULL, NULL); } if (osErr == noErr) { osErr = ExtractSingleItem(&reply, objectRef); (void) NavDisposeReply(&reply); } return osErr; }
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; }
const StringPtr kApplicationName = "\pYourAppNameHere"; ////////// // // GetOneFileWithPreview // Display the appropriate file-opening dialog box, with an optional QuickTime preview pane. If the user // selects a file, return information about it using the theFSSpecPtr parameter. // // Note that both StandardGetFilePreview and NavGetFile use the function specified by theFilterProc as a // file filter. This framework always passes NULL in the theFilterProc parameter. If you use this function // in your own code, keep in mind that on Windows the function specifier must be of type FileFilterUPP and // on Macintosh it must be of type NavObjectFilterUPP. (You can use the QTFrame_GetFileFilterUPP to create // a function specifier of the appropriate type.) Also keep in mind that Navigation Services expects a file // filter function to return true if a file is to be displayed, while the Standard File Package expects the // filter to return false if a file is to be displayed. // ////////// OSErr GetOneFileWithPreview (short theNumTypes, TypeListPtr theTypeList, FSSpecPtr theFSSpecPtr, void *theFilterProc) { #if TARGET_OS_WIN32 StandardFileReply myReply; #endif #if TARGET_OS_MAC NavReplyRecord myReply; NavDialogOptions myDialogOptions; NavTypeListHandle myOpenList = NULL; NavEventUPP myEventUPP = NewNavEventUPP(HandleNavEvent); #endif OSErr myErr = noErr; if (theFSSpecPtr == NULL) return(paramErr); #if TARGET_OS_WIN32 // prompt the user for a file StandardGetFilePreview((FileFilterUPP)theFilterProc, theNumTypes, (ConstSFTypeListPtr)theTypeList, &myReply); if (!myReply.sfGood) return(userCanceledErr); // make an FSSpec record myErr = FSMakeFSSpec(myReply.sfFile.vRefNum, myReply.sfFile.parID, myReply.sfFile.name, theFSSpecPtr); #endif #if TARGET_OS_MAC // specify the options for the dialog box NavGetDefaultDialogOptions(&myDialogOptions); myDialogOptions.dialogOptionFlags -= kNavNoTypePopup; myDialogOptions.dialogOptionFlags -= kNavAllowMultipleFiles; BlockMoveData(kApplicationName, myDialogOptions.clientName, kApplicationName[0] + 1); // create a handle to an 'open' resource myOpenList = (NavTypeListHandle)CreateOpenHandle(kApplicationSignature, theNumTypes, theTypeList); if (myOpenList != NULL) HLock((Handle)myOpenList); // prompt the user for a file myErr = NavGetFile(NULL, &myReply, &myDialogOptions, myEventUPP, NULL, (NavObjectFilterUPP)theFilterProc, myOpenList, NULL); if ((myErr == noErr) && myReply.validRecord) { AEKeyword myKeyword; DescType myActualType; Size myActualSize = 0; // get the FSSpec for the selected file if (theFSSpecPtr != NULL) myErr = AEGetNthPtr(&(myReply.selection), 1, typeFSS, &myKeyword, &myActualType, theFSSpecPtr, sizeof(FSSpec), &myActualSize); NavDisposeReply(&myReply); } if (myOpenList != NULL) { HUnlock((Handle)myOpenList); DisposeHandle((Handle)myOpenList); } DisposeNavEventUPP(myEventUPP); #endif return(myErr); }
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; } }
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 ); }
PPOpenPanel::ReturnCodes PPOpenPanel::runModal() { ReturnCodes result = ReturnCodeCANCEL; OSStatus err = noErr; NavDialogRef theOpenDialog; NavDialogCreationOptions dialogOptions; if ((err = NavGetDefaultDialogCreationOptions(&dialogOptions)) == noErr) { dialogOptions.modality = kWindowModalityAppModal; dialogOptions.windowTitle = CFStringCreateWithCString(NULL, caption, kCFStringEncodingASCII); err = NavCreateChooseFileDialog(&dialogOptions, NULL, NULL, NULL, NULL, NULL, &theOpenDialog); if (theOpenDialog) { err = NavDialogRun(theOpenDialog); NavReplyRecord reply; err = NavDialogGetReply (theOpenDialog, &reply); if (err == noErr) { // retrieve filename AEDesc actualDesc; FSRef fileToOpen; //HFSUniStr255 theFileName; //CFStringRef fileNameCFString; err = AECoerceDesc(&reply.selection, typeFSRef, &actualDesc); err = AEGetDescData(&actualDesc, reinterpret_cast<void*>(&fileToOpen), sizeof(FSRef)); // gib ihm int len = PATH_MAX; char* buffer = new char[PATH_MAX+1]; FSRefMakePath (&fileToOpen, (UInt8*)buffer, len); fileName = buffer; delete[] buffer; result = ReturnCodeOK; NavDisposeReply(&reply); } NavDialogDispose(theOpenDialog); } if (dialogOptions.windowTitle) CFRelease(dialogOptions.windowTitle); } return result; }
////////// // // GetOneFileWithPreview // Display the appropriate file-opening dialog box, with an optional QuickTime preview pane. If the user // selects a file, return information about it using the theFSSpecPtr parameter. // // Note that both StandardGetFilePreview and NavGetFile use the function specified by theFilterProc as a // file filter. This framework always passes NULL in the theFilterProc parameter. If you use this function // in your own code, keep in mind that on Windows the function specifier must be of type FileFilterUPP and // on Macintosh it must be of type NavObjectFilterUPP. (You can use the QTFrame_GetFileFilterUPP to create // a function specifier of the appropriate type.) Also keep in mind that Navigation Services expects a file // filter function to return true if a file is to be displayed, while the Standard File Package expects the // filter to return false if a file is to be displayed. // ////////// OSErr GetOneFileWithPreview(short theNumTypes, TypeListPtr theTypeList, FSSpecPtr theFSSpecPtr, void *theFilterProc) { #if TARGET_OS_WIN32 StandardFileReply myReply; #endif #if TARGET_OS_MAC NavReplyRecord myReply; NavDialogOptions myDialogOptions; NavTypeListHandle myOpenList = NULL; NavEventUPP myEventUPP = NewNavEventUPP(HandleNavEvent); #endif OSErr myErr = noErr; if (theFSSpecPtr == NULL) return(paramErr); #if TARGET_OS_WIN32 // prompt the user for a file StandardGetFilePreview((FileFilterUPP)theFilterProc, theNumTypes, (ConstSFTypeListPtr)theTypeList, &myReply); if (!myReply.sfGood) return(userCanceledErr); // make an FSSpec record myErr = FSMakeFSSpec(myReply.sfFile.vRefNum, myReply.sfFile.parID, myReply.sfFile.name, theFSSpecPtr); #endif #if TARGET_OS_MAC // specify the options for the dialog box NavGetDefaultDialogOptions(&myDialogOptions); myDialogOptions.dialogOptionFlags -= kNavNoTypePopup; myDialogOptions.dialogOptionFlags -= kNavAllowMultipleFiles; BlockMoveData(kApplicationName, myDialogOptions.clientName, kApplicationName[0] + 1); // create a handle to an 'open' resource myOpenList = (NavTypeListHandle)CreateOpenHandle(kApplicationSignature, theNumTypes, theTypeList); if (myOpenList != NULL) HLock((Handle)myOpenList); // prompt the user for a file myErr = NavGetFile(NULL, &myReply, &myDialogOptions, myEventUPP, NULL, (NavObjectFilterUPP)theFilterProc, myOpenList, NULL); if ((myErr == noErr) && myReply.validRecord) { AEKeyword myKeyword; DescType myActualType; Size myActualSize = 0; // get the FSSpec for the selected file if (theFSSpecPtr != NULL) myErr = AEGetNthPtr(&(myReply.selection), 1, typeFSS, &myKeyword, &myActualType, theFSSpecPtr, sizeof(FSSpec), &myActualSize); NavDisposeReply(&myReply); } if (myOpenList != NULL) { HUnlock((Handle)myOpenList); DisposeHandle((Handle)myOpenList); } DisposeNavEventUPP(myEventUPP); #endif return(myErr); }
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; }
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 };
CFURLRef GetOpenDialogForUser(kDialogType type, char* title, char* message) { NavDialogCreationOptions dialogOptions; NavDialogRef dialog = NULL; NavReplyRecord replyRecord; CFURLRef fileAsCFURLRef = NULL; FSRef fileAsFSRef; OSStatus status; CFAllocatorRef alloc_default = kCFAllocatorDefault; // = NULL; // Get the standard set of defaults status = NavGetDefaultDialogCreationOptions(&dialogOptions); require_noerr( status, CantGetNavOptions ); dialogOptions.optionFlags = kNavNoTypePopup + kNavSupportPackages + kNavAllowOpenPackages; 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; // Create the dialog if (type == kDialogFile) { status = NavCreateGetFileDialog(&dialogOptions, NULL, NULL, NULL, NULL, NULL, &dialog); } else if (type == kDialogFolder) { status = NavCreateChooseFolderDialog(&dialogOptions, 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 ) 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); // Cleanup CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&replyRecord) ); CantGetReply: CantRunDialog: NavDialogDispose(dialog); CantCreateDialog: CantGetNavOptions: return fileAsCFURLRef; }
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; }
int wxFileDialog::ShowModal() { #if TARGET_CARBON OSErr err; NavDialogCreationOptions dialogCreateOptions; // set default options ::NavGetDefaultDialogCreationOptions(&dialogCreateOptions); // this was always unset in the old code dialogCreateOptions.optionFlags &= ~kNavSelectDefaultLocation; wxMacCFStringHolder message(m_message, m_font.GetEncoding()); dialogCreateOptions.windowTitle = message; wxMacCFStringHolder defaultFileName(m_fileName, m_font.GetEncoding()); dialogCreateOptions.saveFileName = defaultFileName; NavDialogRef dialog; NavObjectFilterUPP navFilterUPP = NULL; CFArrayRef cfArray = NULL; // for popupExtension OpenUserDataRec myData; myData.defaultLocation = m_dir; if (m_dialogStyle & wxSAVE) { dialogCreateOptions.optionFlags |= kNavNoTypePopup; dialogCreateOptions.optionFlags |= kNavDontAutoTranslate; dialogCreateOptions.optionFlags |= kNavDontAddTranslateItems; // The extension is important dialogCreateOptions.optionFlags |= kNavPreserveSaveFileExtension; err = ::NavCreatePutFileDialog(&dialogCreateOptions, 'TEXT', 'TEXT', sStandardNavEventFilter, &myData, // for defaultLocation &dialog); } else { MakeUserDataRec(&myData , m_wildCard); size_t numfilters = myData.extensions.GetCount(); if (numfilters > 0) { CFMutableArrayRef popup = CFArrayCreateMutable( kCFAllocatorDefault , numfilters , &kCFTypeArrayCallBacks ) ; dialogCreateOptions.popupExtension = popup ; myData.menuitems = dialogCreateOptions.popupExtension ; for ( size_t i = 0 ; i < numfilters ; ++i ) { CFArrayAppendValue( popup , (CFStringRef) wxMacCFStringHolder( myData.name[i] , m_font.GetEncoding() ) ) ; } } navFilterUPP = NewNavObjectFilterUPP(CrossPlatformFilterCallback); err = ::NavCreateGetFileDialog(&dialogCreateOptions, NULL, // NavTypeListHandle sStandardNavEventFilter, NULL, // NavPreviewUPP navFilterUPP, (void *) &myData, // inClientData &dialog); } if (err == noErr) err = ::NavDialogRun(dialog); // clean up filter related data, etc. if (navFilterUPP) ::DisposeNavObjectFilterUPP(navFilterUPP); if (cfArray) ::CFRelease(cfArray); if (err != noErr) return wxID_CANCEL; NavReplyRecord navReply; err = ::NavDialogGetReply(dialog, &navReply); if (err == noErr && navReply.validRecord) { AEKeyword theKeyword; DescType actualType; Size actualSize; FSRef theFSRef; wxString thePath ; long count; ::AECountItems(&navReply.selection , &count); for (long i = 1; i <= count; ++i) { err = ::AEGetNthPtr(&(navReply.selection), i, typeFSRef, &theKeyword, &actualType, &theFSRef, sizeof(theFSRef), &actualSize); if (err != noErr) break; CFURLRef fullURLRef; if (m_dialogStyle & wxSAVE) { CFURLRef parentURLRef = ::CFURLCreateFromFSRef(NULL, &theFSRef); if (parentURLRef) { fullURLRef = ::CFURLCreateCopyAppendingPathComponent(NULL, parentURLRef, navReply.saveFileName, false); ::CFRelease(parentURLRef); } } else { fullURLRef = ::CFURLCreateFromFSRef(NULL, &theFSRef); } #ifdef __UNIX__ CFURLPathStyle pathstyle = kCFURLPOSIXPathStyle; #else CFURLPathStyle pathstyle = kCFURLHFSPathStyle; #endif CFStringRef cfString = CFURLCopyFileSystemPath(fullURLRef, pathstyle); thePath = wxMacCFStringHolder(cfString).AsString(m_font.GetEncoding()); if (!thePath) { ::NavDisposeReply(&navReply); return wxID_CANCEL; } m_path = thePath; m_paths.Add(m_path); m_fileName = wxFileNameFromPath(m_path); m_fileNames.Add(m_fileName); } // set these to the first hit m_path = m_paths[0]; m_fileName = wxFileNameFromPath(m_path); m_dir = wxPathOnly(m_path); } ::NavDisposeReply(&navReply); return (err == noErr) ? wxID_OK : wxID_CANCEL; #else // TARGET_CARBON NavDialogOptions mNavOptions; NavObjectFilterUPP mNavFilterUPP = NULL; NavPreviewUPP mNavPreviewUPP = NULL ; NavReplyRecord mNavReply; AEDesc mDefaultLocation ; bool mSelectDefault = false ; OSStatus err = noErr ; // setup dialog mNavFilterUPP = nil; mNavPreviewUPP = nil; mSelectDefault = false; mDefaultLocation.descriptorType = typeNull; mDefaultLocation.dataHandle = nil; NavGetDefaultDialogOptions(&mNavOptions); wxMacStringToPascal( m_message , (StringPtr)mNavOptions.message ) ; wxMacStringToPascal( m_fileName , (StringPtr)mNavOptions.savedFileName ) ; // Set default location, the location // that's displayed when the dialog // first appears FSSpec location ; wxMacFilename2FSSpec( m_dir , &location ) ; err = ::AECreateDesc(typeFSS, &location, sizeof(FSSpec), &mDefaultLocation ); if ( mDefaultLocation.dataHandle ) { if (mSelectDefault) { mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation; } else { mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation; } } memset( &mNavReply , 0 , sizeof( mNavReply ) ) ; mNavReply.validRecord = false; mNavReply.replacing = false; mNavReply.isStationery = false; mNavReply.translationNeeded = false; mNavReply.selection.descriptorType = typeNull; mNavReply.selection.dataHandle = nil; mNavReply.keyScript = smSystemScript; mNavReply.fileTranslation = nil; mNavReply.version = kNavReplyRecordVersion ; // zero all data m_path = wxEmptyString ; m_fileName = wxEmptyString ; m_paths.Empty(); m_fileNames.Empty(); OpenUserDataRec myData; MakeUserDataRec( &myData , m_wildCard ) ; myData.currentfilter = m_filterIndex ; if ( myData.extensions.GetCount() > 0 ) { mNavOptions.popupExtension = (NavMenuItemSpecArrayHandle) NewHandle( sizeof( NavMenuItemSpec ) * myData.extensions.GetCount() ) ; myData.menuitems = mNavOptions.popupExtension ; for ( size_t i = 0 ; i < myData.extensions.GetCount() ; ++i ) { (*mNavOptions.popupExtension)[i].version = kNavMenuItemSpecVersion ; (*mNavOptions.popupExtension)[i].menuCreator = 'WXNG' ; // TODO : according to the new docs -1 to 10 are reserved for the OS (*mNavOptions.popupExtension)[i].menuType = i ; wxMacStringToPascal( myData.name[i] , (StringPtr)(*mNavOptions.popupExtension)[i].menuItemName ) ; } } if ( m_dialogStyle & wxSAVE ) { myData.saveMode = true ; mNavOptions.dialogOptionFlags |= kNavDontAutoTranslate ; mNavOptions.dialogOptionFlags |= kNavDontAddTranslateItems ; err = ::NavPutFile( &mDefaultLocation, &mNavReply, &mNavOptions, sStandardNavEventFilter , NULL, kNavGenericSignature, &myData); // User Data m_filterIndex = myData.currentfilter ; } else { myData.saveMode = false ; mNavFilterUPP = NewNavObjectFilterUPP( CrossPlatformFilterCallback ) ; if ( m_dialogStyle & wxMULTIPLE ) mNavOptions.dialogOptionFlags |= kNavAllowMultipleFiles ; else mNavOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles ; err = ::NavGetFile( &mDefaultLocation, &mNavReply, &mNavOptions, sStandardNavEventFilter , mNavPreviewUPP, mNavFilterUPP, NULL , &myData); m_filterIndex = myData.currentfilter ; } DisposeNavObjectFilterUPP(mNavFilterUPP); if ( mDefaultLocation.dataHandle != nil ) { ::AEDisposeDesc(&mDefaultLocation); } if ( (err != noErr) && (err != userCanceledErr) ) { return wxID_CANCEL ; } if (mNavReply.validRecord) { FSSpec outFileSpec ; AEDesc specDesc ; AEKeyword keyWord ; long count ; ::AECountItems( &mNavReply.selection , &count ) ; for ( long i = 1 ; i <= count ; ++i ) { OSErr err = ::AEGetNthDesc( &mNavReply.selection , i , typeFSS, &keyWord , &specDesc); if ( err != noErr ) { m_path = wxT("") ; return wxID_CANCEL ; } outFileSpec = **(FSSpec**) specDesc.dataHandle; if (specDesc.dataHandle != nil) { ::AEDisposeDesc(&specDesc); } m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ; m_paths.Add( m_path ) ; m_fileName = wxFileNameFromPath(m_path); m_fileNames.Add(m_fileName); } // set these to the first hit m_path = m_paths[ 0 ] ; m_fileName = wxFileNameFromPath(m_path); m_dir = wxPathOnly(m_path); NavDisposeReply( &mNavReply ) ; return wxID_OK ; } return wxID_CANCEL; #endif // TARGET_CARBON }
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; }
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; }
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; }
void GetOpenFileFromUser( char *title, char *path, char *okMsg, char *cancelMsg ) { // Allow the user to choose an existing file NavDialogCreationOptions dialogOptions; NavDialogRef dialog; NavReplyRecord replyRecord; CFURLRef fileAsCFURLRef = NULL; FSRef fileAsFSRef; OSStatus status; UInt8 output_dir_name[1024]; ZFileSpec fs( path ); // 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 ); // Create the dialog status = NavCreateGetFileDialog(&dialogOptions, NULL, 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 ); FSRefMakePath( &fileAsFSRef, output_dir_name, 1024 ); if( okMsg ) { zMsgQueue( "%s osx=1 filespec='%s'", okMsg, escapeQuotes( (char*)output_dir_name ) ); } // Cleanup CantExtractFSRef: UserCanceled: verify_noerr( NavDisposeReply(&replyRecord) ); CantGetReply: CantRunDialog: NavDialogDispose(dialog); CantCreateDialog: CantGetNavOptions: return; }