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