home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / Sessions / Traut / ZStrings / Source / MacOS / GraphicalTool / MacZStringWindow.cp < prev    next >
Encoding:
Text File  |  2001-06-23  |  21.3 KB  |  786 lines

  1. /*==================================================================
  2.     File:        MacZStringWindow.cp
  3.  
  4.     Contains:    Primary window class for the Mac ZString tool
  5.                 (based on the PowerPlant framework)
  6.  
  7.     Written by:    Eric Traut
  8.  
  9.     Copyright:    2000-2001 Connectix Corporation
  10.     
  11.     This source has been placed into the public domain by
  12.     Connectix Corporation. You have the right to modify, 
  13.     distribute or use this code without any legal limitations
  14.     or finanicial/licensing requirements. Connectix is not 
  15.     liable for any problems that result from the use of this 
  16.     code.
  17.     
  18.     If you have comments, feedback, questions, or would like
  19.     to submit bug fixes or updates to this code, please email
  20.     opensource@connectix.com.
  21. ==================================================================*/
  22.  
  23. #include "MacZStringWindow.h"
  24. #include "FileIconPane.h"
  25. #include "FileSelectionGroupView.h"
  26.  
  27. #include "ZStringTool.h"
  28. #include "MacZString.h"
  29.  
  30. #include <LPopupButton.h>
  31. #include <LEditText.h>
  32. #include <LString.h>
  33. #include <LPushButton.h>
  34. #include <LStaticText.h>
  35. #include <LIconControl.h>
  36. #include <LCheckBox.h>
  37. #include <LRadioButton.h>
  38. #include <UStandardDialogs.h>
  39. #include <UClassicDialogs.h>
  40.  
  41. #include <stdlib.h>
  42. #include <stdio.h>
  43. #include <new>
  44.  
  45. extern "C" {
  46. #include <FSp_fopen.h>
  47. }
  48.  
  49.  
  50.  
  51. // ---------------------------------------------------------------------------
  52. //    • MacZStringWindow                        Stream Constructor          [public]
  53. // ---------------------------------------------------------------------------
  54.  
  55. MacZStringWindow::MacZStringWindow(
  56.     LStream *    inStream)
  57.     :    LWindow(inStream),
  58.         LListener()
  59. {
  60. }
  61.         
  62.  
  63. // ---------------------------------------------------------------------------
  64. //    • ~MacZStringWindow                        Destructor                  [public]
  65. // ---------------------------------------------------------------------------
  66.  
  67. MacZStringWindow::~MacZStringWindow()
  68. {
  69.  
  70. }
  71.  
  72.  
  73. // ---------------------------------------------------------------------------
  74. //    • FinishCreateSelf                                              [private]
  75. // ---------------------------------------------------------------------------
  76.  
  77. void
  78. MacZStringWindow::FinishCreateSelf()
  79. {
  80.     LWindow::FinishCreateSelf();
  81.     
  82.     RegisterWidgets();
  83.     UpdateButtonStatus();
  84. }
  85.  
  86.  
  87. // ---------------------------------------------------------------------------
  88. //    • RegisterWidgets                                                  [private]
  89. // ---------------------------------------------------------------------------
  90.  
  91. void
  92. MacZStringWindow::RegisterWidgets()
  93. {
  94.     LPopupButton * popupButton;
  95.     LPushButton * pushButton;
  96.     FileSelectionGroupView * groupView;
  97.     
  98.     // Register the various controls that send messages 
  99.     popupButton = dynamic_cast<LPopupButton *>(FindPaneByID(pane_LanguagePopup));
  100.     ThrowIfNULL_(popupButton);
  101.     popupButton->AddListener(this);
  102.  
  103.     pushButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_ExtractButton));
  104.     ThrowIfNULL_(pushButton);
  105.     pushButton->AddListener(this);
  106.  
  107.     pushButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_CompareButton));
  108.     ThrowIfNULL_(pushButton);
  109.     pushButton->AddListener(this);
  110.  
  111.     pushButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_OverrideButton));
  112.     ThrowIfNULL_(pushButton);
  113.     pushButton->AddListener(this);
  114.  
  115.     pushButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_QuitButton));
  116.     ThrowIfNULL_(pushButton);
  117.     pushButton->AddListener(this);
  118.  
  119.     pushButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_SourceFileChooseButton));
  120.     ThrowIfNULL_(pushButton);
  121.     pushButton->AddListener(this);
  122.  
  123.     pushButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_CompareFileChooseButton));
  124.     ThrowIfNULL_(pushButton);
  125.     pushButton->AddListener(this);
  126.  
  127.     pushButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_DestFileChooseButton));
  128.     ThrowIfNULL_(pushButton);
  129.     pushButton->AddListener(this);
  130.     
  131.     groupView = dynamic_cast<FileSelectionGroupView *>(FindPaneByID(pane_SourceGroupBox));
  132.     ThrowIfNULL_(groupView);
  133.     groupView->AddListener(this);
  134.  
  135.     groupView = dynamic_cast<FileSelectionGroupView *>(FindPaneByID(pane_CompareGroupBox));
  136.     ThrowIfNULL_(groupView);
  137.     groupView->AddListener(this);
  138.  
  139.     groupView = dynamic_cast<FileSelectionGroupView *>(FindPaneByID(pane_DestGroupBox));
  140.     ThrowIfNULL_(groupView);
  141.     groupView->AddListener(this);
  142. }
  143.  
  144.  
  145. // ---------------------------------------------------------------------------
  146. //    • ListenToMessage                                                  [private]
  147. // ---------------------------------------------------------------------------
  148.  
  149. void
  150. MacZStringWindow::ListenToMessage(
  151.     MessageT        inMessage,
  152.     void *            ioParam)
  153. {
  154.     switch (inMessage)
  155.     {
  156.         case pane_LanguagePopup:
  157.         {
  158.             // Update the resource text for for the selected language
  159.             LStr255 resString;
  160.             
  161.             LPopupButton * popupButton = dynamic_cast<LPopupButton *>(FindPaneByID(pane_LanguagePopup));
  162.             ThrowIfNULL_(popupButton);
  163.  
  164.             LEditText * editTextControl = dynamic_cast<LEditText *>(FindPaneByID(pane_LanguageResourceTextBox));
  165.             ThrowIfNULL_(editTextControl);
  166.                 
  167.             resString.Assign(popupButton->GetValue() + 127);
  168.             editTextControl->SetText(resString);
  169.             break;
  170.         }
  171.         
  172.         case pane_ExtractButton:
  173.             DoExtract();
  174.             break;
  175.         
  176.         case pane_CompareButton:
  177.             DoCompare();
  178.             break;
  179.         
  180.         case pane_OverrideButton:
  181.             DoCreateOverride();
  182.             break;
  183.         
  184.         case pane_QuitButton:
  185.             // Just send a synthetic quit command up to the app
  186.             ObeyCommand(cmd_Quit, NULL);
  187.             break;
  188.         
  189.         case pane_SourceFileChooseButton:
  190.             SelectFile(pane_SourceFileNameStaticText, pane_SourceFileIcon, mSourceFileSpec, true);
  191.             break;
  192.             
  193.         case pane_CompareFileChooseButton:
  194.             SelectFile(pane_CompareFileNameStaticText, pane_CompareFileIcon, mCompareFileSpec, true);
  195.             break;
  196.         
  197.         case pane_DestFileChooseButton:
  198.             SelectFile(pane_DestFileNameStaticText, pane_DestFileIcon, mDestFileSpec, false);
  199.             break;
  200.         
  201.         case pane_SourceGroupBox:
  202.             SetFile(pane_SourceFileNameStaticText, pane_SourceFileIcon, *(FSSpec *)ioParam, mSourceFileSpec);
  203.             break;
  204.         
  205.         case pane_CompareGroupBox:
  206.             SetFile(pane_CompareFileNameStaticText, pane_CompareFileIcon, *(FSSpec *)ioParam, mCompareFileSpec);
  207.             break;
  208.         
  209.         case pane_DestGroupBox:
  210.             SetFile(pane_DestFileNameStaticText, pane_DestFileIcon, *(FSSpec *)ioParam, mDestFileSpec);
  211.             break;
  212.         
  213.         default:
  214.             break;
  215.     }
  216. }
  217.  
  218.  
  219. // ---------------------------------------------------------------------------
  220. //    • UpdateButtonStatus                                          [private]
  221. // ---------------------------------------------------------------------------
  222.  
  223. void
  224. MacZStringWindow::UpdateButtonStatus()
  225. {
  226.     LPushButton * extractButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_ExtractButton));
  227.     ThrowIfNULL_(extractButton);
  228.  
  229.     LPushButton * compareButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_CompareButton));
  230.     ThrowIfNULL_(compareButton);
  231.  
  232.     LPushButton * overrideButton = dynamic_cast<LPushButton *>(FindPaneByID(pane_OverrideButton));
  233.     ThrowIfNULL_(overrideButton);
  234.     
  235.     // We can only extract & override if there is a source and dest
  236.     if (mSourceFileSpec.IsValid() && mDestFileSpec.IsValid())
  237.     {
  238.         extractButton->Enable();
  239.         overrideButton->Enable();
  240.     }
  241.     else
  242.     {
  243.         extractButton->Disable();
  244.         overrideButton->Disable();
  245.     }
  246.  
  247.     // We can only compare if there is also a compare file
  248.     if (mSourceFileSpec.IsValid() && mDestFileSpec.IsValid() && mCompareFileSpec.IsValid())
  249.         compareButton->Enable();
  250.     else
  251.         compareButton->Disable();
  252. }
  253.  
  254.  
  255. // ---------------------------------------------------------------------------
  256. //    • GetUserOptions                                              [protected]
  257. // ---------------------------------------------------------------------------
  258.  
  259. void
  260. MacZStringWindow::GetUserOptions(
  261.     ZToolOptions &        outOptions)
  262. {
  263.     // Read the user preferences.
  264.     LCheckBox *        checkBox;
  265.     LRadioButton *    radioButton;
  266.     
  267.     checkBox = dynamic_cast<LCheckBox *>(FindPaneByID(pane_AllowSemicolonCheckbox));
  268.     ThrowIfNULL_(checkBox);
  269.     outOptions.mAllowTagSemicolon = (checkBox->GetValue() != 0);
  270.  
  271.     checkBox = dynamic_cast<LCheckBox *>(FindPaneByID(pane_SortOutputCheckbox));
  272.     ThrowIfNULL_(checkBox);
  273.     outOptions.mCategorizeOutput = (checkBox->GetValue() != 0);
  274.  
  275.     checkBox = dynamic_cast<LCheckBox *>(FindPaneByID(pane_OutputDuplErrorCheckbox));
  276.     ThrowIfNULL_(checkBox);
  277.     outOptions.mFlagDuplicates = (checkBox->GetValue() != 0);
  278.  
  279.     checkBox = dynamic_cast<LCheckBox *>(FindPaneByID(pane_PrintWarningCheckbox));
  280.     ThrowIfNULL_(checkBox);
  281.     outOptions.mOutputWarnings = (checkBox->GetValue() != 0);
  282.  
  283.     checkBox = dynamic_cast<LCheckBox *>(FindPaneByID(pane_ConvertHighASCIICheckbox));
  284.     ThrowIfNULL_(checkBox);
  285.     outOptions.mConvertHighASCIIChar = (checkBox->GetValue() != 0);
  286.  
  287.     radioButton = dynamic_cast<LRadioButton *>(FindPaneByID(pane_NumericOutputRadioButton));
  288.     ThrowIfNULL_(checkBox);
  289.     outOptions.mOutputNumericTags = (checkBox->GetValue() != 0);
  290. }
  291.  
  292.  
  293. // ---------------------------------------------------------------------------
  294. //    • DoExtract                                                      [protected]
  295. // ---------------------------------------------------------------------------
  296.  
  297. void
  298. MacZStringWindow::DoExtract()
  299. {
  300.     char *                    newBinaryImage = NULL;
  301.     UInt32                    newBinarySize;
  302.     FILE *                    reportFile = NULL;
  303.     Z_Boolean                reportOK;
  304.  
  305.     reportFile = FSp_fopen(&mDestFileSpec.GetFSSpec(), "w");
  306.     if (reportFile == NULL)
  307.     {
  308.         DisplayError("\pCould not open output file. Perhaps it is in use or locked.");
  309.         goto CleanUpAndReturn;
  310.     }
  311.  
  312.     // Process the data.
  313.     {
  314.         StCursor        watchCursor;
  315.  
  316.         ZStringTool        stringTool;
  317.         ZToolOptions    options;
  318.         GetUserOptions(options);
  319.         
  320.         if (!ReadBinaryImage(mSourceFileSpec, newBinaryImage, newBinarySize))
  321.             goto CleanUpAndReturn;
  322.         
  323.         stringTool.ProcessBinaries(newBinaryImage, newBinarySize, NULL, 0, options);
  324.         reportOK = stringTool.PrintReport(reportFile, options);
  325.     }
  326.  
  327.     if (!reportOK)
  328.         DisplayError("\pOne or more errors occurred during the extraction. See output for details.");
  329.     else
  330.         DisplaySuccess("\pExtraction was successful. See destination file for results.");
  331.  
  332.     // Make it look like an MS IE html file.
  333.     SetTypeAndCreator(mDestFileSpec, 'TEXT', 'MSIE');
  334.  
  335. CleanUpAndReturn:
  336.     if (reportFile != NULL)
  337.         fclose(reportFile);
  338.  
  339.     delete [] newBinaryImage;
  340.  
  341.     UpdateFileIcons();
  342. }
  343.  
  344.  
  345. // ---------------------------------------------------------------------------
  346. //    • DoCompare                                                      [protected]
  347. // ---------------------------------------------------------------------------
  348.  
  349. void
  350. MacZStringWindow::DoCompare()
  351. {
  352.     char *                    newBinaryImage = NULL;
  353.     UInt32                    newBinarySize;
  354.     char *                    oldBinaryImage = NULL;
  355.     UInt32                    oldBinarySize;
  356.     FILE *                    reportFile = NULL;
  357.     Z_Boolean                reportOK;
  358.  
  359.     reportFile = FSp_fopen(&mDestFileSpec.GetFSSpec(), "w");
  360.     if (reportFile == NULL)
  361.     {
  362.         DisplayError("\pCould not open output file. Perhaps it is in use or locked.");
  363.         goto CleanUpAndReturn;
  364.     }
  365.  
  366.     // Process the data.
  367.     {
  368.         StCursor        watchCursor;
  369.  
  370.         ZStringTool        stringTool;
  371.         ZToolOptions    options;
  372.         GetUserOptions(options);
  373.  
  374.         if (!ReadBinaryImage(mSourceFileSpec, newBinaryImage, newBinarySize))
  375.             goto CleanUpAndReturn;
  376.  
  377.         if (!ReadBinaryImage(mCompareFileSpec, oldBinaryImage, oldBinarySize))
  378.             goto CleanUpAndReturn;
  379.  
  380.         stringTool.ProcessBinaries(newBinaryImage, newBinarySize, oldBinaryImage, oldBinarySize, options);
  381.         reportOK = stringTool.PrintReport(reportFile, options);
  382.     }
  383.  
  384.     if (!reportOK)
  385.         DisplayError("\pOne or more errors occurred during the comparison. See output for details.");
  386.     else
  387.         DisplaySuccess("\pComparison was successful. See destination file for results.");
  388.  
  389.     // Make it look like an MS IE html file.
  390.     SetTypeAndCreator(mDestFileSpec, 'TEXT', 'MSIE');
  391.  
  392. CleanUpAndReturn:
  393.     if (reportFile != NULL)
  394.         fclose(reportFile);
  395.  
  396.     delete [] newBinaryImage;
  397.     delete [] oldBinaryImage;
  398.  
  399.     UpdateFileIcons();
  400. }
  401.  
  402.  
  403. // ---------------------------------------------------------------------------
  404. //    • DoCreateOverride                                              [protected]
  405. // ---------------------------------------------------------------------------
  406.  
  407. void
  408. MacZStringWindow::DoCreateOverride()
  409. {
  410.     char *                    overrideFileImage = NULL;
  411.     UInt32                    overrideFileSize;
  412.     FILE *                    reportFile = NULL;
  413.     Handle                    newResHandle = NULL;
  414.     char *                    dictionary = NULL;
  415.     UInt32                    dictLength;
  416.  
  417.     // Determine what override ID to use.
  418.     LEditText * editTextControl = dynamic_cast<LEditText *>(FindPaneByID(pane_LanguageResourceTextBox));
  419.     ThrowIfNULL_(editTextControl);
  420.     SInt16 overrideID = editTextControl->GetValue();
  421.  
  422.     // Process the data.
  423.     {
  424.         StCursor        watchCursor;
  425.  
  426.         ZStringTool        stringTool;
  427.         ZToolOptions    options;
  428.         GetUserOptions(options);
  429.         
  430.         if (!ReadBinaryImage(mSourceFileSpec, overrideFileImage, overrideFileSize))
  431.             goto CleanUpAndReturn;
  432.         
  433.         stringTool.ProcessBinaries(overrideFileImage, overrideFileSize, NULL, 0, options);
  434.         stringTool.CreateOverrideDictionary(dictionary, dictLength);
  435.     }
  436.  
  437.     newResHandle = ::NewHandle(dictLength);
  438.     if (newResHandle == NULL)
  439.     {
  440.         DisplayError("\pOut of memory. Couldn't allocate new resource. Operation cancelled\n");
  441.         goto CleanUpAndReturn;
  442.     }
  443.  
  444.     memcpy(*newResHandle, dictionary, dictLength);
  445.  
  446.     // Try to open an existing file for write. If we can't, 
  447.     // we'll create a new one.
  448.     SInt16 resFileID = ::FSpOpenResFile(&mDestFileSpec.GetFSSpec(), fsRdWrPerm);
  449.     
  450.     if (resFileID == -1)
  451.     {
  452.         ::FSpCreateResFile(&mDestFileSpec.GetFSSpec(), 'RSED', 'rsrc', 0);
  453.     
  454.         resFileID = ::FSpOpenResFile(&mDestFileSpec.GetFSSpec(), fsRdWrPerm);
  455.     }
  456.     
  457.     if (resFileID == -1)
  458.     {
  459.         DisplayError("\pCould not open output file. Perhaps it is in use or locked.");
  460.         goto CleanUpAndReturn;
  461.     }
  462.     
  463.     // Remove any existing resource with the same ID.
  464.     Handle oldDictionary = ::Get1Resource(kZStringOverrideDictionaryResType, overrideID);
  465.     if (oldDictionary != NULL)
  466.         ::RemoveResource(oldDictionary);
  467.     
  468.     // Now, add the new resource.
  469.     ::AddResource(newResHandle, kZStringOverrideDictionaryResType, overrideID, "\p");
  470.     ::WriteResource(newResHandle);
  471.     ::CloseResFile(resFileID);
  472.  
  473.     // The resource is no longer valid because we closed the file.
  474.     newResHandle = NULL;
  475.  
  476.     DisplaySuccess("\pOverride dictionary was successfully created.");
  477.  
  478. CleanUpAndReturn:
  479.     if (newResHandle != NULL)
  480.         ::DisposeHandle(newResHandle);
  481.     
  482.     if (reportFile != NULL)
  483.         fclose(reportFile);
  484.  
  485.     delete [] overrideFileImage;
  486.     delete [] dictionary;
  487.     
  488.     UpdateFileIcons();
  489. }
  490.  
  491.  
  492. // ---------------------------------------------------------------------------
  493. //    • SelectFile                                                  [protected]
  494. // ---------------------------------------------------------------------------
  495.  
  496. void
  497. MacZStringWindow::SelectFile(
  498.     PaneIDT                    inTextID,
  499.     PaneIDT                    inIconID,
  500.     MacZStringFileSpec &    outFileSpec,
  501.     Boolean                    inExistingFile)
  502. {
  503.     FSSpec                fsSpec;
  504.     Boolean                specOK;
  505.     
  506.     if (inExistingFile)
  507.     {
  508.         UConditionalDialogs::LFileChooser        fileChooser;
  509.         LFileTypeList        typeList(fileTypes_All);
  510.         
  511.         specOK = fileChooser.AskChooseOneFile(typeList, fsSpec);
  512.     }
  513.     else
  514.     {
  515.         UConditionalDialogs::LFileDesignator    fileDesignator;
  516.         fileDesignator.SetFileCreator(FOUR_CHAR_CODE('****'));
  517.         specOK = fileDesignator.AskDesignateFile("\pZStringOutput.html");
  518.         
  519.         if (specOK)
  520.             fileDesignator.GetFileSpec(fsSpec);
  521.     }
  522.     
  523.     // If the selection was OK, update the user interface
  524.     if (specOK)
  525.         SetFile(inTextID, inIconID, fsSpec, outFileSpec);
  526.  
  527.     UpdateButtonStatus();
  528. }
  529.  
  530.  
  531. // ---------------------------------------------------------------------------
  532. //    • SetFile                                                  [protected]
  533. // ---------------------------------------------------------------------------
  534.  
  535. void
  536. MacZStringWindow::SetFile(
  537.     PaneIDT                    inTextID,
  538.     PaneIDT                    inIconID,
  539.     const FSSpec &            inFileSpec,
  540.     MacZStringFileSpec &    outFileSpec)
  541. {
  542.     outFileSpec.SetFileSpec(inFileSpec);
  543.     
  544.     LStaticText *    staticTextItem;
  545.     LStr255            fileName(inFileSpec.name);
  546.     
  547.     // Set the static text to indicate the file name
  548.     staticTextItem = dynamic_cast<LStaticText *>(FindPaneByID(inTextID));
  549.     ThrowIfNULL_(staticTextItem);
  550.     staticTextItem->SetText(fileName);
  551.     staticTextItem->Enable();
  552.     
  553.     // Set the icon
  554.     FileIconPane * iconPane = dynamic_cast<FileIconPane *>(FindPaneByID(inIconID));
  555.     ThrowIfNULL_(iconPane);
  556.     iconPane->Enable();
  557.     
  558.     if (outFileSpec.GetIconRef() != NULL)
  559.         iconPane->SetIconRef(outFileSpec.GetIconRef());
  560.     else
  561.         iconPane->SetIconID(icon_HTMLFileTypeIcon);
  562.  
  563.     UpdateButtonStatus();
  564. }
  565.  
  566.  
  567. // ---------------------------------------------------------------------------
  568. //    • UpdateFileIcons                                          [protected]
  569. // ---------------------------------------------------------------------------
  570.  
  571. void
  572. MacZStringWindow::UpdateFileIcons()
  573. {
  574.     // In case the creation of a file overwrote an existing file
  575.     // or created a new one, we'll update the file icons so the icon 
  576.     // in the Finder matches our icon.
  577.  
  578.     if (mSourceFileSpec.IsValid())
  579.         SetFile(pane_SourceFileNameStaticText, pane_SourceFileIcon, mSourceFileSpec.GetFSSpec(), mSourceFileSpec);
  580.  
  581.     if (mCompareFileSpec.IsValid())
  582.         SetFile(pane_CompareFileNameStaticText, pane_CompareFileIcon, mCompareFileSpec.GetFSSpec(), mCompareFileSpec);
  583.  
  584.     if (mDestFileSpec.IsValid())
  585.         SetFile(pane_DestFileNameStaticText, pane_DestFileIcon, mDestFileSpec.GetFSSpec(), mDestFileSpec);
  586. }
  587.  
  588.  
  589. /*------------------------------------------------------------------
  590.     ReadBinaryImage
  591. ------------------------------------------------------------------*/
  592.  
  593. Boolean
  594. MacZStringWindow::ReadBinaryImage(
  595.     const FSSpec &    inFileSpec,
  596.     char * &        outMemoryImage,
  597.     UInt32 &        outLength)
  598. {
  599.     FSSpec    theSpec = inFileSpec;
  600.     OSErr     err = noErr;
  601.     
  602.     // get the catalog info
  603.     CInfoPBRec    catInfo;
  604.     {
  605.         catInfo.hFileInfo.ioCompletion    = NULL;
  606.         catInfo.hFileInfo.ioVRefNum        = inFileSpec.vRefNum;
  607.         catInfo.hFileInfo.ioNamePtr        = const_cast<StringPtr>(inFileSpec.name);
  608.         catInfo.hFileInfo.ioFDirIndex    = 0;
  609.         catInfo.hFileInfo.ioDirID        = inFileSpec.parID;
  610.         err = ::PBGetCatInfoSync(&catInfo);
  611.     }
  612.     if (err != noErr)
  613.     {
  614.         DisplayError("\pError reading catalog info");
  615.         return false;
  616.     }
  617.     
  618.     // Allocate total memory required for binary image.
  619.     // We allocate the combined logical lengths of both forks. Since 
  620.     // we won't be scanning the resource map or the override resources 
  621.     // this will actually be a little more memory than we need.
  622.     outMemoryImage = new (std::nothrow) char[catInfo.hFileInfo.ioFlLgLen + catInfo.hFileInfo.ioFlRLgLen];
  623.     if (outMemoryImage == NULL)
  624.     {
  625.         DisplayError("\pNot enough memory to load file.");
  626.         return false;
  627.     }
  628.     
  629.     if (catInfo.hFileInfo.ioFlAttrib & ioDirMask)
  630.     {
  631.         DisplayError("\pSelected item is a directory.");
  632.         return false;
  633.     }
  634.     
  635.     // Initalize read data
  636.        Byte *    outMemPtr    = reinterpret_cast<Byte *>(outMemoryImage);
  637.     outLength    = 0;
  638.     
  639.     if (catInfo.hFileInfo.ioFlLgLen > 0)    // Data fork exists?
  640.     {
  641.         SInt16    dfRefNum = -1;
  642.         
  643.         // Open the data fork
  644.         err = ::FSpOpenDF(&theSpec, fsRdPerm, &dfRefNum);
  645.         if (err != noErr)
  646.         {
  647.             DisplayError("\pError opening data fork.");
  648.             return false;
  649.         }
  650.         
  651.         // Seek the start of file (redundant)
  652.         err = ::SetFPos(dfRefNum, fsFromStart, 0);
  653.         if (err != noErr)
  654.         {
  655.             DisplayError("\pError seeking start-of-file.");
  656.             return false;
  657.         }
  658.         
  659.         // Read the entire logical data fork
  660.         long    readLength    = catInfo.hFileInfo.ioFlLgLen;
  661.         err = ::FSRead(dfRefNum, &readLength, outMemPtr);
  662.         if (err != noErr)
  663.         {
  664.             DisplayError("\pError reading data fork.");
  665.             ::FSClose(dfRefNum);
  666.             return false;
  667.         }
  668.         outMemPtr += readLength;
  669.         outLength += readLength;
  670.         
  671.         // Close the data fork
  672.         ::FSClose(dfRefNum);    // Error is ignored
  673.     }
  674.     
  675.     if (catInfo.hFileInfo.ioFlRLgLen > 0)    // Resource fork exists?
  676.     {
  677.         // Preserve original resource file
  678.         SInt16    originalResFile = ::CurResFile();
  679.         SInt16    rfRefNum = -1;
  680.         
  681.         // Open resource fork
  682.         rfRefNum = ::FSpOpenResFile(&theSpec, fsRdPerm);
  683.         if ((err = ::ResError()) != noErr)
  684.         {
  685.             DisplayError("\pError opening resource fork.");
  686.             return false;
  687.         }
  688.         
  689.         // Read resources
  690.         UInt32 typeCount = ::Count1Types();
  691.         for (UInt32 i = 1; i <= typeCount; i++)    // loop through res types
  692.         {
  693.             ResType    resType;
  694.             ::Get1IndType(&resType, i);
  695.             
  696.             // Skip over override dictionary res types.
  697.             if (resType != kZStringOverrideDictionaryResType)
  698.             {
  699.                 UInt32    resCount = ::Count1Resources(resType);
  700.                 for (UInt32 i = 1; i <= resCount; i++)    // loop through res count
  701.                 {
  702.                     // Read resource
  703.                     Handle     resHandle = ::Get1IndResource(resType, i);
  704.                     if (resHandle != NULL)
  705.                     {
  706.                         Size    resSize = ::GetHandleSize(resHandle);
  707.                         ::BlockMoveData(*resHandle, outMemPtr, resSize);
  708.                         outMemPtr += resSize;
  709.                         outLength += resSize;
  710.                         ::ReleaseResource(resHandle);
  711.                     }
  712.                 }
  713.             }                
  714.         }
  715.         
  716.         // Close the resource fork
  717.         ::CloseResFile(rfRefNum);
  718.         
  719.         // Restore original resource file
  720.         ::UseResFile(originalResFile);
  721.     }
  722.     
  723.     return true;
  724. }
  725.  
  726.  
  727. /*------------------------------------------------------------------
  728.     DisplayError
  729. ------------------------------------------------------------------*/
  730.  
  731. void
  732. MacZStringWindow::DisplayError(
  733.     StringPtr            inErrorString)
  734. {
  735.     ::ParamText(inErrorString, "\p", "\p", "\p");
  736.     UModalAlerts::StopAlert(ALRT_Error);
  737. }
  738.         
  739.  
  740. /*------------------------------------------------------------------
  741.     DisplaySuccess
  742. ------------------------------------------------------------------*/
  743.  
  744. void
  745. MacZStringWindow::DisplaySuccess(
  746.     StringPtr            inSuccessString)
  747. {
  748.     ::ParamText(inSuccessString, "\p", "\p", "\p");
  749.     UModalAlerts::NoteAlert(ALRT_Error);
  750. }
  751.         
  752.  
  753. // ---------------------------------------------------------------------------
  754. //    • SetTypeAndCreator                                              [private]
  755. // ---------------------------------------------------------------------------
  756.  
  757. OSErr
  758. MacZStringWindow::SetTypeAndCreator(
  759.     const FSSpec &        inFileSpec,
  760.     OSType                inType,
  761.     OSType                inCreator)
  762. {
  763.     CInfoPBRec            pb;
  764.     OSErr                tempErr;
  765.  
  766.     memset(&pb, 0, sizeof(CInfoPBRec));
  767.  
  768.     pb.hFileInfo.ioVRefNum = inFileSpec.vRefNum;
  769.     pb.hFileInfo.ioNamePtr = (StringPtr)&inFileSpec.name[0];
  770.     pb.hFileInfo.ioDirID = inFileSpec.parID;
  771.     pb.hFileInfo.ioFDirIndex = 0;
  772.  
  773.     tempErr = ::PBGetCatInfoSync(&pb);
  774.     if (tempErr == noErr)
  775.     {
  776.         pb.hFileInfo.ioDirID = inFileSpec.parID;
  777.         pb.hFileInfo.ioFlFndrInfo.fdType = inType;
  778.         pb.hFileInfo.ioFlFndrInfo.fdCreator = inCreator;
  779.         tempErr = ::PBSetCatInfoSync(&pb);
  780.     }
  781.  
  782.     return tempErr;
  783. }
  784.  
  785.  
  786.