Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Windows.c
/* |
File: Windows.c |
Contains: Handle application's windows |
Written by: Chris White |
Copyright: Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
8/5/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#include <Types.h> |
#include <Quickdraw.h> |
#include <QDOffscreen.h> |
#include <Devices.h> |
#include <LowMem.h> /* For MemError() */ |
#include <Script.h> |
#include <TextUtils.h> |
#include <Dialogs.h> |
#include <Folders.h> |
#include <stddef.h> |
#include <Sound.h> |
#include <CodeFragments.h> |
#include <StandardFile.h> |
#include <Folders.h> |
#include "FragmentTool.h" |
#include "FragmentStuff.h" |
#include "Dialogs.h" |
#include "Streams.h" |
#include "Utilities.h" |
#include "Prototypes.h" |
static OSErr CreateContentList ( WindowRef theWindow, tContentsProcPtr contentsProc, void* refCon ); |
static void AddContentsToList ( WindowRef theWindow ); |
static void DoDialogItemHit ( DialogRef theDialog, int16 theItem ); |
static int8 GetStageFromItem ( int16 theItem ); |
static int16 GetItemFromStage ( int8 theStage ); |
static OSErr CreateTempAndCopyFragment ( tHeaderHan sourceHeader, FSSpecPtr sourceSpec, int16 sourceIndex, |
tHeaderHan targetHeader ); |
void DoNewDocument ( void ) |
{ |
OSErr theErr; |
int16 theRef; |
int16 theVol; |
int32 theDir; |
FSSpec theSpec; |
Str255 tmpStr = "\p"; |
Str255 theFile = "\pFragmentTool "; |
hdrHand theHeader; |
Size headerSize; |
theErr = FindFolder ( kOnSystemDisk, kTemporaryFolderType, kCreateFolder, &theVol, &theDir ); |
OSTypeToPStr ( TickCount ( ), tmpStr ); |
ConcatPStr ( theFile, tmpStr, sizeof ( Str255 ) ); |
theErr = FSMakeFSSpec ( theVol, theDir, theFile, &theSpec ); |
theErr = FSpCreate ( &theSpec, kFourQuestionMarks, kCFragLibraryFileType, smSystemScript ); |
// The file has been created with both forks, but it doesn't have a |
// resource map yet. If we try to open it now, we'll get an eofErr (-39). |
FSpCreateResFile ( &theSpec, kFourQuestionMarks, kCFragLibraryFileType, smSystemScript ); |
theRef = FSpOpenResFile ( &theSpec, fsRdWrPerm ); |
if ( theRef == -1 ) |
{ |
theErr = ResError ( ); |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return; |
} |
headerSize = offsetof ( cfrgHeader, arrayStart ); |
theHeader = (hdrHand) NewHandleClear ( headerSize ); |
(*theHeader)->version = 1; // Current version number |
AddResource ( (Handle) theHeader, kCFragResourceType, kCFragResourceID, "\p" ); |
CloseResFile ( theRef ); |
GetIndString ( tmpStr, 1000, 4 ); // Default document name |
theErr = OpenDocument ( &theSpec, tmpStr ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return; |
} |
return; |
} |
void DoOpenDocument ( void ) |
{ |
OSErr theErr; |
StandardFileReply theReply; |
StandardGetFile ( nil, -1, nil, &theReply ); |
if ( theReply.sfGood ) |
{ |
theErr = OpenDocument ( &theReply.sfFile, nil ); |
if ( theErr ) |
AlertUser ( kGenericErrorStr, theErr, nil ); |
} |
return; |
} |
OSErr OpenDocument ( FSSpecPtr fileSpec, StringPtr documentName ) |
{ |
OSErr theErr; |
int16 theFileRef, saveFile; |
WindowRef theWindow; |
tWindowInfoPtr theInfo; |
tAddFragmentsRec theRec; |
Str255 theTitle; |
if ( documentName ) |
CopyPStr ( documentName, theTitle, sizeof ( Str255 ) ); |
else |
CopyPStr ( fileSpec->name, theTitle, sizeof ( Str255 ) ); |
saveFile = CurResFile ( ); |
SetResLoad ( false ); |
theFileRef = FSpOpenResFile ( fileSpec, fsRdPerm ); |
SetResLoad ( true ); |
UseResFile ( saveFile ); |
if ( theFileRef == -1 ) |
return ResError ( ); |
theRec.u.out.theFileRef = theFileRef; |
theErr = CreateDocumentWindow ( &theWindow, theTitle, AddFragments, (void*) &theRec ); |
if ( theErr ) |
return theErr; |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
theInfo->bUntitled = (documentName) ? true : false; |
theInfo->dataHandle = theRec.u.in.theDataHandle; |
BlockMoveData ( fileSpec, &theInfo->fileSpec, sizeof ( FSSpec ) ); |
return theErr; |
} |
OSErr CreateDocumentWindow ( WindowRef* windowRef, Str255 windowTitle, |
tContentsProcPtr contentsProc, void* refCon ) |
{ |
OSErr theErr; |
WindowRef theWindow; |
theWindow = GetNewCWindow ( kDisplayWindow, nil, (WindowRef) -1L ); |
if ( theWindow == nil ) |
return (ResError ( )) ? ResError ( ) : resNotFound; |
theErr = CreateWindowInfo ( theWindow, sizeof ( tWindowInfo ) ); |
if ( theErr ) goto CleanupAndBail; |
theErr = CreateContentList ( theWindow, contentsProc, refCon ); |
if ( theErr ) goto CleanupAndBail; |
// Since the application can function without the Drag Manager, an |
// error here is not considered fatal. |
theErr = InstallDragHandlers ( theWindow ); |
SetWindowType ( theWindow, kDocumentWindowType ); |
SetPortWindowPort ( theWindow ); |
TextFont ( kFontIDGeneva ); |
TextFace ( normal ); |
TextSize ( 9 ); |
SetWTitle ( theWindow, windowTitle ); |
SelectWindow ( theWindow ); |
ShowWindow ( theWindow ); |
*windowRef = theWindow; |
return noErr; |
CleanupAndBail: |
// Don't forget to free any storage we've used so far |
DestroyDocumentWindow ( theWindow ); |
return theErr; |
} |
// |
// This will close the document's file, dispose of any storage we've hung |
// off the window, remove any drag handlers, and then dispose of the window. |
// |
WindowRef DestroyDocumentWindow ( WindowRef windowRef ) |
{ |
if ( windowRef ) |
{ |
tWindowInfoPtr theInfo; |
theInfo = (tWindowInfoPtr) GetWRefCon ( windowRef ); |
if ( theInfo ) |
{ |
if ( theInfo->listRef ) |
LDispose ( theInfo->listRef ); |
if ( theInfo->dataHandle ) |
DisposeHandle ( theInfo->dataHandle ); |
DisposePtr ( (Ptr) theInfo ); |
} |
RemoveDragHandlers ( windowRef ); |
DisposeWindow ( windowRef ); |
} |
// Return nil so it can be assigned to the window |
// reference which was passed in |
return nil; |
} |
//////////////////////////////////////////////////////////////////////////////////// |
// |
// Draw *only* the grow icon |
// |
void DrawClippedGrowIcon ( WindowRef theWindow ) |
{ |
Rect portRect = theWindow->portRect; |
RgnHandle oldClip = NULL; |
Rect newClip; |
SetPort ( theWindow ); |
oldClip = NewRgn ( ); |
GetClip ( oldClip ); |
newClip = portRect; |
newClip.top = newClip.bottom - 15; |
newClip.left = newClip.right - 15; |
ClipRect ( &newClip ); |
DrawGrowIcon ( theWindow ); |
SetClip ( oldClip ); |
DisposeRgn ( oldClip ); |
return; |
} |
// |
// This is passed into the CreateDocumentWindow routine |
// to add the contents to the newly created list. |
// |
OSErr AddFragments ( ListRef theList, void* refCon ) |
{ |
OSErr theErr; |
int16 theFileRef, saveFile; |
int index, itemCount; |
Handle resourceScratch; |
tHeaderHan parsedResource; |
tAddFragmentsRec* theRec; |
theRec = (tAddFragmentsRec*) refCon; |
theFileRef = theRec->u.out.theFileRef; |
parsedResource = (tHeaderHan) NewHandleClear ( sizeof ( tHeader ) ); |
theErr = MemError ( ); |
if ( theErr ) |
return theErr; |
saveFile = CurResFile ( ); |
UseResFile ( theFileRef ); |
resourceScratch = Get1Resource ( kCFragResourceType, kCFragResourceID ); |
theErr = ResError ( ); |
if ( theErr || resourceScratch == nil) |
return (theErr) ? theErr : resNotFound; |
UseResFile ( saveFile ); |
if ( parsedResource ) |
{ |
ParseResource ( resourceScratch, parsedResource ); |
itemCount = (*parsedResource)->itemCount; |
for ( index = 0; index < itemCount; index++ ) |
{ |
tItemPtr dstItem; |
dstItem = &(*parsedResource)->itemList[index]; |
AddFragToList ( theList, dstItem ); |
} |
theRec->u.in.theDataHandle = (Handle) parsedResource; |
} |
ReleaseResource ( resourceScratch ); |
return noErr; |
} // AddFragments |
// |
// This returns the Nth document window, ignoring the front-most |
// |
WindowRef GetIndexedDocumentWindow ( int theIndex ) |
{ |
Boolean bFirst = true; |
int thisIndex = 0; // Must be zero-based, like the List Manager |
WindowRef currWindow; |
currWindow = FrontWindow ( ); |
while ( currWindow ) |
{ |
if ( GetWindowType ( currWindow ) == kDocumentWindowType ) |
{ |
// Skip the front-most document since that's the source document |
if ( bFirst ) |
bFirst = false; |
else |
{ |
if ( thisIndex == theIndex ) |
return currWindow; |
thisIndex++; |
} |
} |
currWindow = GetNextWindow ( currWindow ); |
} |
return nil; |
} |
// |
// Creates the storage for the data to hang off a window or dialog |
// |
OSErr CreateWindowInfo ( WindowRef windowRef, Size infoSize ) |
{ |
OSErr theErr; |
Ptr theInfo = nil; |
theInfo = NewPtrClear ( infoSize ); |
theErr = MemError ( ); |
if ( theErr ) |
return theErr; |
SetWRefCon ( windowRef, (long) theInfo ); |
return noErr; |
} |
// |
// Closes all the open documents. Called just before a quit, or as |
// the result of an option click in a windows go away box. |
// |
Boolean DoCloseAllDocuments ( void ) |
{ |
Boolean bCancelled = false; |
WindowRef aWindow; |
aWindow = FrontWindow ( ); |
while ( aWindow && !bCancelled ) |
{ |
bCancelled = DoCloseDocument ( aWindow ); |
aWindow = GetNextWindow ( aWindow ); |
} |
return bCancelled; |
} |
Boolean DoCloseDocument ( WindowRef theWindow ) |
{ |
int16 windowType; |
if ( theWindow ) |
{ |
windowType = GetWindowType ( theWindow ); |
if ( windowType == kDAWindowType ) |
CloseDeskAcc ( GetWindowKind ( theWindow ) ); |
else if ( windowType == kDocumentWindowType ) |
{ |
int i; |
tWindowInfoPtr theInfo; |
tHeaderHan theHeader; |
tItemPtr anItem; |
// Check for any fragments that have temp files |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
if ( theInfo->bDirty ) |
if ( DoSaveBeforeClosing ( theWindow ) ) // Did the user cancel? |
return kCancelled; |
theHeader = (tHeaderHan) theInfo->dataHandle; |
HLock ( (Handle) theHeader ); |
for ( i = 0; i < GetItemCount ( theHeader ); i++ ) |
{ |
anItem = GetNthItem ( theHeader, i ); |
if ( anItem == nil ) |
break; |
DecrementTempUsageCount ( anItem ); |
} |
HUnlock ( (Handle) theHeader ); |
DestroyDocumentWindow ( theWindow ); |
} |
else if ( windowType == kListWindowType ) |
DestroyDialog ( theWindow ); |
AdjustMenus ( ); |
} |
return kNotCancelled; |
} // CloseDocument |
Boolean DoSaveBeforeClosing ( WindowRef theWindow ) |
{ |
int16 theItem; |
DialogRef theDialog; |
WindowRef dialogWindow; |
Str255 theTitle, theReason; |
theDialog = GetNewDialog ( kSaveDontsaveDialog, nil, (WindowRef) -1 ); |
dialogWindow = GetDialogWindow ( theDialog ); |
SetPortWindowPort ( dialogWindow ); |
GetWTitle ( theWindow, theTitle ); |
if ( gQuit ) |
GetIndString ( theReason, 1000, 6 ); |
else |
GetIndString ( theReason, 1000, 7 ); |
ParamText ( theTitle, theReason, nil, nil ); |
ShowWindow ( dialogWindow ); |
SelectWindow ( dialogWindow ); |
SetDialogDefaultItem ( theDialog, kStdOkItemIndex ); |
SetDialogCancelItem ( theDialog, kStdCancelItemIndex ); |
// As long as the only enabled items are the dimissers, |
// there is no need to call ModalDialog within a loop. |
ModalDialog ( nil, &theItem ); |
DisposeDialog ( theDialog ); |
if ( theItem == kStdOkItemIndex ) |
return DoSave ( theWindow ); |
return theItem == kStdCancelItemIndex; |
} |
Boolean DoSave ( WindowRef theWindow ) |
{ |
int16 saveFile, theFileRef; |
int i; |
OSErr theErr; |
Handle resourceScratch; |
tWindowInfoPtr theInfo; |
tHeaderHan theHeader; |
tItemPtr anItem; |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
#if DEBUGGING |
if ( theInfo == nil ) DebugStr ( "\p theInfo == nil" ); |
#endif |
if ( theInfo->bUntitled ) |
return DoSaveAs ( theWindow ); |
// Check for any fragments that have been deleted... |
theHeader = (tHeaderHan) theInfo->dataHandle; |
HLock ( (Handle) theHeader ); |
for ( i = 0; i < GetItemCount ( theHeader ); i++ ) |
{ |
anItem = GetNthItem ( theHeader, i ); |
if ( anItem->bDeleted ) |
{ |
if ( anItem->bExistsInDocument ) |
{ |
theErr = DeleteFragment ( theHeader, &theInfo->fileSpec, i ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return kNotCancelled; |
} |
anItem->bExistsInDocument = false; |
} |
DecrementTempUsageCount ( anItem ); |
} |
} |
// ...and for any new fragments |
for ( i = 0; i < GetItemCount ( theHeader ); i++ ) |
{ |
anItem = GetNthItem ( theHeader, i ); |
if ( anItem->bDeleted || anItem->bExistsInDocument ) |
continue; |
anItem->codeOffset = 0L; |
theErr = AppendFileData ( GetTempSpecPtr ( anItem ), &theInfo->fileSpec, &anItem->codeOffset, &anItem->codeLength ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return kNotCancelled; |
} |
anItem->bExistsInDocument = true; |
} |
HUnlock ( (Handle) theHeader ); |
saveFile = CurResFile ( ); |
theFileRef = FSpOpenResFile ( &theInfo->fileSpec, fsRdWrPerm ); |
theErr = ResError ( ); |
if ( theErr ) |
{ |
int16 theIndex; |
theIndex = (theErr == opWrErr || theErr == permErr) ? kFileOpenStr : kGenericErrorStr; |
AlertUser ( theIndex, (theErr == noErr) ? resNotFound : theErr, nil ); |
return kNotCancelled; |
} |
UseResFile ( theFileRef ); |
resourceScratch = Get1Resource ( kCFragResourceType, kCFragResourceID ); |
theErr = ResError ( ); |
if ( theErr || resourceScratch == nil ) |
{ |
AlertUser ( kGenericErrorStr, (theErr == noErr) ? resNotFound : theErr, nil ); |
return kNotCancelled; |
} |
theErr = BuildResource ( (tHeaderHan) theInfo->dataHandle, resourceScratch ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return kNotCancelled; |
} |
ChangedResource ( resourceScratch ); |
UpdateResFile ( theFileRef ); |
ReleaseResource ( resourceScratch ); |
CloseResFile ( theFileRef ); |
UseResFile ( saveFile ); |
SetDocumentDirty ( theWindow, false ); |
return kNotCancelled; |
} |
Boolean DoSaveAs ( WindowRef theWindow ) |
{ |
tWindowInfoPtr theInfo; |
StandardFileReply theReply; |
Str255 defaultName; |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
#if DEBUGGING |
if ( theInfo == nil ) DebugStr ( "\p theInfo == nil" ); |
#endif |
GetWTitle ( theWindow, defaultName ); |
StandardPutFile ( "\p", defaultName, &theReply ); |
if ( theReply.sfGood ) |
{ |
OSErr theErr; |
if ( theInfo->bUntitled ) |
{ |
theInfo->bUntitled = false; |
DoSave ( theWindow ); |
theErr = FSpCreate ( &theReply.sfFile, kFourQuestionMarks, kCFragLibraryFileType, theReply.sfScript ); |
theErr = FSpExchangeFiles ( &theInfo->fileSpec, &theReply.sfFile ); |
FSpDelete ( &theInfo->fileSpec ); |
BlockMoveData ( &theReply.sfFile, &theInfo->fileSpec, sizeof ( FSSpec ) ); |
SetWTitle ( theWindow, theReply.sfFile.name ); |
} |
else // User selected ÒSave AsÉÓ |
{ |
int16 theRef, saveFile; |
int i; |
FSSpec oldSpec; |
tItemPtr anItem; |
hdrHand theResource = nil; |
tHeaderHan theHeader; |
BlockMoveData ( &theInfo->fileSpec, &oldSpec, sizeof ( FSSpec ) ); |
BlockMoveData ( &theReply.sfFile, &theInfo->fileSpec, sizeof ( FSSpec ) ); |
theErr = FSpCreate ( &theInfo->fileSpec, kFourQuestionMarks, kCFragLibraryFileType, theReply.sfScript ); |
theHeader = (tHeaderHan) theInfo->dataHandle; |
HLock ( (Handle) theHeader ); |
// copy each fragment's data fork |
for ( i = 0; i < GetItemCount ( theHeader ); i++ ) |
{ |
FSSpecPtr theSpecPtr; |
anItem = GetNthItem ( theHeader, i ); |
if ( anItem->bDeleted ) |
continue; |
if ( anItem->bExistsInDocument ) |
theSpecPtr = &oldSpec; |
else |
{ |
theSpecPtr = GetTempSpecPtr ( anItem ); |
anItem->codeOffset = 0L; |
} |
theErr = AppendFileData ( theSpecPtr, &theInfo->fileSpec, &anItem->codeOffset, &anItem->codeLength ); |
if ( theErr ) |
{ |
AlertUser ( kGenericErrorStr, theErr, nil ); |
return kNotCancelled; |
} |
anItem->bExistsInDocument = true; |
} |
HUnlock ( (Handle) theHeader ); |
FSpCreateResFile ( &theInfo->fileSpec, kFourQuestionMarks, kCFragLibraryFileType, smSystemScript ); |
theRef = FSpOpenResFile ( &theInfo->fileSpec, fsRdWrPerm ); |
theResource = (hdrHand) NewHandleClear ( offsetof ( cfrgHeader, arrayStart ) ); |
(*theResource)->version = 1; // Current version number |
theErr = BuildResource ( (tHeaderHan) theInfo->dataHandle, (Handle) theResource ); |
saveFile = CurResFile ( ); |
theRef = FSpOpenResFile ( &theInfo->fileSpec, fsRdWrPerm ); |
// If the file is already open, it may not be the current resource file |
UseResFile ( theRef ); |
AddResource ( (Handle) theResource, kCFragResourceType, kCFragResourceID, "\p" ); |
UpdateResFile ( theRef ); |
ReleaseResource ( (Handle) theResource ); |
CloseResFile ( theRef ); |
UseResFile ( saveFile ); |
SetWTitle ( theWindow, theReply.sfFile.name ); |
SetDocumentDirty ( theWindow, false ); |
} |
return kNotCancelled; |
} |
return kCancelled; |
} |
static OSErr CreateContentList ( WindowRef theWindow, tContentsProcPtr contentsProc, void* refCon ) |
{ |
OSErr theErr; |
ListHandle theList; |
Point cellSize = {0, 32767}; |
Cell firstCell = {0, 0}; |
Rect dataRect = {0, 0, 0, 1}; |
Rect viewRect; |
// The width of a cell needs to be 32767 so any hiliting |
// doesn't stop short of the window width after it's been resized. |
viewRect = theWindow->portRect; |
viewRect.bottom -= 15; viewRect.right -= 15; |
theList = LNew ( &viewRect, &dataRect, cellSize, 0, theWindow, |
false, false, true, true ); |
if ( theList ) |
{ |
(*theList)->selFlags = lOnlyOne; |
(*theList)->lClickLoop = gClickLoopUPP; |
SetWListRef ( theWindow, theList ); |
// Since the calling routine is always in the same architecture type as |
// the callback routine, we don't need to worry about any Mixed Mode |
// complications. We just treat it as a straight forward routine pointer. |
if ( contentsProc ) |
{ |
theErr = (*contentsProc) ( theList, refCon ); |
if ( theErr ) |
return theErr; |
} |
LSetSelect ( true, firstCell, theList ); |
// Now the list has been fully prepared, turn the drawing mode on |
LSetDrawingMode ( true, theList ); |
} |
return noErr; |
} // CreateContentList |
Boolean IsDocumentDirty ( WindowRef theWindow ) |
{ |
if ( GetWindowType ( theWindow ) == kDocumentWindowType ) |
{ |
tWindowInfoPtr theInfo; |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
if ( theInfo ) |
return ( theInfo->bDirty ); |
} |
return false; |
} |
void SetDocumentDirty ( WindowRef theWindow, Boolean bIsDirty ) |
{ |
if ( GetWindowType ( theWindow ) == kDocumentWindowType ) |
{ |
tWindowInfoPtr theInfo; |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
if ( theInfo ) |
theInfo->bDirty = bIsDirty; |
AdjustMenus ( ); |
} |
return; |
} |
void SetWListRef ( WindowRef theWindow, ListHandle theList ) |
{ |
((tWindowInfoPtr) GetWRefCon ( theWindow ))->listRef = theList; |
return; |
} |
ListHandle GetWListRef ( WindowRef theWindow ) |
{ |
return ((tWindowInfoPtr) GetWRefCon ( theWindow ))->listRef; |
} |
void SetWFileSpec ( WindowRef theWindow, FSSpecPtr theSpec ) |
{ |
BlockMoveData ( theSpec, &((tWindowInfoPtr) GetWRefCon ( theWindow ))->fileSpec, sizeof ( FSSpec ) ); |
return; |
} |
/*----------------------- Handle window update events ----------------------*/ |
void DoUpdate ( EventRecord* theEvent ) |
{ |
WindowRef theWindow; |
SInt16 theType; |
GrafPtr savePort; |
theWindow = (WindowRef) theEvent->message; |
theType = GetWindowType ( theWindow ); |
GetPort ( &savePort ); |
SetPortWindowPort ( theWindow ); |
BeginUpdate ( theWindow ); // visRgn temporarily = updateRgn |
EraseRect ( &theWindow->portRect ); |
switch ( theType ) |
{ |
case kDocumentWindowType: |
{ |
ListHandle theList = nil; |
theList = GetWListRef ( theWindow ); |
if ( theList ) |
LUpdate ( (*theList)->port->visRgn, theList ); |
DrawClippedGrowIcon ( theWindow ); |
} |
break; |
case kListWindowType: |
{ |
ListHandle theList = nil; |
tDialogInfoPtr theInfo; |
UpdateDialog ( theWindow, theWindow->visRgn ); |
theInfo = (tDialogInfoPtr) GetWRefCon ( theWindow ); |
theList = theInfo->listRef; |
if ( theList ) |
LUpdate ( (*theList)->port->visRgn, theList ); |
} |
break; |
case kGetInfoWindowType: |
{ |
TEHandle textH; |
UpdateDialog ( theWindow, theWindow->visRgn ); |
textH = ((DialogPeek) theWindow)->textH; |
if ( textH ) |
TEUpdate ( &(*textH)->viewRect, textH ); |
} |
break; |
} |
EndUpdate ( theWindow ); // restore normal visRgn of grafport |
SetPort ( savePort ); |
return; |
} // DoUpdate |
void DoActivate ( EventRecord* theEvent ) |
{ |
SInt16 itemHit; |
SInt16 theType; |
ListHandle theList = nil; |
WindowRef theWindow = (WindowRef) theEvent->message; |
Boolean bActiveFlag = theEvent->modifiers & 1; |
theType = GetWindowType ( theWindow ); |
switch ( theType ) |
{ |
case kDocumentWindowType: |
{ |
LActivate ( bActiveFlag, GetWListRef ( theWindow ) ); |
DrawClippedGrowIcon ( theWindow ); |
} |
break; |
case kListWindowType: |
{ |
tDialogInfoPtr theInfo = (tDialogInfoPtr) GetWRefCon ( theWindow ); |
theList = theInfo->listRef; |
if ( theList ) |
LActivate ( bActiveFlag, theList ); |
DialogSelect ( theEvent, &theWindow, &itemHit ); |
} |
break; |
case kGetInfoWindowType: |
{ |
TEHandle textH; |
textH = ((DialogPeek) theWindow)->textH; |
if ( textH ) |
{ |
if ( bActiveFlag ) |
TEActivate ( textH ); |
else |
TEDeactivate ( textH ); |
} |
DialogSelect ( theEvent, &theWindow, &itemHit ); |
} |
break; |
} |
AdjustMenus ( ); |
} // DoActivate |
void DoContentClick ( WindowRef theWindow, EventRecord* theEvent ) |
{ |
WindowRef frontWindow; |
// If a movable modal is active, ignore click in an inactive |
// window, otherwise select it or handle the content click. |
frontWindow = FrontWindow ( ); |
if ( theWindow != frontWindow ) |
{ |
if ( IsMovableModal ( frontWindow ) ) |
SysBeep ( 30 ); |
else |
SelectWindow ( theWindow ); |
} |
else |
{ |
if ( IsMovableModal ( theWindow ) ) |
DoDialogContentClick ( theWindow, theEvent ); |
else |
{ |
Boolean bWasHandled; |
bWasHandled = HandleListClick ( theWindow, theEvent ); |
AdjustMenus ( ); |
} |
} |
return; |
} // DoContentClick |
void DoGrowWindow ( WindowRef theWindow, EventRecord* theEvent ) |
{ |
const short kMinDocSize = 64; |
const short kMaxDocSize = 32767; |
long newSize; |
Rect limitRect; |
// set up the limiting rectangle |
SetRect ( &limitRect, kMinDocSize, kMinDocSize, kMaxDocSize, kMaxDocSize ); |
// call Window Manager to let the user drag size box |
newSize = GrowWindow ( theWindow, theEvent->where, &limitRect ); |
if ( newSize ) // if the user changed its size |
{ |
short h, v; |
h = newSize & 0x0000FFFF; |
v = newSize >> 16; |
SizeWindow ( theWindow, h, v, true ); |
h -= 15; v -= 15; |
LSize ( h, v, GetWListRef ( theWindow ) ); |
SetPort ( theWindow ); |
InvalRect ( &theWindow->portRect ); |
} |
return; |
} // DoGrowWindow |
void DoDragWindow ( WindowRef theWindow, EventRecord* theEvent ) |
{ |
WindowRef frontWindow; |
// If a movable modal is active, ignore click in an inactive |
// title bar, otherwise let the Window Manager handle it. |
frontWindow = FrontWindow ( ); |
if ( theWindow != frontWindow && IsMovableModal ( frontWindow ) ) |
SysBeep ( 30 ); |
else |
{ |
RgnHandle theRgn; |
Rect dragRect; |
theRgn = GetGrayRgn ( ); |
dragRect = (*theRgn)->rgnBBox; |
DragWindow ( theWindow, theEvent->where, &dragRect ); |
} |
return; |
} |
Boolean IsMovableModal ( WindowRef theWindow ) |
{ |
return (GetWVariant ( theWindow ) == movableDBoxProc); |
} |
int16 GetWindowType ( WindowRef theWindow ) |
{ |
int16 theType = 0; |
if ( theWindow ) |
{ |
theType = GetWindowKind ( theWindow ); |
if ( theType < 0 ) |
theType = kDAWindowType; |
else if ( theType == kApplicationWindowKind ) |
theType = kDocumentWindowType; |
else |
{ |
tDialogInfoPtr theInfo = (tDialogInfoPtr) GetWRefCon ( theWindow ); |
if ( theInfo ) |
theType = theInfo->windowType; |
} |
} |
return theType; |
} |
void SetWindowType ( WindowRef theWindow, int16 theType ) |
{ |
int16 theKind; |
if ( theWindow ) |
{ |
theKind = GetWindowKind ( theWindow ); |
if ( theKind != kApplicationWindowKind ) |
{ |
tDialogInfoPtr theInfo = (tDialogInfoPtr) GetWRefCon ( theWindow ); |
if ( theInfo ) |
theInfo->windowType = theType; |
} |
} |
return; |
} |
int16 GetWindowSubType ( WindowRef theWindow ) |
{ |
int16 theKind; |
int16 theType = 0; |
if ( theWindow ) |
{ |
theKind = GetWindowKind ( theWindow ); |
if ( theKind != kApplicationWindowKind ) |
{ |
tDialogInfoPtr theInfo = (tDialogInfoPtr) GetWRefCon ( theWindow ); |
if ( theInfo ) |
theType = theInfo->windowSubType; |
} |
} |
return theType; |
} |
void SetWindowSubType ( WindowRef theWindow, int16 theType ) |
{ |
int16 theKind; |
if ( theWindow ) |
{ |
theKind = GetWindowKind ( theWindow ); |
if ( theKind != kApplicationWindowKind ) |
{ |
tDialogInfoPtr theInfo = (tDialogInfoPtr) GetWRefCon ( theWindow ); |
if ( theInfo ) |
theInfo->windowSubType = theType; |
} |
} |
return; |
} |
void DoZoomWindow ( WindowRef theWindow, EventRecord* theEvent, int16 windowPart ) |
{ |
Point globalPt = theEvent->where; |
SetPort ( theWindow ); |
if ( TrackBox ( theWindow, globalPt, windowPart ) ) |
{ |
/* |
TO DO: |
This doesn't handle multiple screens |
*/ |
ZoomWindow ( theWindow, windowPart, true ); |
InvalRect ( &theWindow->portRect ); |
} |
return; |
} |
OSErr CopyWindowFragment ( WindowRef source, int16 sourceIndex, WindowRef target ) |
{ |
int16 itemIndex; |
OSErr theErr; |
tWindowInfoPtr sourceInfo = nil; |
tWindowInfoPtr targetInfo = nil; |
itemIndex = GetIndexFromNthWindowItem ( source, sourceIndex ); |
sourceInfo = (tWindowInfoPtr) GetWRefCon ( source ); |
targetInfo = (tWindowInfoPtr) GetWRefCon ( target ); |
theErr = CreateTempAndCopyFragment ( (tHeaderHan) sourceInfo->dataHandle, &sourceInfo->fileSpec, |
itemIndex, (tHeaderHan) targetInfo->dataHandle ); |
if ( theErr == noErr ) |
{ |
SignedByte theState; |
tItemPtr theItem; |
theState = HGetState ( sourceInfo->dataHandle ); |
HLock ( sourceInfo->dataHandle ); |
theItem = GetNthItem ( (tHeaderHan) sourceInfo->dataHandle, itemIndex ); |
AddFragToList ( GetWListRef ( target ), theItem ); |
HSetState ( sourceInfo->dataHandle, theState ); |
SetDocumentDirty ( target, true ); |
} |
return theErr; |
} |
OSErr MoveWindowFragment ( WindowRef source, int16 sourceIndex, WindowRef target ) |
{ |
OSErr theErr = noErr; |
theErr = CopyWindowFragment ( source, sourceIndex, target ); |
if ( !theErr ) |
theErr = DeleteWindowFragment ( source, sourceIndex ); |
return theErr; |
} |
OSErr DeleteWindowFragment ( WindowRef theWindow, int16 theIndex ) |
{ |
int16 itemIndex; |
OSErr theErr; |
tWindowInfoPtr theInfo; |
// Since we don't support undo just yet, there's no need |
// to copy it to a temporary file. |
itemIndex = GetIndexFromNthWindowItem ( theWindow, theIndex ); |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
theErr = DeleteFragment ( (tHeaderHan) theInfo->dataHandle, nil, itemIndex ); |
if ( theErr == noErr ) |
{ |
DeleteFromList ( GetWListRef ( theWindow ), theIndex ); |
SetDocumentDirty ( theWindow, true ); |
} |
return theErr; |
} |
OSErr CreateTempAndCopyFragment ( tHeaderHan sourceHeader, FSSpecPtr sourceSpec, int16 sourceIndex, |
tHeaderHan targetHeader ) |
{ |
SignedByte sourceState, targetState; |
OSErr theErr; |
tItemPtr sourceItem, targetItem; |
FSSpec tempSpec; |
sourceState = HGetState ( (Handle) sourceHeader ); |
HLock ( (Handle) sourceHeader ); |
targetState = HGetState ( (Handle) targetHeader ); |
HLock ( (Handle) targetHeader ); |
sourceItem = GetNthItem ( sourceHeader, sourceIndex ); |
// Do we already have a temporary file that contains this fragment |
if ( GetTempUsageCount ( sourceItem ) ) |
{ |
theErr = CopyFragment ( sourceHeader, nil, sourceIndex, targetHeader, nil ); |
targetItem = GetLastItem ( targetHeader ); |
targetItem->bExistsInDocument = false; |
IncrementTempUsageCount ( targetItem ); |
} |
else |
{ |
theErr = CreateTemporaryFile ( &tempSpec ); |
theErr = CopyFragment ( sourceHeader, sourceSpec, sourceIndex, targetHeader, &tempSpec ); |
if ( theErr ) |
// We'll let the system handle the temp file. It may |
// be useful for debugging, if nothing else. |
return theErr; |
sourceItem = GetNthItem ( sourceHeader, sourceIndex ); |
IncrementTempUsageCount ( sourceItem ); |
BlockMoveData ( &tempSpec, GetTempSpecPtr ( sourceItem ), sizeof ( FSSpec ) ); |
targetItem = GetLastItem ( targetHeader ); |
targetItem->bExistsInDocument = false; |
targetItem->tempFilePtr = sourceItem->tempFilePtr; |
IncrementTempUsageCount ( targetItem ); |
} |
HSetState ( (Handle) sourceHeader, sourceState ); |
HSetState ( (Handle) sourceHeader, targetState ); |
return theErr; |
} |
tItemPtr GetNthWindowItem ( WindowRef theWindow, int16 theIndex ) |
{ |
tWindowInfoPtr theInfo = nil; |
theIndex = GetIndexFromNthWindowItem ( theWindow, theIndex ); |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
return GetNthItem ( (tHeaderHan) theInfo->dataHandle, theIndex ); |
} |
int16 GetIndexFromNthWindowItem ( WindowRef theWindow, int16 theIndex ) |
{ |
int16 theSize; |
int i; |
Cell theCell = { 0, 0 }; |
tWindowInfoPtr theInfo = nil; |
tHeaderHan theHeader; |
Str255 theText; |
theInfo = (tWindowInfoPtr) GetWRefCon ( theWindow ); |
// First, get the text we're looking for. Two fragments with the same name |
// but different architectures are quite likely. We need to include the type. |
theSize = sizeof ( Str255 ); |
theCell.v = theIndex; |
LGetCell ( &theText[1], &theSize, theCell, theInfo->listRef ); |
theText[0] = theSize; |
theHeader = (tHeaderHan) theInfo->dataHandle; |
// Now, scan our items looking for a match |
for ( i = 0; i < GetItemCount ( theHeader ); i++ ) |
{ |
tItemPtr theItem; |
unsigned char archTypeStr[5]; |
Str255 itemText; |
theItem = GetNthItem ( theHeader, i ); |
// Since we're looking for an item in the window, ignore deleted items |
if ( theItem->bDeleted ) |
continue; |
CopyPStr ( theItem->name, itemText, sizeof ( Str255 ) ); |
ConcatPStr ( itemText, "\p\t", sizeof ( Str255 ) ); |
OSTypeToPStr ( theItem->archType, archTypeStr ); |
ConcatPStr ( itemText, archTypeStr, sizeof ( Str255 ) ); |
if ( EqualString ( theText, itemText, true, true ) ) |
return i; |
} |
#if DEBUGGING |
DebugStr ( "\p GetIndexFromNthWindowItem returning 0" ); |
#endif |
return 0; |
} |
void AddFragToList ( ListRef theList, tItemPtr theItem ) |
{ |
unsigned char archTypeStr[5]; |
Str255 theText; |
CopyPStr ( theItem->name, theText, sizeof ( Str255 ) ); |
ConcatPStr ( theText, "\p\t", sizeof ( Str255 ) ); |
OSTypeToPStr ( theItem->archType, archTypeStr ); |
ConcatPStr ( theText, archTypeStr, sizeof ( Str255 ) ); |
AddToList ( theList, theText ); |
return; |
} |
void UpdateFragInList ( WindowRef theWindow, int16 theIndex, StringPtr newName ) |
{ |
unsigned char archTypeStr[5]; |
tItemPtr theItem; |
ListRef theList; |
Str255 theText; |
theItem = GetNthWindowItem ( theWindow, theIndex ); |
theList = GetWListRef ( theWindow ); |
CopyPStr ( newName, theText, sizeof ( Str255 ) ); |
ConcatPStr ( theText, "\p\t", sizeof ( Str255 ) ); |
OSTypeToPStr ( theItem->archType, archTypeStr ); |
ConcatPStr ( theText, archTypeStr, sizeof ( Str255 ) ); |
UpdateList ( theList, theIndex, theText ); |
return; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-30