ResKnife/Template Editor/Classes/TemplateWindow.cpp
2001-10-19 19:41:13 +00:00

1 line
61 KiB
C++
Raw Permalink Blame History

#include "TemplateWindow.h"
/*** CREATOR ***/
TemplateWindow::TemplateWindow( WindowRef newWindow )
{
// clear all instance bytes
BlockZero( this, sizeof(TemplateWindow) );
// set the window to the one just created
window = newWindow;
}
/*** DESTRUCTOR ***/
TemplateWindow::~TemplateWindow( void )
{
ReadControls();
}
/*** USE TEMPLATE ***/
OSStatus TemplateWindow::UseTemplate( Handle newTmpl )
{
tmpl = newTmpl;
return noErr;
}
/*** PARSE DATA ***/
OSStatus TemplateWindow::ParseData( Handle data )
{
#pragma unused( data )
OSStatus error = noErr;
error = ParseTemplate();
error = CreateControls();
return error;
}
/*** PARSE TEMPLATE ***/
OSStatus TemplateWindow::ParseTemplate( void )
{
SInt32 size = GetHandleSize( tmpl );
SInt8 state = HGetState( tmpl );
HLock( tmpl );
ElementPtr current = elements = new Element;
elementCount++;
unsigned long position = 0; // start parsing at offset zero (unsurprisingly)
while( position < size )
{
// fill in element data
short labelSize = *(*tmpl + position);
BlockMoveData( *tmpl + position, &current->label, labelSize +1 );
position += labelSize +1; // don't forget length byte!
BlockMoveData( *tmpl + position, &current->type, sizeof(ResType) );
position += sizeof(ResType); // but restype is always 4 bytes :)
// create new element
if( position < size )
{
elementCount++;
current->next = new Element;
current = current->next;
}
}
// clean up
HSetState( tmpl, state );
return noErr;
}
/*** CREATE CONTROLS ***/
OSStatus TemplateWindow::CreateControls( void )
{
OSStatus error = noErr;
ControlRef root, label, secondaryLabel, group, radio, checkbox, edit, listcount;
CreateRootControl( window, &root );
Rect windowBounds, rect, secondaryLabelRect;
GetWindowPortBounds( window, &windowBounds );
// get resource data (the really tedious way - I ought to make this easier)
Plug_WindowRef plugWindow = Host_GetPlugWindowFromWindowRef( window );
if( plugWindow == null ) DebugStr("\pplugWindow == null");
Plug_ResourceRef resource = Host_GetTargetResource( plugWindow );
if( resource == null ) DebugStr("\presource == null");
Handle data = Host_GetResourceData( resource );
SInt32 size = GetHandleSize( data );
SInt8 state = HGetState( data );
HLock( data );
// set control font style
ControlID id;
ControlFontStyleRec fontStyle, rectLabelStyle;
fontStyle.flags = kControlUseFontMask + kControlUseJustMask;
fontStyle.font = kControlFontSmallSystemFont;
fontStyle.just = teJustLeft;
rectLabelStyle.flags = kControlUseFontMask + kControlUseJustMask;
rectLabelStyle.font = kControlFontSmallSystemFont;
rectLabelStyle.just = teJustRight;
// set up bounds for first control
bounds.top = bounds.bottom = windowBounds.top; // bounds.top is ignored, bounds.bottom is the bottom of the previous control
bounds.left = windowBounds.left +110 + 8; // bounds.left and .right are the sides of the controls excluding the label
bounds.right = windowBounds.right - 8;
// declare variables
CFStringRef text = null;
signed long position = 0; // offset of data currently being processed
unsigned char boolBit = 0;
ElementPtr current = elements;
ElementPtr recursionOrigin = null; // bug: only handles one level of recursion
signed long recursionTotal = 0;
unsigned long recursionIndex = 0, recursionCount = 0;
unsigned long m = 0, n = 0; // counters, one is always unique, the other is an element index
for( ; m < elementCount; m++ )
{
n++; // advance unique counter
// create controls
switch( current->type )
{
case 'BOOL': // BOOL is two bytes long, false == 0x0000, true == 0x0100
{ Boolean valid = false;
if( size > position ) valid = (Boolean) ((unsigned short) *(*data + position)) > 0;
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom + 2*16 +12 );
CreateRadioGroupControl( window, &rect, &group );
SetRect( &rect, rect.left, rect.top, rect.right, rect.top +16 );
error = CreateRadioButtonControl( window, &rect, CFSTR("False"), !valid, true, &radio ); // false is embedded at index zreo
error = EmbedControl( radio, group );
OffsetRect( &rect, 0, 16 +4 );
error = CreateRadioButtonControl( window, &rect, CFSTR("True"), valid, true, &radio ); // true is embedded at index one
error = EmbedControl( radio, group );
SetControlValue( group, valid +1 );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom + 2*16 +12 );
rect.bottom += 4;
position += 2;
// set control ID
id.id = n;
id.signature = kBooleanGroupSignature;
SetControlID( group, &id );
} break;
case 'BBIT':
case 'FBIT':
if( boolBit == 0 )
{
// greate group box
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom + 20*8 +32 );
CreateGroupBoxControl( window, &rect, CFSTR("Some bits to click"), true, &group );
bounds.bottom += 24;
// set control ID
id.id = n;
id.signature = kBooleanGroupSignature;
SetControlID( group, &id );
}
else
{
id.id = n - boolBit;
id.signature = kBooleanGroupSignature;
GetControlByID( window, &id, &group );
}
// create checkbox
{ SInt32 content = 0x00000000;
if( size > position && current->type == 'BBIT' )
content = ((*(char*)(*data + position) << boolBit) & 0x80)? 1:0;
SetRect( &rect, bounds.left +8, bounds.bottom +4, bounds.right -8, bounds.bottom +20 );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), current->label, kCFStringEncodingMacRoman );
CreateCheckBoxControl( window, &rect, text, content, true, &checkbox );
EmbedControl( checkbox, group ); // checkboxes are embedded from 0 to 7, in direct bit order
if( current->type == 'FBIT' )
HiliteControl( checkbox, kControlDisabledPart ); // kControlInactivePart might work too
// DisableControl( checkbox );
// DeactivateControl( checkbox );
// HideControl( checkbox );
// advance BBIT counter
boolBit += 1;
if( boolBit == 8 )
{
boolBit = 0;
position += 1;
rect.bottom += 12;
}
} break;
case 'DBYT':
{ Str255 number;
SInt8 content = 0x00;
if( size > position ) content = *((char*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 1;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'DWRD':
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 2;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'DLNG':
{ Str255 number;
SInt32 content = 0x00000000;
if( size > position +3 ) content = *((long*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'HBYT':
{ Str255 number;
SInt8 content = 0x00;
if( size > position ) content = *((char*)(*data + position));
NumToString( (long) content, number );
// convert to hex here
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 1;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
// add dollar denoting hex
SetRect( &secondaryLabelRect, bounds.left -24, bounds.bottom +9, bounds.left -6, bounds.bottom +22 );
CreateStaticTextControl( window, &secondaryLabelRect, CFSTR("$"), &rectLabelStyle, &secondaryLabel );
} break;
case 'HWRD':
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position));
NumToString( (long) content, number );
// convert to hex here
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +21 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 2;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
// add dollar denoting hex
SetRect( &secondaryLabelRect, bounds.left -24, bounds.bottom +9, bounds.left -6, bounds.bottom +22 );
CreateStaticTextControl( window, &secondaryLabelRect, CFSTR("$"), &rectLabelStyle, &secondaryLabel );
} break;
case 'HLNG':
{ Str255 number;
SInt32 content = 0x00000000;
if( size > position +3 ) content = *((long*)(*data + position));
NumToString( (long) content, number );
// convert to hex here
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +21 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
// add dollar denoting hex
SetRect( &secondaryLabelRect, bounds.left -24, bounds.bottom +9, bounds.left -6, bounds.bottom +22 );
CreateStaticTextControl( window, &secondaryLabelRect, CFSTR("$"), &rectLabelStyle, &secondaryLabel );
} break;
case 'FBYT':
position += 1;
break;
case 'FWRD':
position += 2;
break;
case 'FLNG':
position += 4;
break;
case 'AWRD':
position += position % 2;
break;
case 'ALNG':
position += position % 4;
break;
case 'CHAR': // one byte
{ UInt8 content = 0x00;
if( size > position ) content = *((unsigned char*)(*data + position));
text = CFStringCreateWithBytes( CFAllocatorGetDefault(), (unsigned char *) &content, 1, kCFStringEncodingMacRoman, false );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 1;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'TNAM': // four bytes
{ UInt32 content = 0x00000000;
if( size > position +3 ) content = *((unsigned long*)(*data + position));
text = CFStringCreateWithBytes( CFAllocatorGetDefault(), (unsigned char *) &content, 4, kCFStringEncodingMacRoman, false );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'CSTR': // one to 32,768 bytes?
{ SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position ) // bug: if the bytes do not end in a 0x00, the function just keeps on reading!
text = CFStringCreateWithCString( CFAllocatorGetDefault(), (char *) (*data + position), kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += CFStringGetLength(text) +1;
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'ECST': // one to 32,768 bytes?
{ SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position )
text = CFStringCreateWithCString( CFAllocatorGetDefault(), (char *) (*data + position), kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += CFStringGetLength(text) +1; // null byte
position += (CFStringGetLength(text) % 2 == 0)? 1:0; // to pad or not to pad?
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'OCST': // one to 32,768 bytes?
{ SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position )
text = CFStringCreateWithCString( CFAllocatorGetDefault(), (char *) (*data + position), kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += CFStringGetLength(text) +1; // null byte
position += (CFStringGetLength(text) % 2 == 1)? 1:0; // to pad or not to pad?
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'PSTR': // one to 256 bytes
{ unsigned char length = 0;
if( size > position ) length = *(*data + position);
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position )
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), (unsigned char *) (*data + position), kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += length +1;
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'ESTR': // one to 256 bytes
{ unsigned char length = 0;
if( size > position ) length = *(*data + position);
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position )
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), (unsigned char *) (*data + position), kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += length +1;
position += (length % 2 == 0)? 1:0;
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'OSTR': // one to 256 bytes
{ unsigned char length = 0;
if( size > position ) length = *(*data + position);
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position )
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), (unsigned char *) (*data + position), kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += length +1;
position += (length % 2 == 1)? 1:0;
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'WSTR': // one to 65,536 bytes
{ unsigned short length = 0;
if( size > position +1 ) BlockMoveData( *data + position, &length, 2 ); // length = *((unsigned short*) *data + position);
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position +1 )
text = CFStringCreateWithBytes( CFAllocatorGetDefault(), (unsigned char *) (*data + position +2), (CFIndex) length, kCFStringEncodingMacRoman, false );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += length +2;
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'LSTR': // one to 4,294,967,296 bytes
{ unsigned long length = 0;
if( size > position +3 ) BlockMoveData( *data + position, &length, 4 ); // length = *((unsigned long*) *data + position);
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position +3 )
text = CFStringCreateWithBytes( CFAllocatorGetDefault(), (unsigned char *) (*data + position +4), (CFIndex) length, kCFStringEncodingMacRoman, false );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
position += length +4;
rect.bottom += 4;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
} break;
case 'HEXD': // bug: should display in hex - wait until hex is implemented :-) // infinetly long (limited only by CFString)
{ SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( size > position )
text = CFStringCreateWithBytes( CFAllocatorGetDefault(), (unsigned char *) (*data + position), size - position, kCFStringEncodingMacRoman, false );
else text = CFSTR("");
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
rect.bottom += 4;
position = size; // bug: should ensure termination of parsing
// set control ID
id.id = n;
id.signature = kHexDumpSignature;
SetControlID( edit, &id );
} break;
case 'RECT': // four SInt16s: top, left, bottom, right
{ // greate group box
SInt16 menuID = 2001; // bug: make into a constant
SInt16 titleWidth = 0;
SInt16 titleJustification = teJustLeft;
Style titleStyle = normal;
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom + 26*4 +40 );
error = CreatePopupGroupBoxControl( window, &rect, CFSTR("A Rectangle"), true, menuID, true, titleWidth, titleJustification, titleStyle, &group );
// set control ID
id.id = n;
id.signature = kRectGroupSignature;
SetControlID( group, &id );
// create top
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left + (bounds.right - bounds.left -32) /2 +8, bounds.bottom +40, bounds.right -12, bounds.bottom +54 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
EmbedControl( edit, group ); // embed order: top, label, left, label, bottom, label, right, label
SetRect( &secondaryLabelRect, bounds.left +12, bounds.bottom +40, bounds.left + (bounds.right - bounds.left -32) /2 -8, bounds.bottom +54 );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), "\pTop", kCFStringEncodingMacRoman );
CreateStaticTextControl( window, &secondaryLabelRect, text, &rectLabelStyle, &secondaryLabel );
EmbedControl( secondaryLabel, group );
} position += 2;
// create left
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
OffsetRect( &rect, 0, 26 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
EmbedControl( edit, group ); // embed order: top, label, left, label, bottom, label, right, label
OffsetRect( &secondaryLabelRect, 0, 26 );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), "\pLeft", kCFStringEncodingMacRoman );
CreateStaticTextControl( window, &secondaryLabelRect, text, &rectLabelStyle, &secondaryLabel );
EmbedControl( secondaryLabel, group );
} position += 2;
// create bottom
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
OffsetRect( &rect, 0, 26 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
EmbedControl( edit, group ); // embed order: top, label, left, label, bottom, label, right, label
OffsetRect( &secondaryLabelRect, 0, 26 );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), "\pBottom", kCFStringEncodingMacRoman );
CreateStaticTextControl( window, &secondaryLabelRect, text, &rectLabelStyle, &secondaryLabel );
EmbedControl( secondaryLabel, group );
} position += 2;
// create right
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
OffsetRect( &rect, 0, 26 );
CreateEditTextControl( window, &rect, text, false, true, &fontStyle, &edit );
EmbedControl( edit, group ); // embed order: top, label, left, label, bottom, label, right, label
OffsetRect( &secondaryLabelRect, 0, 26 );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), "\pRight", kCFStringEncodingMacRoman );
CreateStaticTextControl( window, &secondaryLabelRect, text, &rectLabelStyle, &secondaryLabel );
EmbedControl( secondaryLabel, group );
} position += 2;
rect.top = bounds.bottom +14;
rect.bottom += 18;
} break;
case 'ZCNT':
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position)) +1; // add one for zero-based count
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateStaticTextControl( window, &rect, text, &fontStyle, &listcount );
rect.bottom += 4;
position += 2;
// set recursion total (number of times to repeat)
recursionTotal = content;
// set control ID
id.id = n;
id.signature = kListCountSignature;
SetControlID( edit, &id );
} break;
case 'OCNT':
{ Str255 number;
SInt16 content = 0x0000;
if( size > position +1 ) content = *((short*)(*data + position));
NumToString( (long) content, number );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), number, kCFStringEncodingMacRoman );
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
CreateStaticTextControl( window, &rect, text, &fontStyle, &listcount );
rect.bottom += 4;
position += 2;
// set recursion total (number of times to repeat)
recursionTotal = content;
// set control ID
id.id = n;
id.signature = kListCountSignature;
SetControlID( edit, &id );
} break;
case 'LSTB': // repeats to end of resource
{ recursionTotal = -1;
recursionIndex = m;
recursionOrigin = current;
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
rect.bottom += 4;
} break;
case 'LSTC': // repeats recursionTotal times
{ recursionIndex = m;
recursionOrigin = current;
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
rect.bottom += 4;
} break;
case 'LSTZ': // repeats until 0x00 is encountered as first byte of next block
{ recursionTotal = -2;
recursionIndex = m;
recursionOrigin = current;
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
rect.bottom += 4;
} break;
case 'LSTE':
{ recursionCount++;
if( recursionTotal == -2 )
{
UInt8 content = 0x00;
if( size > position ) content = *((unsigned char*)(*data + position));
if( content != 0x00 )
{
// set current parser back to where recursion began from
m = recursionIndex;
current = recursionOrigin;
}
}
else if( recursionTotal == -1 )
{
if( size > position )
{
// set current parser back to where recursion began from
m = recursionIndex;
current = recursionOrigin;
}
}
else if( recursionCount < recursionTotal )
{
// set current parser back to where recursion began from
m = recursionIndex;
current = recursionOrigin;
}
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
rect.bottom += 4;
} break;
/* default:
SetRect( &rect, bounds.left, bounds.bottom +8, bounds.right, bounds.bottom +22 );
if( current->type & 0xFF000000 == 'P' << 24 )
{
// do Pxxx string
SInt32 length;
Str255 number;
number[0] = 3;
number[1] = (char) current->type << 8;
number[2] = (char) current->type << 16;
number[3] = (char) current->type << 24;
StringToNum( number, &length );
if( size > position )
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), (unsigned char *) (*data + position), kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateStaticTextControl( window, &rect, text, &fontStyle, &edit );
position += length + 1;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
}
else if( current->type & 0xFF000000 == 'C' << 24 )
{
// do Cxxx string
SInt32 length;
Str255 number;
number[0] = 3;
number[1] = (char) current->type << 8;
number[2] = (char) current->type << 16;
number[3] = (char) current->type << 24;
StringToNum( number, &length );
if( size > position )
text = CFStringCreateWithCString( CFAllocatorGetDefault(), *data + position, kCFStringEncodingMacRoman );
else text = CFSTR("");
CreateStaticTextControl( window, &rect, text, &fontStyle, &edit );
position += length + 1;
// set control ID
id.id = n;
id.signature = kEditFieldSignature;
SetControlID( edit, &id );
}
else if( current->type & 0xFF000000 == 'H' << 24 )
{
// do Hxxx string
}
// else I don't know what it is.
rect.bottom += 4;
break;
*/ }
// create label
if( (current->type != 'AWRD') && (current->type != 'ALNG') && ((current->type & 0xFF000000) != ('F' << 24)) ) // skip aligns and fillers
{
SetRect( &rect, windowBounds.left +8, rect.top, windowBounds.left +100, rect.bottom );
text = CFStringCreateWithPascalString( CFAllocatorGetDefault(), current->label, kCFStringEncodingMacRoman );
// Host_DebugError( current->label, rect.top );
CreateStaticTextControl( window, &rect, text, &fontStyle, &label );
id.id = n;
id.signature = kLabelSignature;
SetControlID( label, &id );
}
// save rect for next element to use
bounds.top = bounds.bottom = rect.bottom;
// advance current element
current = current->next;
}
if( current != null ) Host_DebugError( "\pLast element<6E>s 'next' parameter != 0", (long) current ); // last element should have null as it's "next" param
HSetState( data, state );
return error;
}
/*** READ CONTROLS ***/
OSStatus TemplateWindow::ReadControls( void )
{
OSStatus error = noErr;
// get resource ref
Plug_WindowRef plugWindow = Host_GetPlugWindowFromWindowRef( window );
if( plugWindow == null ) DebugStr("\pplugWindow == null");
Plug_ResourceRef resource = Host_GetTargetResource( plugWindow );
if( resource == null ) DebugStr("\presource == null");
// create blank resource
UInt32 size = 0;
Handle data = NewHandle(0);
// cycle through each element of the template
ControlID id;
ControlRef control, group;
ElementPtr current = elements;
ElementPtr recursionOrigin = null; // bug: only handles one level of recursion
signed long recursionTotal = 0;
unsigned long recursionIndex = 0, recursionCount = 0;
unsigned long m = 0, n = 0; // counters, one is always unique, the other is an element index
for( ; m < elementCount; m++ )
{
n++; // advance unique counter
// read controls
switch( current->type )
{
case 'BOOL': // BOOL is two bytes long, false == 0x0000, true == 0x0100
{ UInt16 value = 0;
// get control value
id.id = n;
id.signature = kBooleanGroupSignature;
error = GetControlByID( window, &id, &control );
if( !error ) value = GetControlValue( control ) -1; // false gives 1, true gives 2
value <<= 8;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +2 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 2 );
HSetState( data, state );
}
size += 2;
} break;
case 'BBIT':
case 'FBIT':
{ // read all eight bits in simultaneously
// nb. re. filler bits - the control exists but is disabled/hidden. reading it gives value of 0
id.id = n;
id.signature = kBooleanGroupSignature;
error = GetControlByID( window, &id, &group );
if( !error )
{
// read checkboxs
UInt8 value = 0x00;
GetIndexedSubControl( group, 1, &control );
value += (GetControlValue( control ) & 0x01) << 7;
GetIndexedSubControl( group, 2, &control );
value += (GetControlValue( control ) & 0x01) << 6;
GetIndexedSubControl( group, 3, &control );
value += (GetControlValue( control ) & 0x01) << 5;
GetIndexedSubControl( group, 4, &control );
value += (GetControlValue( control ) & 0x01) << 4;
GetIndexedSubControl( group, 5, &control );
value += (GetControlValue( control ) & 0x01) << 3;
GetIndexedSubControl( group, 6, &control );
value += (GetControlValue( control ) & 0x01) << 2;
GetIndexedSubControl( group, 7, &control );
value += (GetControlValue( control ) & 0x01) << 1;
GetIndexedSubControl( group, 8, &control );
value += (GetControlValue( control ) & 0x01) << 0;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 1 );
HSetState( data, state );
}
}
// update size & advance element counter
size += 1;
n += 7;
} break;
case 'DBYT':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt8 value;
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value = (char) number;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 1 );
HSetState( data, state );
}
size += 1;
}
DisposePtr( buffer );
}
}
} break;
case 'DWRD':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt16 value;
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value = (short) number;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +2 );
error = MemError();
if( !error )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 2 );
Host_DebugError( "\pvalue", value );
HSetState( data, state );
}
else Host_DebugError( "\pMemError() occoured", error );
size += 2;
}
else Host_DebugError( "\pGetControlData() failed", error );
DisposePtr( buffer );
}
else Host_DebugError( "\pGetControlDataSize() failed", error );
}
else Host_DebugError( "\pCould not get EditText control", error );
} break;
case 'DLNG':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt32 value;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &value );
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +4 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 4 );
HSetState( data, state );
}
size += 4;
}
DisposePtr( buffer );
}
}
} break;
case 'HBYT':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt8 value;
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value = (char) number;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 1 );
HSetState( data, state );
}
size += 1;
}
DisposePtr( buffer );
}
}
} break;
case 'HWRD':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt16 value;
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value = (short) number;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +2 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 2 );
HSetState( data, state );
}
size += 2;
}
DisposePtr( buffer );
}
}
} break;
case 'HLNG':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt32 value;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &value );
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +4 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 4 );
HSetState( data, state );
}
size += 4;
}
DisposePtr( buffer );
}
}
} break;
case 'FBYT':
{ SInt8 state = HGetState( data );
SetHandleSize( data, size +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
*((char *) *data + size) = 0x00;
HSetState( data, state );
}
size += 1;
} break;
case 'FWRD':
{ SInt16 value = 0;
SInt8 state = HGetState( data );
SetHandleSize( data, size +2 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 2 );
// *((short *) *data + size) = 0x0000;
HSetState( data, state );
}
size += 2;
} break;
case 'FLNG':
{ SInt32 value = 0;
SInt8 state = HGetState( data );
SetHandleSize( data, size +4 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 4 );
// *((long *) *data + size) = 0x00000000;
HSetState( data, state );
}
size += 4;
} break;
case 'AWRD':
{ SInt8 state = HGetState( data );
SetHandleSize( data, size + size % 2 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
while( size % 2 )
{
*((char *) *data + size) = 0x00;
size++;
}
HSetState( data, state );
}
} break;
case 'ALNG':
{ SInt8 state = HGetState( data );
SetHandleSize( data, size + size % 4 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
while( size % 4 )
{
*((char *) *data + size) = 0x00;
size++;
}
HSetState( data, state );
}
} break;
case 'CHAR': // one byte
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( (bufferSize > 1)? bufferSize:1 ); // ensures minimum buffer of one byte
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// put zero into buffer if actualSize == 0
if( actualSize < 1 ) *((char *) buffer) = 0x00;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( buffer, *data + size, 1 );
HSetState( data, state );
}
size += 1;
}
DisposePtr( buffer );
}
}
} break;
case 'TNAM': // four bytes
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( (bufferSize > 4)? bufferSize:4 ); // ensures minimum buffer of four bytes
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
Str255 text;
text[0] = 4;
BlockMoveData( buffer, &text[1], 4 );
Host_DebugError( text, bufferSize );
if( !error )
{
// put zero into buffer if actualSize == 0
if( actualSize < 4 ) *((long *) buffer) = 0x00000000;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +4 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( buffer, *data + size, 4 );
HSetState( data, state );
}
size += 4;
}
DisposePtr( buffer );
}
}
} break;
case 'CSTR':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( buffer, *data + size, actualSize );
*((char *)(*data + size + actualSize)) = 0x00; // add zero byte
HSetState( data, state );
}
size += actualSize +1;
}
DisposePtr( buffer );
}
}
} break;
case 'ECST':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// decide if I need a padding byte or not
Boolean pad = (actualSize % 2 == 0)? true:false;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize + (pad? 1:0) +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( buffer, *data + size, actualSize );
*((char *)(*data + size + actualSize)) = 0x00; // add zero byte
if( pad ) *((char *)(*data + size + actualSize +1)) = 0x00; // add pad byte
HSetState( data, state );
}
size += actualSize + (pad? 1:0) +1;
}
DisposePtr( buffer );
}
}
} break;
case 'OCST':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// decide if I need a padding byte or not
Boolean pad = (actualSize % 2 == 1)? true:false;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize + (pad? 1:0) +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( buffer, *data + size, actualSize );
*((char *)(*data + size + actualSize)) = 0x00; // add zero byte
if( pad ) *((char *)(*data + size + actualSize +1)) = 0x00; // add pad byte
HSetState( data, state );
}
size += actualSize + (pad? 1:0) +1;
}
DisposePtr( buffer );
}
}
} break;
case 'PSTR':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
*((char *)(*data + size)) = (char) actualSize; // add length byte
BlockMoveData( buffer, *data + size +1, actualSize );
HSetState( data, state );
}
size += actualSize +1;
}
DisposePtr( buffer );
}
}
} break;
case 'ESTR':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// decide if I need a padding byte or not
Boolean pad = (actualSize % 2 == 0)? true:false;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize + (pad? 1:0) +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
*((char *)(*data + size)) = (char) actualSize; // add length byte
BlockMoveData( buffer, *data + size +1, actualSize );
if( pad ) *((char *)(*data + size + actualSize +1)) = 0x00; // add pad byte
HSetState( data, state );
}
size += actualSize + (pad? 1:0) +1;
}
DisposePtr( buffer );
}
}
} break;
case 'OSTR':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// decide if I need a padding byte or not
Boolean pad = (actualSize % 2 == 1)? true:false;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize + (pad? 1:0) +1 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
*((char *)(*data + size)) = (char) actualSize; // add length byte
BlockMoveData( buffer, *data + size +1, actualSize );
if( pad ) *((char *)(*data + size + actualSize +1)) = 0x00; // add pad byte
HSetState( data, state );
}
size += actualSize + (pad? 1:0) +1;
}
DisposePtr( buffer );
}
}
} break;
case 'WSTR':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize +2 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
*((short *)(*data + size)) = (short) actualSize; // add length bytes
BlockMoveData( buffer, *data + size +2, actualSize );
HSetState( data, state );
}
size += actualSize +2;
}
DisposePtr( buffer );
}
}
} break;
case 'LSTR':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize +4 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
*((long *)(*data + size)) = (long) actualSize; // add length bytes
BlockMoveData( buffer, *data + size +4, actualSize );
HSetState( data, state );
}
size += actualSize +4;
}
DisposePtr( buffer );
}
}
} break;
case 'HEXD':
{ id.id = n;
id.signature = kEditFieldSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size + actualSize );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( buffer, *data + size, actualSize );
HSetState( data, state );
}
size += actualSize;
}
DisposePtr( buffer );
}
}
} break;
case 'RECT':
{ id.id = n;
id.signature = kRectGroupSignature;
error = GetControlByID( window, &id, &group );
if( !error )
{
// read checkboxs
Rect value;
error = GetIndexedSubControl( group, 2, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value.top = (short) number;
}
DisposePtr( buffer );
}
}
else value.top = 0;
error = GetIndexedSubControl( group, 4, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value.left = (short) number;
}
DisposePtr( buffer );
}
}
else value.left = 0;
error = GetIndexedSubControl( group, 6, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value.bottom = (short) number;
}
DisposePtr( buffer );
}
}
else value.bottom = 0;
error = GetIndexedSubControl( group, 8, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlEditTextPart, kControlEditTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlEditTextPart, kControlEditTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value.right = (short) number;
}
DisposePtr( buffer );
}
}
else value.right = 0;
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +8 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 8 );
HSetState( data, state );
}
size += 8;
}
} break;
case 'ZCNT':
case 'OCNT':
{ id.id = n;
id.signature = kListCountSignature;
error = GetControlByID( window, &id, &control );
if( !error )
{
// find out how much text has been typed
Size bufferSize, actualSize;
error = GetControlDataSize( control, kControlLabelPart, kControlStaticTextTextTag, &bufferSize );
if( !error )
{
// allocate buffer and read data
Ptr buffer = NewPtrClear( bufferSize );
error = GetControlData( control, kControlLabelPart, kControlStaticTextTextTag, bufferSize, buffer, &actualSize );
if( !error )
{
// convert buffer into desired format
SInt16 value;
SInt32 number;
Str255 string;
string[0] = actualSize;
BlockMoveData( buffer, &string[1], actualSize );
StringToNum( string, &number );
value = (short) number;
// set recursion total (number of times to repeat)
recursionTotal = value; // actually, this value is ignored :) -- I count occourences of LSTE instead
// append correct data to handle
SInt8 state = HGetState( data );
SetHandleSize( data, size +2 );
if( !MemError() )
{
HLock( data ); // lock handle after increasing it's size
BlockMoveData( &value, *data + size, 2 );
HSetState( data, state );
}
size += 2;
}
DisposePtr( buffer );
}
}
} break;
case 'LSTB': // repeats to end of resource
{ recursionTotal = -1;
recursionIndex = m;
recursionOrigin = current;
} break;
case 'LSTC': // repeats recursionTotal times
{ recursionIndex = m;
recursionOrigin = current;
} break;
case 'LSTZ': // repeats until 0x00 is encountered as first byte of next block
{ recursionTotal = -2;
recursionIndex = m;
recursionOrigin = current;
} break;
case 'LSTE':
{ recursionCount++;
/* if( recursionTotal == -2 )
{
UInt8 content = 0x00;
if( size > position ) content = *((unsigned char*)(*data + position));
if( content != 0x00 )
{
// set current parser back to where recursion began from
m = recursionIndex;
current = recursionOrigin;
}
}
else if( recursionTotal == -1 )
{
if( size > position )
{
// set current parser back to where recursion began from
m = recursionIndex;
current = recursionOrigin;
}
}
else if( recursionCount < recursionTotal )
{
// set current parser back to where recursion began from
m = recursionIndex;
current = recursionOrigin;
}
*/ } break;
default:
break;
}
// advance current element
current = current->next;
}
// save any changes
if( !error )
{
Handle original = Host_GetResourceData( resource );
Host_DebugError( "\ptesting if handles match<63>", 0 );
if( !HandlesMatch( original, data ) ) // only save if data changed
{
Host_DebugError( "\pthey don't, saving changes<65>", 0 );
SInt8 state = HGetState( original );
HLock( original );
SetHandleSize( original, size );
BlockMoveData( *data, *original, size );
HSetState( original, state );
Host_SetResourceDirty( resource, true );
}
else Host_DebugError( "\pthey do match, don't save changes", 0 );
Host_ReleaseResourceData( resource );
}
else Host_DebugError( "\pan error occoured somewhere, don't save any changes", error );
// clean up and leave
DisposeHandle( data );
return error;
}
/*** HANDLES MATCH ***/
Boolean HandlesMatch( const Handle one, const Handle two )
{
Size sizeOne = GetHandleSize( one );
Size sizeTwo = GetHandleSize( two );
if( sizeOne != sizeTwo ) return false;
else
{
SInt8 stateOne = HGetState( one );
SInt8 stateTwo = HGetState( two );
HLock( one );
HLock( two );
char *a = *one;
char *b = *two;
for( unsigned short i = 0; i < sizeOne; i++ )
if( *a++ != *b++ ) return false;
HSetState( one, stateOne );
HSetState( two, stateTwo );
return true;
}
}