home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / nshellmegasource1.50 / mega src / commands / sfget.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-10  |  9.8 KB  |  481 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     sfget.c
  4.     
  5.     Copyright (c) 1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. #ifdef __MWERKS__            // Get the appropriate A4 stuff
  16. #include <A4Stuff.h>
  17. #else
  18. #include <SetUpA4.h>
  19. #endif
  20.  
  21. #include <GestaltEqu.h>
  22. #include <Folders.h>
  23.  
  24. #include "nshc.h"
  25. #include "str_utl.proto.h"
  26. #include "nshc_utl.proto.h"
  27.  
  28. /* ======================================== */
  29.  
  30. // constants
  31.  
  32. #define SFGetDialog        16000
  33. #define    SFGetButton        10
  34.  
  35. /* ======================================== */
  36.  
  37. // typedefs
  38.  
  39. typedef struct {
  40.     StandardFileReply    *replyPtr;
  41.     FSSpec                oldSelection;
  42.     } SFData, *SFDataPtr;
  43.  
  44. /* ======================================== */
  45.  
  46. // globals
  47.  
  48. Boolean    gHasFindFolder;
  49. short    gFileRef;
  50. FSSpec    gDeskFolderSpec;
  51. Str255    gPath;
  52. Str32    gVarName;
  53.  
  54. /* ======================================== */
  55.  
  56. // prototypes - for local use only
  57.  
  58. int     sfget( void );
  59. void    sfget_button(StringPtr selName,DialogPtr theDlg);
  60. void    sfget_close_rsrc(void);
  61. OSErr   sfget_ensure_name(FSSpec *fSpec);
  62. int     sfget_gestalt( OSType selector, int bit );
  63. OSErr   sfget_get_desktop_folder(short vRefNum);
  64. int     sfget_init(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls );
  65. int     sfget_open_rsrc(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls);
  66. int     sfget_path( StandardFileReply *sfReply );
  67. int     sfget_pre7( void );
  68. Boolean sfget_same_file(FSSpec *file1,FSSpec *file2);
  69. pascal  short sfget_hook(short item,DialogPtr theDlg,Ptr userData);
  70.  
  71. /* ======================================== */
  72.  
  73. // utility
  74.  
  75.  
  76. int    sfget_pre7( void )
  77. {
  78.     long    response;
  79.     
  80.     if ( Gestalt( 'sysv', &response ) )
  81.         return( 1 );
  82.         
  83.     if ( response < 0x700 )
  84.         return( 1 );
  85.     else
  86.         return( 0 );
  87. }
  88.  
  89. int sfget_path( StandardFileReply *sfReply )
  90. {
  91.     CInfoPBRec    block;
  92.     int            error;
  93.     Str255        temp;
  94.  
  95.     error = 0;
  96.     gPath[0] = 0;
  97.     temp[0] = 0;
  98.     block.dirInfo.ioNamePtr = temp;
  99.     block.dirInfo.ioDrParID = sfReply->sfFile.parID;
  100.     
  101.     if ( sfReply->sfFile.parID != 1)
  102.         do {
  103.         
  104.             block.dirInfo.ioVRefNum = sfReply->sfFile.vRefNum;
  105.             block.dirInfo.ioFDirIndex = -1;
  106.             block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
  107.     
  108.             error = PBGetCatInfo(&block,false);
  109.             
  110.             if ( temp[0] + gPath[0] + 1 > 255 )
  111.                 error = 1;
  112.             
  113.             if (!error) {
  114.                 temp[ ++temp[0] ] = ':';
  115.                 pStrAppend(temp,gPath);
  116.                 pStrCopy(gPath,temp);
  117.                 }
  118.     
  119.         } while (!error && (block.dirInfo.ioDrDirID != fsRtDirID));
  120.  
  121.     if ( error )
  122.         return( error );
  123.  
  124.     if ( gPath[0] + sfReply->sfFile.name[0] > 255 )
  125.         error = 1;
  126.     else
  127.         pStrAppend( gPath, sfReply->sfFile.name );
  128.  
  129.     if ( sfReply->sfFile.parID == 1 )
  130.         if ( gPath[0] < 255 )
  131.             gPath[ ++gPath[0] ] = ':';
  132.         else
  133.             error = 1;
  134.  
  135.     return( error );
  136. }
  137.  
  138. /* ======================================== */
  139.  
  140. int    sfget_gestalt( OSType selector, int bit )
  141. {
  142.     long    response;
  143.     OSErr    error;
  144.     
  145.     if ( error = Gestalt( selector, &response ) )
  146.         return(false);
  147.         
  148.     if ( response & ( 1L << bit ) )
  149.         return(true);
  150.     else
  151.         return(false);
  152. }
  153.  
  154. /* ======================================== */
  155.  
  156. OSErr sfget_ensure_name(FSSpec *fss)
  157. {
  158.     DirInfo infoPB;
  159.     OSErr err;
  160.  
  161.     if (fss->name[0] != '\0')
  162.         return( 0 );
  163.         
  164.     infoPB.ioNamePtr = fss->name;
  165.     infoPB.ioVRefNum = fss->vRefNum;
  166.     infoPB.ioDrDirID = fss->parID;
  167.     infoPB.ioFDirIndex = -1;
  168.     err = PBGetCatInfo(&infoPB,false);
  169.     fss->parID = infoPB.ioDrParID;
  170.     
  171.     return( err );
  172. }
  173.  
  174. /* ======================================== */
  175.  
  176. Boolean sfget_same_file(FSSpec *file1,FSSpec *file2)
  177. {
  178.     if ( file1->vRefNum != file2->vRefNum )
  179.         return( 0 );
  180.         
  181.     if ( file1->parID != file2->parID )
  182.         return( 0 );
  183.         
  184.     if ( !EqualString(file1->name,file2->name,false,true) )
  185.         return( 0 );
  186.     
  187.     return( 1 );
  188. }
  189.  
  190. /* ======================================== */
  191.  
  192. OSErr sfget_get_desktop_folder(short vRefNum)
  193. {
  194.     DirInfo infoPB;
  195.     OSErr    error;
  196.     
  197.     if (!gHasFindFolder) {
  198.         gDeskFolderSpec.vRefNum = -9999;
  199.         return( -1 );
  200.         }
  201.     
  202.     gDeskFolderSpec.name[0] = '\0';
  203.  
  204.     error = FindFolder(vRefNum,kDesktopFolderType,kDontCreateFolder,&gDeskFolderSpec.vRefNum,&gDeskFolderSpec.parID);
  205.  
  206.     if ( error )
  207.         return( error );
  208.     
  209.     return( sfget_ensure_name( &gDeskFolderSpec ) );
  210. }
  211.  
  212. /* ======================================== */
  213.  
  214. // sfget
  215.  
  216. int sfget( void )
  217. {
  218.     int                    my_err;
  219.     Point                where = {-1,-1};
  220.     SFData                sfData;
  221.     StandardFileReply    sfReply;
  222.     
  223.     /* initialize user data area */
  224.     
  225.     sfData.replyPtr = &sfReply;
  226.     sfData.oldSelection.vRefNum = -9999;    /* init to ridiculous value */
  227.     
  228.     CustomGetFile(nil,-1,nil,&sfReply,SFGetDialog,where,sfget_hook,nil,nil,nil,&sfData);
  229.     
  230.     if (sfReply.sfGood)
  231.         my_err = sfget_path( &sfReply );
  232.     else
  233.         my_err = 1;
  234.         
  235.     return( my_err );
  236. }
  237.  
  238. /* ======================================== */
  239.  
  240. pascal short sfget_hook(short item,DialogPtr theDlg,Ptr userData)
  241. {
  242.     Boolean hiliteButton;
  243.     FSSpec curSpec;
  244.     OSType refCon;
  245.     SFDataPtr sfData;
  246.     
  247.     refCon = GetWRefCon(theDlg);
  248.     if (refCon!=sfMainDialogRefCon)
  249.         return item;
  250.         
  251.     sfData = (SFDataPtr) userData;
  252.     
  253.     if (item==sfHookFirstCall || item==sfHookLastCall)
  254.         return item;
  255.     
  256.     if (item==sfItemVolumeUser) {
  257.         sfData->replyPtr->sfFile.name[0] = '\0';
  258.         sfData->replyPtr->sfFile.parID = 2;
  259.         sfData->replyPtr->sfIsFolder = false;
  260.         sfData->replyPtr->sfIsVolume = false;
  261.         sfData->replyPtr->sfFlags = 0;
  262.         item = sfHookChangeSelection;
  263.         }
  264.         
  265.     if (!sfget_same_file(&sfData->replyPtr->sfFile,&sfData->oldSelection)) {
  266.     
  267.         BlockMove(&sfData->replyPtr->sfFile,&curSpec,sizeof(FSSpec));
  268.         sfget_ensure_name(&curSpec);
  269.         
  270.         if (curSpec.vRefNum!=sfData->oldSelection.vRefNum)
  271.             sfget_get_desktop_folder(curSpec.vRefNum);
  272.             
  273.         sfget_button(curSpec.name,theDlg);
  274.         
  275.         BlockMove(&sfData->replyPtr->sfFile,&sfData->oldSelection,sizeof(FSSpec));
  276.         }
  277.     
  278.     if (item==SFGetButton)
  279.         item = sfItemOpenButton;
  280.         
  281.     return item;
  282. }
  283.  
  284. /* ======================================== */
  285.  
  286. void sfget_button( StringPtr selName ,DialogPtr theDlg )
  287. {
  288.     Handle iHndl;
  289.     Rect iRect;
  290.     short iType;
  291.     Str255 temp;
  292.         
  293.     pStrCopy( temp, "\pSelect" );
  294.     pStrAppend( temp, "\p \"");
  295.     pStrAppend( temp, selName );
  296.     temp[ ++temp[0] ] = '"';
  297.  
  298.     GetDItem(theDlg,SFGetButton,&iType,&iHndl,&iRect);
  299.     SetCTitle(iHndl,temp);
  300.     SetDItem(theDlg,SFGetButton,iType,iHndl,&iRect);
  301. }
  302.  
  303. /* ======================================== */
  304.  
  305. int sfget_init(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls )
  306. {
  307.     char    *p;
  308.     char    *q;
  309.     char    c;
  310.     int        argc;
  311.     int        error;
  312.     int        i;
  313.     int        prompt;
  314.     int        usage;
  315.     int        var;
  316.     Str255    prompt_str;
  317.     
  318.     // return if bad include file version
  319.         
  320.     if (nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION ))
  321.         return( 0 );
  322.     
  323.     // return if pre system 7 os
  324.         
  325.     if ( sfget_pre7() ) {
  326.         nshc_calls->NSH_putStr_err("\psfget: This command requires System 7.\r");
  327.         nshc_parms->result = NSHC_ERR_GENERAL;
  328.         nshc_parms->action = nsh_idle;
  329.         return( 0 );
  330.         }
  331.  
  332.     // return if bad usage
  333.         
  334.     usage = 0;
  335.     argc = nshc_parms->argc;
  336.     prompt = nshc_got_option(nshc_parms, 'p');
  337.  
  338.     if ((argc != 2) && (argc != 4))
  339.         usage = 1;
  340.         
  341.     if ( (argc == 4) && ( prompt != 1 ) && ( prompt != 2 ) )
  342.         usage = 1;
  343.     
  344.     if ( usage ) {
  345.         nshc_calls->NSH_putStr_err("\pUsage: sfget variable_name [-p \"prompt string\"].\r");
  346.         nshc_parms->result = NSHC_ERR_PARMS;
  347.         nshc_parms->action = nsh_idle;
  348.         return( 0 );
  349.         }
  350.         
  351.     // return if bad prompt string
  352.     
  353.     if (prompt) {
  354.     
  355.         p = &nshc_parms->arg_buf[nshc_parms->argv[prompt + 1]];
  356.             
  357.         if ( cStrLen( p ) > 255 ) {
  358.             nshc_calls->NSH_putStr_err("\psfget: Prompt string is too long.");
  359.             nshc_parms->result = NSHC_ERR_PARMS;
  360.             nshc_parms->action = nsh_idle;
  361.             return( 0 );
  362.             }
  363.         else
  364.             pStrFromC( prompt_str, p );
  365.             
  366.         ParamText( prompt_str, "\p",  "\p",  "\p" );
  367.         
  368.         }
  369.     else
  370.         ParamText( "\pSelect a folder or file:", "\p",  "\p",  "\p" );
  371.     
  372.     // return if bad variable name
  373.     
  374.     if ( prompt == 1 )
  375.         var = 3;
  376.     else
  377.         var = 1;
  378.         
  379.     p = q = &nshc_parms->arg_buf[ nshc_parms->argv[ var ] ];
  380.     i = 0;
  381.     while (c = *p++) {
  382.         error = 1;
  383.         if ( c == '_' ) error = 0; else
  384.         if ( ( c >= 'a' ) && ( c <= 'z' ) ) error = 0; else
  385.         if ( ( c >= 'A' ) && ( c <= 'Z' ) ) error = 0; else
  386.         if ( ( c >= '0' ) && ( c <= '9' ) ) error = 0;
  387.         if (error) {
  388.             nshc_calls->NSH_putStr_err( "\psfget: Invalid variable name = " );
  389.             nshc_calls->NSH_puts_err( q );
  390.             nshc_calls->NSH_putchar_err( '\r' );
  391.             nshc_parms->result = NSHC_ERR_PARMS;
  392.             nshc_parms->action = nsh_idle;
  393.             return( 0 );
  394.             }
  395.         gVarName[++i] = c;
  396.         }
  397.         
  398.     if ( i > 31 ) {
  399.         nshc_calls->NSH_putStr_err( "\psfget: Variable name too long = " );
  400.         nshc_calls->NSH_puts_err( q );
  401.         nshc_calls->NSH_putchar_err( '\r' );
  402.         nshc_parms->result = NSHC_ERR_PARMS;
  403.         nshc_parms->action = nsh_idle;
  404.         return( 0 );
  405.         }
  406.     else
  407.         gVarName[0] = i;
  408.  
  409.     gHasFindFolder = sfget_gestalt( gestaltFindFolderAttr, gestaltFindFolderPresent );
  410.  
  411.     return( 1 );
  412. }
  413.  
  414. /* ======================================== */
  415.  
  416. int sfget_open_rsrc(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  417. {
  418.     Str255    fileName;
  419.  
  420.     pStrFromC( fileName, &nshc_parms->arg_buf[nshc_parms->argv[0]] );
  421.     
  422.     gFileRef = -1;
  423.     
  424.     if ( !nshc_calls->NSH_path_which( fileName ) )
  425.         gFileRef = OpenResFile( fileName );
  426.         
  427.     if ( gFileRef < 0 ) {
  428.         nshc_calls->NSH_putStr_err("\psfget: Could not open resource file.\r");
  429.         nshc_parms->result = NSHC_ERR_PARMS;
  430.         nshc_parms->action = nsh_idle;
  431.         return( 1 );
  432.         }
  433.     else
  434.         return( 0 );
  435. }
  436.  
  437. /* ======================================== */
  438.  
  439. void sfget_close_rsrc(void)
  440. {
  441.     if (gFileRef)
  442.         CloseResFile(gFileRef);
  443. }
  444.  
  445. /* ======================================== */
  446.  
  447. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  448. {
  449.     int        error;
  450.     
  451. #ifdef __MWERKS__
  452.     long oldA4  = SetCurrentA4();
  453. #else
  454.     RememberA0();
  455.     SetUpA4();
  456. #endif
  457.     
  458.     if ( sfget_init( nshc_parms, nshc_calls ) ) {
  459.     
  460.         error = sfget_open_rsrc( nshc_parms, nshc_calls );
  461.     
  462.         if ( !error )
  463.             error = sfget();
  464.             
  465.         sfget_close_rsrc();
  466.         
  467.         if ( !error )
  468.             nshc_calls->NSH_var_set( gVarName, gPath );
  469.  
  470.          nshc_parms->action = nsh_idle;
  471.         nshc_parms->result = error;
  472.             
  473.         }
  474.  
  475. #ifdef __MWERKS__
  476.     SetA4(oldA4);
  477. #else
  478.     RestoreA4();
  479. #endif
  480. }
  481.