mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 20:47:44 +00:00
1573 lines
38 KiB
C++
1573 lines
38 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||
*
|
||
* The contents of this file are subject to the Netscape Public License
|
||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||
* http://www.mozilla.org/NPL/
|
||
*
|
||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||
* for the specific language governing rights and limitations under the
|
||
* NPL.
|
||
*
|
||
* The Initial Developer of this code under the NPL is Netscape
|
||
* Communications Corporation. Portions created by Netscape are
|
||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||
* Reserved.
|
||
*/
|
||
|
||
#include "prefwutil.h"
|
||
|
||
#include "resgui.h"
|
||
#include "uprefd.h"
|
||
#include "macutil.h"
|
||
#include "ufilemgr.h"
|
||
#include "uerrmgr.h"
|
||
#include "xp_mem.h"
|
||
#include "macgui.h"
|
||
#include "COffscreenCaption.h"
|
||
|
||
Boolean CFilePicker::sResult = FALSE;
|
||
Boolean CFilePicker::sUseDefault = FALSE; // Use default directory
|
||
CStr255 CFilePicker::sPrevName;
|
||
|
||
CFilePicker::CFilePicker( LStream* inStream ): LView( inStream )
|
||
{
|
||
// WARNING: if you add any streamable data here (because you're making a new custom
|
||
// Cppb in constructor) you will clobber CPrefFilePicker, which inherits from
|
||
// this class. So beware!
|
||
fCurrentValue.vRefNum = 0;
|
||
fCurrentValue.parID = 0;
|
||
fCurrentValue.name[ 0 ] = 0;
|
||
fSet = FALSE;
|
||
fBrowseButton = NULL;
|
||
fPathName = NULL;
|
||
fPickTypes = Applications;
|
||
}
|
||
|
||
void CFilePicker::FinishCreateSelf()
|
||
{
|
||
ThrowIfNil_(fBrowseButton = dynamic_cast<LControl*>(FindPaneByID(kBrowseButton)));
|
||
ThrowIfNil_(fPathName = dynamic_cast<LCaption*>(FindPaneByID(kPathNameCaption)));
|
||
|
||
fBrowseButton->SetValueMessage(msg_Browse);
|
||
fBrowseButton->AddListener(this);
|
||
}
|
||
|
||
void CFilePicker::SetFSSpec( const FSSpec& fileSpec, Boolean touchSetFlag )
|
||
{
|
||
if (touchSetFlag)
|
||
fSet = TRUE;
|
||
fCurrentValue = fileSpec;
|
||
|
||
SetCaptionForPath( fPathName, fileSpec );
|
||
BroadcastMessage( msg_FolderChanged, this );
|
||
}
|
||
|
||
void CFilePicker::ListenToMessage( MessageT inMessage, void* /*ioParam*/ )
|
||
{
|
||
StandardFileReply reply;
|
||
FSSpec currentValue;
|
||
|
||
currentValue = GetFSSpec();
|
||
reply.sfFile = currentValue;
|
||
|
||
if ( inMessage == msg_Browse )
|
||
{
|
||
switch ( fPickTypes )
|
||
{
|
||
case MailFiles:
|
||
reply.sfFile = CPrefs::GetFilePrototype( CPrefs::MailFolder );
|
||
case AnyFile:
|
||
case Folders:
|
||
case TextFiles:
|
||
case ImageFiles:
|
||
case Applications:
|
||
{
|
||
// <20> pose the dialog and get the users new choice
|
||
if ( CFilePicker::DoCustomGetFile( reply, fPickTypes, TRUE ) )
|
||
SetFSSpec( reply.sfFile );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void CFilePicker::SetCaptionForPath( LCaption* captionToSet, const FSSpec& folderSpec )
|
||
{
|
||
CStr255 pathName = FSSpecToPathName( folderSpec );
|
||
SetCaptionDescriptor( captionToSet, pathName, smTruncMiddle );
|
||
}
|
||
|
||
CStr255 CFilePicker::FSSpecToPathName( const FSSpec& spec )
|
||
{
|
||
char* pPathName = CFileMgr::PathNameFromFSSpec( spec, true );
|
||
if ( pPathName == NULL && fPickTypes == Applications )
|
||
{
|
||
CStr255 badName(spec.name);
|
||
ErrorManager::PlainAlert
|
||
( (char *)GetCString(BAD_APP_LOCATION_RESID), badName,
|
||
(char *)GetCString(REBUILD_DESKTOP_RESID), NULL );
|
||
return badName;
|
||
}
|
||
CStr255 cPathName(pPathName);
|
||
XP_FREE( pPathName );
|
||
return cPathName;
|
||
}
|
||
|
||
void CFilePicker::SetButtonTitle( Handle buttonHdl, CStr255& name, const Rect& buttonRect )
|
||
{
|
||
short result; //
|
||
short width; //
|
||
|
||
sPrevName = name;
|
||
|
||
CStr255 finalString(::GetCString(SELECT_RESID));
|
||
|
||
width = ( buttonRect.right - buttonRect.left )
|
||
- ( StringWidth( finalString ) + 2 * CharWidth( '<EFBFBD>' ) );
|
||
|
||
result = ::TruncString( width, name, smTruncMiddle );
|
||
|
||
finalString += name;
|
||
SetControlTitle( (ControlHandle)(buttonHdl), finalString );
|
||
ValidRect( &buttonRect );
|
||
}
|
||
|
||
#define kIsFolderFlag 0x10 // flag indicating the file is a directory.
|
||
#define kInvisibleFlag 0x4000 // flag indicating that the file is invisible.
|
||
|
||
#define kGetDirButton 10
|
||
#define kDefaultButton 12
|
||
|
||
PROCEDURE( CFilePicker::OnlyFoldersFileFilter, uppFileFilterYDProcInfo )
|
||
pascal Boolean CFilePicker::OnlyFoldersFileFilter( CInfoPBPtr pBlock, void* /*data*/ )
|
||
{
|
||
Boolean isFolder;
|
||
Boolean isInvisible;
|
||
Boolean dontShow;
|
||
|
||
isFolder = ((pBlock->hFileInfo).ioFlAttrib) & kIsFolderFlag;
|
||
isInvisible = ((pBlock->dirInfo).ioDrUsrWds.frFlags) & kInvisibleFlag;
|
||
dontShow = !isFolder || isInvisible;
|
||
|
||
return dontShow;
|
||
}
|
||
|
||
PROCEDURE( CFilePicker::IsMailFileFilter, uppFileFilterYDProcInfo )
|
||
pascal Boolean CFilePicker::IsMailFileFilter( CInfoPBPtr pBlock, void* /*data*/ )
|
||
{
|
||
Boolean isEudora;
|
||
Boolean isMine;
|
||
Boolean dontShow;
|
||
|
||
isMine = ( pBlock->hFileInfo).ioFlFndrInfo.fdCreator == emSignature;
|
||
isEudora = ( pBlock->hFileInfo).ioFlFndrInfo.fdCreator == 'CSOm';
|
||
dontShow = !isMine && !isEudora;
|
||
|
||
return dontShow;
|
||
}
|
||
|
||
PROCEDURE( CFilePicker::SetCurrDirHook, uppDlgHookYDProcInfo )
|
||
pascal short CFilePicker::SetCurrDirHook( short item, DialogPtr /*dialog*/, void* /*data*/ )
|
||
{
|
||
if ( item == sfHookFirstCall )
|
||
return sfHookChangeSelection;
|
||
return item;
|
||
}
|
||
|
||
PROCEDURE( CFilePicker::DirectoryHook, uppDlgHookYDProcInfo )
|
||
pascal short CFilePicker::DirectoryHook( short item, DialogPtr dialog, void* data )
|
||
{
|
||
short type; // menu item selected
|
||
Handle handle; // needed for GetDialogItem
|
||
Rect rect; // needed for GetDialogItem
|
||
|
||
CStr255 tempName = sPrevName;
|
||
CStr255 name;
|
||
|
||
CInfoPBRec pb;
|
||
StandardFileReply* sfrPtr;
|
||
OSErr err;
|
||
short returnVal;
|
||
|
||
// <20> default, except in special cases below
|
||
returnVal = item;
|
||
|
||
// <20> this function is only for main dialog box
|
||
if ( GetWRefCon((WindowPtr)dialog ) != sfMainDialogRefCon )
|
||
return returnVal;
|
||
|
||
DirInfo* dipb = (DirInfo*)&pb;
|
||
// <20> get sfrPtr from 3rd parameter to hook function
|
||
sfrPtr = (StandardFileReply*)((PickClosure*)data)->reply;
|
||
|
||
GetDialogItem( dialog, kGetDirButton, &type, &handle, &rect );
|
||
|
||
if ( item == sfHookFirstCall )
|
||
{
|
||
// <20> determine current folder name and set title of Select button
|
||
dipb->ioCompletion = NULL;
|
||
dipb->ioNamePtr = (StringPtr)&tempName;
|
||
dipb->ioVRefNum = sfrPtr->sfFile.vRefNum;
|
||
dipb->ioDrDirID = sfrPtr->sfFile.parID;
|
||
dipb->ioFDirIndex = - 1;
|
||
err = PBGetCatInfoSync(&pb);
|
||
name = tempName;
|
||
CFilePicker::SetButtonTitle( handle, name, rect );
|
||
|
||
return sfHookChangeSelection;
|
||
}
|
||
else
|
||
{
|
||
// <20> track name of folder that can be selected
|
||
// (also allow selection of folder aliases)
|
||
if ( ( sfrPtr->sfIsFolder) || ( sfrPtr->sfIsVolume) ||
|
||
((sfrPtr->sfFlags & kIsAlias) && (sfrPtr->sfType == kContainerFolderAliasType)) )
|
||
name = sfrPtr->sfFile.name;
|
||
else
|
||
{
|
||
dipb->ioCompletion = NULL;
|
||
dipb->ioNamePtr = (StringPtr)&tempName;
|
||
dipb->ioVRefNum = sfrPtr->sfFile.vRefNum;
|
||
dipb->ioFDirIndex = -1;
|
||
dipb->ioDrDirID = sfrPtr->sfFile.parID;
|
||
err = PBGetCatInfoSync(&pb);
|
||
name = tempName;
|
||
}
|
||
|
||
// <20> change directory name in button title as needed
|
||
if ( name != sPrevName )
|
||
CFilePicker::SetButtonTitle( handle, name, rect );
|
||
|
||
switch ( item )
|
||
{
|
||
// <20> force return by faking a cancel
|
||
case kGetDirButton:
|
||
sResult = TRUE;
|
||
returnVal = sfItemCancelButton;
|
||
break;
|
||
|
||
// <20> use default directory
|
||
case kDefaultButton:
|
||
sUseDefault = TRUE;
|
||
returnVal = sfItemCancelButton;
|
||
break;
|
||
|
||
// <20> flag no directory was selected
|
||
case sfItemCancelButton:
|
||
sResult = FALSE;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
return returnVal;
|
||
}
|
||
|
||
Boolean CFilePicker::DoCustomGetFile( StandardFileReply& reply,
|
||
CFilePicker::PickEnum pickTypes, Boolean isInited )
|
||
{
|
||
Point loc = { -1, -1 };
|
||
OSErr gesErr;
|
||
long gesResponse;
|
||
FileFilterYDUPP filter = NULL;
|
||
DlgHookYDUPP dialogHook;
|
||
short dlogID = 0;
|
||
OSType types[ 4 ];
|
||
OSType* typeP;
|
||
short typeCount = -1;
|
||
Boolean* resultP = &reply.sfGood;
|
||
Boolean wantPreview = FALSE;
|
||
PickClosure closure;
|
||
|
||
reply.sfIsVolume = 0;
|
||
reply.sfIsFolder = 0;
|
||
reply.sfFlags = 0;
|
||
reply.sfScript = smSystemScript;
|
||
reply.sfGood = FALSE;
|
||
closure.reply = &reply;
|
||
closure.inited = isInited;
|
||
typeP = types;
|
||
|
||
if ( isInited )
|
||
dialogHook = &PROCPTR( SetCurrDirHook );
|
||
else
|
||
dialogHook = NULL;
|
||
|
||
// <20><>initialize name of previous selection
|
||
sPrevName = reply.sfFile.name;
|
||
|
||
StPrepareForDialog preparer;
|
||
gesErr = Gestalt( gestaltStandardFileAttr, &gesResponse );
|
||
if ( gesResponse & ( 1L << gestaltStandardFile58 ) )
|
||
{
|
||
switch ( pickTypes )
|
||
{
|
||
case Folders:
|
||
{
|
||
filter = &PROCPTR( OnlyFoldersFileFilter );
|
||
dlogID = DLOG_GETFOLDER;
|
||
dialogHook = &PROCPTR( DirectoryHook );
|
||
resultP = &sResult;
|
||
typeP = NULL;
|
||
}
|
||
break;
|
||
|
||
case AnyFile:
|
||
{
|
||
typeP = NULL;
|
||
}
|
||
break;
|
||
|
||
case MailFiles:
|
||
{
|
||
filter = &PROCPTR( IsMailFileFilter );
|
||
types[ 0 ] = 'TEXT';
|
||
typeCount = 1;
|
||
}
|
||
break;
|
||
|
||
case TextFiles:
|
||
{
|
||
types[ 0 ] = 'TEXT';
|
||
typeCount = 1;
|
||
}
|
||
break;
|
||
|
||
case ImageFiles:
|
||
{
|
||
types[ 0 ] = 'GIFf';
|
||
types[ 1 ] = 'TEXT';
|
||
types[ 2 ] = 'JPEG';
|
||
typeCount = 3;
|
||
wantPreview = TRUE;
|
||
}
|
||
break;
|
||
|
||
case Applications:
|
||
{
|
||
types[0] = 'APPL';
|
||
types[1] = 'adrp'; // Application aliases
|
||
typeCount = 2;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( wantPreview && UEnvironment::HasGestaltAttribute( gestaltQuickTime, 0xFFFF ) )
|
||
::CustomGetFilePreview( filter, typeCount, typeP, &reply, dlogID, loc, dialogHook,
|
||
NULL, NULL, NULL, &closure );
|
||
else
|
||
::CustomGetFile( filter, typeCount, typeP, &reply, dlogID, loc, dialogHook,
|
||
NULL, NULL, NULL, &closure );
|
||
|
||
// follow any folder aliases that may be returned
|
||
if (*resultP && pickTypes == Folders) {
|
||
Boolean b1, b2;
|
||
ThrowIfOSErr_( ResolveAliasFile(&reply.sfFile, true, &b1, &b2) );
|
||
}
|
||
|
||
return *resultP;
|
||
}
|
||
|
||
Boolean CFilePicker::DoCustomPutFile( StandardFileReply& reply,
|
||
const CStr255& prompt, Boolean inited )
|
||
{
|
||
Point loc = { -1, -1 };
|
||
CStr255 filename = CStr255::sEmptyString;
|
||
DlgHookYDUPP dialogHook = NULL;
|
||
|
||
if ( inited )
|
||
{
|
||
filename = reply.sfFile.name;
|
||
dialogHook = &PROCPTR( SetCurrDirHook );
|
||
}
|
||
|
||
CustomPutFile( (ConstStr255Param)prompt,
|
||
(ConstStr255Param)filename,
|
||
&reply,
|
||
0,
|
||
loc,
|
||
dialogHook,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
NULL );
|
||
|
||
return reply.sfGood;
|
||
}
|
||
|
||
// ===========================================================================
|
||
// COtherSizeDialog
|
||
// ===========================================================================
|
||
|
||
const ResIDT edit_SizeField = 1504;
|
||
|
||
COtherSizeDialog::COtherSizeDialog( LStream* inStream ): LDialogBox( inStream )
|
||
{
|
||
}
|
||
|
||
void COtherSizeDialog::FinishCreateSelf()
|
||
{
|
||
LDialogBox::FinishCreateSelf();
|
||
|
||
mSizeField = (LEditField*)FindPaneByID( edit_SizeField );
|
||
|
||
// Set the edit field to go on duty whenever
|
||
// this dialog box goes on duty.
|
||
|
||
fRef = NULL;
|
||
SetLatentSub( mSizeField );
|
||
}
|
||
|
||
void COtherSizeDialog::SetValue( Int32 inFontSize )
|
||
{
|
||
if ( inFontSize > 128 )
|
||
inFontSize = 128;
|
||
|
||
mSizeField->SetValue( inFontSize );
|
||
mSizeField->SelectAll();
|
||
}
|
||
|
||
Int32 COtherSizeDialog::GetValue() const
|
||
{
|
||
Int32 size;
|
||
|
||
size = mSizeField->GetValue();
|
||
if ( size > 128 )
|
||
size = 128;
|
||
|
||
return size;
|
||
}
|
||
|
||
void COtherSizeDialog::SetReference( LControl* which )
|
||
{
|
||
fRef = which;
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// <09> ListenToMessage
|
||
// ---------------------------------------------------------------------------
|
||
// This member function illustrates an alternate method for this dialog box
|
||
// to communicate with its invoker when the user clicks the defualt (OK) button.
|
||
// Usually, when the user clicks the default button, LDialogBox::ListenToMessage()
|
||
// calls the supercommander's ObeyCommand() function passing it the value message
|
||
// of the default button and a pointer to the dialog box object in the ioParam
|
||
// parameter. This method also passes the value message of the default button,
|
||
// but rather than sending a pointer to the dialog in ioParam, it sends the
|
||
// new point size.
|
||
//
|
||
// The advantage of using the alternate method is that the client that invokes
|
||
// the dialog doesn't have to call any of the dialog class's member functions
|
||
// to get its value and is not responsible for closing the dialog box. The
|
||
// disadvantage is that you have to pass all the information back through
|
||
// ObeyCommand()'s single ioParam parameter.
|
||
|
||
void COtherSizeDialog::ListenToMessage(MessageT inMessage, void *ioParam)
|
||
{
|
||
Int32 newFontSize;
|
||
|
||
switch ( inMessage )
|
||
{
|
||
case msg_ChangeFontSize:
|
||
// This is the command number associated with this dialog's
|
||
// OK button. It's also used as a command number to send
|
||
// to the dialog's supercommander which is presumably
|
||
// the commander that created and invoked the dialog.
|
||
|
||
newFontSize = mSizeField->GetValue();
|
||
|
||
// Note that we use the second parameter of ObeyCommand() to
|
||
// specify the new font size. When the menu mechanism invokes
|
||
// ObeyCommand(), the second parameter is always nil.
|
||
|
||
BroadcastMessage( msg_ChangeFontSize, this );
|
||
|
||
// Since we want the OK button to close the dialog box as
|
||
// well as change the font size, we change the message to close
|
||
// and let the flow fall through to the default case.
|
||
|
||
inMessage = cmd_Close;
|
||
|
||
// FALLTHROUGH INTENTIONAL
|
||
// to get the base class to close the dialog box
|
||
|
||
default:
|
||
LDialogBox::ListenToMessage(inMessage, ioParam);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
LArrowGroup::LArrowGroup( LStream* inStream ): LView( inStream )
|
||
{
|
||
fSize = NULL;
|
||
fArrows = NULL;
|
||
fValue = 0L;
|
||
fMinValue = 0L;
|
||
fMaxValue = 99999999L;
|
||
fStringID = MEGA_RESID;
|
||
this->BuildControls();
|
||
}
|
||
|
||
void LArrowGroup::SetStringID(ResIDT stringID)
|
||
{
|
||
fStringID = stringID;
|
||
}
|
||
|
||
void LArrowGroup::ListenToMessage( MessageT message, void* ioParam )
|
||
{
|
||
if ( message == msg_ArrowsHit )
|
||
{
|
||
Int16 whichHalf = *(Int16*)ioParam;
|
||
|
||
if ( whichHalf == mTopHalf )
|
||
SetValue( fValue + 1 );
|
||
else
|
||
SetValue( fValue - 1 );
|
||
}
|
||
}
|
||
|
||
void LArrowGroup::SetValue( Int32 value )
|
||
{
|
||
if ( value < fMinValue )
|
||
value = fMinValue;
|
||
else if ( value > fMaxValue )
|
||
value = fMaxValue;
|
||
|
||
CStr255 string;
|
||
NumToString( value, string );
|
||
string += CStr255(*GetString(fStringID));
|
||
fSize->SetDescriptor( string );
|
||
fValue = value;
|
||
}
|
||
|
||
void LArrowGroup::SetMaxValue( Int32 newMax )
|
||
{
|
||
if ( fValue > newMax )
|
||
SetValue( newMax );
|
||
fMaxValue = newMax;
|
||
}
|
||
|
||
void LArrowGroup::SetMinValue( Int32 newMin )
|
||
{
|
||
if ( fValue < newMin )
|
||
SetValue( newMin );
|
||
fMinValue = newMin;
|
||
}
|
||
|
||
|
||
void LArrowGroup::BuildControls()
|
||
{
|
||
SPaneInfo paneInfo;
|
||
|
||
paneInfo.paneID = 'Actl';
|
||
paneInfo.width = 15;
|
||
paneInfo.height = 25;
|
||
paneInfo.visible = TRUE;
|
||
paneInfo.enabled = TRUE;
|
||
paneInfo.left = mFrameSize.width - 16;
|
||
paneInfo.top = 0;
|
||
paneInfo.userCon = 0;
|
||
paneInfo.superView = this;
|
||
|
||
fArrows = new LArrowControl( paneInfo, msg_ArrowsHit );
|
||
ThrowIfNil_(fArrows);
|
||
fArrows->AddListener( this );
|
||
|
||
paneInfo.paneID = 'capt';
|
||
paneInfo.width = mFrameSize.width - 16;
|
||
paneInfo.height = 12;
|
||
paneInfo.left = 0;
|
||
paneInfo.top = 5;
|
||
|
||
fSize = new COffscreenCaption(paneInfo, "\p", 10000);
|
||
}
|
||
|
||
CColorButton::CColorButton( LStream *inStream ): LButton( inStream )
|
||
{
|
||
fInside = FALSE;
|
||
mNormalID = 0;
|
||
mPushedID = 1;
|
||
}
|
||
|
||
void CColorButton::DrawGraphic( ResIDT inGraphicID )
|
||
{
|
||
Rect frame;
|
||
|
||
CalcLocalFrameRect( frame );
|
||
UGraphics::SetFore( CPrefs::Black );
|
||
if ( IsEnabled() )
|
||
{
|
||
if ( inGraphicID == mPushedID )
|
||
{
|
||
::PenSize( 2, 2 );
|
||
::PenPat( &qd.black );
|
||
::FrameRect( &frame );
|
||
}
|
||
else
|
||
{
|
||
::PenSize( 1, 1 );
|
||
::PenPat( &qd.black );
|
||
::FrameRect( &frame );
|
||
UGraphics::SetFore( CPrefs::White );
|
||
::InsetRect( &frame, 1, 1 );
|
||
::FrameRect( &frame );
|
||
UGraphics::SetFore( CPrefs::Black );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
::PenSize( 1, 1 );
|
||
::PenPat( &qd.gray );
|
||
::FrameRect( &frame );
|
||
::PenPat( &qd.black );
|
||
|
||
}
|
||
|
||
RGBForeColor( &fColor );
|
||
|
||
if ( inGraphicID == mPushedID )
|
||
::InsetRect( &frame, 3, 3 );
|
||
else
|
||
::InsetRect( &frame, 2, 2 );
|
||
|
||
::FillRect( &frame, &( UQDGlobals::GetQDGlobals()->black ) );
|
||
UGraphics::SetFore( CPrefs::Black );
|
||
}
|
||
|
||
void CColorButton::HotSpotResult( short inHotSpot )
|
||
{
|
||
Point where;
|
||
where.h = where.v = 0;
|
||
RGBColor outColor;
|
||
|
||
if ( ::GetColor(where, (unsigned char *)*GetString(PICK_COLOR_RESID),
|
||
&fColor,&outColor) )
|
||
{
|
||
if ( !UGraphics::EqualColor(fColor, outColor) )
|
||
{
|
||
fColor = outColor;
|
||
BroadcastValueMessage();
|
||
}
|
||
}
|
||
|
||
// <20> turn off the black border
|
||
HotSpotAction( inHotSpot, FALSE, TRUE );
|
||
|
||
}
|
||
|
||
FileIconsLister::FileIconsLister (CGAPopupMenu * target)
|
||
: StdPopup (target)
|
||
{
|
||
fIcons = nil;
|
||
}
|
||
|
||
FileIconsLister::~FileIconsLister()
|
||
{ // Debugging purposes only
|
||
}
|
||
|
||
void
|
||
FileIconsLister::SetIconList (CApplicationIconInfo * icons)
|
||
{
|
||
fIcons = icons;
|
||
}
|
||
|
||
short
|
||
FileIconsLister::GetCount()
|
||
{
|
||
if (fIcons == NULL)
|
||
return 0;
|
||
else
|
||
return fIcons->GetFileTypeArraySize();
|
||
}
|
||
|
||
CStr255
|
||
FileIconsLister::GetText (short item)
|
||
{
|
||
CFileType * fileType;
|
||
fIcons->fDocumentIcons->FetchItemAt (item, &fileType);
|
||
return fileType->fIconSig;
|
||
}
|
||
|
||
// <20><> Constructors/destructors
|
||
|
||
CMimeTable::CMimeTable(LStream *inStream) : LTable(inStream)
|
||
{
|
||
fContainer = NULL;
|
||
fNetscapeIcon = NULL;
|
||
fPluginIcon = NULL;
|
||
}
|
||
|
||
void CMimeTable::FinishCreateSelf()
|
||
{
|
||
SetCellDataSize(sizeof(PrefCellInfo));
|
||
|
||
for (TableIndexT i = 1; i <= CPrefs::sMimeTypes.GetCount(); i++) // Insert a row for each mime type
|
||
{
|
||
CMimeMapper * mime;
|
||
CPrefs::sMimeTypes.FetchItemAt(i, &mime);
|
||
ThrowIfNil_(mime);
|
||
if (!mime->IsTemporary())
|
||
{
|
||
CMimeMapper * duplicate = new CMimeMapper(*mime);
|
||
PrefCellInfo cellInfo;
|
||
InsertRows(1, i, &cellInfo);
|
||
BindCellToApplication(i, duplicate);
|
||
}
|
||
}
|
||
|
||
// Cache a handle to the Navigator application icon
|
||
CApplicationIconInfo* netscapeInfo = fApplList.GetAppInfo(emSignature);
|
||
ThrowIfNil_(netscapeInfo);
|
||
ThrowIfNil_(netscapeInfo->fDocumentIcons);
|
||
fNetscapeIcon = netscapeInfo->fApplicationIcon;
|
||
|
||
// Cache a handle to the standard plug-in icon
|
||
LArrayIterator iterator(*(netscapeInfo->fDocumentIcons));
|
||
CFileType* fileInfo;
|
||
while (iterator.Next(&fileInfo))
|
||
{
|
||
if (fileInfo->fIconSig == emPluginFile)
|
||
{
|
||
fPluginIcon = fileInfo->fIcon;
|
||
break;
|
||
}
|
||
}
|
||
|
||
LTable::FinishCreateSelf();
|
||
|
||
// Set latent subcommander of supercommander of supercommander, which is the
|
||
// view that contains the scroller of this table, to table
|
||
// if( GetSuperCommander()->GetSuperCommander() )
|
||
// (GetSuperCommander()->GetSuperCommander())->SetLatentSub(this);
|
||
LCommander::SwitchTarget(this);
|
||
}
|
||
|
||
CApplicationIconInfo* CMimeTable::GetAppInfo(CMimeMapper* mapper)
|
||
{
|
||
return fApplList.GetAppInfo(mapper->GetAppSig(), mapper);
|
||
}
|
||
|
||
|
||
// Sets cell data to values of the mapper
|
||
void CMimeTable::BindCellToApplication(TableIndexT row, CMimeMapper* mapper)
|
||
{
|
||
CApplicationIconInfo* appInfo = GetAppInfo(mapper);
|
||
|
||
// Now figure out the extensions from the netlib
|
||
PrefCellInfo cellInfo(mapper, appInfo);
|
||
TableCellT cell;
|
||
cell.row = row;
|
||
cell.col = 1;
|
||
SetCellData(cell, &cellInfo);
|
||
}
|
||
|
||
|
||
void CMimeTable::DrawSelf()
|
||
{
|
||
RgnHandle localUpdateRgnH = GetLocalUpdateRgn();
|
||
Rect updateRect = (**localUpdateRgnH).rgnBBox;
|
||
DisposeRgn(localUpdateRgnH);
|
||
|
||
{
|
||
StColorState saveTheColor;
|
||
RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF};
|
||
RGBBackColor(&white);
|
||
EraseRect(&updateRect);
|
||
}
|
||
|
||
LTable::DrawSelf();
|
||
}
|
||
|
||
|
||
void CMimeTable::HiliteCell(const TableCellT &inCell)
|
||
{
|
||
StColorState saveTheColor;
|
||
RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF};
|
||
RGBBackColor(&white);
|
||
|
||
LTable::HiliteCell(inCell);
|
||
}
|
||
|
||
|
||
void CMimeTable::UnhiliteCell(const TableCellT &inCell)
|
||
{
|
||
StColorState saveTheColor;
|
||
RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF};
|
||
RGBBackColor(&white);
|
||
|
||
LTable::UnhiliteCell(inCell);
|
||
}
|
||
|
||
|
||
|
||
#define offsetTable 7
|
||
#define offsetTextTop 15
|
||
#define offsetMimeType (offsetTable + 0)
|
||
#define offsetIcon (offsetTable + 166)
|
||
#define offsetHandler (offsetIcon + 24)
|
||
#define widthMimeType (offsetIcon - offsetMimeType - 5)
|
||
|
||
void CMimeTable::DrawCell(const TableCellT &inCell)
|
||
{
|
||
Rect cellFrame;
|
||
|
||
if (FetchLocalCellFrame(inCell, cellFrame))
|
||
{
|
||
::PenPat( &(UQDGlobals::GetQDGlobals()->gray) );
|
||
::MoveTo(cellFrame.left, cellFrame.bottom-1);
|
||
::LineTo(cellFrame.right, cellFrame.bottom-1);
|
||
::PenPat( &(UQDGlobals::GetQDGlobals()->black) );
|
||
|
||
PrefCellInfo cellInfo;
|
||
GetCellData(inCell, &cellInfo);
|
||
UTextTraits::SetPortTextTraits(10000); // HACK
|
||
|
||
// Draw mime type
|
||
CStr255 description = cellInfo.fMapper->GetDescription();
|
||
if (description.IsEmpty())
|
||
description = cellInfo.fMapper->GetMimeName();
|
||
short result = ::TruncString(widthMimeType, description, smTruncMiddle);
|
||
::MoveTo(offsetMimeType, cellFrame.top+offsetTextTop);
|
||
::DrawString(description);
|
||
|
||
// Draw the icon
|
||
CMimeMapper::LoadAction loadAction = cellInfo.fMapper->GetLoadAction();
|
||
if (loadAction == CMimeMapper::Launch || loadAction == CMimeMapper::Plugin || loadAction == CMimeMapper::Internal)
|
||
{
|
||
Rect r;
|
||
r.left = offsetIcon;
|
||
r.top = cellFrame.top + 2;
|
||
r.right = r.left + 16;
|
||
r.bottom = r.top + 16;
|
||
|
||
Handle iconHandle;
|
||
if (loadAction == CMimeMapper::Plugin)
|
||
iconHandle = fPluginIcon;
|
||
else if (loadAction == CMimeMapper::Internal)
|
||
iconHandle = fNetscapeIcon;
|
||
else
|
||
iconHandle = cellInfo.fIconInfo->fApplicationIcon;
|
||
XP_ASSERT(iconHandle);
|
||
|
||
if (iconHandle)
|
||
{
|
||
if (loadAction == CMimeMapper::Launch && !(cellInfo.fIconInfo->fApplicationFound))
|
||
::PlotIconSuite(&r, atHorizontalCenter, ttDisabled, iconHandle);
|
||
else
|
||
::PlotIconSuite(&r, atHorizontalCenter, ttNone, iconHandle);
|
||
}
|
||
}
|
||
|
||
// Draw the handler name
|
||
::MoveTo(offsetHandler, cellFrame.top+offsetTextTop);
|
||
switch (loadAction)
|
||
{
|
||
case CMimeMapper::Save:
|
||
::DrawString(*GetString(SAVE_RESID));
|
||
break;
|
||
case CMimeMapper::Unknown:
|
||
::DrawString(*GetString(UNKNOWN_RESID));
|
||
break;
|
||
case CMimeMapper::Internal:
|
||
::DrawString(*GetString(INTERNAL_RESID));
|
||
break;
|
||
case CMimeMapper::Launch:
|
||
::DrawString(cellInfo.fMapper->GetAppName());
|
||
break;
|
||
case CMimeMapper::Plugin:
|
||
::DrawString(cellInfo.fMapper->GetPluginName());
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// Returns PrefCellInfo for the given cell
|
||
void CMimeTable::GetCellInfo(PrefCellInfo& cellInfo, int row)
|
||
{
|
||
TableCellT cell;
|
||
cell.row = row;
|
||
cell.col = 1;
|
||
GetCellData(cell, &cellInfo);
|
||
}
|
||
|
||
void CMimeTable::FreeMappers()
|
||
{
|
||
TableCellT cell;
|
||
cell.col = 1;
|
||
PrefCellInfo cellInfo;
|
||
for (int i=1; i<= mRows; i++)
|
||
{
|
||
cell.row = i;
|
||
GetCellData(cell, &cellInfo);
|
||
delete cellInfo.fMapper;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
// Scroll the view as little as possible to move the specified cell
|
||
// entirely within the frame. Currently we only handle scrolling
|
||
// up or down a single line (when the selection moves because of
|
||
// and arrow key press).
|
||
//
|
||
void CMimeTable::ScrollCellIntoFrame(const TableCellT& inCell)
|
||
{
|
||
// Compute bounds of specified cell in image coordinates
|
||
Int32 cellLeft = 0;
|
||
Int32 cellRight = 1;
|
||
Int32 cellBottom = inCell.row * mRowHeight - 2;
|
||
Int32 cellTop = cellBottom - mRowHeight + 2;
|
||
|
||
if (ImagePointIsInFrame(cellLeft, cellTop) &&
|
||
ImagePointIsInFrame(cellRight, cellBottom))
|
||
{
|
||
return; // Cell is already within Frame
|
||
}
|
||
else
|
||
{
|
||
if (cellTop + mImageLocation.v < mFrameLocation.v)
|
||
ScrollImageTo(cellLeft, cellTop, true); // Scroll up
|
||
else
|
||
ScrollPinnedImageBy(0, mRowHeight, true); // Scroll down
|
||
}
|
||
}
|
||
|
||
Boolean CMimeTable::HandleKeyPress(const EventRecord &inKeyEvent)
|
||
{
|
||
Char16 theChar = inKeyEvent.message & charCodeMask;
|
||
Boolean handled = false;
|
||
|
||
TableIndexT tableRows;
|
||
TableIndexT tableCols;
|
||
TableCellT currentCell;
|
||
GetSelectedCell(currentCell);
|
||
GetTableSize(tableRows, tableCols);
|
||
|
||
switch (theChar)
|
||
{
|
||
case char_UpArrow:
|
||
currentCell.row--;
|
||
if (currentCell.row >= 1)
|
||
SelectCell(currentCell);
|
||
handled = true;
|
||
break;
|
||
|
||
case char_DownArrow:
|
||
currentCell.row++;
|
||
if (currentCell.row <= tableRows)
|
||
SelectCell(currentCell);
|
||
handled = true;
|
||
break;
|
||
|
||
case char_PageUp:
|
||
case char_PageDown:
|
||
case char_Home:
|
||
case char_End:
|
||
default:
|
||
handled = LCommander::HandleKeyPress(inKeyEvent);
|
||
}
|
||
|
||
return handled;
|
||
}
|
||
|
||
|
||
|
||
/************************************************************************************
|
||
Preferences MimeMapping window
|
||
************************************************************************************/
|
||
// utility callback function for getting icons
|
||
pascal Handle MyIconGetter( ResType theType, Ptr yourDataPtr );
|
||
|
||
// function that creates an item cache that we want
|
||
OSErr CreateCache(Handle & cache, short resID);
|
||
|
||
static IconGetterUPP MyIconGetterUPP = NULL;
|
||
|
||
pascal Handle MyIconGetter( ResType theType, Ptr yourDataPtr )
|
||
{
|
||
Handle res, resCopy;
|
||
|
||
resCopy = res = ::Get1Resource( theType, (short)yourDataPtr );
|
||
|
||
::HandToHand( &resCopy );
|
||
::ReleaseResource( res );
|
||
return resCopy;
|
||
}
|
||
|
||
|
||
OSErr CreateCache( Handle& cache, short resID )
|
||
{
|
||
if ( MyIconGetterUPP == NULL )
|
||
MyIconGetterUPP = NewIconGetterProc( MyIconGetter );
|
||
|
||
OSErr err = MakeIconCache( &cache, MyIconGetterUPP, (Ptr)resID );
|
||
|
||
if ( err )
|
||
return err;
|
||
|
||
Rect r;
|
||
r.top = r.left = 0;
|
||
r.bottom = r.right = 16;
|
||
|
||
err = LoadIconCache( &r, atHorizontalCenter, ttNone, cache );
|
||
return err;
|
||
}
|
||
|
||
|
||
Handle CFileType::sDefaultDocIcon = NULL;
|
||
|
||
CFileType::CFileType( OSType iconSig )
|
||
{
|
||
InitializeDefaults();
|
||
fIconSig = iconSig;
|
||
fIcon = sDefaultDocIcon;
|
||
}
|
||
|
||
CFileType::~CFileType()
|
||
{
|
||
if ( fIcon && ( fIcon != sDefaultDocIcon ) )
|
||
::DisposeIconSuite( fIcon, TRUE );
|
||
}
|
||
|
||
// Initializes default values
|
||
void CFileType::InitializeDefaults()
|
||
{
|
||
if ( sDefaultDocIcon == NULL )
|
||
{
|
||
StUseResFile resFile(kSystemResFile);
|
||
::CreateCache( sDefaultDocIcon, genericDocumentIconResource );
|
||
}
|
||
ThrowIfNil_( sDefaultDocIcon );
|
||
}
|
||
|
||
// Clear the default values
|
||
void CFileType::ClearDefaults()
|
||
{
|
||
if ( sDefaultDocIcon )
|
||
::DisposeIconSuite( sDefaultDocIcon, TRUE );
|
||
sDefaultDocIcon = NULL;
|
||
}
|
||
|
||
// <20><> globals
|
||
Handle CApplicationIconInfo::sDefaultAppIcon = NULL;
|
||
LArray * CApplicationIconInfo::sDocumentIcons = NULL;
|
||
Boolean CApplicationIconInfo::sHandlesAE = TRUE;
|
||
|
||
// Call me when application has not been found. Assigns default values
|
||
CApplicationIconInfo::CApplicationIconInfo( OSType appSig )
|
||
{
|
||
InitializeDefaults();
|
||
|
||
fAppSig = appSig;
|
||
fApplicationIcon = sDefaultAppIcon;
|
||
fDocumentIcons = sDocumentIcons;
|
||
fHandlesAE = sHandlesAE;
|
||
fApplicationFound = FALSE;
|
||
}
|
||
|
||
// Call me when app was found
|
||
CApplicationIconInfo::CApplicationIconInfo(
|
||
OSType appSig,
|
||
Handle appIcon,
|
||
LArray* documentIcons,
|
||
Boolean handlesAE)
|
||
{
|
||
InitializeDefaults();
|
||
|
||
fAppSig = appSig;
|
||
fApplicationIcon = appIcon;
|
||
fDocumentIcons = documentIcons;
|
||
fHandlesAE = handlesAE;
|
||
fApplicationFound = TRUE;
|
||
}
|
||
|
||
CApplicationIconInfo::~CApplicationIconInfo()
|
||
{
|
||
if ( fDocumentIcons == sDocumentIcons )
|
||
return; // Do not delete our defaults
|
||
for ( Int32 i = 1; i <= fDocumentIcons->GetCount(); i++ )
|
||
{
|
||
CFileType* f;
|
||
fDocumentIcons->FetchItemAt( i, &f );
|
||
delete f;
|
||
}
|
||
|
||
delete fDocumentIcons;
|
||
|
||
if ( fApplicationIcon != sDefaultAppIcon )
|
||
::DisposeIconSuite( fApplicationIcon, TRUE );
|
||
}
|
||
|
||
// <20><> access
|
||
|
||
// Gets file type by the index
|
||
CFileType* CApplicationIconInfo::GetFileType( int index )
|
||
{
|
||
CFileType* f;
|
||
if (index > fDocumentIcons->GetCount() )
|
||
#ifdef DEBUG
|
||
XP_ABORT();
|
||
#else
|
||
return NULL;
|
||
#endif
|
||
fDocumentIcons->FetchItemAt( index, &f );
|
||
return f;
|
||
}
|
||
|
||
// Gets number of file types
|
||
int CApplicationIconInfo::GetFileTypeArraySize()
|
||
{
|
||
return fDocumentIcons->GetCount();
|
||
}
|
||
|
||
// <20><> misc
|
||
|
||
void CApplicationIconInfo::InitializeDefaults()
|
||
{
|
||
if (sDocumentIcons != NULL)
|
||
return;
|
||
|
||
// Create a default document icon list, size 1, generic icon of type 'TEXT'
|
||
sDocumentIcons = new LArray;
|
||
ThrowIfNil_( sDocumentIcons );
|
||
|
||
CFileType* newType = new CFileType( 'TEXT' );
|
||
ThrowIfNil_( newType );
|
||
|
||
sDocumentIcons->InsertItemsAt( 1, LArray::index_Last, &newType );
|
||
|
||
// Get the default application icon
|
||
StUseResFile resFile(kSystemResFile);
|
||
::CreateCache( sDefaultAppIcon, genericApplicationIconResource );
|
||
ThrowIfNil_( sDefaultAppIcon );
|
||
}
|
||
|
||
void CApplicationIconInfo::ClearDefaults()
|
||
{
|
||
if ( sDocumentIcons == NULL )
|
||
return; // Nothing allocated, nothing deleted
|
||
for ( Int32 i = 1; i <= sDocumentIcons->GetCount(); i++ )
|
||
{
|
||
CFileType* f;
|
||
sDocumentIcons->FetchItemAt( i, &f );
|
||
delete f;
|
||
}
|
||
|
||
delete sDocumentIcons;
|
||
sDocumentIcons = NULL;
|
||
|
||
if ( sDefaultAppIcon )
|
||
DisposeIconSuite( sDefaultAppIcon, TRUE );
|
||
sDefaultAppIcon = NULL;
|
||
|
||
CFileType::ClearDefaults();
|
||
}
|
||
|
||
|
||
|
||
CApplicationList::CApplicationList() : LArray()
|
||
{
|
||
CApplicationIconInfo::InitializeDefaults();
|
||
}
|
||
|
||
CApplicationList::~CApplicationList()
|
||
{
|
||
for (Int32 i = 1; i <= mItemCount; i++)
|
||
{
|
||
CApplicationIconInfo * f;
|
||
FetchItemAt(i, &f);
|
||
delete f;
|
||
}
|
||
CApplicationIconInfo::ClearDefaults();
|
||
}
|
||
|
||
|
||
CApplicationIconInfo* CApplicationList::GetAppInfo(OSType appSig, CMimeMapper* mapper)
|
||
{
|
||
// Try to find the application that matches the sig:
|
||
for ( Int32 i = 1; i <= mItemCount; i++ )
|
||
{
|
||
CApplicationIconInfo* f;
|
||
FetchItemAt( i, &f );
|
||
if ( f->fAppSig == appSig)
|
||
return f;
|
||
}
|
||
|
||
// Could not find an application, must create a new entry
|
||
return CreateNewEntry(appSig, mapper);
|
||
}
|
||
|
||
|
||
// Creates application icon info for an app with a given signature
|
||
// If app is not found, defaults are created
|
||
CApplicationIconInfo* CApplicationList::CreateNewEntry(OSType appSig, CMimeMapper* mapper)
|
||
{
|
||
FSSpec appSpec;
|
||
CApplicationIconInfo* appInfo = NULL;
|
||
|
||
OSErr err = CFileMgr::FindApplication(appSig, appSpec );
|
||
|
||
if ( err != noErr )
|
||
{
|
||
// Application not found, create defaults
|
||
appInfo = new CApplicationIconInfo(appSig);
|
||
}
|
||
else
|
||
{
|
||
if (mapper)
|
||
mapper->SetAppName( appSpec.name );
|
||
appInfo = AppInfoFromFileSpec(appSig, appSpec);
|
||
}
|
||
|
||
InsertItemsAt(1, LArray::index_Last, &appInfo);
|
||
return appInfo;
|
||
}
|
||
|
||
// Horrendous bundle parsing routine.
|
||
// Its parses the bundle, gets all the document icons, and an application icon
|
||
// Failure can occur in many places. Unhandled failures result in a creation of
|
||
// the 'generic' applicatiohe resource
|
||
CApplicationIconInfo* CApplicationList::AppInfoFromFileSpec( OSType appSig, FSSpec appSpec )
|
||
{
|
||
CApplicationIconInfo* newInfo = NULL;
|
||
short refNum;
|
||
Handle bundle = NULL;
|
||
OSErr err;
|
||
Handle appIcon = NULL;
|
||
Boolean handlesAE = TRUE;
|
||
|
||
LArray* documentIcons = NULL;
|
||
BNDLIds* iconOffset;
|
||
BNDLIds* frefOffset;
|
||
short numOfIcons;
|
||
short numOfFrefs; // Really number-1, just like in the resource
|
||
BNDLIds frefBNDL;
|
||
Handle iconFamily;
|
||
OSType iconType;
|
||
Handle frefRes = NULL;
|
||
|
||
Try_
|
||
{
|
||
documentIcons = new LArray();
|
||
ThrowIfNil_( documentIcons );
|
||
|
||
SetResLoad( FALSE );
|
||
refNum = ::FSpOpenResFile( &appSpec,fsRdPerm );
|
||
err = ResError();
|
||
SetResLoad( TRUE );
|
||
ThrowIfOSErr_( err );
|
||
|
||
// BNDL
|
||
bundle = ::Get1IndResource( 'BNDL' , 1 );
|
||
ThrowIfNil_( bundle );
|
||
HLock( bundle );
|
||
HNoPurge( bundle );
|
||
// Get the signature
|
||
::BlockMoveData( *bundle, &appSig, 4 );
|
||
|
||
GetResourcePointers( bundle, iconOffset, frefOffset, numOfIcons, numOfFrefs );
|
||
|
||
// We have the offsets for FREF and ICN# resources
|
||
// Not every FREF has a matching icon, so we read in all
|
||
// the FREFs and try to find the matching icon for each
|
||
for ( int i = 0; i <= numOfFrefs; i++ )
|
||
{
|
||
// Algorithm:
|
||
// Get the FREF resource specified in BNDL
|
||
// Find the ICN# resource from BNDL with same local ID
|
||
// Get the icon specified in ICN# resource.
|
||
// If getting of the icon fails in any case, use the default icon
|
||
frefBNDL = frefOffset[i];
|
||
iconFamily = NULL;
|
||
iconType = 'DUMB';
|
||
frefRes = ::Get1Resource( 'FREF', frefBNDL.resID );
|
||
if ( frefRes == NULL ) // Ignore the record if FREF resource is not found
|
||
continue;
|
||
::BlockMoveData( *frefRes, &iconType, 4 );
|
||
::ReleaseResource( frefRes );
|
||
|
||
if ( ( iconType == 'fold' ) || // folders are not files
|
||
( iconType == '****' ) || // any file will default to text later
|
||
( iconType == 'pref' ) || // prefs are also ignored
|
||
( iconType == 'PREF' ) )
|
||
continue;
|
||
|
||
for ( int j = 0; j <= numOfIcons; j++ )
|
||
{
|
||
BNDLIds iconBndl = iconOffset[j];
|
||
if ( iconBndl.localID == frefBNDL.localID )
|
||
{
|
||
err = ::CreateCache( iconFamily, iconBndl.resID );
|
||
if (err)
|
||
iconFamily = NULL;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( iconType == 'APPL' )
|
||
{
|
||
// Special handling of the application icon
|
||
if ( iconFamily == NULL )
|
||
appIcon = CApplicationIconInfo::sDefaultAppIcon;
|
||
else
|
||
appIcon = iconFamily;
|
||
}
|
||
else
|
||
{ // Document icons
|
||
CFileType* newType = NULL;
|
||
if ( iconFamily == NULL )
|
||
newType = new CFileType( iconType );
|
||
else
|
||
newType = new CFileType( iconType, iconFamily );
|
||
|
||
documentIcons->InsertItemsAt( 1, LArray::index_Last, &newType );
|
||
}
|
||
} // Done parsing all the file types
|
||
|
||
HUnlock( bundle );
|
||
HPurge( bundle );
|
||
ReleaseResource( bundle );
|
||
// Figure out if the application handles AppleEvents
|
||
Handle sizeRes = ::Get1Resource( 'SIZE', -1 );
|
||
if ( sizeRes == NULL )
|
||
handlesAE = FALSE;
|
||
else
|
||
{
|
||
char aeChar;
|
||
aeChar = (*sizeRes)[1];
|
||
handlesAE = aeChar & 2;
|
||
}
|
||
|
||
// Error handling: no file types
|
||
if ( documentIcons->GetCount() == 0 ) // No icons were read, add 1 dummy one
|
||
{
|
||
CFileType* newType = new CFileType( 'TEXT' );
|
||
documentIcons->InsertItemsAt( 1, LArray::index_Last, &newType );
|
||
}
|
||
// Error handling: no application icon
|
||
if ( appIcon == NULL )
|
||
appIcon = CApplicationIconInfo::sDefaultAppIcon;
|
||
newInfo = new CApplicationIconInfo( appSig, appIcon, documentIcons, handlesAE );
|
||
}
|
||
Catch_(inErr)
|
||
{
|
||
newInfo = new CApplicationIconInfo( appSig );
|
||
}
|
||
EndCatch_
|
||
|
||
CloseResFile( refNum );
|
||
err = ResError();
|
||
ThrowIfNil_( newInfo );
|
||
return newInfo;
|
||
}
|
||
|
||
void CApplicationList::GetResourcePointers(
|
||
Handle bundle,
|
||
BNDLIds* &iconOffset,
|
||
BNDLIds* &frefOffset,
|
||
short& numOfIcons,
|
||
short& numOfFrefs)
|
||
{
|
||
OSType resType;
|
||
Ptr bundlePtr = NULL;
|
||
|
||
bundlePtr = *bundle;
|
||
|
||
::BlockMoveData( bundlePtr + 8, &resType, 4 ); // Get the first resource type
|
||
if ( resType == 'ICN#' )
|
||
{
|
||
::BlockMoveData( bundlePtr + 12, &numOfIcons, 2 );
|
||
iconOffset = (BNDLIds*)( bundlePtr + 14 );
|
||
//::BlockMove( (Ptr)iconOffset + ( numOfIcons + 1) * sizeof( BNDLIds ), &resType, 4 ); // Just checkin'
|
||
::BlockMoveData( (Ptr)iconOffset + (numOfIcons + 1) * sizeof( BNDLIds ) + 4, &numOfFrefs, 2 );
|
||
frefOffset = (BNDLIds*)( (Ptr)iconOffset + 6 + ( numOfIcons + 1 ) * sizeof( BNDLIds ) );
|
||
}
|
||
else // FREF
|
||
{
|
||
::BlockMoveData( bundlePtr + 12, &numOfFrefs, 2 );
|
||
frefOffset = (BNDLIds*) (bundlePtr + 14 );
|
||
//::BlockMove( (Ptr)frefOffset + ( numOfFrefs + 1 ) * sizeof( BNDLIds ), &resType, 4 ); // Just checkin'
|
||
::BlockMoveData( (Ptr)frefOffset + ( numOfFrefs + 1 ) * sizeof( BNDLIds ) + 4, &numOfIcons, 2 );
|
||
iconOffset = (BNDLIds*)( (Ptr)frefOffset + 6 + (numOfFrefs + 1) * sizeof(BNDLIds) );
|
||
}
|
||
}
|
||
|
||
PrefCellInfo::PrefCellInfo(CMimeMapper * mapper, CApplicationIconInfo * iconInfo)
|
||
{
|
||
fMapper = mapper;
|
||
fIconInfo = iconInfo;
|
||
}
|
||
|
||
PrefCellInfo::PrefCellInfo()
|
||
{
|
||
fMapper = NULL;
|
||
fIconInfo = NULL;
|
||
}
|
||
|
||
|
||
Boolean
|
||
LFocusEditField::HandleKeyPress(
|
||
const EventRecord &inKeyEvent)
|
||
{
|
||
Boolean keyHandled = true;
|
||
LControl *keyButton = nil;
|
||
|
||
switch (inKeyEvent.message & charCodeMask) {
|
||
|
||
case char_Enter:
|
||
case char_Return:
|
||
BroadcastMessage(mReturnMessage, this);
|
||
return true;
|
||
default:
|
||
return LEditField::HandleKeyPress(inKeyEvent);
|
||
}
|
||
}
|
||
|
||
LFocusEditField::LFocusEditField(
|
||
const LFocusEditField &inOriginal)
|
||
: LEditField(inOriginal),
|
||
LBroadcaster(inOriginal)
|
||
{
|
||
mFocusBox = nil;
|
||
if (inOriginal.mFocusBox != nil) {
|
||
mFocusBox = new LFocusBox(*(inOriginal.mFocusBox));
|
||
}
|
||
}
|
||
|
||
LFocusEditField::LFocusEditField(
|
||
LStream *inStream)
|
||
: LEditField(inStream)
|
||
{
|
||
mFocusBox = new LFocusBox;
|
||
mFocusBox->Hide();
|
||
mFocusBox->AttachPane(this);
|
||
}
|
||
LFocusEditField::~LFocusEditField()
|
||
{
|
||
|
||
}
|
||
void
|
||
LFocusEditField::BeTarget()
|
||
{
|
||
if(mFocusBox != nil) {
|
||
mFocusBox->Show();
|
||
}
|
||
LEditField::BeTarget();
|
||
}
|
||
void
|
||
LFocusEditField::DontBeTarget()
|
||
{
|
||
if(mFocusBox != nil) {
|
||
mFocusBox->Hide();
|
||
}
|
||
LEditField::DontBeTarget();
|
||
}
|
||
LFocusBox*
|
||
LFocusEditField::GetFocusBox()
|
||
{
|
||
return mFocusBox;
|
||
}
|
||
|
||
/********************************************************************
|
||
|
||
OneClickLListBox implementation.
|
||
|
||
Derived from LListBox. Overrides ClickSelf so that it sends a
|
||
message when it has only been clicked once, not twice.
|
||
|
||
********************************************************************/
|
||
OneClickLListBox::OneClickLListBox( LStream* inStream ): LListBox( inStream )
|
||
{
|
||
mSingleClickMessage = msg_Nothing;
|
||
}
|
||
|
||
|
||
void OneClickLListBox::ClickSelf(const SMouseDownEvent &inMouseDown)
|
||
{
|
||
if(SwitchTarget(this))
|
||
{
|
||
FocusDraw();
|
||
if (::LClick(inMouseDown.whereLocal, inMouseDown.macEvent.modifiers, mMacListH))
|
||
{
|
||
BroadcastMessage(mDoubleClickMessage, this);
|
||
} else {
|
||
BroadcastMessage(mSingleClickMessage, this);
|
||
}
|
||
}
|
||
}
|
||
|
||
Boolean OneRowLListBox::HandleKeyPress(const EventRecord &inKeyEvent)
|
||
{
|
||
if(OneClickLListBox::HandleKeyPress(inKeyEvent))
|
||
{
|
||
Char16 theKey = inKeyEvent.message & charCodeMask;
|
||
// based on LListBox::HandleKeyPress--only broadcast when our class handled it
|
||
// (window might close--deleting us--before we broadcast)
|
||
if ( UKeyFilters::IsNavigationKey(theKey) ||
|
||
( UKeyFilters::IsPrintingChar(theKey) && ! (inKeyEvent.modifiers & cmdKey) ) )
|
||
{
|
||
BroadcastMessage(mSingleClickMessage, this);
|
||
}
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
|
||
int16 OneRowLListBox::GetRows()
|
||
{
|
||
return ((**mMacListH).dataBounds.bottom);
|
||
}
|
||
|
||
OneRowLListBox::OneRowLListBox( LStream* inStream ): OneClickLListBox( inStream )
|
||
{
|
||
FocusDraw();
|
||
if((*mMacListH)->dataBounds.right == 0)
|
||
::LAddColumn(1 , 0, mMacListH);
|
||
(*mMacListH)->selFlags |= lOnlyOne;
|
||
}
|
||
|
||
void OneRowLListBox::AddRow(int32 rowNum, char* data, int16 datalen)
|
||
{
|
||
if(SwitchTarget(this))
|
||
{
|
||
FocusDraw();
|
||
Cell theCell;
|
||
theCell.h = 0;
|
||
rowNum = ::LAddRow(1 , rowNum, mMacListH);
|
||
theCell.v = rowNum;
|
||
::LSetCell(data,datalen ,theCell, mMacListH);
|
||
}
|
||
}
|
||
void OneRowLListBox::GetCell(int32 rowNum, char* data, int16* datalen)
|
||
{
|
||
FocusDraw();
|
||
Cell theCell;
|
||
theCell.h = 0;
|
||
theCell.v = rowNum;
|
||
::LGetCell(data,datalen ,theCell, mMacListH);
|
||
}
|
||
void OneRowLListBox::SetCell(int32 rowNum, char* data, int16 datalen)
|
||
{
|
||
if(SwitchTarget(this))
|
||
{
|
||
FocusDraw();
|
||
Cell theCell;
|
||
theCell.h = 0;
|
||
theCell.v = rowNum;
|
||
::LSetCell(data,datalen ,theCell, mMacListH);
|
||
}
|
||
}
|
||
|
||
void OneRowLListBox::RemoveRow(int32 rowNum)
|
||
{
|
||
FocusDraw();
|
||
::LDelRow(1 , rowNum, mMacListH);
|
||
}
|