]> git.saurik.com Git - wxWidgets.git/blame - src/mac/filedlg.cpp
several mac fixes (Mark Newsams patches)
[wxWidgets.git] / src / mac / filedlg.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: filedlg.cpp
2f1ae414 3// Purpose: wxFileDialog
e9576ca5
SC
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "filedlg.h"
14#endif
15
16#include "wx/defs.h"
5fde6fcc 17#include "wx/app.h"
e9576ca5
SC
18#include "wx/utils.h"
19#include "wx/dialog.h"
20#include "wx/filedlg.h"
21#include "wx/intl.h"
22
03e11df5
GD
23#if !defined(__UNIX__)
24 #include "PLStringFuncs.h"
25#endif
5b781a67 26
2f1ae414 27#if !USE_SHARED_LIBRARY
e9576ca5 28IMPLEMENT_CLASS(wxFileDialog, wxDialog)
2f1ae414 29#endif
e9576ca5 30
519cb848
SC
31// begin wxmac
32
03e11df5 33#if defined(__UNIX__)
5fde6fcc 34 #include <Carbon/Carbon.h>
03e11df5
GD
35#else
36 #include <Navigation.h>
37#endif
5b781a67 38
03e11df5
GD
39#ifndef __UNIX__
40 #include "morefile.h"
41 #include "moreextr.h"
42 #include "fullpath.h"
43 #include "fspcompa.h"
44 #include "PLStringFuncs.h"
45#endif
519cb848 46
5b781a67
SC
47extern bool gUseNavServices ;
48
4d4d8bbf
SC
49// the data we need to pass to our standard file hook routine
50// includes a pointer to the dialog, a pointer to the standard
51// file reply record (so we can inspect the current selection)
52// and a copy of the "previous" file spec of the reply record
53// so we can see if the selection has changed
54
55const int kwxMacFileTypes = 10 ;
56
57struct OpenUserDataRec {
58 int currentfilter ;
59 wxString name [kwxMacFileTypes] ;
60 wxString extensions[kwxMacFileTypes] ;
61 OSType filtermactypes[kwxMacFileTypes] ;
62 int numfilters ;
63};
64typedef struct OpenUserDataRec
65 OpenUserDataRec, *OpenUserDataRecPtr;
66
5b781a67
SC
67static pascal void NavEventProc(
68 NavEventCallbackMessage inSelector,
69 NavCBRecPtr ioParams,
70 NavCallBackUserData ioUserData);
71
72#if TARGET_CARBON
73 static NavEventUPP sStandardNavEventFilter = NewNavEventUPP(NavEventProc);
74#else
75 static NavEventUPP sStandardNavEventFilter = NewNavEventProc(NavEventProc);
76#endif
77
78static pascal void
79NavEventProc(
80 NavEventCallbackMessage inSelector,
81 NavCBRecPtr ioParams,
4d4d8bbf 82 NavCallBackUserData ioUserData )
5b781a67 83{
4d4d8bbf 84 OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ;
5b781a67
SC
85 if (inSelector == kNavCBEvent) {
86 // In Universal Headers 3.2, Apple changed the definition of
87 /*
88 #if UNIVERSAL_INTERFACES_VERSION >= 0x0320 // Universal Headers 3.2
89 UModalAlerts::ProcessModalEvent(*(ioParams->eventData.eventDataParms.event));
90
91 #else
92 UModalAlerts::ProcessModalEvent(*(ioParams->eventData.event));
93 #endif
94 */
95
5fde6fcc 96 wxTheApp->MacHandleOneEvent(ioParams->eventData.eventDataParms.event);
4d4d8bbf
SC
97 } else if ( inSelector == kNavCBPopupMenuSelect )
98 {
99 NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ;
100 data->currentfilter = menu->menuType ;
5b781a67
SC
101 }
102}
103
519cb848
SC
104char * gfilters[] =
105{
106 "*.TXT" ,
4d4d8bbf
SC
107 "*.TIF" ,
108 "*.JPG" ,
519cb848
SC
109
110 NULL
111} ;
112
113OSType gfiltersmac[] =
114{
115 'TEXT' ,
4d4d8bbf
SC
116 'TIFF' ,
117 'JPEG' ,
519cb848
SC
118
119 '****'
120} ;
121
2f1ae414
SC
122
123#if !TARGET_CARBON
124
519cb848
SC
125static void wxMacSetupStandardFile(short newVRefNum, long newDirID)
126{
127 enum
128 { SFSaveDisk = 0x214, CurDirStore = 0x398 };
129 *(short *) SFSaveDisk = -1 * newVRefNum;
130 *(long *) CurDirStore = newDirID;
131}
132
133static void wxMacSetupStandardFileFromPath( const char* s )
134{
135 Str255 volume ;
136 Str255 path ;
137 short vRefNum ;
138 long dirRef ;
139 short i,j ;
140 Boolean isDirectory ;
141
142 for (i=0 ; (s[i]!=0) && (s[i]!=':') ;i++)
143 {
144 volume[i]=s[i] ;
145 }
146 volume[i]=':' ;
147 volume[i+1]=0 ;
148
149 // then copy the rest of the filename
150
151 for (j=0;(s[i]!=0);i++,j++)
152 {
153 path[j]=s[i] ;
154 }
155 path[j]=0 ;
156
157 c2pstr((Ptr) volume) ;
158 c2pstr((Ptr) path) ;
159
160 SetVol(volume, 0) ;
161 GetVol( NULL, &vRefNum ) ;
162
163 GetDirectoryID( vRefNum , fsRtDirID , path , &dirRef , &isDirectory ) ;
164 wxMacSetupStandardFile(vRefNum, dirRef) ;
165}
166
167enum {
168 kSelectItem = 10, // select button item number
169 kSFGetFileDlgID = 251, // dialog resource number
170 kStrListID = 251, // our strings
171 kSelectStrNum = 1, // word 'Select: ' for button
172 kDesktopStrNum = 2, // word 'Desktop' for button
173 kSelectNoQuoteStrNum = 3, // word 'Select: ' for button
174
175 kUseQuotes = true, // parameter for SetButtonName
176 kDontUseQuotes = false
177};
178
519cb848
SC
179static void GetLabelString(StringPtr theStr, short stringNum)
180{
181 GetIndString(theStr, kStrListID, stringNum);
182}
183
184static void CopyPStr(StringPtr src, StringPtr dest)
185{
186 BlockMoveData(src, dest, 1 + src[0]);
187}
188
189static char GetSelectKey(void)
190{
191 // this is the key used to trigger the select button
192
193 // NOT INTERNATIONAL SAVVY; should at least grab it from resources
194
195 return 's';
196}
197
198// FlashButton briefly highlights the dialog button
199// as feedback for key equivalents
200
201static void FlashButton(DialogPtr theDlgPtr, short buttonID)
202{
203 short buttonType;
204 Handle buttonHandle;
205 Rect buttonRect;
206 unsigned long finalTicks;
207
208 GetDialogItem(theDlgPtr, buttonID, &buttonType, &buttonHandle, &buttonRect);
209 HiliteControl((ControlHandle) buttonHandle, kControlButtonPart);
210 Delay(10, &finalTicks);
211 HiliteControl((ControlHandle) buttonHandle, 0);
212}
213
214static Boolean SameFSSpec(FSSpecPtr spec1, FSSpecPtr spec2)
215{
216 return (spec1->vRefNum == spec2->vRefNum
217 && spec1->parID == spec2->parID
218 && EqualString(spec1->name, spec2->name, false, false));
219}
220// MyModalDialogFilter maps a key to the Select button, and handles
221// flashing of the button when the key is hit
222
223static pascal Boolean SFGetFolderModalDialogFilter(DialogPtr theDlgPtr, EventRecord *eventRec,
5fde6fcc 224 short *item, void *dataPtr)
519cb848
SC
225{
226#pragma unused (dataPtr)
227
228 // make certain the proper dialog is showing, 'cause standard file
229 // can nest dialogs but calls the same filter for each
230
231 if (((WindowPeek) theDlgPtr)->refCon == sfMainDialogRefCon)
232 {
233 // check if the select button was hit
234 /*
235 if ((eventRec->what == keyDown)
236 && (eventRec->modifiers & cmdKey)
237 && ((eventRec->message & charCodeMask) == GetSelectKey()))
238 {
239 *item = kSelectItem;
240 FlashButton(theDlgPtr, kSelectItem);
241 return true;
242 }
243 */
244 }
245
246 return false;
247}
5b781a67 248#endif !TARGET_CARBON
519cb848 249
4d4d8bbf
SC
250void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter )
251{
252 myData->currentfilter = 0 ;
253
254 if ( filter && filter[0] )
255 {
256 wxString filter2(filter) ;
257 int filterIndex = 0;
258 bool isName = true ;
259 wxString current ;
260 for( unsigned int i = 0; i < filter2.Len(); i++ )
261 {
262 if( filter2.GetChar(i) == wxT('|') )
263 {
264 if( isName ) {
265 myData->name[filterIndex] = current ;
266 }
267 else {
268 myData->extensions[filterIndex] = current.MakeUpper() ;
269 ++filterIndex ;
270 }
271 isName = !isName ;
272 current = "" ;
273 }
274 else
275 {
276 current += filter2.GetChar(i) ;
277 }
278 }
279 if ( filterIndex > 0 )
280 {
281 wxASSERT_MSG( !isName , "incorrect format of format string" ) ;
282 myData->extensions[filterIndex] = current.MakeUpper() ;
283 ++filterIndex ;
284 }
285
286 myData->numfilters = filterIndex ;
287 for ( int i = 0 ; i < myData->numfilters ; i++ )
288 {
289 int j ;
290 for ( j = 0 ; gfilters[j] ; j++ )
291 {
292 if ( strcmp( myData->extensions[i] , gfilters[j] ) == 0 )
293 {
294 myData->filtermactypes[i] = gfiltersmac[j] ;
295 break ;
296 }
297 }
298 if( gfilters[j] == NULL )
299 {
300 myData->filtermactypes[i] = '****' ;
301 }
302 }
303 }
304 else
305 {
306 myData->numfilters = 0 ;
307 }
308
309}
310void ExtendedOpenFile( ConstStr255Param message , ConstStr255Param path , const char *filter , FileFilterYDUPP fileFilter, StandardFileReply *theSFR )
519cb848
SC
311{
312 Point thePt;
313 OpenUserDataRec myData;
314 FSSpec tempSpec;
315 Boolean folderFlag;
316 Boolean wasAliasedFlag;
317 DlgHookYDUPP dlgHookUPP;
318 ModalFilterYDUPP myModalFilterUPP;
319 OSErr err;
320 SFTypeList types ;
321
322
323 // presumably we're running System 7 or later so CustomGetFile is
324 // available
325
326 // set initial contents of Select button to a space
327
2f1ae414 328 memcpy( theSFR->sfFile.name , "\p " , 2 ) ;
519cb848
SC
329
330 // point the user data parameter at the reply record so we can get to it later
331
4d4d8bbf 332 MakeUserDataRec( &myData , filter ) ;
519cb848 333 // display the dialog
2f1ae414
SC
334
335#if !TARGET_CARBON
519cb848
SC
336
337 dlgHookUPP = NULL ;
338// dlgHookUPP = NewDlgHookYDProc(SFGetFolderDialogHook);
339 myModalFilterUPP = NewModalFilterYDProc(SFGetFolderModalDialogFilter);
340
341 thePt.h = thePt.v = -1; // center dialog
342
343 ParamText( message , NULL , NULL , NULL ) ;
344
345 CustomGetFile( fileFilter,
346 -1, // show all types
347 NULL,
348 theSFR,
349 kSFGetFileDlgID,
350 thePt, // top left point
351 dlgHookUPP,
352 myModalFilterUPP,
353 nil, // activate list
354 nil, // activate proc
355 &myData);
356
357 DisposeRoutineDescriptor(dlgHookUPP);
358 DisposeRoutineDescriptor(myModalFilterUPP);
2f1ae414
SC
359#else
360#endif
519cb848
SC
361 // if cancel wasn't pressed and no fatal error occurred...
362
363 if (theSFR->sfGood)
364 {
365 // if no name is in the reply record file spec,
366 // use the file spec of the parent folder
367
368 if (theSFR->sfFile.name[0] == '\0')
369 {
370 err = FSMakeFSSpec(theSFR->sfFile.vRefNum, theSFR->sfFile.parID,
371 "\p", &tempSpec);
372 if (err == noErr)
373 {
374 theSFR->sfFile = tempSpec;
375 }
376 else
377 {
378 // no name to return, forget it
379
380 theSFR->sfGood = false;
381 }
382 }
383
384 // if there is now a name in the file spec, check if it's
385 // for a folder or a volume
386
387 if (theSFR->sfFile.name[0] != '\0')
388 {
389 // the parID of the root of a disk is always fsRtParID == 1
390
391 if (theSFR->sfFile.parID == fsRtParID)
392 {
393 theSFR->sfIsVolume = true;
394 theSFR->sfIsFolder = false; // it would be reasonable for this to be true, too
395 }
396
397 // we have a valid FSSpec, now let's make sure it's not for an alias file
398
399 err = ResolveAliasFile(&theSFR->sfFile, true, &folderFlag, &wasAliasedFlag);
400 if (err != noErr)
401 {
402 theSFR->sfGood = false;
403 }
404
405 // did the alias resolve to a folder?
406
407 if (folderFlag && ! theSFR->sfIsVolume)
408 {
409 theSFR->sfIsFolder = true;
410 }
411 }
412 }
413}
414
4d4d8bbf
SC
415static Boolean CheckFile( ConstStr255Param name , OSType type , OpenUserDataRecPtr data)
416{
417 Str255 filename ;
418 PLstrcpy( filename , name ) ;
419
420 if ( data->numfilters > 0 )
421 {
422 for( int j = 1 ; j <= filename[0] ; j++ )
423 {
424 filename[j] = toupper( filename[j] ) ;
425 }
426 //for ( int i = 0 ; i < data->numfilters ; ++i )
427 int i = data->currentfilter ;
428 if ( data->extensions[i].Right(2) == ".*" )
429 return true ;
430
431 {
432 if ( type == data->filtermactypes[i] )
433 return true ;
434
435 wxString extension = data->extensions[i] ;
436 if ( extension.GetChar(0) == '*' )
437 extension = extension.Mid(1) ;
438
439 if ( filename[0] >= extension.Len() && extension == (char*) filename + 1 + filename[0] - extension.Len() )
440 return true ;
441 }
442 return false ;
443 }
444 return true ;
445}
446
5fde6fcc 447static pascal Boolean CrossPlatformFileFilter(CInfoPBPtr myCInfoPBPtr, void *dataPtr)
519cb848 448{
519cb848
SC
449 OpenUserDataRecPtr data = (OpenUserDataRecPtr) dataPtr ;
450 // return true if this item is invisible or a file
451
452 Boolean visibleFlag;
453 Boolean folderFlag;
454
455 visibleFlag = ! (myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible);
456 folderFlag = (myCInfoPBPtr->hFileInfo.ioFlAttrib & 0x10);
457
458 // because the semantics of the filter proc are "true means don't show
459 // it" we need to invert the result that we return
460
461 if ( !visibleFlag )
462 return true ;
463
464 if ( !folderFlag )
465 {
4d4d8bbf 466 return !CheckFile( myCInfoPBPtr->hFileInfo.ioNamePtr , myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdType , data ) ;
519cb848
SC
467 }
468
469 return false ;
470}
471
472// end wxmac
473
474wxString wxFileSelector(const char *title,
e9576ca5
SC
475 const char *defaultDir, const char *defaultFileName,
476 const char *defaultExtension, const char *filter, int flags,
477 wxWindow *parent, int x, int y)
478{
479 // If there's a default extension specified but no filter, we create a suitable
480 // filter.
481
482 wxString filter2("");
483 if ( defaultExtension && !filter )
484 filter2 = wxString("*.") + wxString(defaultExtension) ;
485 else if ( filter )
486 filter2 = filter;
487
488 wxString defaultDirString;
489 if (defaultDir)
490 defaultDirString = defaultDir;
491 else
492 defaultDirString = "";
493
494 wxString defaultFilenameString;
495 if (defaultFileName)
496 defaultFilenameString = defaultFileName;
497 else
498 defaultFilenameString = "";
499
500 wxFileDialog fileDialog(parent, title, defaultDirString, defaultFilenameString, filter2, flags, wxPoint(x, y));
501
502 if ( fileDialog.ShowModal() == wxID_OK )
503 {
504 strcpy(wxBuffer, (const char *)fileDialog.GetPath());
505 return wxBuffer;
506 }
507 else
8be97d65 508 return wxGetEmptyString();
e9576ca5
SC
509}
510
169935ad 511WXDLLEXPORT wxString wxFileSelectorEx(const char *title,
e9576ca5
SC
512 const char *defaultDir,
513 const char *defaultFileName,
514 int* defaultFilterIndex,
515 const char *filter,
516 int flags,
517 wxWindow* parent,
518 int x,
519 int y)
520
521{
522 wxFileDialog fileDialog(parent, title ? title : "", defaultDir ? defaultDir : "",
523 defaultFileName ? defaultFileName : "", filter ? filter : "", flags, wxPoint(x, y));
524
525 if ( fileDialog.ShowModal() == wxID_OK )
526 {
527 *defaultFilterIndex = fileDialog.GetFilterIndex();
528 strcpy(wxBuffer, (const char *)fileDialog.GetPath());
529 return wxBuffer;
530 }
531 else
8be97d65 532 return wxGetEmptyString();
e9576ca5
SC
533}
534
535wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
536 const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
537 long style, const wxPoint& pos)
538{
539 m_message = message;
540 m_dialogStyle = style;
541 m_parent = parent;
542 m_path = "";
543 m_fileName = defaultFileName;
544 m_dir = defaultDir;
545 m_wildCard = wildCard;
546 m_filterIndex = 1;
547}
548
4d4d8bbf
SC
549
550Boolean CrossPlatformFilterCallback (
551 AEDesc *theItem,
552 void *info,
553 void *callBackUD,
554 NavFilterModes filterMode
555)
556{
557 bool display = true;
558 OpenUserDataRecPtr data = (OpenUserDataRecPtr) callBackUD ;
559
560 if (filterMode == kNavFilteringBrowserList)
561 {
562 NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*) info ;
563 if (theItem->descriptorType == typeFSS && !theInfo->isFolder)
564 {
565 FSSpec spec;
566 memcpy( &spec , *theItem->dataHandle , sizeof(FSSpec) ) ;
567 display = CheckFile( spec.name , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ;
568 }
569 }
570
571 return display;
572}
573
e9576ca5
SC
574int wxFileDialog::ShowModal()
575{
5b781a67
SC
576 #if !TARGET_CARBON
577 if ( !gUseNavServices )
578 {
519cb848
SC
579 if ( m_dialogStyle & wxSAVE )
580 {
581 StandardFileReply reply ;
582 Str255 prompt ;
583 Str255 filename ;
584
03e11df5
GD
585#if TARGET_CARBON
586 c2pstrcpy((StringPtr)prompt, m_message) ;
587#else
519cb848
SC
588 strcpy((char *)prompt, m_message) ;
589 c2pstr((char *)prompt ) ;
03e11df5
GD
590#endif
591#if TARGET_CARBON
592 c2pstrcpy((StringPtr)filename, m_fileName) ;
593#else
519cb848
SC
594 strcpy((char *)filename, m_fileName) ;
595 c2pstr((char *)filename ) ;
03e11df5
GD
596#endif
597
2f1ae414 598 #if !TARGET_CARBON
519cb848
SC
599
600 StandardPutFile( prompt , filename , &reply ) ;
2f1ae414
SC
601
602 #else
603 #endif
519cb848
SC
604 if ( reply.sfGood == false )
605 {
606 m_path = "" ;
607 return wxID_CANCEL ;
608 }
609 else
610 {
bedaf53e 611 m_path = wxMacFSSpec2MacFilename( &reply.sfFile ) ;
519cb848
SC
612 return wxID_OK ;
613 }
614 }
615 else
616 {
617 OSType types = '????' ;
618 Str255 prompt ;
619 Str255 path ;
620
03e11df5
GD
621#if TARGET_CARBON
622 c2pstrcpy((StringPtr)prompt, m_message) ;
623#else
519cb848
SC
624 strcpy((char *)prompt, m_message) ;
625 c2pstr((char *)prompt ) ;
03e11df5
GD
626#endif
627#if TARGET_CARBON
628 c2pstrcpy((StringPtr)path, m_dir ) ;
629#else
630 strcpy((char *)path, m_dir ) ;
519cb848 631 c2pstr((char *)path ) ;
03e11df5 632#endif
519cb848 633
519cb848 634 StandardFileReply reply ;
2f1ae414
SC
635 FileFilterYDUPP crossPlatformFileFilterUPP = 0 ;
636 #if !TARGET_CARBON
519cb848
SC
637 crossPlatformFileFilterUPP =
638 NewFileFilterYDProc(CrossPlatformFileFilter);
2f1ae414 639 #endif
519cb848
SC
640
641 ExtendedOpenFile( prompt , path , m_wildCard , crossPlatformFileFilterUPP, &reply);
2f1ae414
SC
642 #if !TARGET_CARBON
643 DisposeFileFilterYDUPP(crossPlatformFileFilterUPP);
644 #endif
519cb848
SC
645 if ( reply.sfGood == false )
646 {
647 m_path = "" ;
648 return wxID_CANCEL ;
649 }
650 else
651 {
bedaf53e 652 m_path = wxMacFSSpec2MacFilename( &reply.sfFile ) ;
519cb848
SC
653 return wxID_OK ;
654 }
655 }
e9576ca5
SC
656 return wxID_CANCEL;
657}
5b781a67
SC
658 else
659#endif
660 {
661 NavDialogOptions mNavOptions;
662 NavObjectFilterUPP mNavFilterUPP = NULL;
663 NavPreviewUPP mNavPreviewUPP = NULL ;
664 NavReplyRecord mNavReply;
665 AEDesc mDefaultLocation ;
666 bool mSelectDefault = false ;
667
668 ::NavGetDefaultDialogOptions(&mNavOptions);
669
670 mNavFilterUPP = nil;
671 mNavPreviewUPP = nil;
672 mSelectDefault = false;
673 mNavReply.validRecord = false;
674 mNavReply.replacing = false;
675 mNavReply.isStationery = false;
676 mNavReply.translationNeeded = false;
677 mNavReply.selection.descriptorType = typeNull;
678 mNavReply.selection.dataHandle = nil;
679 mNavReply.keyScript = smSystemScript;
680 mNavReply.fileTranslation = nil;
681
682 // Set default location, the location
683 // that's displayed when the dialog
684 // first appears
685
686 FSSpec location ;
bedaf53e 687 wxMacFilename2FSSpec( m_dir , &location ) ;
5b781a67
SC
688 OSErr err = noErr ;
689
690 mDefaultLocation.descriptorType = typeNull;
691 mDefaultLocation.dataHandle = nil;
692
693 err = ::AECreateDesc(typeFSS, &location, sizeof(FSSpec), &mDefaultLocation );
694
695 if ( mDefaultLocation.dataHandle ) {
696
697 if (mSelectDefault) {
698 mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
699 } else {
700 mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation;
701 }
702 }
703
03e11df5
GD
704#if TARGET_CARBON
705 c2pstrcpy((StringPtr)mNavOptions.message, m_message) ;
706#else
5b781a67
SC
707 strcpy((char *)mNavOptions.message, m_message) ;
708 c2pstr((char *)mNavOptions.message ) ;
03e11df5
GD
709#endif
710#if TARGET_CARBON
711 c2pstrcpy((StringPtr)mNavOptions.savedFileName, m_fileName) ;
712#else
5b781a67
SC
713 strcpy((char *)mNavOptions.savedFileName, m_fileName) ;
714 c2pstr((char *)mNavOptions.savedFileName ) ;
03e11df5 715#endif
5b781a67
SC
716
717 if ( m_dialogStyle & wxSAVE )
718 {
719
720 mNavOptions.dialogOptionFlags |= kNavNoTypePopup ;
721 mNavOptions.dialogOptionFlags |= kNavDontAutoTranslate ;
722 mNavOptions.dialogOptionFlags |= kNavDontAddTranslateItems ;
723
724 err = ::NavPutFile(
725 &mDefaultLocation,
726 &mNavReply,
727 &mNavOptions,
728 sStandardNavEventFilter ,
729 'TEXT',
730 'TEXT',
731 0L); // User Data
732 }
733 else
734 {
4d4d8bbf
SC
735 OpenUserDataRec myData;
736 MakeUserDataRec( &myData , m_wildCard ) ;
737 NavTypeListHandle typelist = NULL ;
738
739 if ( myData.numfilters > 0 )
740 {
741 mNavOptions.popupExtension = (NavMenuItemSpecArrayHandle) NewHandle( sizeof( NavMenuItemSpec ) * myData.numfilters ) ;
742 for ( int i = 0 ; i < myData.numfilters ; ++i ) {
743 (*mNavOptions.popupExtension)[i].version = kNavMenuItemSpecVersion ;
744 (*mNavOptions.popupExtension)[i].menuCreator = 'WXNG' ;
745 (*mNavOptions.popupExtension)[i].menuType = i ;
746 #if TARGET_CARBON
747 c2pstrcpy((StringPtr)(*mNavOptions.popupExtension)[i].menuItemName, myData.name[i]) ;
748 #else
749 strcpy((char *)(*mNavOptions.popupExtension)[i].menuItemName, myData.name[i]) ;
750 c2pstr((char *)(*mNavOptions.popupExtension)[i].menuItemName ) ;
751 #endif
752 }
753 }
754
755 mNavFilterUPP = NewNavObjectFilterProc( CrossPlatformFilterCallback ) ;
5b781a67
SC
756 if ( m_dialogStyle & wxMULTIPLE )
757 mNavOptions.dialogOptionFlags |= kNavAllowMultipleFiles ;
758 else
759 mNavOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles ;
760
761 err = ::NavGetFile(
762 &mDefaultLocation,
763 &mNavReply,
764 &mNavOptions,
765 sStandardNavEventFilter ,
766 mNavPreviewUPP,
767 mNavFilterUPP,
4d4d8bbf
SC
768 typelist /*inFileTypes.TypeListHandle() */,
769 &myData); // User Data
770 if ( typelist )
771 DisposeHandle( (Handle) typelist ) ;
5b781a67
SC
772 }
773
4d4d8bbf 774 DisposeNavObjectFilterUPP(mNavFilterUPP);
5b781a67
SC
775 if ( mDefaultLocation.dataHandle != nil )
776 {
777 ::AEDisposeDesc(&mDefaultLocation);
778 }
779
780 if ( (err != noErr) && (err != userCanceledErr) ) {
781 m_path = "" ;
782 return wxID_CANCEL ;
783 }
784
785 if (mNavReply.validRecord) {
786
787 FSSpec outFileSpec ;
788 AEDesc specDesc ;
789
790 long count ;
791 ::AECountItems( &mNavReply.selection , &count ) ;
792 for ( long i = 1 ; i <= count ; ++i )
793 {
794 OSErr err = ::AEGetNthDesc( &mNavReply.selection , i , typeFSS, NULL , &specDesc);
795 if ( err != noErr ) {
796 m_path = "" ;
797 return wxID_CANCEL ;
798 }
799 outFileSpec = **(FSSpec**) specDesc.dataHandle;
800 if (specDesc.dataHandle != nil) {
801 ::AEDisposeDesc(&specDesc);
802 }
803
804
805 // outFolderDirID = thePB.dirInfo.ioDrDirID;
bedaf53e 806 m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ;
5b781a67
SC
807 m_paths.Add( m_path ) ;
808 m_fileNames.Add(m_fileName);
809 }
810 // set these to the first hit
811 m_path = m_paths[ 0 ] ;
812 m_fileName = wxFileNameFromPath(m_path);
813 m_dir = wxPathOnly(m_path);
814
815 return wxID_OK ;
816 }
817 return wxID_CANCEL;
818 }
819}
e9576ca5
SC
820
821// Generic file load/save dialog
169935ad 822static wxString
e9576ca5
SC
823wxDefaultFileSelector(bool load, const char *what, const char *extension, const char *default_name, wxWindow *parent)
824{
825 char *ext = (char *)extension;
826
827 char prompt[50];
828 wxString str;
829 if (load)
830 str = "Load %s file";
831 else
832 str = "Save %s file";
833 sprintf(prompt, wxGetTranslation(str), what);
834
835 if (*ext == '.') ext++;
836 char wild[60];
837 sprintf(wild, "*.%s", ext);
838
839 return wxFileSelector (prompt, NULL, default_name, ext, wild, 0, parent);
840}
841
842// Generic file load dialog
169935ad 843wxString
e9576ca5
SC
844wxLoadFileSelector(const char *what, const char *extension, const char *default_name, wxWindow *parent)
845{
846 return wxDefaultFileSelector(TRUE, what, extension, default_name, parent);
847}
848
849
850// Generic file save dialog
169935ad 851wxString
e9576ca5
SC
852wxSaveFileSelector(const char *what, const char *extension, const char *default_name, wxWindow *parent)
853{
854 return wxDefaultFileSelector(FALSE, what, extension, default_name, parent);
855}
856
857