ResKnife/Carbon/Classes/DataBrowser.cpp

634 lines
23 KiB
C++
Raw Blame History

#include "DataBrowser.h"
#include "ResourceObject.h"
#include "InspectorWindow.h"
#include "Errors.h"
#include "Utility.h" // for TypeToCFString() et cetera
extern globals g;
#if TARGET_API_MAC_CARBON // CarbonLib 1.1+ or Public Beta only
/*** INITALISE DATA BROWSER ***/
OSStatus FileWindow::InitDataBrowser( void )
{
OSStatus error = noErr;
// get the db control - compatable with both CarbonLib and nib based versions
ControlID id = { kDataBrowserSignature, 0 };
GetControlByID( window, &id, &dataBrowser );
// set control ref to FileWindow
SetControlReference( dataBrowser, (long) this );
// turn off frame and focus
Boolean frame = false;
SetControlData( dataBrowser, kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, sizeof(Boolean), &frame );
#if !USE_NIBS
// add empty columns
AddDataBrowserColumn( dataBrowser, kDBNameColumn, 0 ); // save column order into prefs file: Get/SetDataBrowserUserState()
AddDataBrowserColumn( dataBrowser, kDBTypeColumn, 1 );
AddDataBrowserColumn( dataBrowser, kDBIDColumn, 2 );
AddDataBrowserColumn( dataBrowser, kDBSizeColumn, 3 );
#endif
// add callbacks
DataBrowserCallbacks theCallbacks;
theCallbacks.version = kDataBrowserLatestCallbacks;
InitDataBrowserCallbacks( &theCallbacks );
theCallbacks.u.v1.itemDataCallback = NewDataBrowserItemDataUPP( DataBrowserItemData );
theCallbacks.u.v1.itemCompareCallback = NewDataBrowserItemCompareUPP( SortDataBrowser );
theCallbacks.u.v1.itemNotificationCallback = NewDataBrowserItemNotificationUPP( DataBrowserMessage );
theCallbacks.u.v1.addDragItemCallback = NewDataBrowserAddDragItemUPP( DataBrowserAddDragItem );
theCallbacks.u.v1.acceptDragCallback = NewDataBrowserAcceptDragUPP( DataBrowserAcceptDrag );
theCallbacks.u.v1.receiveDragCallback = NewDataBrowserReceiveDragUPP( DataBrowserReceiveDrag );
theCallbacks.u.v1.postProcessDragCallback = NewDataBrowserPostProcessDragUPP( DataBrowserPostProcessDrag );
SetDataBrowserCallbacks( dataBrowser, &theCallbacks );
// setup rest of browser, inc. adding all resources
DataBrowserItemID item;
for( UInt32 n = 1; n <= numResources; n++ )
{
item = n;
error = AddDataBrowserItems( dataBrowser, kDataBrowserNoItem, 1, &item, kDataBrowserItemNoProperty );
if( error ) DebugError( "\pError occoured adding resource to data browser." );
}
// add data fork if present
if( resourceMap->RepresentsDataFork() ) // requires data fork to be first in chain
{
item = kDataBrowserDataForkItem; // curently 0xFFFFFFFF
error = AddDataBrowserItems( dataBrowser, kDataBrowserNoItem, 1, &item, kDataBrowserItemNoProperty );
if( error ) DebugError( "\pError occoured adding data fork to data browser." );
}
SetDataBrowserSortProperty( dataBrowser, kDBTypeColumn );
SetDataBrowserTableViewRowHeight( dataBrowser, 16 +2 );
SetDataBrowserListViewDisclosureColumn( dataBrowser, kDBNameColumn, true );
// set up drag tracking
SetControlDragTrackingEnabled( dataBrowser, true );
return error;
}
/*** ADD DATA BROWSER COLUMN ***/
void AddDataBrowserColumn( ControlRef browser, DataBrowserPropertyID column, UInt16 position )
{
DataBrowserListViewColumnDesc columnDesc;
switch( column )
{
case kDataBrowserNameColumn:
columnDesc.propertyDesc.propertyID = kDataBrowserNameColumn;
columnDesc.propertyDesc.propertyType = kDataBrowserIconAndTextType;
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewDefaultColumnFlags | kDataBrowserListViewSelectionColumn;
columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
columnDesc.headerBtnDesc.minimumWidth = 150;
columnDesc.headerBtnDesc.maximumWidth = 250;
columnDesc.headerBtnDesc.titleOffset = 0;
columnDesc.headerBtnDesc.titleString = CFSTR("Resource Name"); // these should be resources for ease of localisation
columnDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault;
columnDesc.headerBtnDesc.btnFontStyle.style = normal;
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
break;
case kDataBrowserTypeColumn:
columnDesc.propertyDesc.propertyID = kDataBrowserTypeColumn;
columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewDefaultColumnFlags;
columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
columnDesc.headerBtnDesc.minimumWidth = (g.systemVersion < kMacOSX)? 56:72;
columnDesc.headerBtnDesc.maximumWidth = columnDesc.headerBtnDesc.minimumWidth;
columnDesc.headerBtnDesc.titleOffset = 0;
columnDesc.headerBtnDesc.titleString = CFSTR("Type"); // these should be resources for ease of localisation
columnDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushRight;
columnDesc.headerBtnDesc.btnFontStyle.style = normal;
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
break;
case kDataBrowserIDColumn:
columnDesc.propertyDesc.propertyID = kDataBrowserIDColumn;
columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewDefaultColumnFlags;
columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
columnDesc.headerBtnDesc.minimumWidth = (g.systemVersion < kMacOSX)? 56:72;
columnDesc.headerBtnDesc.maximumWidth = columnDesc.headerBtnDesc.minimumWidth;
columnDesc.headerBtnDesc.titleOffset = 0;
columnDesc.headerBtnDesc.titleString = CFSTR("ID"); // these should be resources for ease of localisation
columnDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushRight;
columnDesc.headerBtnDesc.btnFontStyle.style = normal;
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
break;
case kDataBrowserSizeColumn:
columnDesc.propertyDesc.propertyID = kDataBrowserSizeColumn;
columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
columnDesc.propertyDesc.propertyFlags = kDataBrowserListViewDefaultColumnFlags;
columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
columnDesc.headerBtnDesc.minimumWidth = (g.systemVersion < kMacOSX)? 56:72;
columnDesc.headerBtnDesc.maximumWidth = columnDesc.headerBtnDesc.minimumWidth;
columnDesc.headerBtnDesc.titleOffset = 0;
columnDesc.headerBtnDesc.titleString = CFSTR("Size"); // these should be resources for ease of localisation
columnDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
columnDesc.headerBtnDesc.btnFontStyle.just = teFlushRight;
columnDesc.headerBtnDesc.btnFontStyle.style = normal;
columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
break;
}
// create column and make respond to sorting
AddDataBrowserListViewColumn( browser, &columnDesc, position );
}
/*** HANDLE ITEM DATA I/O ***/
pascal OSStatus DataBrowserItemData( ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserItemDataRef itemData, Boolean setValue )
{
#pragma unused( setValue )
OSStatus result = noErr;
if( setValue ) return result;
FileWindowPtr file = (FileWindowPtr) GetControlReference( browser );
ResourceObjectPtr resource = file->GetResource( itemID );
if( resource == null )
DebugError( "\pNull resource returned within DataBrowserItemData()" );
switch( property )
{
case kDataBrowserItemIsEditableProperty:
if( true ) // should item be editable? (i.e. is it a name, ID or type?)
SetDataBrowserItemDataBooleanValue( itemData, true );
break;
case kDataBrowserItemIsContainerProperty:
if( resource->Type() == kIconFamilyType )
SetDataBrowserItemDataBooleanValue( itemData, true );
break;
case kDBNameColumn:
{ // icon <20> no resource for the icon!
IconRef theIcon = null;
#if !USE_NIBS
if( itemID != kDataBrowserDataForkItem )
{
Str255 iconString;
TypeToPString( resource->Type(), iconString );
IconFamilyHandle iconFamily = (IconFamilyHandle) Get1NamedResource( kIconFamilyType, iconString );
if( iconFamily )
{
RegisterIconRefFromIconFamily( kResKnifeCreator, resource->Type(), iconFamily, &theIcon );
ReleaseResource( (Handle) iconFamily ); // when dragging a rect this call caused other columns not to be displayed !?!
}
}
#endif
if( theIcon == null )
GetIconRef( kOnSystemDisk, kResKnifeCreator, kResourceFileType, &theIcon );
SetDataBrowserItemDataIcon( itemData, theIcon );
ReleaseIconRef( theIcon );
// resource name
CFStringRef nameCFStr;
if( itemID == kDataBrowserDataForkItem )
{
#if USE_NIBS // OS 9 version is not bundled at the present time
nameCFStr = CFBundleCopyLocalizedString( CFBundleGetMainBundle(), CFSTR("Data Fork"), null, null ); // bug: doesn't actually get localized string!
#else
nameCFStr = CFSTR("Data Fork");
#endif
SetDataBrowserItemDataRGBColor( itemData, &g.textColour );
}
else if( *resource->Name() == 0x00 )
{
#if USE_NIBS // OS 9 version is not bundled at the present time
nameCFStr = CFBundleCopyLocalizedString( CFBundleGetMainBundle(), CFSTR("Untitled Resource"), null, null ); // bug: doesn't actually get localized string!
#else
nameCFStr = CFSTR("Untitled Resource");
#endif
SetDataBrowserItemDataRGBColor( itemData, &g.textColour );
}
else nameCFStr = CFStringCreateWithPascalString( CFAllocatorGetDefault(), resource->Name(), kCFStringEncodingMacRoman );
SetDataBrowserItemDataText( itemData, nameCFStr );
#if USE_NIBS // OS 9 uses CFSTR()
CFRelease( nameCFStr );
#endif
} break;
case kDBTypeColumn:
{ // resource type
if( itemID == kDataBrowserDataForkItem )
{
SetDataBrowserItemDataText( itemData, CFSTR("-") );
}
else
{
CFStringRef typeString;
TypeToCFString( resource->Type(), &typeString );
SetDataBrowserItemDataText( itemData, typeString );
CFRelease( typeString );
}
} break;
case kDBIDColumn:
{ // resource ID
if( itemID == kDataBrowserDataForkItem )
{
SetDataBrowserItemDataText( itemData, CFSTR("-") );
}
else
{
SInt16 id = resource->ID();
Str255 idPString;
NumToString( id, (StringPtr) &idPString );
CFStringRef idString = CFStringCreateWithPascalString( CFAllocatorGetDefault(), idPString, kCFStringEncodingMacRoman );
SetDataBrowserItemDataText( itemData, idString );
CFRelease( idString );
}
} break;
case kDBSizeColumn:
{ SInt32 size = resource->Size();
UInt8 power = 0, remainder = 0;
Str255 sizePString, frac;
while( size >= 1024 && power <= 30 )
{
power += 10; // 10 == KB, 20 == MB, 30 == GB
remainder = (UInt8) ((size % 1024) / 102.4); // 102.4 gives one dp, 10.24 would give two dps, 1.024 would give three dps
size /= 1024;
}
NumToString( (long) size, (StringPtr) &sizePString );
NumToString( remainder, (StringPtr) &frac );
if( power ) // some division has occoured
{
if( sizePString[0] < 3 && remainder > 0 )
{
AppendPString( (unsigned char *) &sizePString, "\p." ); // bug: should be a comma on european systems
AppendPString( (unsigned char *) &sizePString, (unsigned char *) &frac );
}
if( power == 10 ) AppendPString( (unsigned char *) &sizePString, "\p KB" );
else if( power == 20 ) AppendPString( (unsigned char *) &sizePString, "\p MB" );
else if( power == 30 ) AppendPString( (unsigned char *) &sizePString, "\p GB" ); // everything bigger will be given in GB
}
CFStringRef sizeString = CFStringCreateWithPascalString( CFAllocatorGetDefault(), sizePString, kCFStringEncodingMacRoman );
SetDataBrowserItemDataText( itemData, sizeString );
CFRelease( sizeString );
} break;
default:
result = errDataBrowserPropertyNotSupported;
break;
}
return result;
}
/*** SORT DATA BROWSER ***/
pascal Boolean SortDataBrowser( ControlRef browser, DataBrowserItemID itemOne, DataBrowserItemID itemTwo, DataBrowserPropertyID sortProperty )
{
short result;
Str255 typeOne, typeTwo;
StringPtr nameOne, nameTwo;
FileWindowPtr file = (FileWindowPtr) GetControlReference( browser );
// send data fork to top regardless of property
if( itemOne == kDataBrowserDataForkItem ) return true;
if( itemTwo == kDataBrowserDataForkItem ) return false;
// validate data browser item IDs
if( itemOne <= kDataBrowserNoItem || itemOne > file->GetResourceCount() )
{
DebugError( "\psort item one was invalid" );
return false;
}
if( itemTwo <= kDataBrowserNoItem || itemTwo > file->GetResourceCount() )
{
DebugError( "\psort item two was invalid" );
return false;
}
// get resource corrisponding to item ID
ResourceObjectPtr resourceOne = file->GetResource( itemOne );
ResourceObjectPtr resourceTwo = file->GetResource( itemTwo );
if( resourceOne == null || resourceTwo == null )
DebugError( "\pNull resource returned within SortDataBrowser()" );
// sort resources according to property user has selected
switch( sortProperty )
{
case kDBNameColumn:
nameOne = resourceOne->Name();
nameTwo = resourceTwo->Name();
result = CompareString( nameOne, nameTwo, null );
return result < 0;
case kDBTypeColumn:
TypeToPString( resourceOne->Type(), typeOne );
TypeToPString( resourceTwo->Type(), typeTwo );
result = CompareString( typeOne, typeTwo, null );
return result < 0;
case kDBIDColumn:
return resourceOne->ID() < resourceTwo->ID();
case kDBSizeColumn:
return resourceOne->Size() < resourceTwo->Size();
case kDataBrowserItemNoProperty: // this is valid when first constructing the data browser
// DebugError( "\pkDataBrowserItemNoProperty passed to sort function" );
return false;
default:
DebugError( "\pInvalid sort property given" );
return false;
}
return false;
}
/*** DATA BROWSER MESSAGE ***/
pascal void DataBrowserMessage( ControlRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message, DataBrowserItemDataRef itemData )
{
#pragma unused( itemID, itemData )
FileWindowPtr file = (FileWindowPtr) GetControlReference( browser );
switch( message )
{
case kDataBrowserItemDoubleClicked:
{ KeyMap theKeys;
Boolean shiftKeyDown = false,
optionKeyDown = false,
controlKeyDown = false;
GetKeys( theKeys );
if( theKeys[1] & (shiftKey >> shiftKeyBit) ) shiftKeyDown = true;
if( theKeys[1] & (optionKey >> shiftKeyBit) ) optionKeyDown = true;
if( theKeys[1] & (controlKey >> shiftKeyBit) ) controlKeyDown = true;
if( optionKeyDown ) file->OpenResource( itemID, kMenuCommandOpenHex );
else if( controlKeyDown ) file->OpenResource( itemID, kMenuCommandOpenTemplate );
else file->OpenResource( itemID, kMenuCommandOpenDefault );
} break;
case kDataBrowserItemSelected:
case kDataBrowserItemDeselected:
case kDataBrowserSelectionSetChanged:
// file->SetHeaderText();
if( g.inspector )
g.inspector->Update();
break;
case kDataBrowserEditStarted:
case kDataBrowserEditStopped:
case kDataBrowserItemAdded:
case kDataBrowserItemRemoved:
case kDataBrowserContainerOpened:
case kDataBrowserContainerClosing:
case kDataBrowserContainerClosed:
case kDataBrowserContainerSorting:
case kDataBrowserContainerSorted:
case kDataBrowserTargetChanged:
case kDataBrowserUserStateChanged:
break;
}
}
/*** ADD DRAG ITEM ***/
pascal Boolean DataBrowserAddDragItem( ControlRef browser, DragRef drag, DataBrowserItemID item, DragItemRef *itemRef )
{
#pragma unused( item )
// if drag already has phfs flavour, don't add another
UInt16 numFlavours;
CountDragItemFlavors( drag, *itemRef, &numFlavours );
if( numFlavours > 0 ) return true;
// add 'create file' callback
if( itemRef ) *itemRef = ItemReference( item );
FlavorFlags flags = flavorNotSaved;
DragSendDataUPP sendData = NewDragSendDataUPP( SendPromisedFile );
SetDragSendProc( drag, sendData, browser );
// setup imaginary file
PromiseHFSFlavor promisedFile;
promisedFile.fileType = kResourceFileType;
promisedFile.fileCreator = kResKnifeCreator;
promisedFile.fdFlags = null; // finder flags
promisedFile.promisedFlavor = kResourceTransferType;
// add phfs and TEXT flavours
AddDragItemFlavor( drag, *itemRef, flavorTypePromiseHFS, &promisedFile, sizeof(PromiseHFSFlavor), flags );
return true;
/* OSErr error = noErr;
DragReference theDragRef;
ItemReference theItemRef = 1;
// create the drag reference
NewDrag( &theDragRef );
if( MemError() ) return;
SetDragSendProc( theDragRef, sendProc, this );
RgnHandle dragRgn = NewRgn(),
subtractRgn = NewRgn();
// get region of dragged items, using translucent dragging where possible
Point dragOffset;
GWorldPtr imageGWorld = nil;
resData = GetResourceData( ownerWindow );
while( resData )
{
if( r.selected )
UnionRgn( r.nameIconRgn, dragRgn, dragRgn ); // add new region to rest of drag region
resData = r.next;
}
if( g.translucentDrag )
{
short resCounter = 0;
SetPt( &dragOffset, 0, kFileHeaderHeight );
resData = GetResourceData( ownerWindow );
while( !r.selected )
{
resCounter++;
resData = r.next;
}
error = CreateDragImage( resData, &imageGWorld );
if( !error )
{
// init mask region
RgnHandle maskRgn = NewRgn();
CopyRgn( r.nameIconRgn, maskRgn );
OffsetRgn( maskRgn, 0, -kFileLineHeight * resCounter );
// init rects
Rect sourceRect, destRect;
SetRect( &sourceRect, 0, 0, g.nameColumnWidth, kFileLineHeight );
SetRect( &destRect, 0, 0, g.nameColumnWidth, kFileLineHeight );
OffsetRect( &destRect, 0, kFileHeaderHeight );
// init GWorld
PixMapHandle imagePixMap = GetGWorldPixMap( imageGWorld );
DragImageFlags imageFlags = kDragStandardTranslucency | kDragRegionAndImage;
error = SetDragImage( theDragRef, imagePixMap, maskRgn, dragOffset, imageFlags );
CopyBits( &GrafPtr( imageGWorld )->portBits, &GrafPtr( ownerWindow )->portBits, &sourceRect, &destRect, srcCopy, maskRgn );
if( error ) SysBeep(0);
DisposeGWorld( imageGWorld );
DisposeRgn( maskRgn );
}
}
// subtract middles from icons
MakeGlobal( ownerWindow, NewPoint(), &globalMouse );
CopyRgn( dragRgn, subtractRgn ); // duplicate region
InsetRgn( subtractRgn, 2, 2 ); // inset it by 2 pixels
DiffRgn( dragRgn, subtractRgn, dragRgn ); // subtract subRgn from addRgn, save in nameIconRgn
OffsetRgn( dragRgn, globalMouse.h, globalMouse.v ); // change drag region to global coords
// add flavour data to drag
error = AddDragItemFlavor( theDragRef, theItemRef, flavorTypePromiseHFS, &theFile, sizeof(PromiseHFSFlavor), theFlags );
error = AddDragItemFlavor( theDragRef, theItemRef, kResType, nil, 0, theFlags );
// track the drag, then clean up
error = TrackDrag( theDragRef, theEvent, dragRgn );
if( theDragRef ) DisposeDrag( theDragRef );
if( subtractRgn ) DisposeRgn( subtractRgn );
if( dragRgn ) DisposeRgn( dragRgn );
return error == noErr; */
}
/*** ACCEPT DRAG ***/
pascal Boolean DataBrowserAcceptDrag( ControlRef browser, DragRef drag, DataBrowserItemID item )
{
#pragma unused( browser, drag, item )
/* OSStatus error = noErr;
Size size = null;
DragItemRef dragItem = 1;
UInt16 index, totalItems;
CountDragItems( theDrag, &totalItems );
for( index = 1; index <= totalItems; index++ )
{
GetDragItemReferenceNumber( theDrag, index, &dragItem );
error = GetFlavourDataSize( theDrag, dragItem, kDragFlavourTypeResource, &size );
// if( error ) return false;
if( !error ) index = totalItems; // stop when valid item is reached
}
return size >= sizeof(ResTransferDesc);
*/ return true;
}
/*** RECEIVE DRAG ***/
pascal Boolean DataBrowserReceiveDrag( ControlRef browser, DragRef drag, DataBrowserItemID item )
{
#pragma unused( browser, drag, item )
return true;
}
/*** POST<53>PROCESS DRAG ***/
pascal void DataBrowserPostProcessDrag( ControlRef browser, DragRef drag, OSStatus trackDragResult )
{
#pragma unused( browser, drag, trackDragResult )
}
/*** SEND PROMISED FILE ***/
pascal OSErr SendPromisedFile( FlavorType type, void *dragSendRefCon, ItemReference item, DragReference drag )
{
OSErr error = noErr;
ControlRef browser = (ControlRef) dragSendRefCon;
FSSpec fileSpec;
Str255 fileName;
short vRefNum;
long dirID;
if( type != flavorTypePromiseHFS ) return badDragFlavorErr;
// create file
GetIndString( fileName, kFileNameStrings, kStringNewDragFileName );
FindFolder( kOnSystemDisk, /*kTemporaryFolderType*/kDesktopFolderType, kCreateFolder, &vRefNum, &dirID );
FSMakeFSSpec( vRefNum, dirID, fileName, &fileSpec );
FSpCreateResFile( &fileSpec, kResKnifeCreator, kResourceFileType, smSystemScript );
// save resources into file
DragData clientData; // waiting for jim to add a ControlRef to DataBrowserItemUPP; bug: jim no longer works at Apple
clientData.browser = browser;
clientData.fileSpec = &fileSpec;
DataBrowserItemUPP callback = NewDataBrowserItemUPP( AddResourceToDragFile );
/* control, container, recurse, state, callback, clientData */
ForEachDataBrowserItem( browser, kDataBrowserNoItem, true, kDataBrowserItemIsSelected, callback, &clientData );
// save resources in file
/* ResourceObjectPtr resource = GetResourceData( file->window );
short refNum = FSpOpenResFile( &fileSpec, fsRdWrPerm );
UseResFile( refNum );
while( resData )
{
if( resource->Selected() )
AddResource( resource->Data(), resource->Type(), resource->ID(), resource->Name() );
resData = resource->Next();
}
CloseResFile( refNum );
UseResFile( g.appResFile );
*/
error = SetDragItemFlavorData( drag, item, type, &fileSpec, sizeof(FSSpec), 0 );
return error;
}
/*** ADD RESOURCE TO DRAG FILE ***/
pascal void AddResourceToDragFile( DataBrowserItemID item, DataBrowserItemState state, void *clientData )
{
#pragma unused( state )
// FSSpecPtr fileSpec = (FSSpecPtr) clientData;
WindowRef window = GetControlOwner( ((DragDataPtr) clientData)->browser );
FileWindowPtr file = (FileWindowPtr) GetWindowRefCon( window );
ResourceObjectPtr resource = file->GetResource( item );
// add resource to file
short oldFile = CurResFile();
short refNum = FSpOpenResFile( ((DragDataPtr) clientData)->fileSpec, fsRdWrPerm );
UseResFile( refNum );
AddResource( resource->Data(), resource->Type(), resource->ID(), resource->Name() );
if( ResError() == addResFailed )
{
DisplayError( "\pDrag Partially Failed", "\pCould not add a resource to file." );
}
else
{
SetResAttrs( resource->Data(), resource->Attributes() );
ChangedResource( resource->Data() );
// clean up & move on
DetachResource( resource->Data() );
}
CloseResFile( refNum );
UseResFile( oldFile );
}
#else
/*********************/
/* FAKE DATA BROWSER */
/*********************/
/*** CLEAR SELECTION ***/
OSStatus FileWindow::ClearSelection( void )
{
ResourceObjectPtr resource = resourceMap;
while( resource )
{
resource->Select( false );
resource = resource->Next();
}
return noErr;
}
#endif