Пример #1
0
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;
}
Пример #2
0
// this code originates from the NavServices sample code in the CarbonLib SDK
OSStatus DoSaveAsPDF(WindowRef w, void *ourDataP)
{
    OSStatus 			err = noErr;
    static NavEventUPP	gNavEventProc = NULL;		// event proc for our Nav Dialogs 
    NavDialogCreationOptions	dialogOptions;
    if(!gNavEventProc){
        gNavEventProc = NewNavEventUPP(NavEventProc);
        if(!gNavEventProc)
            err = memFullErr;
    }

    if(!err && (( err = NavGetDefaultDialogCreationOptions( &dialogOptions )) == noErr ))
    {
	OurSaveDialogData *dialogDataP = NULL;
	CFStringRef	tempString;
	CopyWindowTitleAsCFString(w, &tempString);

        dialogOptions.saveFileName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, 
                                                kFileTypePDFCFStr, tempString);
	
	CFRelease(tempString);
	
	// make the dialog modal to our parent doc, AKA sheets
        dialogOptions.parentWindow = w;
	dialogOptions.modality = kWindowModalityWindowModal;
	
	dialogDataP = (OurSaveDialogData *)malloc(sizeof(OurSaveDialogData));
	if(dialogDataP){
	    dialogDataP->dialogRef = NULL;
	    dialogDataP->parentWindow = w;
	    dialogDataP->documentDataP = ourDataP;
	    err = NavCreatePutFileDialog(&dialogOptions, kFileTypePDF, kFileCreator,
						    gNavEventProc, dialogDataP,
						    &dialogDataP->dialogRef);
	    if (!err && dialogDataP->dialogRef != NULL)
	    {
		err = NavDialogRun( dialogDataP->dialogRef );
		if (err != noErr)
		{
		    NavDialogDispose( dialogDataP->dialogRef );
		    dialogDataP->dialogRef = NULL;
		    free(dialogDataP);
		}
	    }
	}else
	    err = memFullErr;
       	
     	if ( dialogOptions.saveFileName != NULL )
	    CFRelease( dialogOptions.saveFileName );

    }
    return err;
}
Пример #3
0
fileData*
MacOSXDirScanner::saveFileDialog() { 

    //XXX not finished yet. 

    fprintf(stderr, "start OSX File Save Dialog\n");
    OSStatus   err;
    NavDialogRef  saveDialog;

    NavDialogCreationOptions dialogAttributes;
        
    int n = 0;
    if ( savefD ) { 
        delete savefD;
        savefD = NULL;
    }

    if( AudicleWindow::our_fullscreen )
    {
        glutReshapeWindow( AudicleWindow::main()->m_w, AudicleWindow::main()->m_h );
        glutPostRedisplay();
        AudicleWindow::our_fullscreen = FALSE;
        return NULL;
    }

    err = NavGetDefaultDialogCreationOptions( &dialogAttributes );
    
    dialogAttributes.modality = kWindowModalityAppModal;   
    
    gNavEventHandlerPtr = NewNavEventUPP( dialogFileCallback );    
    
    err = NavCreatePutFileDialog( &dialogAttributes, 'ChuK', kNavGenericSignature,
                                  gNavEventHandlerPtr, NULL, &saveDialog );
    
    if ( !AudicleGfx::cursor_on ) { ShowCursor(); AudicleGfx::cursor_on = true; }
    err = NavDialogRun( saveDialog );
    
    if ( err != noErr )
    {
        NavDialogDispose( saveDialog );
        DisposeNavEventUPP( gNavEventHandlerPtr );
        return NULL;
    }
    
    
    return savefD;
}
Пример #4
0
	OSFileRequest::OSFileRequest (const int reqType, const char *title,
																const char *fileType, const char *ext, const char *baseName,
																const char *path,	const char *_baseDirType, int bufLen)
	:	type(reqType),
		m_data(new Data)
	{
		m_data->status = NavGetDefaultDialogCreationOptions(&m_data->dialogOptions);
		m_data->dialogOptions.modality = kWindowModalityAppModal;
		m_data->dialogOptions.windowTitle = CFStringCreateWithCString(NULL, title, kCFStringEncodingMacRoman);
		m_data->dialogOptions.saveFileName = CFStringCreateWithCString(NULL, baseName, kCFStringEncodingMacRoman);
		if (type == FREQ_LOAD)
		{
			m_data->status = NavCreateGetFileDialog(&m_data->dialogOptions, NULL, NULL, NULL, NULL, NULL, &m_data->dialog);
		}
		else if (type == FREQ_SAVE)
		{
			m_data->status = NavCreatePutFileDialog(&m_data->dialogOptions, kUnknownType, kUnknownType, NULL, NULL, &m_data->dialog);
		}
	}
OSStatus SaveFileDialog(
    WindowRef parentWindow,
    CFStringRef documentName,
    OSType filetype,
    OSType fileCreator,
    void *inContextData,
    NavDialogRef *outDialog )
{
    NavDialogCreationOptions	dialogOptions;
    OSStatus					theErr = noErr;

    NavGetDefaultDialogCreationOptions( &dialogOptions );

    dialogOptions.clientName = CFStringCreateWithPascalString( NULL, LMGetCurApName(), GetApplicationTextEncoding());
    dialogOptions.saveFileName = documentName;
    dialogOptions.modality = ( parentWindow != NULL ) ? kWindowModalityWindowModal : kWindowModalityAppModal;
    dialogOptions.parentWindow = parentWindow;

    theErr = NavCreatePutFileDialog( &dialogOptions, filetype, fileCreator, GetEventUPP(), inContextData, outDialog );

    if ( theErr == noErr )
    {
        theErr = NavDialogRun( *outDialog );
        if ( theErr != noErr )
        {
            NavDialogDispose( *outDialog );
        }
        if ( theErr != noErr || dialogOptions.modality == kWindowModalityAppModal )
        {
            *outDialog = NULL;	// The dialog has already been disposed.
        }
    }

    if ( dialogOptions.clientName != NULL )
    {
        CFRelease( dialogOptions.clientName );
    }

    return theErr;
}
Пример #6
0
QString Q3FileDialog::macGetSaveFileName(const QString &start, const QString &filter,
                                         QString *, QWidget *parent, const char* /*name*/,
                                         const QString& caption, QString *selectedFilter)
{
    OSErr err;
    QString retstr;
    NavDialogCreationOptions options;
    NavGetDefaultDialogCreationOptions(&options);
    static const int w = 450, h = 350;
    options.optionFlags |= kNavDontConfirmReplacement;
    options.modality = kWindowModalityAppModal;
    options.location.h = options.location.v = -1;
    QString workingDir;
    QString initialSelection;
    if (!start.isEmpty()) {
        Q3UrlOperator u(encodeFileName(start));
        if (u.isLocalFile() && QFileInfo(u.path()).isDir()) {
            workingDir = start;
        } else {
            if (u.isLocalFile()) {
                QFileInfo fi(u.dirPath());
                if (fi.exists()) {
                    workingDir = u.dirPath();
                    initialSelection = u.fileName();
                }
            } else {
                workingDir = u.toString();
            }
        }
        if (!initialSelection.isEmpty())
            options.saveFileName = CFStringCreateWithCharacters(0,
                                                            (UniChar *)initialSelection.unicode(),
                                                            initialSelection.length());
    }
    if(!caption.isEmpty())
        options.windowTitle = CFStringCreateWithCharacters(NULL, (UniChar *)caption.unicode(),
                                                           caption.length());
    if(parent && parent->isVisible()) {
        Qt::WindowType wt = parent->window()->windowType();
        if (wt != Qt::Desktop && wt != Qt::Sheet && wt != Qt::Drawer) {
            options.modality = kWindowModalityWindowModal;
            options.parentWindow = qt_mac_window_for(parent);
        } else {
            parent = parent->window();
            QString s = parent->windowTitle();
            options.clientName = CFStringCreateWithCharacters(NULL, (UniChar *)s.unicode(), s.length());
            options.location.h = (parent->x() + (parent->width() / 2)) - (w / 2);
            options.location.v = (parent->y() + (parent->height() / 2)) - (h / 2);

            QRect r = QApplication::desktop()->screenGeometry(
                QApplication::desktop()->screenNumber(parent));
            if(options.location.h + w > r.right())
                options.location.h -= (options.location.h + w) - r.right() + 10;
            if(options.location.v + h > r.bottom())
                options.location.v -= (options.location.v + h) - r.bottom() + 10;
        }
    } else if(QWidget *p = qApp->mainWidget()) {
        static int last_screen = -1;
        int scr = QApplication::desktop()->screenNumber(p);
        if(last_screen != scr) {
            QRect r = QApplication::desktop()->screenGeometry(scr);
            options.location.h = (r.x() + (r.width() / 2)) - (w / 2);
            options.location.v = (r.y() + (r.height() / 2)) - (h / 2);
        }
    }

    QList<qt_mac_filter_name*> filts = makeFiltersList(filter);
    qt_mac_nav_filter_type t;
    t.index = 0;
    t.filts = &filts;
    if(filts.count() > 1) {
        int i = 0;
        CFStringRef *arr = (CFStringRef *)malloc(sizeof(CFStringRef) * filts.count());
        for (QList<qt_mac_filter_name*>::Iterator it = filts.begin(); it != filts.end(); ++it) {
            QString rg = (*it)->description;
            arr[i++] = CFStringCreateWithCharacters(NULL, (UniChar *)rg.unicode(), rg.length());
        }
        options.popupExtension = CFArrayCreate(NULL, (const void **)arr, filts.count(), NULL);
    }

    NavDialogRef dlg;
    if(NavCreatePutFileDialog(&options, 'cute', kNavGenericSignature, make_navProcUPP(),
                              (void *) (filts.isEmpty() ? NULL : &t), &dlg)) {
        qDebug("Shouldn't happen %s:%d", __FILE__, __LINE__);
        return retstr;
    }
    if (!workingDir.isEmpty()) {
        FSRef fsref;
        if (qt_mac_create_fsref(workingDir, &fsref) == noErr) {
            AEDesc desc;
            if (AECreateDesc(typeFSRef, &fsref, sizeof(FSRef), &desc) == noErr)
                NavCustomControl(dlg, kNavCtlSetLocation, (void*)&desc);
        }
    }
    NavDialogRun(dlg);
    if (selectedFilter) {
        NavMenuItemSpec navSpec;
        bzero(&navSpec, sizeof(NavMenuItemSpec));
        qt_mac_filter_name *sel_filt_name = makeFiltersList(*selectedFilter).at(0);
        for (int i = 0; i < filts.count(); ++i) {
            const qt_mac_filter_name *filter = filts.at(i);
            if (sel_filt_name->description == filter->description
                    && sel_filt_name->regxp == filter->regxp
                    && sel_filt_name->filter == filter->filter) {
                navSpec.menuType = i;
                break;
            }
        }
        NavCustomControl(dlg, kNavCtlSelectCustomType, &navSpec);
    }
    if(options.modality == kWindowModalityWindowModal) { //simulate modality
        QWidget modal_widg(parent, __FILE__ "__modal_dlg",
                           Qt::WType_TopLevel | Qt::WStyle_Customize | Qt::WStyle_DialogBorder);
        modal_widg.createWinId();
        QApplicationPrivate::enterModal(&modal_widg);
        while(g_nav_blocking)
            qApp->processEvents(QEventLoop::WaitForMoreEvents);
        QApplicationPrivate::leaveModal(&modal_widg);
    }

    if(NavDialogGetUserAction(dlg) != kNavUserActionSaveAs) {
        NavDialogDispose(dlg);
        return retstr;
    }
    NavReplyRecord ret;
    NavDialogGetReply(dlg, &ret);
    NavDialogDispose(dlg);

    long count;
    err = AECountItems(&(ret.selection), &count);
    if(!ret.validRecord || err != noErr || !count) {
        NavDisposeReply(&ret);
        return retstr;
    }

    AEKeyword        keyword;
    DescType    type;
    Size        size;
    FSRef ref;
    err = AEGetNthPtr(&(ret.selection), 1, typeFSRef, &keyword,
                      &type, &ref, sizeof(ref), &size);
    if(err == noErr) {
        if(!str_buffer) {
            qAddPostRoutine(cleanup_str_buffer);
            str_buffer = (UInt8 *)malloc(1024);
        }
        FSRefMakePath(&ref, str_buffer, 1024);
        retstr = QString::fromUtf8((const char *)str_buffer);
        //now filename
        CFStringGetCString(ret.saveFileName, (char *)str_buffer, 1024, kCFStringEncodingUTF8);
        retstr += QLatin1Char('/') + QString::fromUtf8((const char *)str_buffer);
    }
    NavDisposeReply(&ret);
    if(selectedFilter)
        *selectedFilter = filts.at(t.index)->filter;
    while (!filts.isEmpty())
        delete filts.takeFirst();
    return retstr;
}
CFURLRef GetSaveDialogForUser(char* title, char* message)
{
	NavDialogCreationOptions dialogOptions;
	FSRef output_file;
	CFURLRef fileAsCFURLRef = NULL;
	OSStatus status;
	CFAllocatorRef alloc_default = kCFAllocatorDefault;
	
	
	AEKeyword keyword;
	DescType actual_type;
	Size actual_size;
	FSRef output_dir;
	NavReplyRecord reply;
	CFIndex len;

	// Get the standard set of defaults
	status = NavGetDefaultDialogCreationOptions( &dialogOptions );
	require_noerr( status, CantGetNavOptions );

	dialogOptions.optionFlags = kNavNoTypePopup + kNavSupportPackages + kNavAllowOpenPackages;

	  // = NULL;

	if (title != NULL) {
		CFStringRef cftitle = CFStringCreateWithCString(alloc_default,title,kCFStringEncodingMacRoman);
		dialogOptions.windowTitle = cftitle;
	}

	if (message != NULL) {
		CFStringRef cfmessage = CFStringCreateWithCString(alloc_default,message,kCFStringEncodingMacRoman);
		dialogOptions.message = cfmessage;
	}
	// Make the window app-wide modal
	dialogOptions.modality = kWindowModalityAppModal;

	NavDialogRef dialog;
	status = NavCreatePutFileDialog ( &dialogOptions, NULL, NULL, NULL, NULL, &dialog);
	require_noerr( status, CantCreateDialog );

	status = NavDialogRun(dialog);
	require_noerr( status, CantRunDialog );

	// get dialog reply
	status = NavDialogGetReply(dialog, &reply);
	require( ((status == noErr) || (status == userCanceledErr)), CantGetReply );

	//get file directory
	status = AEGetNthPtr(&(reply.selection), 1, typeFSRef, &keyword, &actual_type,
						 &output_dir, sizeof(output_file), &actual_size);
	require_noerr( status, CantExtractFSRef );

	UInt8 output_dir_name[1024];
	FSRefMakePath(&output_dir, output_dir_name, 1024 );

	// now get filename
	len = CFStringGetLength(reply.saveFileName);
	if (len > 255)
		len = 255;
	UniChar output_filename[255];
	CFStringGetCharacters(reply.saveFileName, CFRangeMake(0, len), output_filename);

	// need to unlink the old file
	if ( reply.replacing )
	{
		FSRef oldfile;

		status = FSMakeFSRefUnicode(&output_dir, len, output_filename,
								 kTextEncodingUnicodeDefault,
								 &oldfile);
		if (status == noErr) status = FSDeleteObject(&oldfile);
		//overwrite failed!
		require_noerr( status, UserCanceled );
	}

	//create fsref again to new file (NOTE: this actually makes a file...)
	status = FSCreateFileUnicode( &output_dir, len, output_filename, kFSCatInfoNone,
								 NULL, &output_file, NULL );
	require_noerr( status, CantExtractFSRef );

	// Convert it to a CFURL
	fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &output_file);

CantExtractFSRef:
UserCanceled:
	verify_noerr( NavDisposeReply(&reply) );
CantGetReply:
CantRunDialog:
	// cleanup dialog
	NavDialogDispose(dialog);
CantCreateDialog:
CantGetNavOptions:
    return fileAsCFURLRef;
}
Пример #8
0
OSStatus	LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
{
	OSStatus		error = noErr;
	NavDialogRef	navRef = NULL;
	NavReplyRecord	navReply;
	
	memset(&navReply, 0, sizeof(navReply));
	
	// Setup the type, creator, and extension
	OSType		type, creator;
	CFStringRef	extension = NULL;
	switch (filter)
	{
		case FFSAVE_WAV:
			type = 'WAVE';
			creator = 'TVOD';
			extension = CFSTR(".wav");
			break;
		
		case FFSAVE_TGA:
			type = 'TPIC';
			creator = 'prvw';
			extension = CFSTR(".tga");
			break;
		
		case FFSAVE_BMP:
			type = 'BMPf';
			creator = 'prvw';
			extension = CFSTR(".bmp");
			break;
		case FFSAVE_JPEG:
			type = 'JPEG';
			creator = 'prvw';
			extension = CFSTR(".jpeg");
			break;
		case FFSAVE_PNG:
			type = 'PNG ';
			creator = 'prvw';
			extension = CFSTR(".png");
			break;
		case FFSAVE_AVI:
			type = '\?\?\?\?';
			creator = '\?\?\?\?';
			extension = CFSTR(".mov");
			break;

		case FFSAVE_ANIM:
			type = '\?\?\?\?';
			creator = '\?\?\?\?';
			extension = CFSTR(".xaf");
			break;

#ifdef _CORY_TESTING
		case FFSAVE_GEOMETRY:
			type = '\?\?\?\?';
			creator = '\?\?\?\?';
			extension = CFSTR(".slg");
			break;
#endif		
		case FFSAVE_RAW:
			type = '\?\?\?\?';
			creator = '\?\?\?\?';
			extension = CFSTR(".raw");
			break;

		case FFSAVE_J2C:
			type = '\?\?\?\?';
			creator = 'prvw';
			extension = CFSTR(".j2c");
			break;
		
		case FFSAVE_ALL:
		default:
			type = '\?\?\?\?';
			creator = '\?\?\?\?';
			extension = CFSTR("");
			break;
	}
	
	// Create the dialog
	error = NavCreatePutFileDialog(&mNavOptions, type, creator, NULL, NULL, &navRef);
	if (error == noErr)
	{
		CFStringRef	nameString = NULL;
		bool		hasExtension = true;
		
		// Create a CFString of the initial file name
		if (!filename.empty())
			nameString = CFStringCreateWithCString(NULL, filename.c_str(), kCFStringEncodingUTF8);
		else
			nameString = CFSTR("Untitled");
			
		// Add the extension if one was not provided
		if (nameString && !CFStringHasSuffix(nameString, extension))
		{
			CFStringRef	tempString = nameString;
			hasExtension = false;
			nameString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), tempString, extension);
			CFRelease(tempString);
		}
		
		// Set the name in the dialog
		if (nameString)
		{
			error = NavDialogSetSaveFileName(navRef, nameString);
			CFRelease(nameString);
		}
		else
		{
			error = paramErr;
		}
	}
	
	gViewerWindow->mWindow->beforeDialog();

	// Run the dialog
	if (error == noErr)
		error = NavDialogRun(navRef);

	gViewerWindow->mWindow->afterDialog();

	if (error == noErr)
		error = NavDialogGetReply(navRef, &navReply);
	
	if (navRef)
		NavDialogDispose(navRef);

	if (error == noErr && navReply.validRecord)
	{
		SInt32	count = 0;
		
		// AE indexes are 1 based...
		error = AECountItems(&navReply.selection, &count);
		if (count > 0)
		{
			// Get the FSRef to the containing folder
			FSRef		fsRef;
			AEKeyword	theAEKeyword;
			DescType	typeCode;
			Size		actualSize = 0;
			
			memset(&fsRef, 0, sizeof(fsRef));
			error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
			
			if (error == noErr)
			{
				char	path[PATH_MAX];		/*Flawfinder: ignore*/
				char	newFileName[SINGLE_FILENAME_BUFFER_SIZE];	/*Flawfinder: ignore*/
				
				error = FSRefMakePath(&fsRef, (UInt8*)path, PATH_MAX);
				if (error == noErr)
				{
					if (CFStringGetCString(navReply.saveFileName, newFileName, sizeof(newFileName), kCFStringEncodingUTF8))
					{
						mFiles.push_back(std::string(path) + "/" +  std::string(newFileName));
					}
					else
					{
						error = paramErr;
					}
				}
				else
				{
					error = paramErr;
				}
			}
		}
	}
	
	return error;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;	
}
Пример #12
0
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
};
Пример #13
0
//---------------------------------------------------------------------
// Gets a file to save from the user. Caller must release the CFURLRef.
//
CFURLRef GetSaveFileFromUser(WindowRef window)
{
	CFURLRef previousFile;
	CFStringRef saveFileName;
	UniChar *chars = NULL;
    CFIndex length;
	NavDialogCreationOptions dialogOptions;
	NavDialogRef dialog;
	NavReplyRecord replyRecord;
	CFURLRef fileAsCFURLRef = NULL;
	FSRef fileAsFSRef;
	FSRef parentDirectory;
	OSStatus status;

	if ( window == NULL ) return NULL;

	// Get the standard set of defaults
	status = NavGetDefaultDialogCreationOptions(&dialogOptions);
	require_noerr( status, CantGetNavOptions );

	// Change a few things (app-wide modal, show the extension)
	dialogOptions.modality = kWindowModalityAppModal;
	dialogOptions.parentWindow = window;
	dialogOptions.optionFlags = kNavDefaultNavDlogOptions | kNavPreserveSaveFileExtension;

	// Set up the default save name
	previousFile = GetWindowProxyFileCFURL(window);
	if (previousFile == NULL)
		dialogOptions.saveFileName = CFStringCreateWithCString(NULL, "Untitled.rtf", kCFStringEncodingASCII);
	else	
		dialogOptions.saveFileName = CFURLCopyLastPathComponent(previousFile);

	// Create the dialog
	status = NavCreatePutFileDialog(&dialogOptions, kUnknownType, kUnknownType, NULL, NULL, &dialog);
	require_noerr( status, CantCreateDialog );

	// Show it
	status = NavDialogRun(dialog);
	require_noerr( status, CantRunDialog );
	
	// Get the reply
	status = NavDialogGetReply(dialog, &replyRecord);
	require( ((status == noErr) || (status == userCanceledErr)), CantGetReply );

	// If the user clicked "Cancel", just bail
	if ( status == userCanceledErr ) goto UserCanceled;

	// Get the file's location and name
	status = AEGetNthPtr(&(replyRecord.selection), 1, typeFSRef, NULL, NULL, &parentDirectory, sizeof(FSRef), NULL);
	require_noerr( status, CantExtractFSRef );

	saveFileName = replyRecord.saveFileName;
    length = CFStringGetLength(saveFileName);
	chars = malloc(length * sizeof(UniChar));
	CFStringGetCharacters(saveFileName, CFRangeMake(0, length), chars);

    // If we are replacing a file, erase the previous one
    if ( replyRecord.replacing ) {

		status = FSMakeFSRefUnicode(&parentDirectory, length, chars, kTextEncodingUnknown, &fileAsFSRef);
		require_noerr( status, CantMakeFSRef );

        status = FSDeleteObject(&fileAsFSRef);
		require_noerr( status, CantDeletePreviousFile );
    }

    // Create the file
	status = FSCreateFileUnicode(&parentDirectory, length, chars, kFSCatInfoNone, NULL, &fileAsFSRef, NULL);
	require_noerr( status, CantCreateSaveFile );

	// Convert the reference to the file to a CFURL
	fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &fileAsFSRef);

	// Cleanup
CantCreateSaveFile:
CantDeletePreviousFile:
CantMakeFSRef:
	if ( chars != NULL ) free(chars);
CantExtractFSRef:
UserCanceled:
	verify_noerr( NavDisposeReply(&replyRecord) );
CantGetReply:
CantRunDialog:
	NavDialogDispose(dialog);
CantCreateDialog:
	if (previousFile) CFRelease(previousFile);
	CFRelease(dialogOptions.saveFileName);
CantGetNavOptions:
    return fileAsCFURLRef;
}
Пример #14
0
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;	
}
Пример #15
0
Boolean AskUserForPutFileName(char* promptStr, char* defaultName, char* pathOfFileSelected, short maxPathLength, FSSpec *specPtr, MyCustomNavItemsData *myCustomItemsDataPtr)
{
	OSStatus err = 0;
	
	NavDialogCreationOptions  dialogOptions;
   	OSType inFileType = 'TEXT'; // what will happen if we always just say TEXT and change our mind later ? (perhaps it will add .txt) ?
   	OSType inFileCreator = kNavGenericSignature;
	NavEventUPP inEventProc = 0;
	Ptr inClientData = (Ptr)myCustomItemsDataPtr;
	NavDialogRef navDialogRef = 0;
	NavReplyRecord replyRecord;
	Boolean gotReply = false;
	
	FSSpec fsSpec;
	char pathName[256]="";
	char theFileName[256]="";
	
	CFStringRef windowTitleCFStrRef = 0;
	CFStringRef clientNameCFStrRef = 0;
	CFStringRef saveFileNameCFStrRef = 0;
	
	if(specPtr) memset(specPtr,0,sizeof(specPtr));
	if(pathOfFileSelected && maxPathLength > 0) pathOfFileSelected[0] = 0;
	
	err = NavGetDefaultDialogCreationOptions(&dialogOptions);
	if(err) return false;
	
	// for now don't customize the dialogs, may want to do this later
	/*if(myCustomItemsDataPtr && myCustomItemsDataPtr->ditlResID) {
		inEventProc = GetMyNavEventHandlerUPP();
	}*/

	if(promptStr && promptStr[0]) {
		windowTitleCFStrRef = CFStringCreateWithCString(NULL, promptStr,kCFStringEncodingMacRoman);
		dialogOptions.windowTitle = windowTitleCFStrRef;
	}
	
	// set the client name so the system can remember the last place the user looked
	clientNameCFStrRef  = CFStringCreateWithCString(NULL,"GNOME",kCFStringEncodingMacRoman);
	dialogOptions.clientName = clientNameCFStrRef;
	
	if(defaultName && defaultName[0]) {
		saveFileNameCFStrRef = CFStringCreateWithCString(NULL, defaultName,kCFStringEncodingMacRoman);
		dialogOptions.saveFileName = saveFileNameCFStrRef;
	}
	
	//err = NavCreatePutFileDialog(&dialogOptions,inFileType,inFileCreator,inEventProc,inClientData,&navDialogRef);
	err = NavCreatePutFileDialog(&dialogOptions,inFileType,inFileCreator,inEventProc,NULL,&navDialogRef);
	if(err) return false;
	
	InitCursor();
	err = NavDialogRun(navDialogRef);
	SetWatchCursor();
	if(err) goto done;
	
	err = NavDialogGetReply(navDialogRef,&replyRecord);
	if(err) goto done;
	
	gotReply = true;
	
	err = AEGetNthPtr(&(replyRecord.selection), 1, typeFSS, NULL, NULL, &fsSpec, sizeof(fsSpec), NULL);
	if(err) goto done;
	
	(void)PathNameFromDirID(fsSpec.parID,fsSpec.vRefNum,pathName); // GetPathWithDelimiterFromDirID
	mypstrcatJM((StringPtr)pathName,fsSpec.name);
	my_p2cstr(pathName);
	
	(void)CFStringGetCString(replyRecord.saveFileName,theFileName,256,kCFStringEncodingMacRoman);
	
	if( (strlen(pathName) + 1 + strlen(theFileName)) < maxPathLength){
		strcpy(pathOfFileSelected,pathName);
		strcat(pathOfFileSelected,":");
		strcat(pathOfFileSelected,theFileName);
	}
	else  {
		err = -1; // path is too long to return
	}
	
	if(!err && specPtr)  *specPtr = fsSpec;
	
done:
	if(windowTitleCFStrRef) { CFRelease(windowTitleCFStrRef);  windowTitleCFStrRef = 0;}
	if(clientNameCFStrRef) { CFRelease(clientNameCFStrRef);  clientNameCFStrRef = 0;}
	if(saveFileNameCFStrRef) { CFRelease(saveFileNameCFStrRef);  saveFileNameCFStrRef = 0;}

	if(gotReply) NavDisposeReply(&replyRecord);
	
	NavDialogDispose(navDialogRef);
	
	if(gotReply && !err) return true;
	return false;
 	
}