2005-05-12 Matt Rice <ratmice@yahoo.com>

* ChangeLog: Fix previous ChangeLog entry.
        * EOInterface/EOActionAssociation.m: Implemented aspects enabled and
        action.
        (-establishConnection): Implement
        (-breakConnection, -subjectChanged, -action): Ditto.
        * EOInterface/EOAssociation.m (-associationClassesForObject:): Fixed
        argument passed to -isUsableWithObject:. Assign count
        (-init): Assign self.
        (-establishConnection:): Add unused local variable to pass to
        NSNextMapEnumeratorPair instead of 0.
        (-breakConnection:): Ditto.
        (-initWithCoder:, -encodeWithCoder:): Initial implementation of
        methods.
        (-valueForAspect:,-setValue:forAspect:,-valueForAspect:atIndex:): Ditto.
        (-setValueForAspect:atIndex:): Ditto.
        * EOInterface/SubclassFlags.h: New file.
        * EOInterface/EOAspectConnector.h/m: New file and implementation.
        * EOInterface/EOColumnAssociation.m: Implemented aspects value and
        enabled
        (-objectKeysTaken): Take identifier key.
        (-establishConnection, -breakConnection, -endEditing): Implement
        methods.
        (-tableView:setObjectValueForTableColumn:row:): Ditto.
        (-tableView:objectValueForTableColumn:row:): Ditto.
        (-tableView:willDisplayCell:forTableColumn:row:): Ditto.
        (-control:didFailToFormatString:errorDescription:): Ditto.
        (-control:textShouldBeginEditing:): Ditto.
        * EOInterface/EOControlAssociation.m: (-control): Ditto
        (-editingAssociation, -establishConnection, -breakConnection): Ditto.
        * EOInterface/EOGenericControlAssociation.m: Implemented aspects value
        and enabled.
        (+objectKeysTaken): add target key.
        (-establishConnection: -breakConnection:, -subjectChanged:): Ditto.
        (-_action:, -endEditing, -control:textShouldBeginEditing:): Ditto.
        * EOInterface/EOMatrixAssociation.m: Implemented aspects image, title,
        and enabled.
        (-establishConnection, -breakConnection, -subjectChanged): Ditto.
        * EOInterface/EOPopUpAssociation.m: Implemented aspects titles,
        selectedTitle, selectedTag, selectedObject, enabled.
        (-initWithObject:, -_action:): Implemented method.
        (-establishConnection:, -breakConnection, -subjectChanged): Ditto.
        * EOInterface/EORadioMatrixAssociation.m: Implemented aspects
        selectedTag, selectedTitle, enabled.
        (NSCell -_selectCellWithTitle:): Private category.
        (-initWithObject:, -_action:): Implemented method.
        (-establishConnection:, -breakConnection, -subjectChanged): Ditto.
        * EOInterface/EOTableViewAssociation.m: Implemented aspects
	enabled, tableView.
        (-establishConnection, -breakConnection, subjectChanged): Implement
        method.
        (-bindToTableView:displayGroup:, -editingAssociation): Ditto.
        (-numberOfRowsInTableView:):
        (-tableView:setObjectValue:forTableColumn:row:): Ditto.
        (-tableView:objectValueForTableColumn:row:): Ditto.
        (-tableView:shouldEditTableColumn:row:): Ditto.
        (-tableView:willDisplayCell:forTableColumn:row:): Ditto.
        (-tableView:selectionDidChange:): Ditto.
        (-control:didFailToFormatString:errorDescription:): Ditto.
        (-control:isValidObject:, -control:textShouldBeginEditing:):
	Ditto.
        (-dealloc): Ditto.
        * EOInterface/EOTextAssociation.m: Implemented aspect value,
enabled.
        (-establishConnection): Implemented method.
        (-breakConnection, -subjectChanged, -endEditing): Ditto.
        (-control:isValidObject:,textShouldBeginEditing:): Ditto.
        (-textShouldEndEditing:): Ditto.
        * EOInterface/GNUmakefile: Make EOInterface a native-library, whitespace
        changes.
        * EOInterface/Makefile.preamble: Change linker flag to use FND_LIBS
        and GUI_LIBS variables.
        * EOInterface/EODisplayGroup.h: Comment on whether ivars are retained.
        * EOInterface/EODisplayGroup.m:
        (DG_SHOULD_CHANGE_SELECTION_TO_IDX): New macros.
        (DG_DISPLAY_ARRAY_FOR_OBJECTS, DG_SHOULD_DISPLAY_ALERT): Ditto.
        (DG_DID_FETCH_OBJECTS, DG_CREATE_OBJECT_FAILED): Ditto.
        (DG_SHOULD_INSERT_OBJECT, DG_DID_INSERT_OBJECT): Ditto.
        (DG_DID_CHANGE_SELECTION): Ditto.
        (NSArray -indexesForObjectsIdenticalTo:): Implement category method.
        (_presentAlertWithTitle:message:): New private methods.
        (-_endObserverNotification:): Implement notification observer methods.
        (-_beginObserverNotification:): Ditto.
        (-objectsInvalidatedInEditingContext:): Ditto.
        (-objectsChangedInEditingContext:): Ditto.
        (+initialize, -init, -initWithCoder:,): Implement methods.
        (-encodeWithCoder:, -setDataSource:, -fetch, -allObjects): Ditto.
        (-setObjectArray:, -redisplay, -updateDisplayedObjects): Ditto.
        (-selectionIndexes, -setSelectionIndexes, -selectObject): Ditto.
        (-selectObjectsIdenticalTo:, -clearSelection, -selectedObjects): Ditto.
        (-selectObjectsIdenticalTo:selectFirstOnNoMatch:): Ditto.
        (-setSelectedObjects, -selectedObject, -setSelectedObject:): Ditto.
        (-insertObjectAtIndex:, -insertObject:atIndex:): Ditto.
        (-setInsertedObjectDefaultValues:, -deleteSelection): Ditto.
        (-observingAssociations, -endEditing, -fetch:, -insert:): Ditto.
        (-selectionChanged, -contentsChanged, -valueForObject🔑): Ditto.
        (-selectedObjectValueForKey:, -valueForObjectAtIndex:): Ditto.
        (-setValue:forObject:key:, -setSelectedObjectValue:forKey:): Ditto.
        (-setValue:forObjectAtIndex:key:, -associationDidBeginEditing:):
	Ditto.
        (-associationDidEndEditing:): Ditto.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@21222 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Matt Rice 2005-05-12 19:55:41 +00:00
parent 56ba650c5c
commit e205cd1324
18 changed files with 1931 additions and 141 deletions

104
ChangeLog
View file

@ -1,3 +1,103 @@
2005-05-12 Matt Rice <ratmice@yahoo.com>
* ChangeLog: Fix previous ChangeLog entry.
* EOInterface/EOActionAssociation.m: Implemented aspects enabled and
action.
(-establishConnection): Implement
(-breakConnection, -subjectChanged, -action): Ditto.
* EOInterface/EOAssociation.m (-associationClassesForObject:): Fixed
argument passed to -isUsableWithObject:. Assign count
(-init): Assign self.
(-establishConnection:): Add unused local variable to pass to
NSNextMapEnumeratorPair instead of 0.
(-breakConnection:): Ditto.
(-initWithCoder:, -encodeWithCoder:): Initial implementation of
methods.
(-valueForAspect:,-setValue:forAspect:,-valueForAspect:atIndex:): Ditto.
(-setValueForAspect:atIndex:): Ditto.
* EOInterface/SubclassFlags.h: New file.
* EOInterface/EOAspectConnector.h/m: New file and implementation.
* EOInterface/EOColumnAssociation.m: Implemented aspects value and
enabled
(-objectKeysTaken): Take identifier key.
(-establishConnection, -breakConnection, -endEditing): Implement
methods.
(-tableView:setObjectValueForTableColumn:row:): Ditto.
(-tableView:objectValueForTableColumn:row:): Ditto.
(-tableView:willDisplayCell:forTableColumn:row:): Ditto.
(-control:didFailToFormatString:errorDescription:): Ditto.
(-control:textShouldBeginEditing:): Ditto.
* EOInterface/EOControlAssociation.m: (-control): Ditto
(-editingAssociation, -establishConnection, -breakConnection): Ditto.
* EOInterface/EOGenericControlAssociation.m: Implemented aspects value
and enabled.
(+objectKeysTaken): add target key.
(-establishConnection: -breakConnection:, -subjectChanged:): Ditto.
(-_action:, -endEditing, -control:textShouldBeginEditing:): Ditto.
* EOInterface/EOMatrixAssociation.m: Implemented aspects image, title,
and enabled.
(-establishConnection, -breakConnection, -subjectChanged): Ditto.
* EOInterface/EOPopUpAssociation.m: Implemented aspects titles,
selectedTitle, selectedTag, selectedObject, enabled.
(-initWithObject:, -_action:): Implemented method.
(-establishConnection:, -breakConnection, -subjectChanged): Ditto.
* EOInterface/EORadioMatrixAssociation.m: Implemented aspects
selectedTag, selectedTitle, enabled.
(NSCell -_selectCellWithTitle:): Private category.
(-initWithObject:, -_action:): Implemented method.
(-establishConnection:, -breakConnection, -subjectChanged): Ditto.
* EOInterface/EOTableViewAssociation.m: Implemented aspects enabled,
tableView.
(-establishConnection, -breakConnection, subjectChanged): Implement
method.
(-bindToTableView:displayGroup:, -editingAssociation): Ditto.
(-numberOfRowsInTableView:):
(-tableView:setObjectValue:forTableColumn:row:): Ditto.
(-tableView:objectValueForTableColumn:row:): Ditto.
(-tableView:shouldEditTableColumn:row:): Ditto.
(-tableView:willDisplayCell:forTableColumn:row:): Ditto.
(-tableView:selectionDidChange:): Ditto.
(-control:didFailToFormatString:errorDescription:): Ditto.
(-control:isValidObject:, -control:textShouldBeginEditing:): Ditto.
(-dealloc): Ditto.
* EOInterface/EOTextAssociation.m: Implemented aspect value, enabled.
(-establishConnection): Implemented method.
(-breakConnection, -subjectChanged, -endEditing): Ditto.
(-control:isValidObject:,textShouldBeginEditing:): Ditto.
(-textShouldEndEditing:): Ditto.
* EOInterface/GNUmakefile: Make EOInterface a native-library, whitespace
changes.
* EOInterface/Makefile.preamble: Change linker flag to use FND_LIBS
and GUI_LIBS variables.
* EOInterface/EODisplayGroup.h: Comment on whether ivars are retained.
* EOInterface/EODisplayGroup.m:
(DG_SHOULD_CHANGE_SELECTION_TO_IDX): New macros.
(DG_DISPLAY_ARRAY_FOR_OBJECTS, DG_SHOULD_DISPLAY_ALERT): Ditto.
(DG_DID_FETCH_OBJECTS, DG_CREATE_OBJECT_FAILED): Ditto.
(DG_SHOULD_INSERT_OBJECT, DG_DID_INSERT_OBJECT): Ditto.
(DG_DID_CHANGE_SELECTION): Ditto.
(NSArray -indexesForObjectsIdenticalTo:): Implement category method.
(_presentAlertWithTitle:message:): New private methods.
(-_endObserverNotification:): Implement notification observer methods.
(-_beginObserverNotification:): Ditto.
(-objectsInvalidatedInEditingContext:): Ditto.
(-objectsChangedInEditingContext:): Ditto.
(+initialize, -init, -initWithCoder:,): Implement methods.
(-encodeWithCoder:, -setDataSource:, -fetch, -allObjects): Ditto.
(-setObjectArray:, -redisplay, -updateDisplayedObjects): Ditto.
(-selectionIndexes, -setSelectionIndexes, -selectObject): Ditto.
(-selectObjectsIdenticalTo:, -clearSelection, -selectedObjects): Ditto.
(-selectObjectsIdenticalTo:selectFirstOnNoMatch:): Ditto.
(-setSelectedObjects, -selectedObject, -setSelectedObject:): Ditto.
(-insertObjectAtIndex:, -insertObject:atIndex:): Ditto.
(-setInsertedObjectDefaultValues:, -deleteSelection): Ditto.
(-observingAssociations, -endEditing, -fetch:, -insert:): Ditto.
(-selectionChanged, -contentsChanged, -valueForObject:key:): Ditto.
(-selectedObjectValueForKey:, -valueForObjectAtIndex:): Ditto.
(-setValue:forObject:key:, -setSelectedObjectValue:forKey:): Ditto.
(-setValue:forObjectAtIndex:key:, -associationDidBeginEditing:): Ditto.
(-associationDidEndEditing:): Ditto.
2005-05-11 Matt Rice <ratmice@yahoo.com>
* EOAccess/Makefile.preamble: Change link flag to use FND_LIBS variable
@ -6,8 +106,8 @@
* EOAccess/EODatabaseDataSource.m (-entity): Look for entity with the
fetch specifications entity name in a model group.
(-databaseContext): Return a registered database context.
* EOAdaptors/Postgres95/LoginPanel/Postgres95LoginPanel.m: Cast return
value of -initWithIdentifier to remove warning with gcc 3.4
* EOAdaptors/Postgres95/LoginPanel/Postgres95LoginPanel.m: Cast before
calling -initWithIdentifier to remove warning with gcc 3.4
* EOControl/EOEditingContext.m (-encodeWithCoder:,-initWithCoder:):
initial implementation of methods.
* EOControl/EOClassDescription.m (-snapshot): cast 'value' to get

View file

@ -35,6 +35,8 @@
#endif
#include "EOActionAssociation.h"
#include "SubclassFlags.h"
#include "EODisplayGroup.h"
@implementation EOActionAssociation
@ -87,17 +89,57 @@
- (void)establishConnection
{
[super establishConnection];
if ([self displayGroupForAspect: @"enabled"] != nil)
subclassFlags |= EnabledAspectMask;
if ([self displayGroupForAspect: @"argument"] != nil)
subclassFlags |= ArgumentAspectMask;
if ([self displayGroupForAspect: @"action"] != nil)
subclassFlags |= ActionAspectMask;
[_object setTarget:self];
[_object setAction: @selector(action:)];
}
- (void)breakConnection
{
subclassFlags = 0;
[super breakConnection];
}
- (void)subjectChanged
{
if (subclassFlags & EnabledAspectMask)
{
EODisplayGroup *dg = [self displayGroupForAspect:@"enabled"];
if ([dg contentsChanged] || [dg selectionChanged])
{
BOOL isEnabled;
isEnabled = [[self valueForAspect:@"enabled"] boolValue];
[_object setEnabled: isEnabled];
}
}
}
- (void)action: (id)sender
{
if (subclassFlags & ActionAspectMask)
{
id target = [[self displayGroupForAspect:@"action"] selectedObject];
SEL action;
action = NSSelectorFromString([self displayGroupKeyForAspect:@"action"]);
if (subclassFlags & ArgumentAspectMask)
{
id arg = [self displayGroupForAspect:@"argument"];
[target performSelector: action withObject: arg];
}
else
{
[target performSelector:action];
}
}
}
@end

View file

@ -0,0 +1,43 @@
/** -*-ObjC-*-
EOAspectConnector.h
Copyright (C) 2005 Free Software Foundation, Inc.
Author: Matt Rice <ratmice@yahoo.com>
This file is part of the GNUstep Database Library
The GNUstep Database Library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2,
or (at your option) any later version.
The GNUstep Database Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNUstep Database Library; see the file COPYING. If not,
write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <AppKit/NSNibConnector.h>
@class NSString;
@class EOAssociation;
@class EODisplayGroup;
@interface EOAspectConnector : NSNibConnector
{
NSString *_aspectName;
NSString *_destinationKey;
EOAssociation *_association;
EODisplayGroup *_dg;
}
- (id) initWithAssociation:(EOAssociation *)association aspectName:(NSString *)name;
- (NSString *)aspectName;
- (NSString *)destinationKey;
- (EOAssociation *)association;
@end

View file

@ -0,0 +1,85 @@
/** -*-ObjC-*-
EOAspectConnector.m
Copyright (C) 2004 Free Software Foundation, Inc.
Author: Matt Rice <ratmice@yahoo.com>
This file is part of the GNUstep Database Library
The GNUstep Database Library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2,
or (at your option) any later version.
The GNUstep Database Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNUstep Database Library; see the file COPYING. If not,
write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "EOAspectConnector.h"
#include <Foundation/NSCoder.h>
#include <EOInterface/EOAssociation.h>
@implementation EOAspectConnector : NSNibConnector
- (id) initWithAssociation:(EOAssociation *)association
aspectName:(NSString *)name
{
self = [super init];
ASSIGN(_aspectName, name);
ASSIGN(_association, association);
ASSIGN(_dg, [association displayGroupForAspect:_aspectName]);
ASSIGN(_destinationKey, [association displayGroupKeyForAspect:_aspectName]);
return self;
}
- (NSString *)aspectName
{
return _aspectName;
}
- (NSString *)destinationKey
{
return _destinationKey;
}
- (EOAssociation *)association
{
return _association;
}
- (id) initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
_association = RETAIN([coder decodeObject]);
_aspectName = RETAIN([coder decodeObject]);
_destinationKey = RETAIN([coder decodeObject]);
_dg = RETAIN([coder decodeObject]);
[_association bindAspect:_aspectName
displayGroup:_dg
key:_destinationKey];
return self;
}
- (void) encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:_association];
[coder encodeObject:_aspectName];
[coder encodeObject:[self destinationKey]];
[coder encodeObject:[_association displayGroupForAspect:[self aspectName]]];
}
- (void) establishConnection
{
[_association establishConnection];
}
@end

View file

@ -29,6 +29,8 @@
#include <Foundation/NSBundle.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSMapTable.h>
#include <Foundation/NSCoder.h>
#include <Foundation/NSException.h>
#else
#include <Foundation/Foundation.h>
#endif
@ -39,30 +41,6 @@
#include "EOAssociation.h"
/*++ TEMPORARY LOCAL DEFINITION ++*/
static inline NSArray *
GSObjCAllSubclassesOfClass(Class baseClass)
{
if (!baseClass)
return nil;
{
Class aClass;
NSMutableArray *result = [NSMutableArray array];
#ifdef GNU_RUNTIME
for (aClass = baseClass->subclass_list;
aClass;
aClass=aClass->sibling_class)
{
[result addObject:aClass];
[result addObjectsFromArray: GSObjCAllSubclassesOfClass(aClass)];
}
#endif
return AUTORELEASE([result copy]);
}
}
/*++ TEMPORARY LOCAL DEFINITION ++*/
@implementation EOAssociation
static NSArray *_emptyArray = nil;
static NSMutableArray *_associationClasses = nil;
@ -141,13 +119,13 @@ static NSMutableArray *_associationClasses = nil;
= RETAIN(GSObjCAllSubclassesOfClass([EOAssociation class]));
}
[_associationClasses count];
count = [_associationClasses count];
arr = [NSMutableArray arrayWithCapacity: count];
for (i = 0; i < count; i++)
{
cls = [_associationClasses objectAtIndex: i];
if ([cls isUsableWithObject: cls])
if ([cls isUsableWithObject: object])
{
[arr addObject: cls];
}
@ -177,16 +155,21 @@ static NSMutableArray *_associationClasses = nil;
- (id)init
{
return [self initWithObject: nil];
self = [self initWithObject: nil];
return self;
}
- (id)initWithCoder: (NSCoder *)coder
{
return [self init];
_object = [coder decodeObject];
self = [self initWithObject:_object];
return self;
}
- (void) encodeWithCoder: (NSCoder*)coder
{
[coder encodeObject:_object];
}
- (void)dealloc
@ -204,6 +187,7 @@ static NSMutableArray *_associationClasses = nil;
NSMapInsert(_displayGroupMap, aspectName, displayGroup);
NSMapInsert(_displayGroupKeyMap, aspectName, key);
}
- (void)establishConnection
{
if (_isConnected == NO)
@ -211,10 +195,11 @@ static NSMutableArray *_associationClasses = nil;
NSMapEnumerator displayGroupEnum;
EODisplayGroup *displayGroup;
Class EOObserverCenterClass = [EOObserverCenter class];
void *unusedKey;
displayGroupEnum = NSEnumerateMapTable(_displayGroupMap);
while (NSNextMapEnumeratorPair(&displayGroupEnum,
0, (void*)&displayGroup))
&unusedKey, (void*)&displayGroup))
{
[EOObserverCenterClass addObserver: self forObject: displayGroup];
}
@ -224,17 +209,20 @@ static NSMutableArray *_associationClasses = nil;
//TODO: cause _object to retain us
}
}
- (void)breakConnection
{
if (_isConnected)
{
NSMapEnumerator displayGroupEnum;
EODisplayGroup *displayGroup;
void *unusedKey;
Class EOObserverCenterClass = [EOObserverCenter class];
displayGroupEnum = NSEnumerateMapTable(_displayGroupMap);
while (NSNextMapEnumeratorPair(&displayGroupEnum,
0, (void *)&displayGroup))
&unusedKey, (void *)&displayGroup))
{
[EOObserverCenterClass removeObserver: self forObject: displayGroup];
}
@ -281,23 +269,76 @@ static NSMutableArray *_associationClasses = nil;
- (id)valueForAspect: (NSString *)aspectName
{
return nil;
EODisplayGroup *dg = [self displayGroupForAspect: aspectName];
NSString *key;
if (dg == nil)
return nil;
key = [self displayGroupKeyForAspect: aspectName];
if (key == nil)
return nil;
return [dg selectedObjectValueForKey: key];
}
- (BOOL)setValue: (id)value forAspect: (NSString *)aspectName
{
return NO;
EODisplayGroup *dg = [self displayGroupForAspect: aspectName];
NSString *key;
if (dg == nil)
return NO;
key = [self displayGroupKeyForAspect: aspectName];
if (key == nil)
return NO;
return [dg setSelectedObjectValue: value forKey: key];
}
- (id)valueForAspect: (NSString *)aspectName
atIndex: (unsigned int)index
{
return nil;
EODisplayGroup *dg = [self displayGroupForAspect: aspectName];
NSString *key;
if (dg == nil)
return nil;
key = [self displayGroupKeyForAspect: aspectName];
if (key == nil)
return NO;
return [dg valueForObjectAtIndex:index
key: key];
}
- (BOOL)setValue: (id)value
forAspect: (NSString *)aspectName
atIndex: (unsigned int)index
{
return NO;
EODisplayGroup *dg = [self displayGroupForAspect: aspectName];
NSString *key;
BOOL flag;
if (dg == nil)
{
return NO;
}
key = [self displayGroupKeyForAspect: aspectName];
if (key == nil)
{
return NO;
}
flag = [dg setValue: value forObjectAtIndex: index key: key];
return flag;
}
- (BOOL)shouldEndEditingForAspect: (NSString *)aspectName

View file

@ -27,6 +27,7 @@
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <AppKit/NSCell.h>
#include <AppKit/NSTableView.h>
#include <AppKit/NSTableColumn.h>
#include <AppKit/NSText.h>
@ -37,7 +38,7 @@
#include "EODisplayGroup.h"
#include "EOColumnAssociation.h"
#include "SubclassFlags.h"
@implementation EOColumnAssociation
@ -71,7 +72,7 @@
static NSArray *_keys = nil;
if (_keys == nil)
{
_keys = [NSArray new];
_keys = [[NSArray alloc] initWithObject: @"identifier"];
}
return _keys;
}
@ -101,23 +102,51 @@
- (void)establishConnection
{
EODisplayGroup *dg = [self displayGroupForAspect:@"value"];
[super establishConnection];
if (dg)
[EOTableViewAssociation bindToTableView: [[self object] tableView]
displayGroup: dg ];
if ([self displayGroupForAspect:@"value"] != nil)
subclassFlags |= ValueAspectMask;
[[self object] setIdentifier: self];
_enabledAspectBound = [self displayGroupForAspect:@"enabled"] != nil;
}
- (void)breakConnection
{
[super breakConnection];
_enabledAspectBound = NO;
}
- (void)subjectChanged
{
}
- (BOOL)endEditing
{
return NO;
BOOL flag = YES;
if (subclassFlags & ValueAspectMask)
{
NSTableView *tv = [[self object] tableView];
int row = tv ? [tv editedRow] : -1;
if (row != -1)
{
[[[self object] tableView] validateEditing];
[[self displayGroupForAspect:@"value"] associationDidEndEditing:self];
}
}
return flag;
}
- (void)setSortingSelector: (SEL)selector
{
_sortingSelector = selector;
}
- (SEL)sortingSelector
{
return _sortingSelector;
@ -129,20 +158,24 @@
forTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
[self setValue:object forAspect:@"value" atIndex:row];
}
- (id)tableView: (NSTableView *)tableView
objectValueForTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
return nil;
return [self valueForAspect:@"value" atIndex:row];
}
- (BOOL)tableView: (NSTableView *)tableView
shouldEditTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
return NO;
if (_enabledAspectBound)
return [[self valueForAspect:@"enabled"] boolValue];
return YES;
}
- (void)tableView: (NSTableView *)tableView
@ -150,25 +183,41 @@ shouldEditTableColumn: (NSTableColumn *)tableColumn
forTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
if (_enabledAspectBound)
[cell setEnabled:[[self valueForAspect:@"value" atIndex:row] boolValue]];
}
- (BOOL)control: (NSControl *)control
didFailToFormatString: (NSString *)string
errorDescription: (NSString *)description
{
return NO;
return [self shouldEndEditingForAspect: @"value"
invalidInput: string
errorDescription: description];;
}
- (BOOL)control: (NSControl *)control
isValidObject: (id)object
{
return NO;
BOOL flag;
/* TODO selected != editing figure this out */
flag = [self setValue:object forAspect:@"value"];
if (flag)
[[self displayGroupForAspect:@"value"] associationDidEndEditing:self];
return flag;
}
- (BOOL)control: (NSControl *)control
textShouldBeginEditing: (NSText *)fieldEditor
{
BOOL flag = [[self object] isEditable];
if (flag)
{
[[self displayGroupForAspect:@"value"] associationDidBeginEditing:self];
return YES;
}
return NO;
}
@end

View file

@ -33,6 +33,9 @@
#endif
#include "EOControlAssociation.h"
#include "EODisplayGroup.h"
#include "SubclassFlags.h"
#include <Foundation/NSRunLoop.h>
@implementation EOControlAssociation : EOGenericControlAssociation
@ -46,11 +49,14 @@
return @"EOControlAssoc";
}
- (void)establishConnection
- (void) establishConnection
{
[super establishConnection];
}
- (void)breakConnection
- (void) breakConnection
{
[super breakConnection];
}
- (NSControl *)control
@ -60,7 +66,7 @@
- (EOGenericControlAssociation *)editingAssociation
{
return nil;
return self;
}
@end

View file

@ -48,11 +48,11 @@
@interface EODisplayGroup : NSObject <NSCoding>
{
@private
EODataSource *_dataSource;
EODataSource *_dataSource; /*Retained*/
NSMutableArray *_allObjects;
NSMutableArray *_displayedObjects;
id _delegate;
id _delegate; /*Not Retained*/
NSArray *_selection;
NSArray *_sortOrdering;

View file

@ -29,27 +29,163 @@ RCS_ID("$Id$")
#ifdef GNUSTEP
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSException.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSSet.h>
#include <Foundation/NSString.h>
#include <Foundation/NSValue.h>
#include <AppKit/NSPanel.h>
#else
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>
#endif
#include <EOControl/EOClassDescription.h>
#include <EOControl/EODataSource.h>
#include <EOControl/EOEditingContext.h>
#include <EOControl/EOKeyValueCoding.h>
#include <EOControl/EOObserver.h>
#include <EOControl/EOQualifier.h>
#include <EOControl/EOSortOrdering.h>
#include "EODisplayGroup.h"
#include "EODeprecated.h"
#include "EOAssociation.h"
#include <limits.h>
#define DG_SHOULD_CHANGE_SELECTION_TO_IDX \
@selector(displayGroup:shouldChangeSelectionToIndexes:)
#define DG_DISPLAY_ARRAY_FOR_OBJECTS \
@selector(displayGroup:displayArrayForObjects:)
#define DG_SHOULD_DISPLAY_ALERT \
@selector(displayGroup:shouldDisplayAlertWithTitle:message:)
#define DG_DID_FETCH_OBJECTS \
@selector(displayGroup:didFetchObjects:)
#define DG_CREATE_OBJECT_FAILED \
@selector(displayGroup:createObjectFailedForDataSource:)
#define DG_SHOULD_INSERT_OBJECT \
@selector(displayGroup:shouldInsertObject:atIndex:)
#define DG_DID_INSERT_OBJECT \
@selector(displayGroup:didInsertObject:)
#define DG_DID_CHANGE_SELECTION \
@selector(displayGroupDidChangeSelection:)
/* undocumented notification */
NSString *EODisplayGroupWillFetchNotification = @"EODisplayGroupWillFetch";
@interface EOIEmptyArray : NSArray
@end
@implementation EOIEmptyArray : NSArray
- (void) release
{
[super release];
}
- (void) dealloc
{
[super dealloc];
}
- (id) autorelease
{
return [super autorelease];
}
@end
@interface GSInlineArray : NSObject
@end
@implementation GSInlineArray(foo)
- (void) release
{
}
- (void) dealloc
{
}
- (id) autorelease
{
return self;
}
@end
@interface NSArray (private)
- (NSArray *)indexesForObjectsIndenticalTo: (NSArray *)array;
@end
@implementation NSArray (private)
- (NSArray *)indexesForObjectsIndenticalTo: (NSArray *)array
{
unsigned idx, i, c = [array count];
NSMutableArray *indices = (id)[NSMutableArray arrayWithCapacity: c];
id object;
NSNumber *number;
for (i = 0; i < c; i++)
{
object = [array objectAtIndex: i];
idx = [self indexOfObjectIdenticalTo: object];
if (idx != NSNotFound)
{
/* We should cache all these numbers. */
number = [NSNumber numberWithUnsignedInt: idx];
[indices addObject: number];
}
}
return AUTORELEASE ([indices copy]);
}
@end
@interface EODisplayGroup (private)
- (void)_presentAlertWithTitle:(NSString *)title
message:(NSString *)message;
@end
@implementation EODisplayGroup (private)
- (void)_presentAlertWithTitle:(NSString *)title
message:(NSString *)message
{
if (_delegate
&& [_delegate respondsToSelector: DG_SHOULD_DISPLAY_ALERT]
&& [_delegate displayGroup: self
shouldDisplayAlertWithTitle: title
message: message] == NO)
{
return;
}
NSRunAlertPanel(title, message, nil, nil, nil);
}
@end
/**
* The EODisplayGoup keeps track of all enterprise objects from
* a particular EODataSource to coordinate their internal state
* with other objects such as UI elements and other EODisplayGroups.
* Commonly the data source is a EODatabaseDataSource (EOAccess)
* which manages the objects of a single entity for a specific
* editing context. The display group is connected to the UI elements
* or other display groups via EOAssociations. This framework is
* responsible to update the enterprise objects when the contents
* and state of the UI elements are changed and to update the UI
* elements when the state of the enterprise objects are changed.
*/
@implementation EODisplayGroup
/* TODO: Check default setting */
static NSString *_globalDefaultStringMatchOperator = nil;
static EOIEmptyArray *emptyArray;
static NSDictionary *emptyDictionary;
+ (void)initialize
{
if (emptyArray == nil)
{
emptyArray = [NSArray new];
emptyDictionary = [NSDictionary new];
}
}
static NSString *_globalDefaultStringMatchOperator = @"caseInsensitiveLike";
+ (NSString *)globalDefaultStringMatchOperator
{
return _globalDefaultStringMatchOperator;
@ -59,8 +195,7 @@ static NSString *_globalDefaultStringMatchOperator = nil;
ASSIGNCOPY(_globalDefaultStringMatchOperator, operator);
}
/* TODO: Check default setting */
static BOOL _globalDefaultForValidatesChangesImmediately= NO;
static BOOL _globalDefaultForValidatesChangesImmediately = NO;
+ (BOOL)globalDefaultForValidatesChangesImmediately
{
return _globalDefaultForValidatesChangesImmediately;
@ -74,6 +209,41 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
{
if ((self = [super init]))
{
_allObjects = [NSMutableArray new];
_displayedObjects = [NSMutableArray new];
_selection = emptyArray;
_observerNotificationBeginProxy
= [[EOObserverProxy alloc] initWithTarget: self
action:
@selector(_beginObserverNotification:)
priority: EOObserverPriorityFirst];
[EOObserverCenter addObserver: _observerNotificationBeginProxy
forObject: self];
_observerNotificationEndProxy
= [[EOObserverProxy alloc] initWithTarget: self
action:
@selector(_endObserverNotification:)
priority: EOObserverPrioritySixth];
[EOObserverCenter addObserver: _observerNotificationEndProxy
forObject: self];
_insertedObjectDefaultValues = emptyDictionary;
_queryMatch = [NSMutableDictionary new];
_queryMin = [NSMutableDictionary new];
_queryMax = [NSMutableDictionary new];
_queryOperator = [NSMutableDictionary new];
_defaultStringMatchOperator
= [[self class] globalDefaultStringMatchOperator];
_defaultStringMatchFormat = @"%@*";
_queryBindings = [NSMutableDictionary new];
_flags.selectsFirstObjectAfterFetch = YES;
_flags._initialized = YES;
}
return self;
}
@ -105,12 +275,38 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
[super dealloc];
}
- (id)initWithCoder: (NSCoder *)coder
- (id) initWithCoder:(NSCoder *)decoder
{
return [self init];
int tmpI;
self = [self init];
[self setDataSource:[decoder decodeObject]];
_delegate = [decoder decodeObject];
ASSIGN(_sortOrdering, [decoder decodeObject]);
ASSIGN(_qualifier, [decoder decodeObject]);
ASSIGN(_localKeys, [decoder decodeObject]);
/* encode _query*, _defaultStringMatch* ?? */
[decoder decodeValueOfObjCType: @encode(int) at: &tmpI];
_flags.selectsFirstObjectAfterFetch = tmpI;
[decoder decodeValueOfObjCType: @encode(int) at: &tmpI];
_flags.autoFetch = tmpI;
return self;
}
- (void)encodeWithCoder: (NSCoder *)coder
- (void)encodeWithCoder: (NSCoder *)encoder
{
int tmpI;
[encoder encodeObject: _dataSource];
[encoder encodeObject: _delegate];
[encoder encodeObject: _sortOrdering];
[encoder encodeObject: _qualifier];
[encoder encodeObject: _localKeys];
tmpI = _flags.selectsFirstObjectAfterFetch;
[encoder encodeValueOfObjCType: @encode(int) at: &tmpI];
tmpI = _flags.autoFetch;
[encoder encodeValueOfObjCType: @encode(int) at: &tmpI];
}
- (BOOL)fetchesOnLoad
@ -190,9 +386,62 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
{
return _dataSource;
}
- (void)setDataSource: (EODataSource *)dataSource
{
ASSIGN(_dataSource, dataSource);
if (_dataSource != dataSource)
{
EOEditingContext *context;
NSNotificationCenter *center;
center = [NSNotificationCenter defaultCenter];
if (_dataSource
&& (context = [_dataSource editingContext]))
{
[context removeEditor: self];
if ([context messageHandler] == self)
{
[context setMessageHandler: nil];
}
[center removeObserver: self
name: EOObjectsChangedInEditingContextNotification
object: context];
[center removeObserver: self
name: EOObjectsChangedInStoreNotification
object: context];
}
[self setObjectArray: nil];
ASSIGN(_dataSource, dataSource);
if ((context = [_dataSource editingContext]))
{
[context addEditor: self];
if ([context messageHandler] == nil)
{
[context setMessageHandler: self];
}
[center addObserver: self
selector: @selector(objectsInvalidatedInEditingContext:)
name: EOInvalidatedAllObjectsInStoreNotification
object: context];
[center addObserver: self
selector: @selector(objectsChangedInEditingContext:)
name: EOObjectsChangedInEditingContextNotification
object: context];
}
if (_delegate
&& [_delegate respondsToSelector:
@selector(displayGroupDidChangeDataSource:)])
{
[_delegate displayGroupDidChangeDataSource: self];
}
}
}
- (EOQualifier *)qualifier
@ -260,18 +509,76 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
- (BOOL)fetch
{
return NO;
BOOL flag = YES;
if (_dataSource
&& (flag = [self endEditing]))
{
if (_delegate
&& [_delegate respondsToSelector:
@selector(displayGroupShouldFetch:)])
{
flag = [_delegate displayGroupShouldFetch: self];
}
if (flag)
{
NSNotificationCenter *center;
NSArray *objects;
center = [NSNotificationCenter defaultCenter];
[center postNotificationName: EODisplayGroupWillFetchNotification
object: self];
if ([_dataSource respondsToSelector:
@selector(setQualifierBindings:)])
{
[_dataSource setQualifierBindings: _queryBindings];
}
objects = [_dataSource fetchObjects];
[self setObjectArray: objects];
if (_delegate
&& [_delegate respondsToSelector: DG_DID_FETCH_OBJECTS])
{
[_delegate displayGroup: self
didFetchObjects: objects];
}
flag = objects ? YES : NO;
}
}
return flag;
}
- (NSArray *)allObjects
{
return AUTORELEASE([_allObjects copy]);
return AUTORELEASE([[NSArray alloc] initWithArray:_allObjects copyItems:NO]);
}
- (void)setObjectArray: (NSArray *)objects
{
NSArray *oldSelection = [self selectedObjects];
BOOL selectFirstOnNoMatch = [self selectsFirstObjectAfterFetch];
if (objects == nil)
{
objects = emptyArray;
}
ASSIGN(_allObjects,
AUTORELEASE([objects mutableCopyWithZone: [self zone]]));
[self updateDisplayedObjects];
[self selectObjectsIdenticalTo: oldSelection
selectFirstOnNoMatch: selectFirstOnNoMatch];
[self redisplay];
}
- (NSArray *)displayedObjects
{
return AUTORELEASE([_displayedObjects copy]);
@ -279,33 +586,151 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
- (void)redisplay
{
/* TODO: Check this again! */
_flags.didChangeContents = YES;
[EOObserverCenter notifyObserversObjectWillChange: nil];
[self willChange];
}
- (void)updateDisplayedObjects
{
NSArray *oldSelection = [self selectedObjects];
volatile NSArray *displayedObjects = [self allObjects];
if (_delegate
&& [_delegate respondsToSelector: DG_DISPLAY_ARRAY_FOR_OBJECTS])
{
displayedObjects
= [_delegate displayGroup: self
displayArrayForObjects: (id)displayedObjects];
}
NS_DURING
{
displayedObjects
= [(id)displayedObjects filteredArrayUsingQualifier: _qualifier];
displayedObjects
= [(id)displayedObjects sortedArrayUsingKeyOrderArray: _sortOrdering];
}
NS_HANDLER
{
[self _presentAlertWithTitle:
@"Exception during sort or filter operatation."
message: [localException reason]];
}
NS_ENDHANDLER;
ASSIGN(_displayedObjects,
AUTORELEASE([(id)displayedObjects mutableCopyWithZone:[self zone]]));
[self selectObjectsIdenticalTo: oldSelection
selectFirstOnNoMatch: NO];
[self redisplay];
}
- (NSArray *)selectionIndexes
{
return nil;
return _selection;
}
- (BOOL)setSelectionIndexes: (NSArray *)selection
{
if ([self endEditing] && selection)
{
if (_delegate
&& [_delegate respondsToSelector: DG_SHOULD_CHANGE_SELECTION_TO_IDX]
&& [_delegate displayGroup: self
shouldChangeSelectionToIndexes: selection] == NO)
{
return NO;
}
else
{
NSNumber *number;
NSArray *newSelection;
NSMutableArray *newObjects;
id object;
unsigned c, i, count, index;
count = [_displayedObjects count];
c = [selection count];
newObjects = (id)[NSMutableArray arrayWithCapacity: c];
for (i = 0; i < c; i++)
{
number = [selection objectAtIndex: i];
index = [number unsignedIntValue];
object = index < count
? [_displayedObjects objectAtIndex: index] : nil;
if (object != nil)
{
[newObjects addObject: object];
}
}
ASSIGNCOPY(_selectedObjects, newObjects);
newSelection =
[_displayedObjects indexesForObjectsIndenticalTo: _selectedObjects];
/* don't release emptyArray */
(_selection == emptyArray) ? _selection = newSelection : ASSIGN(_selection, newSelection);
_flags.didChangeSelection = YES;
if ([_delegate respondsToSelector: DG_DID_CHANGE_SELECTION])
{
[_delegate displayGroupDidChangeSelection:self];
}
[self willChange];
return YES;
}
}
return NO;
}
- (BOOL)selectObject: (id)object
{
return NO;
NSArray *array;
if (object)
{
array = [NSArray arrayWithObject: object];
}
else
{
array = [NSArray array];
}
return [self selectObjectsIdenticalTo: array];
}
- (BOOL)selectObjectsIdenticalTo: (NSArray *)selection
{
return NO;
NSArray *indices;
if (selection && [selection count])
{
indices = [_displayedObjects indexesForObjectsIndenticalTo: selection];
if (indices && ![indices count])
{
indices = nil;
}
}
else
{
indices = selection;
}
return [self setSelectionIndexes: indices];
}
- (BOOL)selectObjectsIdenticalTo: (NSArray *)selection
selectFirstOnNoMatch: (BOOL)flag
{
return NO;
BOOL selectflag = [self selectObjectsIdenticalTo: selection];
if (selectflag && flag
&& [_selection count] == 0
&& [_displayedObjects count] != 0)
{
id object = [_displayedObjects objectAtIndex: 0];
selectflag = [self selectObject: object];
}
return selectflag;
}
- (BOOL)selectNext
@ -319,31 +744,130 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
- (BOOL)clearSelection
{
return NO;
return [self setSelectionIndexes: emptyArray];
}
- (NSArray *)selectedObjects
{
return nil;
return AUTORELEASE([_selectedObjects copy]);
}
- (void)setSelectedObjects: (NSArray *)objects
{
ASSIGN (_selectedObjects,
AUTORELEASE([objects mutableCopyWithZone: [self zone]]));
}
- (id)selectedObject
{
return nil;
id object = nil;
if ([_selectedObjects count])
{
object = [_selectedObjects objectAtIndex: 0];
}
return object;
}
- (void)setSelectedObject: (id)object
{
if (object)
{
[self selectObject: object];
}
else
{
[self clearSelection];
}
}
- (id)insertObjectAtIndex: (unsigned)index
{
return nil;
id object = nil;
if ([self endEditing])
{
object = [_dataSource createObject];
if (object == nil)
{
if (_delegate
&& [_delegate respondsToSelector: DG_CREATE_OBJECT_FAILED])
{
[_delegate displayGroup: self
createObjectFailedForDataSource: _dataSource];
}
else
{
[self _presentAlertWithTitle: @"EODisplayGroup"
message: @"Data source did not provide new object. "];
}
}
else
{
NSArray *defaultValueKeys = [_insertedObjectDefaultValues allKeys];
unsigned i, c = [defaultValueKeys count];
NSString *key;
id value;
/* We cannot use -takeValuesFromDictionary because
we need to call -takeValue:forKeyPath:. */
for (i = 0; i < c; i++)
{
key = [defaultValueKeys objectAtIndex: i];
value = [_insertedObjectDefaultValues valueForKeyPath: key];
[object smartTakeValue: value forKeyPath: key];
}
[self insertObject: object atIndex: index];
}
}
return object;
}
- (void)insertObject: (id)object atIndex: (unsigned)index
{
if ([self endEditing])
{
unsigned c = [_displayedObjects count];
if (c < index)
{
[NSException raise: NSRangeException
format: @"-[%@ %@]: Index %d is out of range %d",
NSStringFromClass([self class]),
NSStringFromSelector(_cmd),
index, c];
}
if (_delegate == nil
|| [_delegate respondsToSelector: DG_SHOULD_INSERT_OBJECT] == NO
|| [_delegate displayGroup: self
shouldInsertObject: object
atIndex: index])
{
NS_DURING
{
[_dataSource insertObject: object];
}
NS_HANDLER
{
[self _presentAlertWithTitle: @"EODisplayGroup insertion error"
message: [localException reason]];
return;
}
NS_ENDHANDLER;
/* It is safe to use the index for _allObjects but it seems
strange. OTOH _allObjects should probably be viewed as set. */
[_allObjects insertObject: object atIndex: index];
[_displayedObjects insertObject: object atIndex: index];
[self redisplay];
if (_delegate
&& [_delegate respondsToSelector: DG_DID_INSERT_OBJECT])
{
[_delegate displayGroup: self didInsertObject: object];
}
[self selectObjectsIdenticalTo: [NSArray arrayWithObject: object]];
}
}
}
- (NSDictionary *)insertedObjectDefaultValues
@ -352,7 +876,7 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
}
- (void)setInsertedObjectDefaultValues: (NSDictionary *)values
{
ASSIGNCOPY(_insertedObjectDefaultValues, values);
(_insertedObjectDefaultValues == emptyDictionary) ? _insertedObjectDefaultValues = [values copy] : ASSIGNCOPY(_insertedObjectDefaultValues, values);
}
- (BOOL)deleteObjectAtIndex: (unsigned)index
@ -361,6 +885,15 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
}
- (BOOL)deleteSelection
{
BOOL flag;
if ([self endEditing])
{
NSArray *selections = [self selectedObjects];
int c = [selections count];
int i;
for (i = 0; i < c; i++)
[[self dataSource] deleteObject: [selections objectAtIndex:i]];
}
return NO;
}
@ -384,15 +917,29 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
- (NSArray *)observingAssociations
{
return nil;
/* not sure if this should be using an EOQualifier somehow */
NSMutableArray *oa = [[NSMutableArray alloc] init];
NSArray *observers = [EOObserverCenter observersForObject: self];
int i, count;
count = [observers count];
for (i = 0; i < count; i ++)
{
id currentObject = [observers objectAtIndex:i];
if ([currentObject isKindOfClass:[EOAssociation class]])
[oa addObject: currentObject];
}
return AUTORELEASE(oa);
}
- (EOAssociation *)editingAssociation
{
return _editingAssociation;
}
- (BOOL)endEditing
{
return NO;
return _editingAssociation ? [_editingAssociation endEditing] : YES;
}
@end
@ -412,11 +959,18 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
{
[self fetch];
}
- (void)insert: (id)sender
{
unsigned idx = 0;
NSArray *selections = [self selectionIndexes];
NSNumber *index = [selections lastObject];
unsigned idx = [index unsignedIntValue];
if ([selections count])
{
NSNumber *index = [selections objectAtIndex: 0];
idx = [index unsignedIntValue];
}
[self insertObjectAtIndex: idx];
}
- (void)delete: (id)sender
@ -444,11 +998,11 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
- (BOOL)selectionChanged
{
return NO;
return _flags.didChangeSelection;
}
- (BOOL)contentsChanged
{
return NO;
return _flags.didChangeContents;
}
- (int)updatedObjectIndex
{
@ -457,32 +1011,65 @@ static BOOL _globalDefaultForValidatesChangesImmediately= NO;
- (id)valueForObject: (id)object key: (NSString *)key
{
return nil;
return [object valueForKeyPath: key];
}
- (id)selectedObjectValueForKey: (NSString *)key
{
return nil;
return [self valueForObject: [self selectedObject] key: key];
}
- (id)valueForObjectAtIndex: (unsigned)index key: (NSString *)key
{
return nil;
return [self valueForObject: [_displayedObjects objectAtIndex: index]
key: key];
}
- (BOOL)setValue: (id)value forObject: (id)object key: (NSString *)key
{
return NO;
SEL didSetValue = @selector(displayGroup:didSetValue:forKey:);
NSException *exception = nil;
NS_DURING
{
[object takeValue:value forKeyPath:key];
}
NS_HANDLER
/* use NSLog because -userInfo may contain useful information. */
NSLog(@"Exception in %@ name:%@ reason:%@ userInfo:%@", NSStringFromSelector(_cmd), [localException name], [localException reason], [localException userInfo]);
return NO;
NS_ENDHANDLER
if ([self validatesChangesImmediately])
exception = [object validateValue: &value forKey: key];
if (exception == nil && [_delegate respondsToSelector:didSetValue])
{
[_delegate displayGroup: self
didSetValue: value
forObject: object
key: key];
return YES;
}
if (exception)
{
/* use NSLog because -userInfo may contain useful information. */
NSLog(@"Exception in %@ name:%@ reason:%@ userInfo:%@", NSStringFromSelector(_cmd), [exception name], [exception reason], [exception userInfo]);
}
return (exception == nil);
}
- (BOOL)setSelectedObjectValue: (id)value forKey: (NSString *)key
{
return NO;
return [self setValue: value forObject: [self selectedObject] key: key];
}
- (BOOL)setValue: (id)value forObjectAtIndex: (unsigned)index
key: (NSString *)key
{
return NO;
return [self setValue: value
forObject: [_displayedObjects objectAtIndex: index]
key: key];
}
- (BOOL)enabledToSetSelectedObjectValueForKey:(NSString *)key
@ -500,9 +1087,12 @@ failedToValidateValue: (NSString *)value
}
- (void)associationDidBeginEditing: (EOAssociation *)association
{
ASSIGN(_editingAssociation,association);
}
- (void)associationDidEndEditing: (EOAssociation *)association
{
ASSIGN(_editingAssociation,nil);
}
@end
@ -514,6 +1104,7 @@ failedToValidateValue: (NSString *)value
}
- (void)editingContextWillSaveChanges: (EOEditingContext *)editingContext
{
}
@end
@ -535,3 +1126,27 @@ failedToValidateValue: (NSString *)value
}
@end
@implementation EODisplayGroup (notifications)
- (void)objectsInvalidatedInEditingContext: (NSNotification *)notif
{
}
- (void)objectsChangedInEditingContext: (NSNotification *)notif
{
_flags.didChangeContents = YES;
[self willChange];
}
@end
@implementation EODisplayGroup (GDL2Private)
- (void) _beginObserverNotification:(id)sender
{
/* FIXME what goes here?? */
}
- (void) _endObserverNotification:(id)sender
{
_flags.didChangeContents = NO;
_flags.didChangeSelection = NO;
[EOObserverCenter notifyObserversObjectWillChange:nil];
}
@end

View file

@ -23,9 +23,11 @@
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef GNUSTEP
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSString.h>
#include <AppKit/NSControl.h>
#include <AppKit/NSText.h>
@ -35,6 +37,8 @@
#endif
#include "EOControlAssociation.h"
#include "EODisplayGroup.h"
#include "SubclassFlags.h"
@implementation EOGenericControlAssociation
+ (NSArray *)aspects
@ -67,7 +71,7 @@
static NSArray *_keys = nil;
if (_keys == nil)
{
_keys = [[NSArray alloc] initWithObject: @"delegate"];
_keys = [[NSArray alloc] initWithObjects: @"delegate", @"target", nil];
}
return _keys;
}
@ -79,17 +83,64 @@
- (void)establishConnection
{
[super establishConnection];
if ([self displayGroupForAspect:@"value"] != nil)
subclassFlags |= ValueAspectMask;
if ([self displayGroupForAspect:@"enabled"] != nil)
subclassFlags |= EnabledAspectMask;
/* where does URL come from, accident or is it undocumented?? */
if ([self displayGroupForAspect:@"URL"] != nil)
subclassFlags |= URLAspectMask;
[[self control] setAction:@selector(_action:)];
[[self control] setTarget:self];
if ([[self object] respondsToSelector: @selector(setDelegate:)])
[[self object] setDelegate:self];
}
- (void)breakConnection
{
subclassFlags = 0;
[super breakConnection];
}
- (void)subjectChanged
{
if (subclassFlags & ValueAspectMask)
{
EODisplayGroup *dg = [self displayGroupForAspect:@"value"];
[[self control] setObjectValue: [self valueForAspect:@"value"]];
}
if (subclassFlags & EnabledAspectMask)
[[self control] setEnabled: [[self valueForAspect: @"enabled"] boolValue]];
[super subjectChanged];
}
- (void) _action: (id)sender
{
[self endEditing];
}
- (BOOL)endEditing
{
return NO;
BOOL flag = NO;
if (subclassFlags & ValueAspectMask)
{
flag = [self setValue: [[self control] objectValue] forAspect: @"value"];
[[self displayGroupForAspect:@"value"] associationDidEndEditing: self];
}
/* not sure if this is neccessary */
if (subclassFlags & EnabledAspectMask)
{
[[self displayGroupForAspect:@"enabled"] associationDidEndEditing: self];
}
return flag;
}
- (NSControl *)control
@ -118,7 +169,35 @@ errorDescription: (NSString *)description
- (BOOL)control: (NSControl *)control
textShouldBeginEditing: (NSText *)fieldEditor
{
return NO;
EODisplayGroup *dg = nil;
BOOL flag = NO;
/* inform display groups for all aspects that the editing association should
change if multiple aspects are bound to the same display group only do so
one time */
if (subclassFlags & ValueAspectMask)
{
dg = [self displayGroupForAspect:@"value"];
flag = [dg endEditing];
if (flag == YES)
{
[dg associationDidBeginEditing:self];
}
}
/* not sure if this is really neccessary */
if (subclassFlags & EnabledAspectMask)
{
EODisplayGroup *dg2 = [self displayGroupForAspect:@"enabled"];
if (dg2 != dg || flag == NO)
{
flag = [dg endEditing];
if (flag == YES)
{
[dg2 associationDidBeginEditing:self];
}
}
}
return flag;
}
@end

View file

@ -27,6 +27,7 @@
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <AppKit/NSButtonCell.h>
#include <AppKit/NSMatrix.h>
#else
#include <Foundation/Foundation.h>
@ -35,6 +36,8 @@
#include "EOControlAssociation.h"
#include "EOMatrixAssociation.h"
#include "EODisplayGroup.h"
#include "SubclassFlags.h"
@implementation EOMatrixAssociation
@ -103,13 +106,153 @@
- (void)establishConnection
{
EODisplayGroup *dg;
if ((dg = [self displayGroupForAspect:@"image"]))
{
subclassFlags |= ImageAspectMask;
NSArray *dispObj = [dg displayedObjects];
int c = [dispObj count];
int rows = [_object numberOfRows];
int i;
if (rows < c)
{
[_object renewRows:[[dg displayedObjects] count] columns:1];
}
else if (rows > c)
{
while (rows != c)
{
[_object removeRow:0];
rows--;
}
}
[_object sizeToFit];
for (i = 0; i < c; i++)
{
NSCell *cell = [_object cellAtRow:i column:0]; // column 0???
[cell setImage: [self valueForAspect:@"image" atIndex:i]];
}
}
if ((dg = [self displayGroupForAspect:@"title"]))
{
subclassFlags |= TitleAspectMask;
NSArray *dispObj = [dg displayedObjects];
int c = [dispObj count];
int rows = [_object numberOfRows];
int i;
if (rows < c)
{
[_object renewRows:[[dg displayedObjects] count] columns:1];
}
else if (rows > c)
{
while (rows != c)
{
[_object removeRow:0];
rows--;
}
}
for (i = 0; i < c; i++)
{
NSCell *cell = [_object cellAtRow:i column:0]; // column 0???
[cell setTitle: [self valueForAspect:@"title" atIndex:i]];
}
}
[_object sizeToFit];
[_object sizeToCells];
[_object setNeedsDisplay:YES];
if ([self displayGroupForAspect:@"enabled"])
{
subclassFlags |= EnabledAspectMask;
}
[super establishConnection];
[self subjectChanged];
}
- (void)breakConnection
{
subclassFlags = 0;
[super breakConnection];
}
- (void)subjectChanged
{
EODisplayGroup *dg;
if (subclassFlags & EnabledAspectMask)
{
dg = [self displayGroupForAspect:@"enabled"];
if ([dg selectionChanged] || [dg contentsChanged])
[_object setEnabled: [[self valueForAspect:@"enabled"] boolValue]];
}
if (subclassFlags & TitleAspectMask)
{
dg = [self displayGroupForAspect:@"title"];
if ([dg selectionChanged] || [dg contentsChanged])
{
NSArray *dispObj = [dg displayedObjects];
int c = [dispObj count];
int rows = [_object numberOfRows];
int i;
if (rows < c)
{
[_object renewRows:[[dg displayedObjects] count] columns:1];
}
else if (rows > c)
{
while (rows != c)
{
[_object removeRow:0];
rows--;
}
}
for (i = 0; i < c; i++)
{
NSCell *cell = [_object cellAtRow:i column:0]; // column 0???
[cell setTitle: [self valueForAspect:@"title" atIndex:i]];
}
[_object sizeToFit];
[_object sizeToCells];
[_object setNeedsDisplay:YES];
}
}
if (subclassFlags & ImageAspectMask)
{
dg = [self displayGroupForAspect:@"image"];
if ([dg selectionChanged] || [dg contentsChanged])
{
NSArray *dispObj = [dg displayedObjects];
int c = [dispObj count];
int rows = [_object numberOfRows];
int i;
if (rows < c)
{
[_object renewRows:[[dg displayedObjects] count] columns:1];
}
else if (rows > c)
{
while (rows != c)
{
[_object removeRow:0];
rows--;
}
}
for (i = 0; i < c; i++)
{
NSCell *cell = [_object cellAtRow:i column:0]; // column 0???
[cell setImage: [self valueForAspect:@"image" atIndex:i]];
}
[_object sizeToFit];
[_object sizeToCells];
[_object setNeedsDisplay:YES];
}
}
}
@end

View file

@ -34,7 +34,9 @@
#endif
#include "EOControlAssociation.h"
#include "EODisplayGroup.h"
#include "EOPopUpAssociation.h"
#include "SubclassFlags.h"
@implementation EOPopUpAssociation
@ -89,6 +91,12 @@
return _classes;
}
- (id) initWithObject:(id)obj
{
self = [super initWithObject:obj];
_tagValueForOther = -1;
return self;
}
+ (NSString *)displayName
{
@ -102,22 +110,161 @@
- (void)establishConnection
{
EODisplayGroup *dg;
[super establishConnection];
if ((dg = [self displayGroupForAspect:@"titles"]))
{
int i,c;
NSArray *dispObj;
NSMutableArray *titles = [[NSMutableArray alloc] init];
subclassFlags |= TitlesAspectMask;
dispObj = [dg displayedObjects];
c = [dispObj count];
[_object removeAllItems];
for (i = 0; i < c; i++)
{
[_object addItemWithTitle: [self valueForAspect:@"titles" atIndex:i]];
/* hmm used in _action.... :*/
[[_object lastItem] setRepresentedObject:[dg valueForObjectAtIndex:i
key:@"self"]];
}
}
if ([self displayGroupForAspect:@"selectedTitle"])
{
subclassFlags |= SelectedTitleAspectMask;
}
if ([self displayGroupForAspect:@"selectedTag"])
{
subclassFlags |= SelectedTagAspectMask;
}
if ([self displayGroupForAspect:@"selectedObject"])
{
subclassFlags |= SelectedObjectAspectMask;
}
if ([self displayGroupForAspect:@"enabled"])
{
subclassFlags |= EnabledAspectMask;
}
if (((subclassFlags & SelectedTitleAspectMask)
&& (subclassFlags & (SelectedTagAspectMask | SelectedObjectAspectMask)))
|| ((subclassFlags & SelectedTagAspectMask)
&& (subclassFlags & (SelectedObjectAspectMask | SelectedTitleAspectMask))))
{
[[NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@"more than one selectedTag, %@ %@",
@"selectedTitle, or selectedObject aspect bound to %@", self]
userInfo:nil] raise];
}
[_object setTarget:self];
[_object setAction:@selector(_action:)];
}
- (void)breakConnection
{
subclassFlags = 0;
[super breakConnection];
}
- (void)subjectChanged
{
EODisplayGroup *dg;
if (subclassFlags & TitlesAspectMask)
{
dg = [self displayGroupForAspect:@"titles"];
if ([dg contentsChanged])
{
int i,c;
NSArray *dispObj;
NSMutableArray *titles = [[NSMutableArray alloc] init];
NSString *key = [self displayGroupKeyForAspect:@"titles"];
dispObj = [dg displayedObjects];
c = [dispObj count];
[_object removeAllItems];
for (i = 0; i < c; i++)
{
[_object addItemWithTitle: [self valueForAspect:@"titles" atIndex:i]];
/* hmm */
[[_object lastItem] setRepresentedObject:[dg valueForObjectAtIndex:i
key:@"self"]];
}
}
}
if (subclassFlags & SelectedTagAspectMask)
{
dg = [self displayGroupForAspect:@"selectedTag"];
if ([dg selectionChanged] || [dg contentsChanged])
{
int tag = [[self valueForAspect:@"selectedTag"] intValue];
int index = [_object indexOfItemWithTag:tag];
[_object selectItemAtIndex:tag];
}
}
else if (subclassFlags & SelectedTitleAspectMask)
{
NSString *title;
dg = [self displayGroupForAspect:@"selectedTitle"];
if ([dg selectionChanged] || [dg contentsChanged])
{
[_object selectItemWithTitle:[self valueForAspect:@"selectedTitle"]];
}
}
else if (subclassFlags & SelectedObjectAspectMask)
{
dg = [self displayGroupForAspect:@"selectedObject"];
if ([dg selectionChanged] || [dg contentsChanged])
{
NSString *titlesKey;
NSString *newTitle;
titlesKey = [self displayGroupKeyForAspect:@"titles"];
newTitle = [[self valueForAspect:@"selectedObject"]
valueForKey:titlesKey];
[_object selectItemWithTitle:newTitle];
}
}
if (subclassFlags & EnabledAspectMask)
{
dg = [self displayGroupForAspect:@"enabled"];
if ([dg selectionChanged] || [dg contentsChanged])
[_object setEnabled: [[self valueForAspect:@"enabled"] boolValue]];
}
}
- (void)setTagValueForOther: (int)value
{
_tagValueForOther = value;
}
- (int)tagValueForOther
{
return _tagValueForOther;
}
- (void) _action:(id)sender
{
if (subclassFlags & SelectedTagAspectMask)
{
[self setValue: [NSNumber numberWithInt: [[_object itemAtIndex: [_object indexOfSelectedItem]] tag]]
forAspect:@"selectedTag"];
}
else if (subclassFlags & SelectedTitleAspectMask)
{
[self setValue: [_object titleOfSelectedItem] forAspect:@"selectedTitle"];
}
else if (subclassFlags & SelectedObjectAspectMask)
{
EODisplayGroup *titlesGroup = [self displayGroupForAspect:@"titles"];
id obj = [[_object itemAtIndex:[_object indexOfSelectedItem]] representedObject];
[self setValue: obj forAspect:@"selectedObject"];
}
}
@end

View file

@ -26,8 +26,9 @@
#ifdef GNUSTEP
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSValue.h>
#include <AppKit/NSMatrix.h>
#include <AppKit/NSButtonCell.h>
#else
#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>
@ -35,6 +36,35 @@
#include "EOControlAssociation.h"
#include "EORadioMatrixAssociation.h"
#include "SubclassFlags.h"
/* GNUstep specific */
@interface NSMatrix (RadioMatrixTitle)
-(BOOL) _selectCellWithTitle:(NSString *)title;
@end
@implementation NSMatrix (RadioMatrixTitle)
-(BOOL) _selectCellWithTitle:(NSString *)title
{
int i = _numRows;
while (i-- > 0)
{
int j = _numCols;
while (j-- > 0)
{
if ([[_cells[i][j] title] isEqual: title])
{
[self selectCellAtRow:i column:j];
return YES;
}
}
}
return NO;
}
@end
@implementation EORadioMatrixAssociation
@ -101,15 +131,60 @@
return @"selectedTitle";
}
- (id) initWithObject:(id)anObject
{
self = [super initWithObject:anObject];
_tagValueForOther = -1;
return self;
}
- (void)establishConnection
{
if ([self displayGroupForAspect: @"enabled"])
subclassFlags |= EnabledAspectMask;
if ([self displayGroupForAspect: @"selectedTag"])
subclassFlags |= SelectedTagAspectMask;
if ([self displayGroupForAspect: @"selectedTitle"])
subclassFlags |= SelectedTitleAspectMask;
[super establishConnection];
[_object setTarget: self];
[_object setAction: @selector(_action:)];
[_object setAllowsEmptySelection:YES];
}
- (void)breakConnection
{
[_object setTarget: nil];
[super breakConnection];
subclassFlags = 0;
}
- (void)subjectChanged
{
if (subclassFlags & EnabledAspectMask)
[[self object] setEnabled: [[self valueForAspect:@"enabled"] boolValue]];
if (subclassFlags & SelectedTagAspectMask)
{
NSCell *cell;
cell = [_object cellWithTag:[[self valueForAspect:@"selectedTag"] intValue]];
if (cell)
{
[_object selectCell:cell];
}
else
{
[_object selectCellWithTag:_tagValueForOther];
}
}
/* not sure if this is even supported in the original i suspect not */
if (subclassFlags & SelectedTitleAspectMask)
{
if (![_object _selectCellWithTitle:[self valueForAspect:@"selectedTitle"]])
[_object selectCellWithTag:_tagValueForOther];
}
}
- (void)setTagValueForOther: (int)value
@ -122,4 +197,15 @@
return _tagValueForOther;
}
- (void) _action:(id)sender
{
if (subclassFlags & SelectedTagAspectMask)
[self setValue: [NSNumber numberWithInt: [[_object selectedCell] tag]]
forAspect: @"selectedTag"];
if (subclassFlags & SelectedTitleAspectMask)
{
[self setValue: [[_object selectedCell] title]
forAspect: @"selectedTitle"];
}
}
@end

View file

@ -24,9 +24,11 @@
*/
#ifdef GNUSTEP
#include <Foundation/NSString.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSMapTable.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSString.h>
#include <Foundation/NSValue.h>
#include <AppKit/NSTableView.h>
#include <AppKit/NSTableColumn.h>
@ -37,8 +39,10 @@
#endif
#include "EOColumnAssociation.h"
#include "EODisplayGroup.h"
@implementation EOTableViewAssociation
static NSMapTable *tvAssociationMap;
+ (NSArray *)aspects
{
static NSArray *_aspects = nil;
@ -88,18 +92,77 @@
- (void)establishConnection
{
[super establishConnection];
_enabledAspectBound = [self displayGroupForAspect:@"enabled"] != nil;
_italicAspectBound = [self displayGroupForAspect:@"italic"] != nil;
_colorAspectBound = [self displayGroupForAspect:@"color"] != nil;
_boldAspectBound = [self displayGroupForAspect:@"bold"] != nil;
}
- (void)breakConnection
{
[super breakConnection];
_enabledAspectBound = NO;
_italicAspectBound = NO;
_colorAspectBound = NO;
_boldAspectBound = NO;
}
- (void)subjectChanged
{
EODisplayGroup *dg = [self displayGroupForAspect:@"source"];
/* this must be before selection changes in the case where the selected row
is not yet inserted */
if ([dg contentsChanged])
[[self object] reloadData];
if ([dg selectionChanged])
{
NSArray *selectionIndexes = RETAIN([dg selectionIndexes]);
unsigned int i, count, newSel;
count = [selectionIndexes count];
for (i = 0; i < count; i++)
{
int rowIndex = [[selectionIndexes objectAtIndex:i] intValue];
[[self object] selectRow: rowIndex
byExtendingSelection: (i != 0)]; /* don't extend the first selection */
[[self object] scrollRowToVisible:rowIndex];
}
}
}
+ (void)bindToTableView: (NSTableView *)tableView
displayGroup: (EODisplayGroup *)displayGroup
{
EOTableViewAssociation *assoc;
if (!tvAssociationMap)
{
tvAssociationMap = NSCreateMapTableWithZone(NSObjectMapKeyCallBacks,
NSNonRetainedObjectMapValueCallBacks,
0, [self zone]);
assoc = [[self allocWithZone:NSDefaultMallocZone()] initWithObject:tableView];
NSMapInsert(tvAssociationMap, (void *)tableView, (void *)assoc);
[assoc bindAspect:@"source" displayGroup:displayGroup key:@""];
[tableView setDataSource:assoc];
[tableView setDelegate:assoc];
[assoc establishConnection];
return;
}
assoc = (EOTableViewAssociation *)NSMapGet(tvAssociationMap, tableView);
if (!assoc)
{
assoc = [[self allocWithZone:NSDefaultMallocZone()] initWithObject:tableView];
[assoc bindAspect:@"source" displayGroup:displayGroup key:@""];
[tableView setDataSource:assoc];
[tableView setDelegate:assoc];
[assoc establishConnection];
NSMapInsert(tvAssociationMap, tableView, assoc);
}
}
- (BOOL)sortsByColumnOrder
@ -113,12 +176,21 @@
- (EOColumnAssociation *)editingAssociation
{
return nil;
int editedColumn = [[self object] editedColumn];
if (editedColumn == -1)
{
return nil;
}
else
{
return [[[[self object] tableColumns] objectAtIndex:editedColumn] identifier];
}
}
- (int)numberOfRowsInTableView: (NSTableView *)tableView
{
return 0;
return [[[self displayGroupForAspect:@"source"] displayedObjects] count];
}
- (void)tableView: (NSTableView *)tableView
@ -126,20 +198,33 @@
forTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
[(EOColumnAssociation *)[tableColumn identifier]
tableView: tableView
setObjectValue: object
forTableColumn: tableColumn
row: row];
}
- (id)tableView: (NSTableView *)tableView
objectValueForTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
return nil;
id object;
object = [[tableColumn identifier] tableView: tableView
objectValueForTableColumn: tableColumn
row: row];
return object;
}
- (BOOL)tableView: (NSTableView *)tableView
shouldEditTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
return NO;
if (_enabledAspectBound)
if ([[self valueForAspect: @"enabled" atIndex:row] boolValue] == NO)
return NO;
return [[tableColumn identifier] tableView:tableView shouldEditTableColumn:tableColumn row:row];
}
- (void)tableView: (NSTableView *)tableView
@ -147,29 +232,67 @@ shouldEditTableColumn: (NSTableColumn *)tableColumn
forTableColumn: (NSTableColumn *)tableColumn
row: (int)row
{
if (_enabledAspectBound)
[cell setEnabled: [[self valueForAspect:@"enabled" atIndex: row] boolValue]];
/* maybe these should setup an attributed string */
if (_italicAspectBound)
; /* TODO */
if (_boldAspectBound)
; /* TODO */
if (_colorAspectBound)
{
if ([cell respondsToSelector:@selector(setTextColor:)])
[cell setTextColor: [self valueForAspect:@"color" atIndex:row]];
}
}
- (void)tableViewSelectionDidChange: (NSNotification *)notification
{
EODisplayGroup *dg = [self displayGroupForAspect:@"source"];
NSMutableArray *selectionIndices = [[NSMutableArray alloc] init];
NSTableView *tv = [notification object];
NSEnumerator *selectionEnum = [tv selectedRowEnumerator];
id index;
while ((index = [selectionEnum nextObject]))
{
[selectionIndices addObject:index];
}
[dg setSelectionIndexes: AUTORELEASE(selectionIndices)];
}
- (BOOL)control: (NSControl *)control
didFailToFormatString: (NSString *)string
errorDescription: (NSString *)description
{
return NO;
return [[self editingAssociation]
control: control
didFailToFormatString: string
errorDescription: description];
}
- (BOOL)control: (NSControl *)control
isValidObject: (id)object
{
return NO;
return [[self editingAssociation] control: control
isValidObject: object];
}
- (BOOL)control: (NSControl *)control
textShouldBeginEditing: (NSText *)fieldEditor
{
return NO;
return [[self editingAssociation] control: control
textShouldBeginEditing: fieldEditor];
}
- (void)controlTextDidEndEditing:(NSNotification *)aNotification
{
[[self displayGroupForAspect:@"source"] endEditing];
}
- (void) dealloc
{
NSMapRemove(tvAssociationMap, self);
[super dealloc];
}
@end

View file

@ -35,7 +35,9 @@
#include <AppKit/AppKit.h>
#endif
#include "EODisplayGroup.h"
#include "EOTextAssociation.h"
#include "SubclassFlags.h"
@implementation EOTextAssociation
@ -74,6 +76,7 @@
}
return _keys;
}
+ (BOOL)isUsableWithObject: (id)object
{
/* NB: NSCStringText is obsolete. So unless someone asks for it,
@ -89,22 +92,94 @@
- (void)establishConnection
{
[super establishConnection];
if ([self displayGroupForAspect:@"value"])
{
subclassFlags |= ValueAspectMask;
if (subclassFlags & ValueAspectMask)
{
id value = [self valueForAspect:@"value"];
if ([value isKindOfClass: [NSString class]])
{
[_object setString:value];
}
else if ([value isKindOfClass: [NSData class]])
{
int oldLength = [[_object string] length];
[_object replaceCharactersInRange:NSMakeRange(0,oldLength)
withRTF: value];
}
}
}
if ([self displayGroupForAspect:@"editable"])
{
subclassFlags |= EditableAspectMask;
[_object setEditable: [[self valueForAspect:@"editable"] boolValue]];
}
[_object setDelegate:self];
}
- (void)breakConnection
{
subclassFlags = 0;
[super breakConnection];
}
- (void)subjectChanged
{
if (subclassFlags & ValueAspectMask)
{
id value = [self valueForAspect:@"value"];
if ([value isKindOfClass: [NSString class]])
{
[_object setString:value];
}
else if ([value isKindOfClass: [NSData class]])
{
int oldLength = [[_object string] length];
[_object replaceCharactersInRange:NSMakeRange(0,oldLength)
withRTF: value];
}
}
if (subclassFlags & EditableAspectMask)
{
[_object setEditable: [[self valueForAspect:@"editable"] boolValue]];
}
}
- (BOOL)endEditing
{
return NO;
BOOL flag = NO;
if (subclassFlags & ValueAspectMask)
{
BOOL isRichText = [_object isRichText];
id value;
if (isRichText)
{
value = [_object RTFFromRange:NSMakeRange(0,[[_object string] length])];
}
else
{
value = [[_object string] copy];
}
flag = [self setValue: value forAspect:@"value"];
if (flag)
{
[[self displayGroupForAspect:@"value"] associationDidEndEditing: self]; }
}
/* dunno if this is neccesary */
if (flag && (subclassFlags & EditableAspectMask))
{
[[self displayGroupForAspect:@"editable"] associationDidEndEditing:self];
}
return flag;
}
- (BOOL)control: (NSControl *)control isValidObject: (id)object
{
return NO;
/* FIXME */
NSLog(@"FIXME %@",NSStringFromSelector(_cmd));
return YES;
}
- (void)control: (NSControl *)control
@ -115,11 +190,20 @@ errorDescription: (NSString *)description
- (BOOL)textShouldBeginEditing: (NSText *) text
{
return NO;
EODisplayGroup *dg = [self displayGroupForAspect:@"value"];
BOOL flag = [dg endEditing];
if (flag == YES)
{
[dg associationDidBeginEditing:self];
}
return flag;
}
- (BOOL)textShouldEndEditing: (NSText *)text
{
return NO;
[self endEditing];
[[self displayGroupForAspect:@"value"] associationDidEndEditing:self];
return YES;
}
@end

View file

@ -27,53 +27,55 @@ include $(GNUSTEP_MAKEFILES)/common.make
include ../Version
# The library to be compiled
LIBRARY_NAME=EOInterface
NATIVE_LIBRARY_NAME=EOInterface
# The C source files to be compiled
EOInterface_C_FILES =
# The Objective-C source files to be compiled
EOInterface_OBJC_FILES = \
EOActionAssociation.m \
EOActionCellAssociation.m \
EOActionInsertionAssociation.m \
EOAssociation.m \
EOColumnAssociation.m \
EOComboBoxAssociation.m \
EOControlAssociation.m \
EODetailSelectionAssociation.m \
EODisplayGroup.m \
EOGenericControlAssociation.m \
EOMasterCopyAssociation.m \
EOMasterDetailAssociation.m \
EOMasterPeerAssociation.m \
EOMatrixAssociation.m \
EOPickTextAssociation.m \
EOPopUpAssociation.m \
EORadioMatrixAssociation.m \
EORecursiveBrowserAssociation.m \
EOTableViewAssociation.m \
EOTextAssociation.m \
NSImage+Additions.m
EOInterface_OBJC_FILES = \
EOActionAssociation.m \
EOActionCellAssociation.m \
EOActionInsertionAssociation.m \
EOAssociation.m \
EOColumnAssociation.m \
EOComboBoxAssociation.m \
EOControlAssociation.m \
EODetailSelectionAssociation.m \
EODisplayGroup.m \
EOGenericControlAssociation.m \
EOMasterCopyAssociation.m \
EOMasterDetailAssociation.m \
EOMasterPeerAssociation.m \
EOMatrixAssociation.m \
EOPickTextAssociation.m \
EOPopUpAssociation.m \
EORadioMatrixAssociation.m \
EORecursiveBrowserAssociation.m \
EOTableViewAssociation.m \
EOTextAssociation.m \
NSImage+Additions.m \
EOAspectConnector.m
EOInterface_HEADER_FILES = \
EOActionAssociation.h \
EOActionInsertionAssociation.h \
EOAssociation.h \
EOColumnAssociation.h \
EOComboBoxAssociation.h \
EOControlAssociation.h \
EODetailSelectionAssociation.h \
EODisplayGroup.h \
EOInterface.h \
EOMasterCopyAssociation.h \
EOMasterDetailAssociation.h \
EOMatrixAssociation.h \
EOPickTextAssociation.h \
EOPopUpAssociation.h \
EORadioMatrixAssociation.h \
EORecursiveBrowserAssociation.h \
EOTextAssociation.h
EOInterface_HEADER_FILES = \
EOActionAssociation.h \
EOActionInsertionAssociation.h \
EOAssociation.h \
EOColumnAssociation.h \
EOComboBoxAssociation.h \
EOControlAssociation.h \
EODetailSelectionAssociation.h \
EODisplayGroup.h \
EOInterface.h \
EOMasterCopyAssociation.h \
EOMasterDetailAssociation.h \
EOMatrixAssociation.h \
EOPickTextAssociation.h \
EOPopUpAssociation.h \
EORadioMatrixAssociation.h \
EORecursiveBrowserAssociation.h \
EOTextAssociation.h \
EOAspectConnector.h
gdl2_AUTOGSDOC_HEADERS = $(EOInterface_HEADER_FILES)
gdl2_AUTOGSDOC_SOURCE = $(EOInterface_OBJC_FILES)
@ -98,7 +100,7 @@ gdl2_AGSDOC_FLAGS = \
-include GNUmakefile.local
include $(GNUSTEP_MAKEFILES)/library.make
include $(GNUSTEP_MAKEFILES)/native-library.make
# Only build the doc if doc=yes was passed on the command line
ifeq ($(doc),yes)
include $(GNUSTEP_MAKEFILES)/documentation.make

View file

@ -57,7 +57,7 @@ ADDITIONAL_INSTALL_DIRS =
# all the libraries the target library depends upon.
ifneq ($(FOUNDATION_LIBRARY_NAME),)
LIBRARIES_DEPEND_UPON = -l$(FOUNDATION_LIBRARY_NAME)
LIBRARIES_DEPEND_UPON = $(FND_LIBS) $(GUI_LIBS)
endif
ifneq ($(FOUNDATION_LIB),gnu)
LIBRARIES_DEPEND_UPON += -lgnustep-baseadd

145
EOInterface/SubclassFlags.h Normal file
View file

@ -0,0 +1,145 @@
/** -*-ObjC-*-
SubclassFlags.h
Copyright (C) 2004 Free Software Foundation, Inc.
Author: Matt Rice <ratmice@yahoo.com>
This file is part of the GNUstep Database Library
The GNUstep Database Library is free software; you can redistribute it
and/or modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2,
or (at your option) any later version.
The GNUstep Database Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNUstep Database Library; see the file COPYING. If not,
write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
please be careful when adding stuff; as this is hideous.
there is one section for every class directly desending from EOAssociation
which includes flags from its subclasses.
*/
#define EnabledAspectMask 0x1
/* EOTableViewAssociation:5 (enabled, italic, source, textColor, bold) */
// EnabledAspectMask 0x1
#define SourceAspectMask 0x2
#define ItalicAspectMask 0x4
#define TextColorAspectMask 0x8
#define BoldAspectMask 0x10
/* EOActionInsertionAssociation:3 (source, enabled, destination) */
// EnabledAspectMask 0x1
// SourceAspectMask 0x2
#define DestinationAspectMask 0x4
/* EOActionAssociation:3 (action, enabled, argument) */
// EnabledAspectMask 0x1
#define ActionAspectMask 0x2
#define ArgumentAspectMask 0x4
/* EOColumnAssociation:2 (value, enabled) */
// EnabledAspectMask 0x1
#define ValueAspectMask 0x2
/* EOGenericControlAssociation:3 (enabled, URL, value) */
// EnabledAspectMask 0x1
// ValueAspectMask 0x2
#define URLAspectMask 0x4
/* EOTextAssociation:3 (editable, URL, value) */
// EnabledAspectMask 0x1
// ValueAspectMask 0x2
#define EditableAspectMask 0x4
/* EORecursiveBrowserAssociation:4 (isLeaf, rootChildren, children, title) */
#define IsLeafAspectMask 0x1
#define RootChildrenAspectMask 0x2
#define TitleAspectMask 0x4
#define ChildrenAspectMask 0x8
/* EODetailSelectionAssociation:1 (selectedObjects) */
#define SelectedObjectsAspectMask 0x1
/* EOMatrixAssociation:3 (enabled, title, image) */
// EnabledAspectMask 0x1
#define ImageAspectMask 0x2
// TitleAspectMask 0x4
/* EOMasterCopyAssociation:1 (parent) */
/* EOMasterDetailAssociation:1 (parent) */
#define ParentAspectMask 0x1
/* EOPickTextAssociation:3 (matchKey2, matchKey3, matchKey1) */
#define MatchKey1AspectMask 0x0
#define MatchKey2AspectMask 0x1
#define MatchKey3AspectMask 0x2
/* EORadioMatrixAssociation:3 (enabled, selectedTitle, selectedTag) */
// EnabledAspectMask 0x1
#define SelectedTitleAspectMask 0x2
#define SelectedTagAspectMask 0x4
/* EOComboBoxAssociation:4 (enabled, selectedObject, titles, selectedTitle) */
// EnabledAspectMask 0x1
// SelectedTitleAspectMask 0x2
#define SelectedObjectAspectMask 0x8
#define TitlesAspectMask 0x10
/* EOPopUpAssociation:5 (enabled, selectedTag, selectedObject, titles, selectedTitle) */
// EnabledAspectMask 0x1
// SelectedTitleAspectMask 0x2
// SelectedTagAspectMask 0x4
// SelectedObjectAspectMask 0x8
// TitlesAspectMask 0x10
#ifdef HELPFUL_COMMENT_MAKER
#include <GNUstepBase/GSObjCRuntime.h>
#include <Foundation/Foundation.h>
#include <EOInterface/EOAssociation.h>
int main()
{
CREATE_AUTORELEASE_POOL(arp);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSArray *a1;
int i;
a1 = GSObjCDirectSubclassesOfClass([EOAssociation class]);
for (i = 0; i < [a1 count]; i++)
{
int n;
NSArray *a2;
NSMutableSet *aSet = [[NSMutableSet alloc] init];
a2 = GSObjCAllSubclassesOfClass([a1 objectAtIndex:i]);
[aSet addObjectsFromArray:[[a1 objectAtIndex:i] aspects]];
for (n = 0; n < [a2 count]; n++)
{
[aSet addObjectsFromArray:[[a2 objectAtIndex:n] aspects]];
}
[dict setObject:aSet forKey:[a1 objectAtIndex:i]];
}
for (i = 0; i < [dict count]; i++)
{
id key = [[dict allKeys] objectAtIndex:i];
NSArray *arr;
int n;
arr = [[dict objectForKey:key] allObjects];
GSPrintf(stdout, @"/* %@:%i %@ */\n", key, [arr count], arr);
}
}
#endif