ResKnife/Carbon/Classes/DataBrowser.cpp

634 lines
22 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