Change 17855: Add ChooseFSObject/GetFolder
[email protected] (Chris Nandor) Sun, 8 Sep 2002 18:38:28 -0400
| Newsgroups | perl.perl5.changes.mac |
|---|---|
| Message-ID | <p05111b08b9a18180aafc@[10.0.1.177]> |
Change 17855 by pudge@pudge-mobile on 2002/09/08 04:36:08
Add ChooseFSObject/GetFolder
From Thomas Wegner
Affected files ...
.... //depot/maint-5.6/macperl/macos/Perl.r#4 edit
.... //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/ChooseFSObject.c#1 add
.... //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/ChooseFSObject.h#1 add
.... //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/Makefile.PL#2 edit
.... //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/StandardFile.pm#3 edit
.... //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/StandardFile.xs#3 edit
.... //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/t/ChooseFSObject.t#1 add
.... //depot/maint-5.6/macperl/macos/macperl/MacPerl.r#10 edit
Differences ...
==== //depot/maint-5.6/macperl/macos/Perl.r#4 (text) ====
Index: macperl/macos/Perl.r
--- macperl/macos/Perl.r#3~14397~ Wed Jan 23 12:03:19 2002
+++ macperl/macos/Perl.r Sat Sep 7 21:36:08 2002
@@ -5,6 +5,9 @@
* as specified in the README file.
*
* $Log: Perl.r,v $
+ * Revision 1.9 2002/09/05 23:36:33 pudge
+ * Add dialogs for the new Choose stuff in StandardFile from Thomas
+ *
* Revision 1.8 2002/01/23 05:45:39 pudge
* Update text
*
@@ -64,6 +67,92 @@
include "Perl.rsrc";
#define MPAppName "perl"
#include "MPVersion.r";
+
+
+/************* Custom Standard File Choose Folder Dialog *********************/
+
+resource 'DLOG' (193, "Std File CustomGetFolder", purgeable) {
+ {45, 25, 257, 368},
+ dBoxProc,
+ invisible,
+ noGoAway,
+ 0x0,
+ 193,
+ "",
+ noAutoCenter
+};
+
+
+resource 'DITL' (193, "Std File CustomGetFolder", purgeable) {
+ { /* array DITLarray: 11 elements */
+ /* [1] */
+ {141, 244, 161, 334},
+ Button {
+ enabled,
+ "Open"
+ },
+ /* [2] */
+ {110, 244, 130, 334},
+ Button {
+ enabled,
+ "Cancel"
+ },
+ /* [3] */
+ {0, 0, 0, 0},
+ HelpItem {
+ disabled,
+ HMScanhdlg {
+ -6042
+ }
+ },
+ /* [4] */
+ {16, 235, 32, 337},
+ UserItem {
+ enabled
+ },
+ /* [5] */
+ {40, 244, 60, 334},
+ Button {
+ enabled,
+ "Eject"
+ },
+ /* [6] */
+ {68, 244, 88, 334},
+ Button {
+ enabled,
+ "Desktop"
+ },
+ /* [7] */
+ {63, 12, 193, 230},
+ UserItem {
+ enabled
+ },
+ /* [8] */
+ {40, 12, 59, 230},
+ UserItem {
+ enabled
+ },
+ /* [9] */
+ {99, 243, 100, 335},
+ Picture {
+ disabled,
+ 11
+ },
+ /* [10] */
+ {171, 244, 191, 334},
+ Button {
+ enabled,
+ "Directory"
+ },
+ /* [11] */
+ {14, 29, 34, 214},
+ Button {
+ enabled,
+ "Select Current Directory:"
+ }
+ }
+};
+
resource 'DLOG' (2001) {
{ 0, 0, 150, 400},
==== //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/ChooseFSObject.c#1 (text) ====
Index: macperl/macos/ext/Mac/StandardFile/ChooseFSObject.c
--- /dev/null Tue May 5 13:32:27 1998
+++ macperl/macos/ext/Mac/StandardFile/ChooseFSObject.c Sat Sep 7 21:36:08 2002
@@ -0,0 +1,294 @@
+/**************************************************************************
+Project : MacPerl
+File : ChooseFSObject.c - Choose File System Objects
+Author : Thomas Wegner
+
+
+Language : MPW C
+
+$Log: ChooseFSObject.c,v $
+Revision 1.1 2002/09/05 23:31:37 pudge
+Add new ChooseFSObject stuff from Thomas
+
+
+
+**************************************************************************/
+
+#include <MacTypes.h>
+#include <Files.h>
+#include <ControlDefinitions.h>
+#include <Dialogs.h>
+#include <LowMem.h>
+#include <StandardFile.h>
+#include <GUSIFileSpec.h>
+#include <string.h>
+
+
+//
+// Utilities
+//
+
+
+static ControlHandle GetDialogCtrl(DialogPtr dlg, short item)
+{
+ short kind;
+ Handle hdl;
+ Rect box;
+
+ GetDialogItem(dlg, item, &kind, &hdl, &box);
+ return (ControlHandle) hdl;
+}
+
+
+
+//
+// Standard File
+//
+
+
+// volume vRefNum of the selected directory when we return from the Standard File dialog
+static short currentVol;
+// directory parID of the selected directory when we return from the Standard File dialog
+static long currentDir;
+
+static StandardFileReply reply;
+static short isAliasFlag = 1 << 15;
+
+
+// File filter proc for StdFChooseFolder
+//
+static pascal Boolean StdFFolderFFilter(CInfoPBPtr pb, Ptr DataPtr)
+{
+ return !(pb->hFileInfo.ioFlAttrib & ioDirMask);
+}
+
+// Dialog hook for StdFChooseFolder
+// When our dialog hook is called, the StandardFileReply struct that we've passed to
+// Standard File has been filled in for the current selection.
+//
+// Old IM Vol. IV, p. 75 and old Tech Note 80 give some hints about the low memory
+// globals SFSaveDisk and CurDirStore.
+//
+static pascal short StdFGetDirDlgHook(short item, DialogPtr dialog, Ptr DataPtr)
+{
+ switch (item) {
+
+ case sfHookFirstCall:
+ // specify where in the file system we open our dialog
+ reply.sfFile.vRefNum = currentVol;
+ reply.sfFile.parID = currentDir;
+ reply.sfFile.name[0] = 0;
+ return sfHookChangeSelection;
+
+ case 10:
+ // <Directory> button
+ if ( reply.sfIsFolder || reply.sfIsVolume || (reply.sfFlags & isAliasFlag) ) {
+
+ FSSpec dir = reply.sfFile;
+
+ if (reply.sfFlags & isAliasFlag) {
+ // resolve that alias file, then we have its parent directory in parID
+ // GUSIFSpResolve( &dir );
+ Boolean targetIsFolder;
+ Boolean wasAliased;
+ ResolveAliasFile( &dir, true, &targetIsFolder, &wasAliased);
+ }
+
+ // we need to move into the directory, to get its directory id, i.e.
+ // the parent directory (parID) of the empty file name
+ GUSIFSpDown( &dir, "\p" );
+
+ currentVol = dir.vRefNum;
+ currentDir = dir.parID;
+
+ // fake Open button item number
+ return sfItemOpenButton;
+ }
+ break;
+
+ case 11:
+ // "Select Current Directory:" button
+
+ currentVol = - ( LMGetSFSaveDisk() ); // access SFSaveDisk
+ currentDir = LMGetCurDirStore() ; // access CurDirStore
+
+ // fake Open button item number
+ return sfItemOpenButton;
+
+ case sfHookNullEvent:
+ if ( reply.sfIsFolder || reply.sfIsVolume || (reply.sfFlags & isAliasFlag) )
+ // enable Directory button
+ HiliteControl(GetDialogCtrl(dialog, 10), 0);
+ else
+ // disable Directory button
+ HiliteControl(GetDialogCtrl(dialog, 10), 255);
+ break;
+ }
+
+ return item;
+}
+
+
+
+//
+// * StdFChooseFolder
+//
+// Choose a folder with Standard File
+//
+
+static pascal Boolean StdFChooseFolder(FSSpec * defaultSpec, FSSpec * result)
+{
+ Point where = {-1, -1};
+ FSSpec selFolder = {0, 0, "\p"};
+ FileFilterYDUPP fileFilterYDUPP;
+ DlgHookYDUPP dialogHookYDUPP;
+
+ fileFilterYDUPP = NewFileFilterYDUPP( StdFFolderFFilter );
+ dialogHookYDUPP = NewDlgHookYDUPP( StdFGetDirDlgHook );
+
+ if (defaultSpec) {
+ GUSIFSpDown( defaultSpec, "\p" );
+
+ currentVol = defaultSpec->vRefNum;
+ currentDir = defaultSpec->parID;
+
+ } else {
+
+ currentVol = - ( LMGetSFSaveDisk() ); // access SFSaveDisk
+ currentDir = LMGetCurDirStore(); // access CurDirStore
+
+ }
+
+
+ CustomGetFile(
+ fileFilterYDUPP, // file filter
+ -1, // numTypes
+ nil, // typeList
+ &reply, // reply record
+ 193, // dialog resource id
+ where, // where
+ dialogHookYDUPP, // dialog hook
+ nil, // modal filter proc
+ nil, // active list
+ nil, // activate proc
+ nil // appl data pointer
+ );
+
+
+ if (reply.sfGood) {
+ selFolder.vRefNum = currentVol;
+ selFolder.parID = currentDir;
+
+ *result = selFolder;
+
+ }
+
+ // dispose proc pointers
+ DisposeFileFilterYDUPP( fileFilterYDUPP );
+ DisposeDlgHookYDUPP( dialogHookYDUPP );
+
+ return reply.sfGood;
+
+}
+
+
+// Simple dialog hook for StdFChooseFile
+//
+static pascal short StdFInitDlgHook(short item, DialogPtr dialog, Ptr DataPtr)
+{
+ switch (item) {
+
+ case sfHookFirstCall:
+ // specify where in the file system we open our dialog
+ reply.sfFile.vRefNum = currentVol;
+ reply.sfFile.parID = currentDir;
+ reply.sfFile.name[0] = 0;
+ return sfHookChangeSelection;
+ }
+
+ return item;
+}
+
+
+//
+// * StdFChooseFile
+//
+// Choose a file with Standard File
+//
+static pascal Boolean StdFChooseFile(FSSpec * defaultSpec, FSSpec * result)
+{
+ Point where = {-1, -1};
+ DlgHookYDUPP dialogHookYDUPP;
+
+ dialogHookYDUPP = NewDlgHookYDUPP( StdFInitDlgHook );
+
+ if (defaultSpec) {
+ GUSIFSpDown( defaultSpec, "\p" );
+
+ currentVol = defaultSpec->vRefNum;
+ currentDir = defaultSpec->parID;
+
+ } else {
+
+ currentVol = - ( LMGetSFSaveDisk() ); // access SFSaveDisk
+ currentDir = LMGetCurDirStore(); // access CurDirStore
+ }
+
+
+ CustomGetFile(
+ nil, // file filter
+ -1, // numTypes
+ nil, // typeList
+ &reply, // reply record
+ -6042, // standard dialog resource id
+ where, // where
+ dialogHookYDUPP, // dialog hook
+ nil, // modal filter proc
+ nil, // active list
+ nil, // activate proc
+ nil // appl data pointer
+ );
+
+
+ if (reply.sfGood) {
+ *result = reply.sfFile;
+ }
+
+ // dispose proc pointer
+ DisposeDlgHookYDUPP( dialogHookYDUPP );
+
+ return reply.sfGood;
+
+}
+
+
+
+//
+// * StdFChooseFSObject
+//
+// Choose a folder or file object with Standard File
+//
+
+pascal Boolean StdFChooseFSObject(char * path, Boolean folder, Boolean hasDefault)
+{
+ FSSpec defaultSpec;
+ FSSpec result;
+ Boolean good;
+
+ if (hasDefault)
+ hasDefault = ( GUSIPath2FSp(path, &defaultSpec) == noErr );
+
+ if (folder)
+ {
+ good = StdFChooseFolder( hasDefault ? &defaultSpec : nil, &result);
+ }
+ else
+ {
+ good = StdFChooseFile( hasDefault ? &defaultSpec : nil, &result);
+ }
+
+ if (good)
+ strcpy( path, GUSIFSp2FullPath(&result) );
+
+ return good;
+}
==== //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/ChooseFSObject.h#1 (text) ====
Index: macperl/macos/ext/Mac/StandardFile/ChooseFSObject.h
--- /dev/null Tue May 5 13:32:27 1998
+++ macperl/macos/ext/Mac/StandardFile/ChooseFSObject.h Sat Sep 7 21:36:08 2002
@@ -0,0 +1,27 @@
+/**************************************************************************
+Project : MacPerl
+File : ChooseFSObject.h - Choose File System Objects
+Author : Thomas Wegner
+
+
+Language : MPW C
+
+$Log: ChooseFSObject.h,v $
+Revision 1.1 2002/09/05 23:31:37 pudge
+Add new ChooseFSObject stuff from Thomas
+
+
+
+**************************************************************************/
+
+#ifndef __CHOOSEFSOBJECT__
+#define __CHOOSEFSOBJECT__
+
+#include <MacTypes.h>
+#include <Files.h>
+
+// Choose a folder or file object with Standard File
+pascal Boolean StdFChooseFSObject(char * path, Boolean folder, Boolean hasDefault);
+
+
+#endif /* __CHOOSEFSOBJECT__ */
==== //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/Makefile.PL#2 (text) ====
Index: macperl/macos/ext/Mac/StandardFile/Makefile.PL
--- macperl/macos/ext/Mac/StandardFile/Makefile.PL#1~11243~ Mon Jul 9 15:16:12 2001
+++ macperl/macos/ext/Mac/StandardFile/Makefile.PL Sat Sep 7 21:36:08 2002
@@ -6,4 +6,5 @@
'LINKTYPE' => 'static dynamic',
TYPEMAPS => '::QuickDraw:typemap ::Events:typemap ::Files:typemap',
XSPROTOARG => '-noprototypes', # XXX remove later?
+ 'OBJECT' => 'ChooseFSObject$(OBJ_EXT) StandardFile$(OBJ_EXT)',
);
==== //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/StandardFile.pm#3 (text) ====
Index: macperl/macos/ext/Mac/StandardFile/StandardFile.pm
--- macperl/macos/ext/Mac/StandardFile/StandardFile.pm#2~12323~ Wed Oct 3 11:42:37 2001
+++ macperl/macos/ext/Mac/StandardFile/StandardFile.pm Sat Sep 7 21:36:08 2002
@@ -23,14 +23,15 @@
use DynaLoader ();
use vars qw($VERSION @ISA @EXPORT);
- $VERSION = '1.00';
+ $VERSION = '1.10';
@ISA = qw(Exporter DynaLoader);
@EXPORT = qw(
StandardPutFile
StandardGetFile
CustomPutFile
CustomGetFile
- StandardOpenDialog
+ ChooseFSObject
+ StandardGetFolder
putDlgID
putSave
@@ -80,6 +81,9 @@
sfStatWarnDialogRefCon
sfLockWarnDialogRefCon
sfErrorDialogRefCon
+
+ kGetFolder
+ kGetFile
);
}
@@ -252,6 +256,12 @@
Refcons to distinguish the dialogs.
+=item kGetFolder
+
+=item kGetFile
+
+These constants may be passed to the FOLDER parameter of the ChooseFSObject function.
+
=cut
sub sfMainDialogRefCon () { 0x73746466; } # 'stdf'
sub sfNewFolderDialogRefCon () { 0x6E666472; } # 'nfdr'
@@ -260,10 +270,33 @@
sub sfLockWarnDialogRefCon () { 0x6C6F636B; } # 'lock'
sub sfErrorDialogRefCon () { 0x65727220; } # 'err '
+sub kGetFolder () { 1; }
+sub kGetFile () { 0; }
+
=back
=include StandardFile.xs
+=cut
+
+=item StandardGetFolder [ DEFAULTPATH ]
+
+Choose a folder. Implemented via ChooseFSObject (see above).
+Optionally, the DEFAULTPATH parameter specifies a directory where Standard File
+starts the choose dialog. DEFAULTPATH should be a valid relative or full path.
+This function is a MacPerl supplement, you will not find it anywhere in Inside Macintosh.
+It will NOT work with versions of the MacPerl application and tool prior to 5.6.1r2.
+
+=cut
+
+sub StandardGetFolder {
+ if (@_ > 1) {
+ croak("Usage: Mac::StandardFile::StandardGetFolder( [ DEFAULTPATH ] )");
+ }
+ ChooseFSObject(kGetFolder, $_[1]);
+}
+
+
=head1 BUGS/LIMITATIONS
=head1 FILES
@@ -271,6 +304,8 @@
=head1 AUTHOR(S)
Matthias Ulrich Neeracher <[email protected]>
+
+Thomas Wegner <[email protected]> contributed the ChooseFSObject function.
=cut
==== //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/StandardFile.xs#3 (text) ====
Index: macperl/macos/ext/Mac/StandardFile/StandardFile.xs
--- macperl/macos/ext/Mac/StandardFile/StandardFile.xs#2~14072~ Fri Jan 4 12:37:44 2002
+++ macperl/macos/ext/Mac/StandardFile/StandardFile.xs Sat Sep 7 21:36:08 2002
@@ -17,6 +17,7 @@
#include <Types.h>
#include <StandardFile.h>
#include <GUSIFileSpec.h>
+#include "ChooseFSObject.h"
typedef struct {
SV * fileFilter;
@@ -368,6 +369,69 @@
OUTPUT:
RETVAL
+
+
+=item ChooseFSObject FOLDER [, DEFAULTPATH ]
+
+Choose a folder or file with Standard File. ChooseFSObject returns a full
+path to the selected file system object if the user confirms the dialog,
+or undef if the dialog is canceled. In the FOLDER parameter you should
+pass 1 (i.e. true) or the constant kGetFolder if you want to choose a folder
+or volume (which is a special kind of folder). Or you pass 0 (i.e. false) or
+the constant kGetFile to choose a file. Optionally, the DEFAULTPATH
+parameter specifies a directory where Standard File starts the choose dialog.
+DEFAULTPATH should be a valid relative or full path. This function is a
+MacPerl supplement, you will not find it anywhere in Inside Macintosh. It
+will NOT work with versions of the MacPerl application and tool prior to
+5.6.1r2.
+
+=cut
+void
+ChooseFSObject(folder, ...)
+
+ Boolean folder;
+ CODE:
+ {
+ STRLEN len;
+ char * defaultPath;
+ char path[256];
+ Str255 msg;
+ Boolean hasDefault;
+
+ if ((items < 1) || (items > 2)) {
+
+ croak("Usage: Mac::StandardFile::ChooseFSObject( FOLDER [, DEFAULTPATH ] )");
+
+ } else if (items == 2 ) {
+
+ defaultPath = (char *) SvPV_nolen(ST(1));
+ len = strlen(defaultPath);
+
+ if ( len > 255 ) {
+ hasDefault = false;
+ } else {
+ hasDefault = true;
+ strcpy( path, defaultPath );
+ }
+
+ } else if (items == 1 ) {
+
+ hasDefault = false;
+
+ }
+
+ if ( StdFChooseFSObject( path, folder, hasDefault ) )
+ {
+ ST(0) = sv_2mortal(newSVpv(path, 0));
+ }
+ else
+ {
+ ST(0) = &PL_sv_undef;
+ }
+
+ }
+
+
=back
-=cut
\ No newline at end of file
+=cut
==== //depot/maint-5.6/macperl/macos/ext/Mac/StandardFile/t/ChooseFSObject.t#1 (text) ====
Index: macperl/macos/ext/Mac/StandardFile/t/ChooseFSObject.t
--- /dev/null Tue May 5 13:32:27 1998
+++ macperl/macos/ext/Mac/StandardFile/t/ChooseFSObject.t Sat Sep 7 21:36:08 2002
@@ -0,0 +1,20 @@
+#! perl -w
+use Mac::StandardFile;
+use File::Spec;
+
+# choose a folder or volume
+$path = ChooseFSObject( kGetFolder, File::Spec->rootdir );
+if ($path) {
+ print "path = $path \n";
+} else {
+ print "User canceled. \n";
+}
+
+# choose a file
+$path = ChooseFSObject( kGetFile );
+if ($path) {
+ print "path = $path \n";
+} else {
+ print "User canceled. \n";
+}
+
==== //depot/maint-5.6/macperl/macos/macperl/MacPerl.r#10 (text) ====
Index: macperl/macos/macperl/MacPerl.r
--- macperl/macos/macperl/MacPerl.r#9~15098~ Thu Mar 7 19:19:44 2002
+++ macperl/macos/macperl/MacPerl.r Sat Sep 7 21:36:08 2002
@@ -9,6 +9,9 @@
Language : MPW C
$Log: MacPerl.r,v $
+Revision 1.18 2002/09/05 23:28:17 pudge
+Add dialogs for the new Choose stuff in StandardFile from Thomas
+
Revision 1.17 2002/03/08 04:12:03 pudge
Cosmetic fixes (Thomas Wegner)
@@ -877,6 +880,92 @@
}
}
};
+
+
+/************* Custom Standard File Choose Folder Dialog *********************/
+
+resource 'DLOG' (193, "Std File CustomGetFolder", purgeable) {
+ {45, 25, 257, 368},
+ dBoxProc,
+ invisible,
+ noGoAway,
+ 0x0,
+ 193,
+ "",
+ noAutoCenter
+};
+
+
+resource 'DITL' (193, "Std File CustomGetFolder", purgeable) {
+ { /* array DITLarray: 11 elements */
+ /* [1] */
+ {141, 244, 161, 334},
+ Button {
+ enabled,
+ "Open"
+ },
+ /* [2] */
+ {110, 244, 130, 334},
+ Button {
+ enabled,
+ "Cancel"
+ },
+ /* [3] */
+ {0, 0, 0, 0},
+ HelpItem {
+ disabled,
+ HMScanhdlg {
+ -6042
+ }
+ },
+ /* [4] */
+ {16, 235, 32, 337},
+ UserItem {
+ enabled
+ },
+ /* [5] */
+ {40, 244, 60, 334},
+ Button {
+ enabled,
+ "Eject"
+ },
+ /* [6] */
+ {68, 244, 88, 334},
+ Button {
+ enabled,
+ "Desktop"
+ },
+ /* [7] */
+ {63, 12, 193, 230},
+ UserItem {
+ enabled
+ },
+ /* [8] */
+ {40, 12, 59, 230},
+ UserItem {
+ enabled
+ },
+ /* [9] */
+ {99, 243, 100, 335},
+ Picture {
+ disabled,
+ 11
+ },
+ /* [10] */
+ {171, 244, 191, 334},
+ Button {
+ enabled,
+ "Directory"
+ },
+ /* [11] */
+ {14, 29, 34, 214},
+ Button {
+ enabled,
+ "Select Current Directory:"
+ }
+ }
+};
+
/************************** Save Dialog **************************/
End of Patch.