This is EDBConnectInspector.m in view mode; [Download] [Up]
#import "EDBConnectInspector.h"
#import "EDBConnector.h"
#import "ConnectBrowserCell.h"
#import "MColCell.h"
#import "EDBOutlet.h"
#import <assert.h>
#define NOLDEBUG
static EDBConnectInspector *onlyInspector = nil;
static int sortFunction(id *ob1,id *ob2)
{
int ret = strcmp([*ob1 outletName],[*ob2 outletName]);
if (!ret)
ret = [*ob1 sequence]-[*ob2 sequence];
return ret;
}
@implementation EDBConnectInspector
+ obtainEDBConnectInspector
{
if (onlyInspector != nil)
return onlyInspector;
return (onlyInspector=[[[self class] alloc] init]);
}
- init
{
char buf [MAXPATHLEN + 1];
NXBundle *bundle;
NXSize size,size1;
NXSplitView *splitView;
NXRect splitFrame;
NXImage *image;
MColCell *mcell;
#ifdef LDEBUG
fprintf(stderr,"%s init\n",[self name]);
#endif
if (onlyInspector && [self class]==[EDBConnectInspector class])
{
[super free];
return onlyInspector;
}
if (![super init])
return nil;
bundle = [NXBundle bundleForClass:[self class]];
[bundle getPath:buf
forResource:"EDBConnectInspector"
ofType:"nib"];
if (![NXApp loadNibFile:buf owner:self withNames:NO fromZone:[self zone]])
{
[super free];
return nil;
}
[[window contentView] getBounds:&splitFrame];
splitView = [[NXSplitView alloc] initFrame:&splitFrame];
[splitView setDelegate:self];
[upperBox removeFromSuperview];
[lowerBox removeFromSuperview];
[splitView addSubview:upperBox];
[splitView addSubview:lowerBox];
[[window contentView] addSubview:splitView];
[splitView display];
[lowerBox getBounds:&splitFrame];
minHeight = splitFrame.size.height;
connections = [[ExtList alloc] init];
mcell = [[MColCell alloc] init];
[mcell addColWithOffset:0];
[mcell addColWithOffset:150];
[connectMatrix setPrototype:mcell];
[connectMatrix getCellSize:&size];
size.width = 300;
[connectMatrix setCellSize:&size];
[connectMatrix addCol];
[connectMatrix setMode:NX_RADIOMODE];
[connectMatrix setEmptySelectionEnabled:YES];
[outletBrowser setDoubleAction:@selector(doubleClickOutlet:)];
[outletBrowser setCellClass:[ConnectBrowserCell class]];
[actionMatrix setTarget:self];
[actionMatrix setAction:@selector(clickAction:)];
[actionMatrix setCellClass:[TextFieldCell class]];
[actionMatrix getCellSize:&size];
[actionScrollView getContentSize:&size1];
size.width = size1.width;
[actionMatrix setCellSize:&size];
[actionMatrix addCol];
[actionMatrix sizeToCells];
[[actionMatrix cellAt:0:0] setSelectable:YES];
[[actionMatrix cellAt:0:0] setEditable:YES];
bundle = [NXBundle bundleForClass:[self class]];
[bundle getPath:buf
forResource:"EDBdimple_nib"
ofType:"tiff"];
image = [[NXImage alloc] initFromFile:buf];
[image setName:"EDBdimple_nib"];
[bundle getPath:buf
forResource:"EDBdimpleH_nib"
ofType:"tiff"];
image = [[NXImage alloc] initFromFile:buf];
[image setName:"EDBdimpleH_nib"];
outletCount = 0;
outlets = NULL;
refreshOnRevert = YES;
onlyInspector = self;
return self;
}
- free
{
[connections free];
[outlets free];
if (self == onlyInspector)
onlyInspector = nil;
return [super free];
}
- revert:sender
{
#ifdef LDEBUG
fprintf(stderr,"%s revert:\n",[self name]);
#endif
if (!refreshOnRevert)
{
refreshOnRevert = YES;
return [super revert:sender];
}
outlets = [object getOutlets];
outletCount = [outlets count];
[self getConnections:connections];
[self displayConnections:connections];
[outletBrowser loadColumnZero];
[self selectOutlet];
return [super revert:sender];
}
- ok:sender
{
NXAtom outletName = NXUniqueString([[[outletBrowser matrixInColumn:0]
selectedCell] stringValue]);
int count = [connections count];
int ind;
id connector;
int outletNr;
id matrix = [outletBrowser matrixInColumn:0];
#ifdef LDEBUG
fprintf(stderr,"%s ok\n",[self name]);
#endif
if (![NXApp isConnecting])
return self;
outletNr = [[outletBrowser matrixInColumn:0] selectedRow];
ind = [connectMatrix selectedRow];
if (ind>=0 && ind<count) // remove Connection
{
connector = [connections objectAt:ind];
[[NXApp activeDocument] removeConnector:connector];
[connections removeObjectAt:ind];
if ([[outlets objectAt:outletNr] multiUse])
[self removeSequenceNumberOf:connector];
[connector free];
[self displayConnections:connections];
if (![[outlets objectAt:outletNr] multiUse] &&
![[outlets objectAt:outletNr] isTarget])
{
matrix = [outletBrowser matrixInColumn:0];
[self outletAt:[matrix selectedCell] inMatrix:matrix
setConnected:NO andDisplay:YES];
}
[connectMatrix selectCellAt:-1:-1];
[okButton setTitle:"Connect"];
}
else // add Connection
{
connector = [self createConnectorForOutlet:outletName withNr:outletNr
andSel:([[outlets objectAt:outletNr] isTarget]) ?
[[actionMatrix cellAt:0:0] stringValue] : NULL];
#ifdef LDEBUG
fprintf(stderr,"%s createConnector: source=%lx (%s),dest=%lx (%s),"
"outlet=%s,sel=%s\n",[self name],(u_long)[NXApp connectSource],
[[NXApp connectSource] name],(u_long)[NXApp connectDestination],
[[NXApp connectDestination] name],outletName,[connector selName]);
#endif
ind = [connections insertOrdered:connector usingFunc:
(SortFunc *)sortFunction];
[[NXApp activeDocument] addConnector:connector];
[self displayConnections:connections];
if (![[outlets objectAt:outletNr] multiUse] &&
![[outlets objectAt:outletNr] isTarget])
[self outletAt:[matrix selectedCell] inMatrix:matrix
setConnected:YES andDisplay:YES];
[connectMatrix selectCellAt:ind:0];
[okButton setTitle:"Disonnect"];
}
return self;
}
- createConnectorForOutlet:(NXAtom)outletName withNr:(int)outletNr
andSel:(const char *)sel
{
id connector;
connector = [[EDBConnector alloc] initWithSource:
[NXApp connectSource] andDestination:[NXApp connectDestination]
forOutlet:outletName andSel:sel];
if ([[outlets objectAt:outletNr] multiUse])
[self setSequenceNumberFor:connector];
return connector;
}
- (BOOL)wantsButtons
{
#ifdef LDEBUG
fprintf(stderr,"%s wantsButtons\n",[self name]);
#endif
return YES;
}
- outletAt:cell inMatrix:matrix setConnected:(BOOL)flag andDisplay:(BOOL)disp
{
if (flag)
{
[cell setBranchImage:[NXImage findImageNamed:"EDBdimple_nib"]];
[cell setBranchImageH:[NXImage findImageNamed:"EDBdimpleH_nib"]];
}
else
{
[cell setBranchImage:nil];
[cell setBranchImageH:nil];
}
if (disp)
[matrix drawCell:cell];
return self;
}
- setSequenceNumberFor:connector
{
NXAtom outletName = [connector outletName];
int ind;
int count = [connections count];
int maxNum;
for (ind=maxNum=0; ind<count; ind++)
{
if (outletName==[[connections objectAt:ind] outletName] &&
[[connections objectAt:ind] sequence]>maxNum)
maxNum = [[connections objectAt:ind] sequence];
}
[connector setSequence:maxNum+1];
return self;
}
- removeSequenceNumberOf:connector
{
NXAtom outletName = [connector outletName];
int ind;
int count = [connections count];
int seqNum = [connector sequence];
int k;
for (ind=0; ind<count; ind++)
{
if (outletName==[[connections objectAt:ind] outletName] &&
(k=[[connections objectAt:ind] sequence])>seqNum)
[[connections objectAt:ind] setSequence:k-1];
}
return self;
}
- clickAction:sender
{
#ifdef LDEBUG
fprintf(stderr,"%s clickAction:\n",[self name]);
#endif
[okButton performClick:self];
return self;
}
- clickConnection:sender
{
int count = [connections count];
int ind = [sender selectedRow];
int outletInd;
#ifdef LDEBUG
fprintf(stderr,"%s clickConnection:\n",[self name]);
#endif
assert(ind<count);
[NXApp displayConnectionBetween:[[connections objectAt:ind] source] and:
[[connections objectAt:ind] destination]];
refreshOnRevert = NO;
outletInd = [self indexOfOutlet:[[connections objectAt:ind] outletName]];
[[outletBrowser matrixInColumn:0] selectCellAt:outletInd:0];
[self fillTargetMatrixForConnection:[connections objectAt:ind]
andOutlet:outletInd];
[okButton setEnabled:YES];
[okButton setTitle:"Disconnect"];
return self;
}
- fillTargetMatrixForConnection:connection andOutlet:(int)outletInd
{
if (outletInd>=0 && outletInd<outletCount &&
[[outlets objectAt:outletInd] isTarget])
{
[[actionMatrix cellAt:0:0] setStringValue:[connection selName]];
[actionMatrix setEnabled:YES];
[actionMatrix selectCellAt:0:0];
}
else
{
[[actionMatrix cellAt:0:0] setStringValueNoCopy:""];
[actionMatrix setEnabled:NO];
}
return self;
}
- clickOutlet:sender
{
NXAtom outletName = NXUniqueString([[[sender matrixInColumn:0]
selectedCell] stringValue]);
int count = [connections count];
int ind;
int outletNr;
#ifdef LDEBUG
fprintf(stderr,"%s clickOutlet:\n",[self name]);
#endif
outletNr = [[sender matrixInColumn:0] selectedRow];
for (ind=0; ind<count &&
[[connections objectAt:ind] outletName]!=outletName; ind++);
if (![[outlets objectAt:outletNr] multiUse] && ind<count)
{
[NXApp displayConnectionBetween:[[connections objectAt:ind] source]
and:[[connections objectAt:ind] destination]];
refreshOnRevert = NO;
[okButton setTitle:"Disconnect"];
[okButton setEnabled:YES];
[connectMatrix selectCellAt:ind:0];
[self fillTargetMatrixForConnection:[connections objectAt:ind]
andOutlet:outletNr];
}
else
{
[okButton setTitle:"Connect"];
[okButton setEnabled:[NXApp isConnecting]];
[connectMatrix selectCellAt:-1:-1];
[self fillTargetMatrixForConnection:nil andOutlet:outletNr];
}
return self;
}
- doubleClickOutlet:sender
{
#ifdef LDEBUG
fprintf(stderr,"%s doubleClickOutlet:\n",[self name]);
#endif
[okButton performClick:self];
return self;
}
- getConnections:list
{
#ifdef LDEBUG
fprintf(stderr,"%s getConnections:\n",[self name]);
#endif
[[NXApp activeDocument] listConnectors:list forSource:object];
[list sortUsingFunc:(SortFunc *)sortFunction];
return self;
}
- displayConnections:list
{
int count = [list count];
int rows,cols;
char name [256];
const char *p;
int outletInd;
#ifdef LDEBUG
fprintf(stderr,"%s displayConnections\n",[self name]);
#endif
[connectMatrix getNumRows:&rows numCols:&cols];
for (rows--; rows>=0; rows--)
[connectMatrix removeRowAt:rows andFree:YES];
for (rows=0; rows<count; rows++)
{
[connectMatrix addRow];
outletInd = [self indexOfOutlet:[[list objectAt:rows] outletName]];
if (outletInd>=0 && [[outlets objectAt:outletInd] multiUse])
{
sprintf(name,"%s-%03d",
[[outlets objectAt:outletInd] outletName],
[[list objectAt:rows] sequence]);
[[connectMatrix cellAt:rows:0] setStringValue:name
at:0 copy:YES];
}
else
[[connectMatrix cellAt:rows:0] setStringValue:
[[list objectAt:rows] outletName] at:0 copy:NO];
[[NXApp activeDocument] getNameIn:name
for:[[list objectAt:rows] destination]];
if (name[0] == '\0')
{
p = [[[list objectAt:rows] destination] name];
if (p == NULL)
p = "First Responder";
[[connectMatrix cellAt:rows:0] setStringValue:p at:1 copy:YES];
}
else
[[connectMatrix cellAt:rows:0] setStringValue:name at:1 copy:YES];
}
[connectMatrix sizeToCells];
[connectScrollView display];
return self;
}
- selectOutlet
{
int count = [connections count];
int ind;
id dest = [NXApp connectDestination];
int outletNr;
[revertButton setEnabled:NO];
if ([NXApp isConnecting])
{
[okButton setEnabled:YES];
for (ind=0; ind<count &&
[[connections objectAt:ind] destination]!=dest; ind++);
if (ind < count) // Connection line for existing Connection
{
outletNr = [self indexOfOutlet:[[connections objectAt:ind]
outletName]];
[[outletBrowser matrixInColumn:0] selectCellAt:outletNr:0];
[connectMatrix selectCellAt:ind:0];
[okButton setTitle:"Disconnect"];
[self fillTargetMatrixForConnection:[connections objectAt:ind]
andOutlet:outletNr];
}
else // Select next free outlet
{
outletNr = [self indexOfFirstFreeOutlet];
[[outletBrowser matrixInColumn:0] selectCellAt:outletNr:0];
[connectMatrix selectCellAt:-1:-1];
[okButton setTitle:"Connect"];
[self fillTargetMatrixForConnection:nil andOutlet:outletNr];
}
}
else
{
[okButton setEnabled:NO];
[okButton setTitle:"Connect"];
[self fillTargetMatrixForConnection:nil andOutlet:-1];
}
return self;
}
- (int)indexOfOutlet:(NXAtom)name
{
int ind;
#ifdef LDEBUG
fprintf(stderr,"%s indexOfOutlet:%s\n",[self name],name);
#endif
for (ind=0; ind<outletCount; ind++)
{
if ([[outlets objectAt:ind] outletName] == name)
return ind;
}
return -1;
}
- (int)indexOfFirstFreeOutlet
{
int ind;
int indConns;
int countConns = [connections count];
#ifdef LDEBUG
fprintf(stderr,"%s indexOfFirstFreeOutlet\n",[self name]);
#endif
for (ind=0; ind<outletCount; ind++)
{
if ([[outlets objectAt:ind] multiUse])
return ind;
for (indConns=0; indConns<countConns &&
[[connections objectAt:indConns] outletName]!=
[[outlets objectAt:ind] outletName]; indConns++);
if (indConns >= countConns)
return ind;
}
return -1;
}
- (BOOL)outletIsConnected:(int)ind
{
int indConns;
int countConns = [connections count];
#ifdef LDEBUG
fprintf(stderr,"%s outletIsConnected\n",[self name]);
#endif
if ([[outlets objectAt:ind] multiUse])
return NO;
for (indConns=0; indConns<countConns &&
[[connections objectAt:indConns] outletName]!=
[[outlets objectAt:ind] outletName]; indConns++);
if (indConns >= countConns)
return NO;
return YES;
}
- outletAddedToObject:sender
{
if (object != sender)
return self;
[self revert:self];
return self;
}
- outlet:(NXAtom)name removedFromObject:sender
{
List *conns;
int count,
ind;
id connector;
if (object != sender)
return self;
conns = [[List alloc] initCount:[connections count]];
[[NXApp activeDocument] listConnectors:conns forSource:object];
count = [conns count];
for (ind=0; ind<count; ind++)
{
connector = [conns objectAt:ind];
if ([connector outletName] == name)
{
[[NXApp activeDocument] removeConnector:connector];
[connector free];
}
}
[self revert:self];
[conns free];
return self;
}
- outletOfObject:sender renamedFrom:(NXAtom)from to:(NXAtom)to
{
List *conns;
int count,
ind;
id connector;
if (object != sender)
return self;
conns = [[List alloc] initCount:[connections count]];
[[NXApp activeDocument] listConnectors:conns forSource:object];
count = [conns count];
for (ind=0; ind<count; ind++)
{
connector = [conns objectAt:ind];
if ([connector outletName] == from)
[connector setOutletName:to];
}
[self revert:self];
[conns free];
return self;
}
- (int)browser:sender fillMatrix:matrix inColumn:(int)column
{
int indOuts;
int countConns = [connections count];
int indConns;
#ifdef LDEBUG
fprintf(stderr,"%s browser:fillMatrix:inColumn:%d\n",[self name],column);
#endif
for (indOuts=0; indOuts<outletCount; indOuts++)
{
[matrix addRow];
[[matrix cellAt:indOuts:0] setStringValueNoCopy:
[[outlets objectAt:indOuts] outletName]];
[[matrix cellAt:indOuts:0] setLoaded:YES];
[[matrix cellAt:indOuts:0] setLeaf:YES];
if ([[outlets objectAt:indOuts] isTarget])
{
[[matrix cellAt:indOuts:0] setBranchImage:
[NXImage findImageNamed:"NXmenuArrow"]];
[[matrix cellAt:indOuts:0] setBranchImageH:
[NXImage findImageNamed:"NXmenuArrowH"]];
}
for (indConns=0; indConns<countConns &&
[[connections objectAt:indConns] outletName]!=
[[outlets objectAt:indOuts] outletName];
indConns++);
if (![[outlets objectAt:indOuts] multiUse] && indConns<countConns)
{
if (![[outlets objectAt:indOuts] isTarget])
[self outletAt:[matrix cellAt:indOuts:0] inMatrix:matrix
setConnected:YES andDisplay:NO];
else
{
[[actionMatrix cellAt:0:0] setStringValue:
[[connections objectAt:indConns] selName]];
[actionMatrix selectTextAt:0:0];
}
}
}
[matrix sizeToCells];
return outletCount;
}
- splitView:sender getMinY:(NXCoord *)minY maxY:(NXCoord *)maxY
ofSubviewAt:(int)offset
{
NXRect rect;
offset = 0;
[sender getBounds:&rect];
*minY = minHeight;
*maxY = rect.size.height - minHeight;
if (*maxY < minHeight)
*maxY = minHeight;
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.