home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / central / prefwutil.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  39.0 KB  |  1,573 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "prefwutil.h"
  20.  
  21. #include "resgui.h"
  22. #include "uprefd.h"
  23. #include "macutil.h"
  24. #include "ufilemgr.h"
  25. #include "uerrmgr.h"
  26. #include "xp_mem.h"
  27. #include "macgui.h"
  28. #include "COffscreenCaption.h"
  29.  
  30. Boolean    CFilePicker::sResult = FALSE;
  31. Boolean    CFilePicker::sUseDefault = FALSE;        // Use default directory
  32. CStr255    CFilePicker::sPrevName;
  33.  
  34. CFilePicker::CFilePicker( LStream* inStream ): LView( inStream )
  35. {
  36.     // WARNING: if you add any streamable data here (because you're making a new custom
  37.     // Cppb in constructor) you will clobber CPrefFilePicker, which inherits from
  38.     // this class.  So beware!
  39.     fCurrentValue.vRefNum = 0;
  40.     fCurrentValue.parID = 0;
  41.     fCurrentValue.name[ 0 ] = 0;
  42.     fSet = FALSE;
  43.     fBrowseButton = NULL;
  44.     fPathName = NULL;
  45.     fPickTypes = Applications;
  46. }
  47.  
  48. void CFilePicker::FinishCreateSelf()
  49. {
  50.     ThrowIfNil_(fBrowseButton    = dynamic_cast<LControl*>(FindPaneByID(kBrowseButton)));
  51.     ThrowIfNil_(fPathName        = dynamic_cast<LCaption*>(FindPaneByID(kPathNameCaption)));
  52.  
  53.     fBrowseButton->SetValueMessage(msg_Browse);
  54.     fBrowseButton->AddListener(this);
  55. }
  56.  
  57. void CFilePicker::SetFSSpec( const FSSpec& fileSpec, Boolean touchSetFlag )
  58. {
  59.     if (touchSetFlag)
  60.         fSet = TRUE;
  61.     fCurrentValue = fileSpec;
  62.     
  63.     SetCaptionForPath( fPathName, fileSpec );
  64.     BroadcastMessage( msg_FolderChanged, this );
  65. }
  66.  
  67. void CFilePicker::ListenToMessage( MessageT inMessage, void* /*ioParam*/ )
  68. {
  69.     StandardFileReply        reply;
  70.     FSSpec                    currentValue;
  71.  
  72.     currentValue = GetFSSpec();
  73.     reply.sfFile = currentValue;
  74.     
  75.     if ( inMessage == msg_Browse )
  76.     {
  77.         switch ( fPickTypes )
  78.         {
  79.             case MailFiles:
  80.                 reply.sfFile = CPrefs::GetFilePrototype( CPrefs::MailFolder );
  81.             case AnyFile:
  82.             case Folders:
  83.             case TextFiles:
  84.             case ImageFiles:
  85.             case Applications:
  86.             {
  87.                 // Ñ pose the dialog and get the users new choice
  88.                 if ( CFilePicker::DoCustomGetFile( reply, fPickTypes, TRUE ) )
  89.                     SetFSSpec( reply.sfFile );
  90.             }
  91.             break;
  92.         }
  93.     }
  94. }
  95.  
  96. void CFilePicker::SetCaptionForPath( LCaption* captionToSet, const FSSpec& folderSpec )
  97. {
  98.     CStr255    pathName = FSSpecToPathName( folderSpec );
  99.     SetCaptionDescriptor( captionToSet, pathName, smTruncMiddle );    
  100. }
  101.  
  102. CStr255 CFilePicker::FSSpecToPathName( const FSSpec& spec )
  103. {
  104.     char* pPathName = CFileMgr::PathNameFromFSSpec( spec, true );
  105.     if ( pPathName == NULL && fPickTypes == Applications )
  106.     {
  107.         CStr255 badName(spec.name);
  108.         ErrorManager::PlainAlert
  109.             ( (char *)GetCString(BAD_APP_LOCATION_RESID), badName,
  110.                 (char *)GetCString(REBUILD_DESKTOP_RESID), NULL );
  111.         return badName;
  112.     }
  113.     CStr255 cPathName(pPathName);
  114.     XP_FREE( pPathName );
  115.     return cPathName;
  116. }
  117.  
  118. void CFilePicker::SetButtonTitle( Handle buttonHdl, CStr255& name, const Rect& buttonRect )
  119. {    
  120.     short            result;    //
  121.     short            width;    //
  122.  
  123.     sPrevName = name;
  124.     
  125.     CStr255 finalString(::GetCString(SELECT_RESID));
  126.  
  127.     width = ( buttonRect.right - buttonRect.left )
  128.         - ( StringWidth( finalString ) + 2 * CharWidth( '╩' ) );
  129.  
  130.     result = ::TruncString( width, name, smTruncMiddle );
  131.     
  132.     finalString += name;
  133.     SetControlTitle( (ControlHandle)(buttonHdl), finalString );
  134.     ValidRect( &buttonRect );
  135. }
  136.  
  137. #define kIsFolderFlag                0x10    // flag indicating the file is a directory.
  138. #define kInvisibleFlag                0x4000    // flag indicating that the file is invisible.
  139.  
  140. #define kGetDirButton                10
  141. #define kDefaultButton                12
  142.  
  143. PROCEDURE( CFilePicker::OnlyFoldersFileFilter, uppFileFilterYDProcInfo )
  144. pascal Boolean CFilePicker::OnlyFoldersFileFilter( CInfoPBPtr pBlock, void* /*data*/ )
  145. {    
  146.     Boolean        isFolder;
  147.     Boolean        isInvisible;
  148.     Boolean        dontShow;
  149.     
  150.     isFolder = ((pBlock->hFileInfo).ioFlAttrib) & kIsFolderFlag;
  151.     isInvisible = ((pBlock->dirInfo).ioDrUsrWds.frFlags) & kInvisibleFlag;
  152.     dontShow = !isFolder || isInvisible;
  153.  
  154.     return dontShow;
  155. }
  156.  
  157. PROCEDURE( CFilePicker::IsMailFileFilter, uppFileFilterYDProcInfo )
  158. pascal Boolean CFilePicker::IsMailFileFilter( CInfoPBPtr pBlock, void* /*data*/ )
  159. {
  160.     Boolean        isEudora;
  161.     Boolean        isMine;
  162.     Boolean        dontShow;
  163.     
  164.     isMine = ( pBlock->hFileInfo).ioFlFndrInfo.fdCreator == emSignature;
  165.     isEudora = ( pBlock->hFileInfo).ioFlFndrInfo.fdCreator == 'CSOm';
  166.     dontShow = !isMine && !isEudora;
  167.     
  168.     return dontShow;
  169. }
  170.  
  171. PROCEDURE( CFilePicker::SetCurrDirHook, uppDlgHookYDProcInfo )
  172. pascal short CFilePicker::SetCurrDirHook( short item, DialogPtr /*dialog*/, void* /*data*/ )
  173. {
  174.     if ( item == sfHookFirstCall )
  175.         return sfHookChangeSelection;
  176.     return item;
  177. }
  178.  
  179. PROCEDURE( CFilePicker::DirectoryHook, uppDlgHookYDProcInfo )
  180. pascal short CFilePicker::DirectoryHook( short item, DialogPtr dialog, void* data )
  181. {
  182.     short                 type;                //    menu item selected
  183.     Handle                handle;                //    needed for GetDialogItem
  184.     Rect                rect;                //    needed for GetDialogItem
  185.  
  186.     CStr255                tempName = sPrevName;
  187.     CStr255             name;
  188.  
  189.     CInfoPBRec            pb;
  190.     StandardFileReply*    sfrPtr;
  191.     OSErr                err;
  192.     short                returnVal;
  193.  
  194.     // Ñ default, except in special cases below
  195.     returnVal = item;
  196.     
  197.     // Ñ this function is only for main dialog box
  198.     if ( GetWRefCon((WindowPtr)dialog ) != sfMainDialogRefCon )
  199.         return returnVal;                    
  200.     
  201.     DirInfo* dipb = (DirInfo*)&pb;
  202.     // Ñ get sfrPtr from 3rd parameter to hook function
  203.     sfrPtr = (StandardFileReply*)((PickClosure*)data)->reply;
  204.  
  205.     GetDialogItem( dialog, kGetDirButton, &type, &handle, &rect );
  206.  
  207.     if ( item == sfHookFirstCall )
  208.     {
  209.         // Ñ determine current folder name and set title of Select button
  210.         dipb->ioCompletion = NULL;
  211.         dipb->ioNamePtr = (StringPtr)&tempName;
  212.         dipb->ioVRefNum = sfrPtr->sfFile.vRefNum;
  213.         dipb->ioDrDirID = sfrPtr->sfFile.parID;
  214.         dipb->ioFDirIndex = - 1;
  215.         err = PBGetCatInfoSync(&pb);
  216.         name = tempName;
  217.         CFilePicker::SetButtonTitle( handle, name, rect );
  218.  
  219.         return sfHookChangeSelection;        
  220.     }
  221.     else
  222.     {
  223.         // Ñ track name of folder that can be selected
  224.         // (also allow selection of folder aliases)
  225.         if ( ( sfrPtr->sfIsFolder) || ( sfrPtr->sfIsVolume) ||
  226.              ((sfrPtr->sfFlags & kIsAlias) && (sfrPtr->sfType == kContainerFolderAliasType)) )
  227.             name = sfrPtr->sfFile.name;
  228.         else
  229.         {
  230.             dipb->ioCompletion = NULL;
  231.             dipb->ioNamePtr = (StringPtr)&tempName;
  232.             dipb->ioVRefNum = sfrPtr->sfFile.vRefNum;
  233.             dipb->ioFDirIndex = -1;
  234.             dipb->ioDrDirID = sfrPtr->sfFile.parID;
  235.             err = PBGetCatInfoSync(&pb);
  236.             name = tempName;
  237.         }
  238.         
  239.         // Ñ change directory name in button title as needed
  240.         if ( name != sPrevName )
  241.             CFilePicker::SetButtonTitle( handle, name, rect );
  242.  
  243.         switch ( item )
  244.         {
  245.             // Ñ force return by faking a cancel
  246.             case kGetDirButton:    
  247.                 sResult = TRUE;            
  248.                 returnVal = sfItemCancelButton;
  249.             break;
  250.             
  251.             // Ñ use default directory
  252.             case kDefaultButton:
  253.                 sUseDefault = TRUE;
  254.                 returnVal = sfItemCancelButton;
  255.             break;                                    
  256.             
  257.             // Ñ flag no directory was selected
  258.             case sfItemCancelButton:
  259.                 sResult = FALSE;
  260.             break;    
  261.             
  262.             default:
  263.                 break;
  264.         }
  265.     }
  266.     return returnVal;
  267. }
  268.  
  269. Boolean CFilePicker::DoCustomGetFile( StandardFileReply& reply, 
  270.     CFilePicker::PickEnum pickTypes, Boolean isInited )
  271. {
  272.     Point                loc = { -1, -1 };
  273.     OSErr                gesErr;
  274.     long                gesResponse;
  275.     FileFilterYDUPP        filter = NULL;
  276.     DlgHookYDUPP        dialogHook;
  277.     short                dlogID = 0;
  278.     OSType                types[ 4 ];
  279.     OSType*                typeP;
  280.     short                typeCount = -1;
  281.     Boolean*            resultP = &reply.sfGood;
  282.     Boolean                wantPreview = FALSE;
  283.     PickClosure            closure;
  284.     
  285.     reply.sfIsVolume = 0;
  286.     reply.sfIsFolder = 0;
  287.     reply.sfFlags = 0;
  288.     reply.sfScript = smSystemScript;
  289.     reply.sfGood = FALSE;
  290.     closure.reply = &reply;
  291.     closure.inited = isInited;
  292.     typeP = types;
  293.     
  294.     if ( isInited )
  295.         dialogHook = &PROCPTR( SetCurrDirHook );
  296.     else
  297.         dialogHook = NULL;
  298.         
  299.     // Ñ╩initialize name of previous selection
  300.     sPrevName = reply.sfFile.name;
  301.  
  302.     StPrepareForDialog preparer;    
  303.     gesErr = Gestalt( gestaltStandardFileAttr, &gesResponse );
  304.     if ( gesResponse & ( 1L << gestaltStandardFile58 ) )
  305.     {
  306.         switch ( pickTypes )
  307.         {
  308.             case Folders:
  309.             {
  310.                 filter = &PROCPTR( OnlyFoldersFileFilter );    
  311.                 dlogID = DLOG_GETFOLDER;
  312.                 dialogHook = &PROCPTR( DirectoryHook );
  313.                 resultP = &sResult;
  314.                 typeP = NULL;
  315.             }
  316.             break;
  317.             
  318.             case AnyFile:
  319.             {
  320.                 typeP = NULL;
  321.             }
  322.             break;
  323.             
  324.             case MailFiles:
  325.             {
  326.                 filter = &PROCPTR( IsMailFileFilter );
  327.                 types[ 0 ] = 'TEXT';
  328.                 typeCount = 1;
  329.             }
  330.             break;
  331.             
  332.             case TextFiles:
  333.             {
  334.                 types[ 0 ] = 'TEXT';
  335.                 typeCount = 1;
  336.             }
  337.             break;
  338.             
  339.             case ImageFiles:
  340.             {
  341.                 types[ 0 ] = 'GIFf';
  342.                 types[ 1 ] = 'TEXT';
  343.                 types[ 2 ] = 'JPEG';
  344.                 typeCount = 3;
  345.                 wantPreview = TRUE;
  346.             }
  347.             break;
  348.             
  349.             case Applications:
  350.             {
  351.                 types[0] = 'APPL';
  352.                 types[1] = 'adrp';    // Application aliases
  353.                 typeCount = 2;
  354.             }
  355.             break;    
  356.         }
  357.     }
  358.     
  359.     if ( wantPreview && UEnvironment::HasGestaltAttribute( gestaltQuickTime, 0xFFFF ) )
  360.         ::CustomGetFilePreview( filter, typeCount, typeP, &reply, dlogID, loc, dialogHook,
  361.             NULL, NULL, NULL, &closure );
  362.     else
  363.         ::CustomGetFile( filter, typeCount, typeP, &reply, dlogID, loc, dialogHook,
  364.             NULL, NULL, NULL, &closure );
  365.  
  366.     // follow any folder aliases that may be returned
  367.     if (*resultP && pickTypes == Folders) {
  368.         Boolean b1, b2;
  369.         ThrowIfOSErr_( ResolveAliasFile(&reply.sfFile, true, &b1, &b2) );
  370.     }
  371.     
  372.     return *resultP;
  373. }
  374.  
  375. Boolean CFilePicker::DoCustomPutFile( StandardFileReply& reply,
  376.     const CStr255& prompt, Boolean inited )
  377. {
  378.     Point            loc = { -1, -1 };
  379.     CStr255            filename = CStr255::sEmptyString;
  380.     DlgHookYDUPP    dialogHook = NULL;
  381.     
  382.     if ( inited  )
  383.     {
  384.         filename = reply.sfFile.name;
  385.         dialogHook = &PROCPTR( SetCurrDirHook );
  386.     }
  387.     
  388.     CustomPutFile( (ConstStr255Param)prompt,
  389.         (ConstStr255Param)filename,
  390.         &reply,
  391.         0,
  392.         loc,
  393.         dialogHook,
  394.         NULL,
  395.         NULL,
  396.         NULL,
  397.         NULL );
  398.         
  399.     return reply.sfGood;
  400. }    
  401.  
  402. // ===========================================================================
  403. //    COtherSizeDialog
  404. // ===========================================================================
  405.  
  406. const ResIDT    edit_SizeField =         1504;
  407.  
  408. COtherSizeDialog::COtherSizeDialog( LStream* inStream ): LDialogBox( inStream )
  409. {
  410. }
  411.  
  412. void COtherSizeDialog::FinishCreateSelf()
  413. {
  414.     LDialogBox::FinishCreateSelf();
  415.     
  416.     mSizeField = (LEditField*)FindPaneByID( edit_SizeField );
  417.  
  418.     //    Set the edit field to go on duty whenever
  419.     //    this dialog box goes on duty.
  420.  
  421.     fRef = NULL;
  422.     SetLatentSub( mSizeField );
  423. }
  424.  
  425. void COtherSizeDialog::SetValue( Int32 inFontSize )
  426. {
  427.     if ( inFontSize > 128 )
  428.         inFontSize = 128;
  429.         
  430.     mSizeField->SetValue( inFontSize );
  431.     mSizeField->SelectAll();
  432. }
  433.  
  434. Int32 COtherSizeDialog::GetValue() const
  435. {
  436.     Int32        size;
  437.     
  438.     size = mSizeField->GetValue();
  439.     if ( size > 128 )
  440.         size = 128;
  441.         
  442.     return size;
  443. }
  444.  
  445. void COtherSizeDialog::SetReference( LControl* which )
  446. {
  447.     fRef = which;
  448. }
  449.  
  450. // ---------------------------------------------------------------------------
  451. //        Ñ ListenToMessage
  452. // ---------------------------------------------------------------------------
  453. //    This member function illustrates an alternate method for this dialog box
  454. //    to communicate with its invoker when the user clicks the defualt (OK) button.
  455. //    Usually, when the user clicks the default button, LDialogBox::ListenToMessage()
  456. //    calls the supercommander's ObeyCommand() function passing it the value message
  457. //    of the default button and a pointer to the dialog box object in the ioParam
  458. //    parameter. This method also passes the value message of the default button,
  459. //    but rather than sending a pointer to the dialog in ioParam, it sends the
  460. //    new point size.
  461. //
  462. //    The advantage of using the alternate method is that the client that invokes
  463. //    the dialog doesn't have to call any of the dialog class's member functions
  464. //    to get its value and is not responsible for closing the dialog box. The
  465. //    disadvantage is that you have to pass all the information back through
  466. //    ObeyCommand()'s single ioParam parameter. 
  467.  
  468. void COtherSizeDialog::ListenToMessage(MessageT inMessage, void *ioParam)
  469. {
  470.     Int32    newFontSize;
  471.  
  472.     switch ( inMessage )
  473.     {
  474.         case msg_ChangeFontSize:
  475.             //    This is the command number associated with this dialog's
  476.             //    OK button. It's also used as a command number to send
  477.             //    to the dialog's supercommander which is presumably
  478.             //    the commander that created and invoked the dialog.
  479.  
  480.             newFontSize = mSizeField->GetValue();
  481.  
  482.             //    Note that we use the second parameter of ObeyCommand() to
  483.             //    specify the new font size. When the menu mechanism invokes
  484.             //    ObeyCommand(), the second parameter is always nil.
  485.             
  486.             BroadcastMessage( msg_ChangeFontSize, this );
  487.             
  488.             //    Since we want the OK button to close the dialog box as
  489.             //    well as change the font size, we change the message to close
  490.             //    and let the flow fall through to the default case.
  491.  
  492.             inMessage = cmd_Close;
  493.             
  494.             //    FALLTHROUGH INTENTIONAL
  495.             //    to get the base class to close the dialog box
  496.  
  497.         default:
  498.             LDialogBox::ListenToMessage(inMessage, ioParam);
  499.             break;
  500.     }
  501. }
  502.  
  503.  
  504. LArrowGroup::LArrowGroup( LStream* inStream ): LView( inStream )
  505. {
  506.     fSize = NULL;
  507.     fArrows = NULL;
  508.     fValue = 0L;
  509.     fMinValue = 0L;
  510.     fMaxValue = 99999999L;
  511.     fStringID = MEGA_RESID;
  512.     this->BuildControls();
  513. }
  514.  
  515. void LArrowGroup::SetStringID(ResIDT stringID)
  516. {
  517.     fStringID = stringID;
  518. }
  519.  
  520. void LArrowGroup::ListenToMessage( MessageT message, void* ioParam )
  521. {
  522.     if ( message == msg_ArrowsHit )
  523.     {
  524.         Int16    whichHalf = *(Int16*)ioParam;
  525.         
  526.         if ( whichHalf == mTopHalf )
  527.             SetValue( fValue + 1 );
  528.         else
  529.             SetValue( fValue - 1 );
  530.     }
  531. }
  532.  
  533. void LArrowGroup::SetValue( Int32 value )
  534. {
  535.     if ( value < fMinValue )
  536.         value = fMinValue;
  537.     else if ( value > fMaxValue )
  538.         value = fMaxValue;
  539.         
  540.     CStr255    string;
  541.     NumToString( value, string );
  542.     string += CStr255(*GetString(fStringID));
  543.     fSize->SetDescriptor( string );
  544.     fValue = value;
  545. }
  546.  
  547. void LArrowGroup::SetMaxValue( Int32 newMax )
  548. {
  549.     if ( fValue > newMax )
  550.         SetValue( newMax );
  551.     fMaxValue = newMax;
  552. }
  553.  
  554. void LArrowGroup::SetMinValue( Int32 newMin )
  555. {
  556.     if ( fValue < newMin )
  557.         SetValue( newMin );
  558.     fMinValue = newMin;
  559. }
  560.  
  561.  
  562. void LArrowGroup::BuildControls()
  563. {
  564.     SPaneInfo        paneInfo;
  565.     
  566.     paneInfo.paneID = 'Actl';
  567.     paneInfo.width = 15;
  568.     paneInfo.height = 25;
  569.     paneInfo.visible = TRUE;
  570.     paneInfo.enabled = TRUE;
  571.     paneInfo.left = mFrameSize.width - 16;
  572.     paneInfo.top = 0;
  573.     paneInfo.userCon = 0;
  574.     paneInfo.superView = this;
  575.  
  576.     fArrows = new LArrowControl( paneInfo, msg_ArrowsHit );
  577.     ThrowIfNil_(fArrows);
  578.     fArrows->AddListener( this );
  579.     
  580.     paneInfo.paneID = 'capt';
  581.     paneInfo.width = mFrameSize.width - 16;
  582.     paneInfo.height = 12;
  583.     paneInfo.left = 0;
  584.     paneInfo.top = 5;
  585.     
  586.     fSize = new COffscreenCaption(paneInfo, "\p", 10000);
  587. }
  588.  
  589. CColorButton::CColorButton( LStream *inStream ): LButton( inStream )
  590. {
  591.     fInside = FALSE;
  592.     mNormalID = 0;
  593.     mPushedID = 1;
  594. }
  595.  
  596. void CColorButton::DrawGraphic( ResIDT inGraphicID )
  597. {
  598.     Rect    frame;
  599.  
  600.     CalcLocalFrameRect( frame );
  601.     UGraphics::SetFore( CPrefs::Black );
  602.     if ( IsEnabled() )
  603.     {
  604.         if ( inGraphicID == mPushedID )
  605.         {
  606.             ::PenSize( 2, 2 );
  607.             ::PenPat( &qd.black );
  608.             ::FrameRect( &frame );
  609.         }
  610.         else
  611.         {
  612.             ::PenSize( 1, 1 );
  613.             ::PenPat( &qd.black );
  614.             ::FrameRect( &frame );
  615.             UGraphics::SetFore( CPrefs::White );
  616.             ::InsetRect( &frame, 1, 1 );
  617.             ::FrameRect( &frame );
  618.             UGraphics::SetFore( CPrefs::Black );
  619.         }
  620.     }
  621.     else
  622.     {
  623.         ::PenSize( 1, 1 );
  624.         ::PenPat( &qd.gray );
  625.         ::FrameRect( &frame );
  626.         ::PenPat( &qd.black );
  627.  
  628.     }
  629.         
  630.     RGBForeColor( &fColor );
  631.  
  632.     if ( inGraphicID == mPushedID )
  633.         ::InsetRect( &frame, 3, 3 );
  634.     else
  635.         ::InsetRect( &frame, 2, 2 );
  636.         
  637.     ::FillRect( &frame, &( UQDGlobals::GetQDGlobals()->black ) );
  638.     UGraphics::SetFore( CPrefs::Black );
  639. }
  640.  
  641. void CColorButton::HotSpotResult( short inHotSpot )
  642. {
  643.     Point where;
  644.     where.h = where.v = 0;
  645.     RGBColor outColor;
  646.  
  647.     if ( ::GetColor(where, (unsigned char *)*GetString(PICK_COLOR_RESID),
  648.                                                         &fColor,&outColor) )
  649.     {
  650.         if ( !UGraphics::EqualColor(fColor, outColor) )
  651.         {
  652.             fColor = outColor;
  653.             BroadcastValueMessage();
  654.         }
  655.     }
  656.  
  657.     // Ñ turn off the black border
  658.     HotSpotAction( inHotSpot, FALSE, TRUE );
  659.  
  660. }
  661.  
  662. FileIconsLister::FileIconsLister (CGAPopupMenu * target)
  663. :    StdPopup (target)
  664. {
  665.     fIcons = nil;
  666. }
  667.  
  668. FileIconsLister::~FileIconsLister()
  669. {    // Debugging purposes only
  670. }
  671.  
  672. void
  673. FileIconsLister::SetIconList (CApplicationIconInfo * icons)
  674. {
  675.     fIcons = icons;
  676. }
  677.  
  678. short
  679. FileIconsLister::GetCount()
  680. {
  681.     if (fIcons == NULL)
  682.         return 0;
  683.     else
  684.         return fIcons->GetFileTypeArraySize();
  685. }
  686.  
  687. CStr255    
  688. FileIconsLister::GetText (short item)
  689. {
  690.     CFileType * fileType;
  691.     fIcons->fDocumentIcons->FetchItemAt (item, &fileType);
  692.     return fileType->fIconSig;
  693. }
  694.  
  695. // ÑÑ Constructors/destructors
  696.  
  697. CMimeTable::CMimeTable(LStream *inStream) : LTable(inStream)
  698. {
  699.     fContainer = NULL;
  700.     fNetscapeIcon = NULL;
  701.     fPluginIcon = NULL;
  702. }
  703.  
  704. void CMimeTable::FinishCreateSelf()
  705. {
  706.     SetCellDataSize(sizeof(PrefCellInfo));
  707.     
  708.     for (TableIndexT i = 1; i <= CPrefs::sMimeTypes.GetCount(); i++)    // Insert a row for each mime type
  709.     {
  710.         CMimeMapper * mime;
  711.         CPrefs::sMimeTypes.FetchItemAt(i, &mime);
  712.         ThrowIfNil_(mime);
  713.         if (!mime->IsTemporary())
  714.         {
  715.             CMimeMapper * duplicate = new CMimeMapper(*mime);
  716.             PrefCellInfo cellInfo;
  717.             InsertRows(1, i, &cellInfo);
  718.             BindCellToApplication(i, duplicate);
  719.         }
  720.     }
  721.     
  722.     // Cache a handle to the Navigator application icon
  723.     CApplicationIconInfo* netscapeInfo = fApplList.GetAppInfo(emSignature);
  724.     ThrowIfNil_(netscapeInfo);
  725.     ThrowIfNil_(netscapeInfo->fDocumentIcons);
  726.     fNetscapeIcon = netscapeInfo->fApplicationIcon;
  727.     
  728.     // Cache a handle to the standard plug-in icon
  729.     LArrayIterator iterator(*(netscapeInfo->fDocumentIcons));
  730.     CFileType* fileInfo;
  731.     while (iterator.Next(&fileInfo))
  732.     {
  733.         if (fileInfo->fIconSig == emPluginFile)    
  734.         {
  735.             fPluginIcon = fileInfo->fIcon;
  736.             break;    
  737.         }
  738.     }
  739.  
  740.     LTable::FinishCreateSelf();
  741.  
  742.     // Set latent subcommander of supercommander of supercommander, which is the
  743.     // view that contains the scroller of this table, to table
  744. //    if( GetSuperCommander()->GetSuperCommander() )
  745. //        (GetSuperCommander()->GetSuperCommander())->SetLatentSub(this);
  746.     LCommander::SwitchTarget(this);
  747. }
  748.  
  749. CApplicationIconInfo* CMimeTable::GetAppInfo(CMimeMapper* mapper)
  750. {
  751.     return fApplList.GetAppInfo(mapper->GetAppSig(), mapper);
  752. }
  753.  
  754.  
  755. // Sets cell data to values of the mapper
  756. void CMimeTable::BindCellToApplication(TableIndexT row, CMimeMapper* mapper)
  757. {
  758.     CApplicationIconInfo* appInfo = GetAppInfo(mapper);
  759.     
  760.     // Now figure out the extensions from the netlib
  761.     PrefCellInfo cellInfo(mapper, appInfo);
  762.     TableCellT cell;
  763.     cell.row = row;
  764.     cell.col = 1;
  765.     SetCellData(cell, &cellInfo);
  766. }
  767.  
  768.  
  769. void CMimeTable::DrawSelf()
  770. {
  771.     RgnHandle localUpdateRgnH = GetLocalUpdateRgn();
  772.     Rect updateRect = (**localUpdateRgnH).rgnBBox;
  773.     DisposeRgn(localUpdateRgnH);
  774.     
  775.     {
  776.         StColorState saveTheColor;
  777.         RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF};
  778.         RGBBackColor(&white);
  779.         EraseRect(&updateRect);
  780.     }
  781.     
  782.     LTable::DrawSelf();
  783. }
  784.  
  785.  
  786. void CMimeTable::HiliteCell(const TableCellT &inCell)
  787. {
  788.     StColorState saveTheColor;
  789.     RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF};
  790.     RGBBackColor(&white);
  791.     
  792.     LTable::HiliteCell(inCell);
  793. }
  794.  
  795.  
  796. void CMimeTable::UnhiliteCell(const TableCellT &inCell)
  797. {
  798.     StColorState saveTheColor;
  799.     RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF};
  800.     RGBBackColor(&white);
  801.     
  802.     LTable::UnhiliteCell(inCell);
  803. }
  804.  
  805.  
  806.  
  807. #define offsetTable            7
  808. #define offsetTextTop        15
  809. #define offsetMimeType        (offsetTable + 0)
  810. #define offsetIcon            (offsetTable + 166)
  811. #define offsetHandler        (offsetIcon + 24)
  812. #define widthMimeType        (offsetIcon - offsetMimeType - 5)
  813.  
  814. void CMimeTable::DrawCell(const TableCellT    &inCell)
  815. {
  816.     Rect cellFrame;
  817.     
  818.     if (FetchLocalCellFrame(inCell, cellFrame))
  819.     {
  820.         ::PenPat( &(UQDGlobals::GetQDGlobals()->gray) );
  821.         ::MoveTo(cellFrame.left, cellFrame.bottom-1);
  822.         ::LineTo(cellFrame.right, cellFrame.bottom-1);
  823.         ::PenPat( &(UQDGlobals::GetQDGlobals()->black) );
  824.         
  825.         PrefCellInfo cellInfo;
  826.         GetCellData(inCell, &cellInfo);
  827.         UTextTraits::SetPortTextTraits(10000);    // HACK
  828.         
  829.         // Draw mime type
  830.         CStr255 description = cellInfo.fMapper->GetDescription();
  831.         if (description.IsEmpty())
  832.             description = cellInfo.fMapper->GetMimeName();
  833.         short result = ::TruncString(widthMimeType, description, smTruncMiddle);
  834.         ::MoveTo(offsetMimeType, cellFrame.top+offsetTextTop);
  835.         ::DrawString(description);
  836.             
  837.         // Draw the icon
  838.         CMimeMapper::LoadAction loadAction = cellInfo.fMapper->GetLoadAction();
  839.         if (loadAction == CMimeMapper::Launch || loadAction == CMimeMapper::Plugin || loadAction == CMimeMapper::Internal)
  840.         {
  841.             Rect r;
  842.             r.left = offsetIcon;
  843.             r.top = cellFrame.top + 2;
  844.             r.right = r.left + 16;
  845.             r.bottom = r.top + 16;
  846.             
  847.             Handle iconHandle;
  848.             if (loadAction == CMimeMapper::Plugin)
  849.                 iconHandle = fPluginIcon;
  850.             else if (loadAction == CMimeMapper::Internal)
  851.                 iconHandle = fNetscapeIcon;
  852.             else
  853.                 iconHandle = cellInfo.fIconInfo->fApplicationIcon;
  854.             XP_ASSERT(iconHandle);
  855.             
  856.             if (iconHandle)
  857.             {
  858.                 if (loadAction == CMimeMapper::Launch && !(cellInfo.fIconInfo->fApplicationFound))
  859.                     ::PlotIconSuite(&r, atHorizontalCenter, ttDisabled, iconHandle);
  860.                 else
  861.                     ::PlotIconSuite(&r, atHorizontalCenter, ttNone, iconHandle);
  862.             }
  863.         }
  864.             
  865.         // Draw the handler name
  866.         ::MoveTo(offsetHandler, cellFrame.top+offsetTextTop);
  867.         switch (loadAction)
  868.         {
  869.             case CMimeMapper::Save:
  870.                 ::DrawString(*GetString(SAVE_RESID));
  871.                 break;
  872.             case CMimeMapper::Unknown:
  873.                 ::DrawString(*GetString(UNKNOWN_RESID));
  874.                 break;
  875.             case CMimeMapper::Internal:
  876.                 ::DrawString(*GetString(INTERNAL_RESID));
  877.                 break;
  878.             case CMimeMapper::Launch:
  879.                 ::DrawString(cellInfo.fMapper->GetAppName());
  880.                 break;
  881.             case CMimeMapper::Plugin:
  882.                 ::DrawString(cellInfo.fMapper->GetPluginName());
  883.                 break;
  884.         }
  885.     }
  886. }
  887.  
  888.  
  889. // Returns PrefCellInfo for the given cell
  890. void CMimeTable::GetCellInfo(PrefCellInfo& cellInfo, int row)
  891. {
  892.     TableCellT    cell;
  893.     cell.row = row;
  894.     cell.col = 1;
  895.     GetCellData(cell, &cellInfo);
  896. }
  897.  
  898. void CMimeTable::FreeMappers()
  899. {
  900.     TableCellT    cell;
  901.     cell.col = 1;
  902.     PrefCellInfo cellInfo;
  903.     for (int i=1; i<= mRows; i++)
  904.     {
  905.         cell.row = i;
  906.         GetCellData(cell, &cellInfo);
  907.         delete cellInfo.fMapper;
  908.     }
  909. }
  910.  
  911.  
  912. //
  913. // Scroll the view as little as possible to move the specified cell
  914. // entirely within the frame.  Currently we only handle scrolling
  915. // up or down a single line (when the selection moves because of
  916. // and arrow key press).
  917. //
  918. void CMimeTable::ScrollCellIntoFrame(const TableCellT& inCell)
  919. {
  920.     // Compute bounds of specified cell in image coordinates
  921.     Int32 cellLeft = 0;
  922.     Int32 cellRight = 1;
  923.     Int32 cellBottom = inCell.row * mRowHeight - 2;
  924.     Int32 cellTop = cellBottom - mRowHeight + 2;
  925.  
  926.     if (ImagePointIsInFrame(cellLeft, cellTop) &&
  927.         ImagePointIsInFrame(cellRight, cellBottom))
  928.     {
  929.         return;                // Cell is already within Frame
  930.     }
  931.     else
  932.     {
  933.         if (cellTop + mImageLocation.v < mFrameLocation.v)        
  934.             ScrollImageTo(cellLeft, cellTop, true);                // Scroll up                    
  935.         else                                
  936.             ScrollPinnedImageBy(0, mRowHeight, true);            // Scroll down
  937.     }
  938. }
  939.  
  940. Boolean    CMimeTable::HandleKeyPress(const EventRecord &inKeyEvent)
  941. {
  942.     Char16 theChar = inKeyEvent.message & charCodeMask;
  943.     Boolean handled = false;
  944.     
  945.     TableIndexT tableRows;
  946.     TableIndexT tableCols;
  947.     TableCellT currentCell;
  948.     GetSelectedCell(currentCell);
  949.     GetTableSize(tableRows, tableCols);
  950.     
  951.     switch (theChar)
  952.     {
  953.         case char_UpArrow:
  954.             currentCell.row--;
  955.             if (currentCell.row >= 1)
  956.                 SelectCell(currentCell);
  957.             handled = true;
  958.             break;
  959.  
  960.         case char_DownArrow:
  961.             currentCell.row++;
  962.             if (currentCell.row <= tableRows)
  963.                 SelectCell(currentCell);
  964.             handled = true;
  965.             break;
  966.             
  967.         case char_PageUp:
  968.         case char_PageDown:
  969.         case char_Home:
  970.         case char_End:
  971.         default:
  972.             handled = LCommander::HandleKeyPress(inKeyEvent);
  973.     }
  974.     
  975.     return handled;
  976. }
  977.  
  978.  
  979.  
  980. /************************************************************************************
  981.  Preferences MimeMapping window
  982.  ************************************************************************************/
  983. // utility callback function for getting icons
  984. pascal Handle MyIconGetter( ResType theType, Ptr yourDataPtr );
  985.  
  986. // function that creates an item cache that we want
  987. OSErr CreateCache(Handle & cache, short resID);
  988.  
  989. static IconGetterUPP MyIconGetterUPP = NULL;
  990.  
  991. pascal Handle MyIconGetter( ResType theType, Ptr yourDataPtr )
  992. {
  993.     Handle res, resCopy;
  994.     
  995.     resCopy = res = ::Get1Resource( theType, (short)yourDataPtr );
  996.     
  997.     ::HandToHand( &resCopy );
  998.     ::ReleaseResource( res );
  999.     return resCopy;
  1000. }
  1001.  
  1002.  
  1003. OSErr CreateCache( Handle& cache, short resID )
  1004. {
  1005.     if ( MyIconGetterUPP == NULL )
  1006.         MyIconGetterUPP = NewIconGetterProc( MyIconGetter );
  1007.  
  1008.     OSErr err = MakeIconCache( &cache, MyIconGetterUPP, (Ptr)resID );
  1009.  
  1010.     if ( err )
  1011.         return err;
  1012.  
  1013.     Rect r;
  1014.     r.top = r.left = 0;
  1015.     r.bottom = r.right = 16;
  1016.  
  1017.     err = LoadIconCache( &r, atHorizontalCenter, ttNone, cache );
  1018.     return err;
  1019. }
  1020.  
  1021.  
  1022. Handle CFileType::sDefaultDocIcon = NULL;
  1023.  
  1024. CFileType::CFileType( OSType iconSig )
  1025. {
  1026.     InitializeDefaults();
  1027.     fIconSig = iconSig;
  1028.     fIcon = sDefaultDocIcon;
  1029. }
  1030.  
  1031. CFileType::~CFileType()
  1032. {
  1033.     if ( fIcon && ( fIcon != sDefaultDocIcon ) )
  1034.         ::DisposeIconSuite( fIcon, TRUE );
  1035. }
  1036.  
  1037. // Initializes default values
  1038. void CFileType::InitializeDefaults()
  1039. {
  1040.     if ( sDefaultDocIcon == NULL )
  1041.     {
  1042.         StUseResFile resFile(kSystemResFile);
  1043.         ::CreateCache( sDefaultDocIcon, genericDocumentIconResource );
  1044.     }
  1045.     ThrowIfNil_( sDefaultDocIcon );
  1046. }
  1047.  
  1048. // Clear the default values
  1049. void CFileType::ClearDefaults()
  1050. {
  1051.     if ( sDefaultDocIcon )
  1052.         ::DisposeIconSuite( sDefaultDocIcon, TRUE );
  1053.     sDefaultDocIcon = NULL;
  1054. }
  1055.  
  1056. // ÑÑ globals
  1057. Handle    CApplicationIconInfo::sDefaultAppIcon = NULL;
  1058. LArray *    CApplicationIconInfo::sDocumentIcons = NULL;
  1059. Boolean    CApplicationIconInfo::sHandlesAE = TRUE;
  1060.  
  1061. // Call me when application has not been found. Assigns default values
  1062. CApplicationIconInfo::CApplicationIconInfo( OSType appSig )
  1063. {
  1064.     InitializeDefaults();
  1065.     
  1066.     fAppSig = appSig;
  1067.     fApplicationIcon = sDefaultAppIcon;
  1068.     fDocumentIcons = sDocumentIcons;
  1069.     fHandlesAE = sHandlesAE;
  1070.     fApplicationFound = FALSE;
  1071. }
  1072.  
  1073. // Call me when app was found
  1074. CApplicationIconInfo::CApplicationIconInfo(
  1075.     OSType        appSig,
  1076.     Handle        appIcon, 
  1077.     LArray*        documentIcons,
  1078.     Boolean        handlesAE)
  1079. {
  1080.     InitializeDefaults();
  1081.     
  1082.     fAppSig = appSig;
  1083.     fApplicationIcon = appIcon;
  1084.     fDocumentIcons = documentIcons;
  1085.     fHandlesAE = handlesAE;
  1086.     fApplicationFound = TRUE;
  1087. }
  1088.  
  1089. CApplicationIconInfo::~CApplicationIconInfo()
  1090. {
  1091.     if ( fDocumentIcons == sDocumentIcons )
  1092.         return;    // Do not delete our defaults
  1093.     for ( Int32 i = 1; i <= fDocumentIcons->GetCount(); i++ )
  1094.     {
  1095.         CFileType* f;
  1096.         fDocumentIcons->FetchItemAt( i, &f );
  1097.         delete f;
  1098.     }
  1099.  
  1100.     delete fDocumentIcons;
  1101.  
  1102.     if ( fApplicationIcon != sDefaultAppIcon )
  1103.         ::DisposeIconSuite( fApplicationIcon, TRUE );
  1104. }
  1105.  
  1106. // ÑÑ access
  1107.  
  1108. // Gets file type by the index
  1109. CFileType* CApplicationIconInfo::GetFileType( int index )
  1110. {
  1111.     CFileType* f;
  1112.     if (index > fDocumentIcons->GetCount() )
  1113. #ifdef DEBUG
  1114.          XP_ABORT();
  1115. #else
  1116.          return NULL; 
  1117. #endif
  1118.     fDocumentIcons->FetchItemAt( index, &f );
  1119.     return f;
  1120. }    
  1121.  
  1122. // Gets number of file types
  1123. int CApplicationIconInfo::GetFileTypeArraySize()
  1124. {
  1125.     return fDocumentIcons->GetCount();
  1126. }
  1127.  
  1128. // ÑÑ misc
  1129.  
  1130. void CApplicationIconInfo::InitializeDefaults()
  1131. {
  1132.     if (sDocumentIcons != NULL)
  1133.         return;
  1134.  
  1135.     // Create a default document icon list, size 1, generic icon of type 'TEXT'
  1136.     sDocumentIcons = new LArray;
  1137.     ThrowIfNil_( sDocumentIcons );
  1138.     
  1139.     CFileType* newType = new CFileType( 'TEXT' );
  1140.     ThrowIfNil_( newType );
  1141.  
  1142.     sDocumentIcons->InsertItemsAt( 1, LArray::index_Last, &newType );
  1143.     
  1144.     // Get the default application icon
  1145.     StUseResFile resFile(kSystemResFile);
  1146.     ::CreateCache( sDefaultAppIcon, genericApplicationIconResource );
  1147.     ThrowIfNil_( sDefaultAppIcon );
  1148. }
  1149.  
  1150. void CApplicationIconInfo::ClearDefaults()
  1151. {
  1152.     if ( sDocumentIcons == NULL )
  1153.         return;    // Nothing allocated, nothing deleted
  1154.     for ( Int32 i = 1; i <= sDocumentIcons->GetCount(); i++ )
  1155.     {
  1156.         CFileType* f;
  1157.         sDocumentIcons->FetchItemAt( i, &f );
  1158.         delete f;
  1159.     }
  1160.  
  1161.     delete sDocumentIcons;
  1162.     sDocumentIcons = NULL;
  1163.  
  1164.     if ( sDefaultAppIcon )
  1165.         DisposeIconSuite( sDefaultAppIcon, TRUE );
  1166.     sDefaultAppIcon = NULL;
  1167.     
  1168.     CFileType::ClearDefaults();
  1169. }
  1170.  
  1171.  
  1172.  
  1173. CApplicationList::CApplicationList() : LArray()
  1174. {
  1175.     CApplicationIconInfo::InitializeDefaults();
  1176. }
  1177.  
  1178. CApplicationList::~CApplicationList()
  1179. {
  1180.     for (Int32 i = 1; i <= mItemCount; i++)
  1181.     {
  1182.         CApplicationIconInfo * f;
  1183.         FetchItemAt(i, &f);
  1184.         delete f;
  1185.     }
  1186.     CApplicationIconInfo::ClearDefaults();
  1187. }
  1188.  
  1189.  
  1190. CApplicationIconInfo* CApplicationList::GetAppInfo(OSType appSig, CMimeMapper* mapper)
  1191. {
  1192.     // Try to find the application that matches the sig:
  1193.     for ( Int32 i = 1; i <= mItemCount; i++ )
  1194.     {
  1195.         CApplicationIconInfo* f;
  1196.         FetchItemAt( i, &f );
  1197.         if ( f->fAppSig == appSig)
  1198.             return f;
  1199.     }
  1200.     
  1201.     // Could not find an application, must create a new entry
  1202.     return CreateNewEntry(appSig, mapper);
  1203. }
  1204.  
  1205.  
  1206. // Creates application icon info for an app with a given signature
  1207. // If app is not found, defaults are created
  1208. CApplicationIconInfo* CApplicationList::CreateNewEntry(OSType appSig, CMimeMapper* mapper)
  1209. {
  1210.     FSSpec                        appSpec;
  1211.     CApplicationIconInfo*        appInfo = NULL;
  1212.     
  1213.     OSErr err = CFileMgr::FindApplication(appSig, appSpec );
  1214.     
  1215.     if ( err != noErr )
  1216.     {
  1217.         // Application not found, create defaults
  1218.         appInfo = new CApplicationIconInfo(appSig);
  1219.     }
  1220.     else
  1221.     {
  1222.         if (mapper)
  1223.             mapper->SetAppName( appSpec.name );
  1224.         appInfo = AppInfoFromFileSpec(appSig, appSpec);    
  1225.     }
  1226.  
  1227.     InsertItemsAt(1, LArray::index_Last, &appInfo);
  1228.     return appInfo;
  1229. }
  1230.  
  1231. // Horrendous bundle parsing routine.
  1232. // Its parses the bundle, gets all the document icons, and an application icon
  1233. // Failure can occur in many places. Unhandled failures result in a creation of
  1234. // the 'generic' applicatiohe resource
  1235. CApplicationIconInfo* CApplicationList::AppInfoFromFileSpec( OSType appSig, FSSpec appSpec )
  1236. {
  1237.     CApplicationIconInfo*    newInfo = NULL;
  1238.     short                    refNum;
  1239.     Handle                    bundle = NULL;
  1240.     OSErr                    err;
  1241.     Handle                    appIcon = NULL;
  1242.     Boolean                    handlesAE = TRUE;
  1243.     
  1244.     LArray*                    documentIcons = NULL;
  1245.     BNDLIds*                iconOffset;
  1246.     BNDLIds*                frefOffset;
  1247.     short                    numOfIcons;
  1248.     short                    numOfFrefs;    // Really number-1, just like in the resource
  1249.     BNDLIds                    frefBNDL;
  1250.     Handle                    iconFamily;
  1251.     OSType                    iconType;
  1252.     Handle                    frefRes = NULL;
  1253.     
  1254.     Try_
  1255.     {
  1256.         documentIcons = new LArray();
  1257.         ThrowIfNil_( documentIcons );
  1258.  
  1259.         SetResLoad( FALSE );
  1260.         refNum = ::FSpOpenResFile( &appSpec,fsRdPerm );
  1261.         err = ResError();
  1262.         SetResLoad( TRUE );
  1263.         ThrowIfOSErr_( err );
  1264.  
  1265.         // BNDL
  1266.         bundle = ::Get1IndResource( 'BNDL' , 1 );
  1267.         ThrowIfNil_( bundle );
  1268.         HLock( bundle );
  1269.         HNoPurge( bundle );
  1270.         // Get the signature
  1271.         ::BlockMoveData( *bundle, &appSig, 4 );
  1272.  
  1273.         GetResourcePointers( bundle, iconOffset, frefOffset, numOfIcons, numOfFrefs );
  1274.  
  1275.         // We have the offsets for FREF and ICN# resources
  1276.         // Not every FREF has a matching icon, so we read in all 
  1277.         // the FREFs and try to find the matching icon for each
  1278.         for ( int i = 0; i <= numOfFrefs; i++ )
  1279.         {
  1280.             // Algorithm:
  1281.             // Get the FREF resource specified in BNDL
  1282.             // Find the ICN# resource from BNDL with same local ID
  1283.             // Get the icon specified in ICN# resource.
  1284.             // If getting of the icon fails in any case, use the default icon
  1285.             frefBNDL = frefOffset[i];
  1286.             iconFamily = NULL;
  1287.             iconType = 'DUMB';
  1288.             frefRes = ::Get1Resource( 'FREF', frefBNDL.resID );
  1289.             if ( frefRes == NULL )    // Ignore the record  if FREF resource is not found
  1290.                 continue;
  1291.             ::BlockMoveData( *frefRes, &iconType, 4 );
  1292.             ::ReleaseResource( frefRes );
  1293.             
  1294.             if ( ( iconType == 'fold' ) ||         // folders are not files
  1295.                  ( iconType == '****' ) ||        // any file will default to text later
  1296.                  ( iconType == 'pref' ) ||        // prefs are also ignored
  1297.                  ( iconType == 'PREF' ) )    
  1298.                 continue;
  1299.                 
  1300.             for ( int j = 0; j <= numOfIcons; j++ )
  1301.             {
  1302.                 BNDLIds iconBndl = iconOffset[j];
  1303.                 if ( iconBndl.localID == frefBNDL.localID )
  1304.                 {
  1305.                     err = ::CreateCache( iconFamily, iconBndl.resID );
  1306.                     if (err)
  1307.                         iconFamily = NULL;
  1308.                     break;
  1309.                 }
  1310.             }
  1311.             
  1312.             if ( iconType == 'APPL' )
  1313.             {
  1314.                 // Special handling of the application icon
  1315.                 if ( iconFamily == NULL )
  1316.                     appIcon = CApplicationIconInfo::sDefaultAppIcon;
  1317.                 else
  1318.                     appIcon = iconFamily;
  1319.             }
  1320.             else
  1321.             {                            // Document icons
  1322.                 CFileType* newType = NULL;
  1323.                 if ( iconFamily == NULL )
  1324.                     newType = new CFileType( iconType );
  1325.                 else
  1326.                     newType = new CFileType( iconType, iconFamily );
  1327.  
  1328.                 documentIcons->InsertItemsAt( 1, LArray::index_Last, &newType );
  1329.             }
  1330.         }    // Done parsing all the file types
  1331.         
  1332.         HUnlock( bundle );
  1333.         HPurge( bundle );
  1334.         ReleaseResource( bundle );
  1335.         // Figure out if the application handles AppleEvents
  1336.         Handle sizeRes = ::Get1Resource( 'SIZE', -1 );
  1337.         if ( sizeRes == NULL )
  1338.             handlesAE = FALSE;
  1339.         else
  1340.         {
  1341.             char aeChar;
  1342.             aeChar = (*sizeRes)[1];
  1343.             handlesAE = aeChar & 2;
  1344.         }
  1345.         
  1346.         // Error handling: no file types
  1347.         if ( documentIcons->GetCount() == 0 )    // No icons were read, add 1 dummy one
  1348.         {
  1349.             CFileType* newType = new CFileType( 'TEXT' );
  1350.             documentIcons->InsertItemsAt( 1, LArray::index_Last, &newType );
  1351.         }
  1352.         // Error handling: no application icon
  1353.         if ( appIcon == NULL )
  1354.             appIcon = CApplicationIconInfo::sDefaultAppIcon;
  1355.         newInfo = new CApplicationIconInfo( appSig, appIcon, documentIcons, handlesAE );
  1356.     }
  1357.     Catch_(inErr)
  1358.     {
  1359.         newInfo = new CApplicationIconInfo( appSig );
  1360.     }
  1361.     EndCatch_
  1362.     
  1363.     CloseResFile( refNum );
  1364.     err = ResError();
  1365.     ThrowIfNil_( newInfo );
  1366.     return newInfo;
  1367. }
  1368.  
  1369. void CApplicationList::GetResourcePointers(
  1370.     Handle bundle,
  1371.     BNDLIds* &iconOffset,
  1372.     BNDLIds* &frefOffset,
  1373.     short& numOfIcons,
  1374.     short& numOfFrefs)
  1375. {
  1376.     OSType        resType;
  1377.     Ptr            bundlePtr = NULL;
  1378.     
  1379.     bundlePtr = *bundle;
  1380.     
  1381.     ::BlockMoveData( bundlePtr + 8, &resType, 4 );        // Get the first resource type
  1382.     if ( resType == 'ICN#' )
  1383.     {
  1384.         ::BlockMoveData( bundlePtr + 12, &numOfIcons, 2 );
  1385.         iconOffset = (BNDLIds*)( bundlePtr + 14 );
  1386.         //::BlockMove( (Ptr)iconOffset + ( numOfIcons + 1) * sizeof( BNDLIds ), &resType, 4 );    // Just checkin'
  1387.         ::BlockMoveData( (Ptr)iconOffset + (numOfIcons + 1) * sizeof( BNDLIds ) + 4, &numOfFrefs, 2 );
  1388.         frefOffset = (BNDLIds*)( (Ptr)iconOffset + 6 + ( numOfIcons + 1 ) * sizeof( BNDLIds ) );
  1389.     }
  1390.     else    // FREF
  1391.     {
  1392.         ::BlockMoveData( bundlePtr + 12, &numOfFrefs, 2 );
  1393.         frefOffset = (BNDLIds*) (bundlePtr + 14 );
  1394.         //::BlockMove( (Ptr)frefOffset + ( numOfFrefs + 1 ) * sizeof( BNDLIds ), &resType, 4 );    // Just checkin'
  1395.         ::BlockMoveData( (Ptr)frefOffset + ( numOfFrefs + 1 ) * sizeof( BNDLIds ) + 4, &numOfIcons, 2 );
  1396.         iconOffset = (BNDLIds*)( (Ptr)frefOffset + 6 + (numOfFrefs + 1) * sizeof(BNDLIds) );            
  1397.     }
  1398. }
  1399.  
  1400. PrefCellInfo::PrefCellInfo(CMimeMapper * mapper, CApplicationIconInfo * iconInfo)
  1401. {
  1402.     fMapper = mapper; 
  1403.     fIconInfo = iconInfo;
  1404. }
  1405.  
  1406. PrefCellInfo::PrefCellInfo()
  1407. {
  1408.     fMapper = NULL;
  1409.     fIconInfo = NULL;
  1410. }
  1411.  
  1412.  
  1413. Boolean
  1414. LFocusEditField::HandleKeyPress(
  1415.     const EventRecord    &inKeyEvent)
  1416. {
  1417.     Boolean        keyHandled = true;
  1418.     LControl    *keyButton = nil;
  1419.     
  1420.     switch (inKeyEvent.message & charCodeMask) {
  1421.     
  1422.         case char_Enter:
  1423.         case char_Return:
  1424.             BroadcastMessage(mReturnMessage, this);
  1425.             return true;
  1426.         default:
  1427.             return LEditField::HandleKeyPress(inKeyEvent);
  1428.     }
  1429. }
  1430.  
  1431. LFocusEditField::LFocusEditField(
  1432.     const LFocusEditField    &inOriginal)
  1433.         : LEditField(inOriginal),
  1434.           LBroadcaster(inOriginal)
  1435. {
  1436.     mFocusBox = nil;
  1437.     if (inOriginal.mFocusBox != nil) {
  1438.         mFocusBox = new LFocusBox(*(inOriginal.mFocusBox));
  1439.     }
  1440. }
  1441.  
  1442. LFocusEditField::LFocusEditField(
  1443.     LStream    *inStream)
  1444.         : LEditField(inStream)
  1445. {
  1446.     mFocusBox = new LFocusBox;
  1447.     mFocusBox->Hide();
  1448.     mFocusBox->AttachPane(this);
  1449. }
  1450. LFocusEditField::~LFocusEditField()
  1451. {
  1452.     
  1453. }
  1454. void
  1455. LFocusEditField::BeTarget()
  1456. {
  1457.     if(mFocusBox != nil) {
  1458.         mFocusBox->Show();
  1459.     }
  1460.     LEditField::BeTarget();
  1461. }
  1462. void
  1463. LFocusEditField::DontBeTarget()
  1464. {
  1465.     if(mFocusBox != nil) {
  1466.         mFocusBox->Hide();
  1467.     }
  1468.     LEditField::DontBeTarget();
  1469. }
  1470. LFocusBox*
  1471. LFocusEditField::GetFocusBox()
  1472. {
  1473.     return mFocusBox;
  1474. }
  1475.  
  1476. /********************************************************************
  1477.  
  1478. OneClickLListBox implementation.
  1479.  
  1480. Derived from LListBox. Overrides ClickSelf so that it sends a 
  1481. message when it has only been clicked once, not twice.
  1482.  
  1483. ********************************************************************/
  1484. OneClickLListBox::OneClickLListBox( LStream* inStream ): LListBox( inStream )
  1485. {
  1486.     mSingleClickMessage = msg_Nothing;
  1487. }
  1488.  
  1489.  
  1490. void    OneClickLListBox::ClickSelf(const SMouseDownEvent &inMouseDown)
  1491. {
  1492.     if(SwitchTarget(this))
  1493.     {
  1494.         FocusDraw();
  1495.         if (::LClick(inMouseDown.whereLocal, inMouseDown.macEvent.modifiers, mMacListH)) 
  1496.         {
  1497.             BroadcastMessage(mDoubleClickMessage, this);
  1498.         } else {
  1499.             BroadcastMessage(mSingleClickMessage, this);
  1500.         }
  1501.     }
  1502. }
  1503.  
  1504. Boolean        OneRowLListBox::HandleKeyPress(const EventRecord &inKeyEvent)
  1505. {
  1506.     if(OneClickLListBox::HandleKeyPress(inKeyEvent))
  1507.     {
  1508.         Char16    theKey = inKeyEvent.message & charCodeMask;
  1509.         // based on LListBox::HandleKeyPress--only broadcast when our class handled it
  1510.         // (window might close--deleting us--before we broadcast)
  1511.         if ( UKeyFilters::IsNavigationKey(theKey) ||
  1512.             ( UKeyFilters::IsPrintingChar(theKey) && ! (inKeyEvent.modifiers & cmdKey) ) )
  1513.         {
  1514.             BroadcastMessage(mSingleClickMessage, this);
  1515.         }
  1516.         return true;
  1517.     }
  1518.     else
  1519.         return false;
  1520. }
  1521.  
  1522.  
  1523. int16        OneRowLListBox::GetRows() 
  1524.     return ((**mMacListH).dataBounds.bottom); 
  1525. }
  1526.  
  1527. OneRowLListBox::OneRowLListBox( LStream* inStream ): OneClickLListBox( inStream )
  1528. {
  1529.     FocusDraw();
  1530.     if((*mMacListH)->dataBounds.right == 0)
  1531.         ::LAddColumn(1 , 0, mMacListH);
  1532.     (*mMacListH)->selFlags |= lOnlyOne;
  1533. }
  1534.  
  1535. void     OneRowLListBox::AddRow(int32 rowNum, char* data, int16 datalen)
  1536. {
  1537.     if(SwitchTarget(this))
  1538.     {
  1539.         FocusDraw();
  1540.         Cell theCell;
  1541.         theCell.h = 0;
  1542.         rowNum = ::LAddRow(1 , rowNum, mMacListH);
  1543.         theCell.v = rowNum;
  1544.         ::LSetCell(data,datalen ,theCell, mMacListH);
  1545.     }
  1546. }
  1547. void     OneRowLListBox::GetCell(int32 rowNum, char* data, int16* datalen)
  1548. {
  1549.     FocusDraw();
  1550.     Cell theCell;
  1551.     theCell.h = 0;
  1552.     theCell.v = rowNum;
  1553.     ::LGetCell(data,datalen ,theCell, mMacListH);
  1554. }
  1555. void     OneRowLListBox::SetCell(int32 rowNum, char* data, int16 datalen)
  1556. {
  1557.     if(SwitchTarget(this))
  1558.     {
  1559.         FocusDraw();
  1560.         Cell theCell;
  1561.         theCell.h = 0;
  1562.         theCell.v = rowNum;
  1563.         ::LSetCell(data,datalen ,theCell, mMacListH);
  1564.     }
  1565. }
  1566.  
  1567. void     OneRowLListBox::RemoveRow(int32 rowNum)
  1568. {
  1569.     FocusDraw();
  1570.     ::LDelRow(1 , rowNum, mMacListH);
  1571. }
  1572.