Merge pull request #170 from gnustep/NSDictionaryController2_branch

This commit is contained in:
Gregory Casamento 2023-03-24 18:33:52 -04:00 committed by GitHub
commit e64d8d4b02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 745 additions and 67 deletions

View file

@ -167,6 +167,7 @@
#import <AppKit/NSDockTile.h> #import <AppKit/NSDockTile.h>
#import <AppKit/NSDocument.h> #import <AppKit/NSDocument.h>
#import <AppKit/NSDocumentController.h> #import <AppKit/NSDocumentController.h>
#import <AppKit/NSDictionaryController.h>
#import <AppKit/NSDrawer.h> #import <AppKit/NSDrawer.h>
#import <AppKit/NSFileWrapperExtensions.h> #import <AppKit/NSFileWrapperExtensions.h>
#import <AppKit/NSFontAssetRequest.h> #import <AppKit/NSFontAssetRequest.h>

View file

@ -0,0 +1,151 @@
/* Definition of class NSDictionaryController
Copyright (C) 2021 Free Software Foundation, Inc.
By: Gregory John Casamento
Date: 16-10-2021
This file is part of the GNUstep Library.
This 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.1 of the License, or (at your option) any later version.
This 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 this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110 USA.
*/
#ifndef _NSDictionaryController_h_GNUSTEP_GUI_INCLUDE
#define _NSDictionaryController_h_GNUSTEP_GUI_INCLUDE
#import <AppKit/NSArrayController.h>
#if OS_API_VERSION(MAC_OS_X_VERSION_10_11, GS_API_LATEST)
APPKIT_EXPORT_CLASS
@interface NSDictionaryControllerKeyValuePair : NSObject
{
NSString *_key;
id _value;
NSString *_localizedKey;
BOOL _explicitlyIncluded;
}
- (instancetype) init;
/**
* Returns a copy of the key
*/
- (NSString *) key;
- (void) setKey: (NSString *)key;
/**
* Returns a strong reference to the value
*/
- (id) value;
- (void) setValue: (id)value;
/**
* Localized key copy
*/
- (NSString *) localizedKey;
- (void) setLocalizedKey: (NSString *)localizedKey;
/**
* Is this key value pair included in the underlying dictionary.
*/
- (BOOL) isExplicitlyIncluded;
- (void) setExplicitlyIncluded: (BOOL)flag;
@end
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GS_API_LATEST)
#if defined(__cplusplus)
extern "C" {
#endif
APPKIT_EXPORT_CLASS
@interface NSDictionaryController : NSArrayController
{
NSMutableDictionary *_contentDictionary;
NSString *_initialKey;
id _initialValue;
NSArray *_includedKeys;
NSArray *_excludedKeys;
NSDictionary *_localizedKeyDictionary;
NSString *_localizedKeyTable;
NSUInteger _count;
}
/**
* Returns a new object conforming to the NSDictionaryControllerKeyValuePair
* informal protocol. Overriden from superclass.
*/
- (NSDictionaryControllerKeyValuePair *) newObject;
/**
* Returns a copy of the initialKey.
*/
- (NSString *) initialKey;
- (void) setInitialKey: (NSString *)initialKey;
/**
* Returns a strong reference to the initialValue.
*/
- (id) initialValue;
- (void) setInitialValue: (id)value;
/**
* Returns a copy of the included keys. Included keys are always represented by a
* key value pair whether or not they are included in the underlying dictionary.
*/
- (NSArray *) includedKeys;
- (void) setIncludedKeys: (NSArray *)includedKeys;
/**
* Returns a copy of the included keys. Included keys are always represented by a
* key value pair whether or not they are included in the underlying dictionary.
*/
- (NSArray *) excludedKeys;
- (void) setExcludedKeys: (NSArray *)excludedKeys;
/**
* Returns a copy of the localized key dictionary.
*/
- (NSDictionary *) localizedKeyDictionary;
/**
* Sets the localized key dictionary.
*/
- (void) setLocalizedKeyDictionary: (NSDictionary *)dict;
/**
* Returns the keyTable which is the dictionary in strings format.
*/
- (NSString *) localizedKeyTable;
/**
* Sets the localized keyTable in strings format.
*/
- (void) setLocalizedKeyTable: (NSString *)keyTable;
@end
#if defined(__cplusplus)
}
#endif
#endif /* GS_API_MACOSX */
#endif /* _NSDictionaryController_h_GNUSTEP_GUI_INCLUDE */

View file

@ -107,14 +107,20 @@ APPKIT_EXPORT id NSNotApplicableMarker;
APPKIT_EXPORT NSString *NSAlignmentBinding; APPKIT_EXPORT NSString *NSAlignmentBinding;
APPKIT_EXPORT NSString *NSContentArrayBinding; APPKIT_EXPORT NSString *NSContentArrayBinding;
APPKIT_EXPORT NSString *NSContentBinding; APPKIT_EXPORT NSString *NSContentBinding;
APPKIT_EXPORT NSString *NSContentDictionaryBinding;
APPKIT_EXPORT NSString *NSContentObjectBinding; APPKIT_EXPORT NSString *NSContentObjectBinding;
APPKIT_EXPORT NSString *NSContentValuesBinding; APPKIT_EXPORT NSString *NSContentValuesBinding;
APPKIT_EXPORT NSString *NSEditableBinding; APPKIT_EXPORT NSString *NSEditableBinding;
APPKIT_EXPORT NSString *NSEnabledBinding; APPKIT_EXPORT NSString *NSEnabledBinding;
APPKIT_EXPORT NSString *NSExcludedKeysBinding;
APPKIT_EXPORT NSString *NSFontBinding; APPKIT_EXPORT NSString *NSFontBinding;
APPKIT_EXPORT NSString *NSFontNameBinding; APPKIT_EXPORT NSString *NSFontNameBinding;
APPKIT_EXPORT NSString *NSFontSizeBinding; APPKIT_EXPORT NSString *NSFontSizeBinding;
APPKIT_EXPORT NSString *NSHiddenBinding; APPKIT_EXPORT NSString *NSHiddenBinding;
APPKIT_EXPORT NSString *NSIncludedKeysBinding;
APPKIT_EXPORT NSString *NSInitialKeyBinding;
APPKIT_EXPORT NSString *NSInitialValueBinding;
APPKIT_EXPORT NSString *NSLocalizedKeyDictionaryBinding;
APPKIT_EXPORT NSString *NSSelectedIndexBinding; APPKIT_EXPORT NSString *NSSelectedIndexBinding;
APPKIT_EXPORT NSString *NSSelectedObjectBinding; APPKIT_EXPORT NSString *NSSelectedObjectBinding;
APPKIT_EXPORT NSString *NSSelectedTagBinding; APPKIT_EXPORT NSString *NSSelectedTagBinding;

View file

@ -1,7 +1,6 @@
MISSING HEADERS ( * = difficult, - = quick, + = placeholder, x = won't do ) MISSING HEADERS ( * = difficult, - = quick, + = placeholder, x = won't do )
--- ---
> NSATSTypesetter.h + > NSATSTypesetter.h +
> NSDictionaryController.h -
> NSDiffableDataSource.h * > NSDiffableDataSource.h *
> NSDraggingItem.h - > NSDraggingItem.h -
> NSDraggingSession.h - > NSDraggingSession.h -

View file

@ -103,6 +103,7 @@ NSDataLinkManager.m \
NSDataLinkPanel.m \ NSDataLinkPanel.m \
NSDatePicker.m \ NSDatePicker.m \
NSDatePickerCell.m \ NSDatePickerCell.m \
NSDictionaryController.m \
NSDockTile.m \ NSDockTile.m \
NSDocument.m \ NSDocument.m \
NSDocumentController.m \ NSDocumentController.m \
@ -435,6 +436,7 @@ NSDataLinkManager.h \
NSDataLinkPanel.h \ NSDataLinkPanel.h \
NSDatePicker.h \ NSDatePicker.h \
NSDatePickerCell.h \ NSDatePickerCell.h \
NSDictionaryController.h \
NSDockTile.h \ NSDockTile.h \
NSDocument.h \ NSDocument.h \
NSDocumentController.h \ NSDocumentController.h \

View file

@ -79,7 +79,7 @@
NSArray *result = [_array objectsAtIndexes: indexes]; NSArray *result = [_array objectsAtIndexes: indexes];
return AUTORELEASE([[GSObservableArray alloc] return AUTORELEASE([[GSObservableArray alloc]
initWithArray: result]); initWithArray: result]);
} }
- (id) valueForKey: (NSString*)key - (id) valueForKey: (NSString*)key
@ -93,7 +93,7 @@
// object until this gets fixed. // object until this gets fixed.
//return AUTORELEASE([[GSObservableArray alloc] //return AUTORELEASE([[GSObservableArray alloc]
return ([[GSObservableArray alloc] return ([[GSObservableArray alloc]
initWithArray: result]); initWithArray: result]);
} }
return result; return result;
@ -104,7 +104,7 @@
NSArray * result = [_array arrayByAddingObject: anObject]; NSArray * result = [_array arrayByAddingObject: anObject];
return AUTORELEASE([[GSObservableArray alloc] return AUTORELEASE([[GSObservableArray alloc]
initWithArray: result]); initWithArray: result]);
} }
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray - (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray
@ -112,7 +112,7 @@
NSArray * result = [_array arrayByAddingObjectsFromArray: anotherArray]; NSArray * result = [_array arrayByAddingObjectsFromArray: anotherArray];
return AUTORELEASE([[GSObservableArray alloc] return AUTORELEASE([[GSObservableArray alloc]
initWithArray: result]); initWithArray: result]);
} }
- (void) addObserver: (NSObject*)anObserver - (void) addObserver: (NSObject*)anObserver
@ -124,9 +124,9 @@
[self addObserver: anObserver [self addObserver: anObserver
toObjectsAtIndexes: indexes toObjectsAtIndexes: indexes
forKeyPath: aPath forKeyPath: aPath
options: options options: options
context: aContext]; context: aContext];
} }
- (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath - (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath
@ -135,7 +135,7 @@
[self removeObserver: anObserver [self removeObserver: anObserver
fromObjectsAtIndexes: indexes fromObjectsAtIndexes: indexes
forKeyPath: aPath]; forKeyPath: aPath];
} }
@end @end
@ -148,7 +148,7 @@
{ {
[self exposeBinding: NSContentArrayBinding]; [self exposeBinding: NSContentArrayBinding];
[self setKeys: [NSArray arrayWithObjects: NSContentBinding, NSContentObjectBinding, nil] [self setKeys: [NSArray arrayWithObjects: NSContentBinding, NSContentObjectBinding, nil]
triggerChangeNotificationsForDependentKey: @"arrangedObjects"]; triggerChangeNotificationsForDependentKey: @"arrangedObjects"];
} }
} }
@ -279,7 +279,7 @@
NSUInteger index = [_arranged_objects indexOfObject: obj]; NSUInteger index = [_arranged_objects indexOfObject: obj];
if (NSNotFound != index) if (NSNotFound != index)
{ {
[tmp addIndex: index]; [tmp addIndex: index];
} }
} }
END_FOR_IN(enumerator) END_FOR_IN(enumerator)
@ -308,7 +308,7 @@
- (BOOL) setSelectionIndex: (NSUInteger)idx - (BOOL) setSelectionIndex: (NSUInteger)idx
{ {
return [self setSelectionIndexes: return [self setSelectionIndexes:
[NSIndexSet indexSetWithIndex: idx]]; [NSIndexSet indexSetWithIndex: idx]];
} }
- (BOOL) setSelectionIndexes: (NSIndexSet*)idx - (BOOL) setSelectionIndexes: (NSIndexSet*)idx
@ -370,7 +370,7 @@
NSUInteger cur = [self selectionIndex]; NSUInteger cur = [self selectionIndex];
[self setSelectionIndexes: [self setSelectionIndexes:
[NSIndexSet indexSetWithIndex: cur + 1]]; [NSIndexSet indexSetWithIndex: cur + 1]];
} }
- (void) selectPrevious: (id)sender - (void) selectPrevious: (id)sender
@ -378,7 +378,7 @@
NSUInteger cur = [self selectionIndex]; NSUInteger cur = [self selectionIndex];
[self setSelectionIndexes: [self setSelectionIndexes:
[NSIndexSet indexSetWithIndex: cur - 1]]; [NSIndexSet indexSetWithIndex: cur - 1]];
} }
- (NSArray*) selectedObjects - (NSArray*) selectedObjects
@ -483,7 +483,7 @@
[self willChangeValueForKey: @"arrangedObjects"]; [self willChangeValueForKey: @"arrangedObjects"];
DESTROY(_arranged_objects); DESTROY(_arranged_objects);
_arranged_objects = [[GSObservableArray alloc] _arranged_objects = [[GSObservableArray alloc]
initWithArray: [self arrangeObjects: _content]]; initWithArray: [self arrangeObjects: _content]];
[self didChangeValueForKey: @"arrangedObjects"]; [self didChangeValueForKey: @"arrangedObjects"];
} }
@ -542,20 +542,20 @@ atArrangedObjectIndexes: (NSIndexSet*)idx
[self unbind: binding]; [self unbind: binding];
kvb = [[GSKeyValueBinding alloc] initWithBinding: @"content" kvb = [[GSKeyValueBinding alloc] initWithBinding: @"content"
withName: binding withName: binding
toObject: anObject toObject: anObject
withKeyPath: keyPath withKeyPath: keyPath
options: options options: options
fromObject: self]; fromObject: self];
// The binding will be retained in the binding table // The binding will be retained in the binding table
RELEASE(kvb); RELEASE(kvb);
} }
else else
{ {
[super bind: binding [super bind: binding
toObject: anObject toObject: anObject
withKeyPath: keyPath withKeyPath: keyPath
options: options]; options: options];
} }
} }
@ -576,15 +576,35 @@ atArrangedObjectIndexes: (NSIndexSet*)idx
[super encodeWithCoder: coder]; [super encodeWithCoder: coder];
if ([coder allowsKeyedCoding]) if ([coder allowsKeyedCoding])
{ {
[coder encodeBool: [self avoidsEmptySelection] forKey: @"NSAvoidsEmptySelection"]; [coder encodeBool: [self avoidsEmptySelection]
[coder encodeBool: [self preservesSelection] forKey: @"NSPreservesSelection"]; forKey: @"NSAvoidsEmptySelection"];
[coder encodeBool: [self selectsInsertedObjects] forKey: @"NSSelectsInsertedObjects"]; [coder encodeBool: [self preservesSelection]
[coder encodeBool: [self clearsFilterPredicateOnInsertion] forKey: forKey: @"NSPreservesSelection"];
@"NSClearsFilterPredicateOnInsertion"]; [coder encodeBool: [self selectsInsertedObjects]
[coder encodeBool: [self automaticallyRearrangesObjects] forKey: @"NSAutomaticallyRearrangesObjects"]; forKey: @"NSSelectsInsertedObjects"];
[coder encodeBool: [self clearsFilterPredicateOnInsertion]
forKey: @"NSClearsFilterPredicateOnInsertion"];
[coder encodeBool: [self automaticallyRearrangesObjects]
forKey: @"NSAutomaticallyRearrangesObjects"];
} }
else else
{ {
BOOL f;
f = _acflags.avoids_empty_selection;
[coder encodeValueOfObjCType: @encode(BOOL)
at: &f];
f = _acflags.preserves_selection;
[coder encodeValueOfObjCType: @encode(BOOL)
at: &f];
f = _acflags.selects_inserted_objects;
[coder encodeValueOfObjCType: @encode(BOOL)
at: &f];
f = _acflags.clears_filter_predicate_on_insertion;
[coder encodeValueOfObjCType: @encode(BOOL)
at: &f];
f = _acflags.automatically_rearranges_objects;
[coder encodeValueOfObjCType: @encode(BOOL)
at: &f];
} }
} }
@ -598,33 +618,49 @@ atArrangedObjectIndexes: (NSIndexSet*)idx
if ([coder allowsKeyedCoding]) if ([coder allowsKeyedCoding])
{ {
if ([coder containsValueForKey: @"NSAvoidsEmptySelection"]) if ([coder containsValueForKey: @"NSAvoidsEmptySelection"])
{ {
[self setAvoidsEmptySelection: [self setAvoidsEmptySelection:
[coder decodeBoolForKey: @"NSAvoidsEmptySelection"]]; [coder decodeBoolForKey: @"NSAvoidsEmptySelection"]];
} }
if ([coder containsValueForKey: @"NSPreservesSelection"]) if ([coder containsValueForKey: @"NSPreservesSelection"])
{ {
[self setPreservesSelection: [self setPreservesSelection:
[coder decodeBoolForKey: @"NSPreservesSelection"]]; [coder decodeBoolForKey: @"NSPreservesSelection"]];
} }
if ([coder containsValueForKey: @"NSSelectsInsertedObjects"]) if ([coder containsValueForKey: @"NSSelectsInsertedObjects"])
{ {
[self setSelectsInsertedObjects: [self setSelectsInsertedObjects:
[coder decodeBoolForKey: @"NSSelectsInsertedObjects"]]; [coder decodeBoolForKey: @"NSSelectsInsertedObjects"]];
} }
if ([coder containsValueForKey: @"NSClearsFilterPredicateOnInsertion"]) if ([coder containsValueForKey: @"NSClearsFilterPredicateOnInsertion"])
{ {
[self setClearsFilterPredicateOnInsertion: [self setClearsFilterPredicateOnInsertion:
[coder decodeBoolForKey: @"NSClearsFilterPredicateOnInsertion"]]; [coder decodeBoolForKey: @"NSClearsFilterPredicateOnInsertion"]];
} }
if ([coder containsValueForKey: @"NSAutomaticallyRearrangesObjects"]) if ([coder containsValueForKey: @"NSAutomaticallyRearrangesObjects"])
{ {
[self setAutomaticallyRearrangesObjects: [self setAutomaticallyRearrangesObjects:
[coder decodeBoolForKey: @"NSAutomaticallyRearrangesObjects"]]; [coder decodeBoolForKey: @"NSAutomaticallyRearrangesObjects"]];
} }
} }
else else
{ {
BOOL f;
[coder decodeValueOfObjCType: @encode(BOOL)
at: &f];
_acflags.avoids_empty_selection = f;
[coder decodeValueOfObjCType: @encode(BOOL)
at: &f];
_acflags.preserves_selection = f;
[coder decodeValueOfObjCType: @encode(BOOL)
at: &f];
_acflags.selects_inserted_objects = f;
[coder decodeValueOfObjCType: @encode(BOOL)
at: &f];
_acflags.clears_filter_predicate_on_insertion = f;
[coder decodeValueOfObjCType: @encode(BOOL)
at: &f];
_acflags.automatically_rearranges_objects = f;
} }
return self; return self;

View file

@ -0,0 +1,477 @@
/* Implementation of class NSDictionaryController
Copyright (C) 2021 Free Software Foundation, Inc.
By: Gregory John Casamento
Date: 16-10-2021
This file is part of the GNUstep Library.
This 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.1 of the License, or (at your option) any later version.
This 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 this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110 USA.
*/
#import <Foundation/NSArray.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSException.h>
#import <Foundation/NSIndexSet.h>
#import <Foundation/NSKeyValueObserving.h>
#import <Foundation/NSPropertyList.h>
#import <Foundation/NSString.h>
#import "AppKit/NSDictionaryController.h"
#import "AppKit/NSKeyValueBinding.h"
#import "GSBindingHelpers.h"
#import "GSFastEnumeration.h"
// Private methods for NSString and NSDictionary...
@interface NSDictionary (GSPrivate_DictionaryToStrings)
- (NSString *) _stringsFromDictionary;
@end
@implementation NSDictionary (GSPrivate_DictionaryToStrings)
- (NSString *) _stringsFromDictionary
{
NSEnumerator *en = [self keyEnumerator];
NSString *k = nil;
NSString *result = @"";
while ((k = [en nextObject]) != nil)
{
NSString *v = [self objectForKey: k];
result = [result stringByAppendingString:
[NSString stringWithFormat: @"\"%@\" = \"%@\";\n", k, v]];
}
return result;
}
@end
@interface NSString (GSPrivate_StringsToDictionary)
- (NSDictionary *) _dictionaryFromStrings;
@end
@implementation NSString (GSPrivate_StringsToDictionary)
- (NSDictionary *) _dictionaryFromStrings
{
NSError *error = nil;
NSDictionary *dictionary =
[NSPropertyListSerialization
propertyListWithData: [self dataUsingEncoding: NSUTF8StringEncoding]
options: NSPropertyListImmutable
format: NULL
error: &error];
if (error != nil)
{
NSLog(@"Error reading strings file: %@", error);
}
return dictionary;
}
@end
@interface NSDictionaryController (GSPrivate_BuildArray)
- (NSArray *) _buildArray: (NSDictionary *)content;
@end
@implementation NSDictionaryController (GSPrivate_BuildArray)
- (NSArray *) _buildArray: (NSDictionary *)content
{
NSArray *allKeys = [content keysSortedByValueUsingSelector: @selector(compare:)];
NSMutableArray *result = [NSMutableArray arrayWithCapacity: [allKeys count]];
FOR_IN(id, k, allKeys)
{
if (![_excludedKeys containsObject: k])
{
NSDictionaryControllerKeyValuePair *kvp =
AUTORELEASE([[NSDictionaryControllerKeyValuePair alloc] init]);
id v = [content objectForKey: k];
NSString *localizedKey = [_localizedKeyDictionary objectForKey: k];
[kvp setLocalizedKey: localizedKey];
[kvp setKey: k];
[kvp setValue: v];
[kvp setExplicitlyIncluded: NO];
if ([_includedKeys containsObject: k])
{
[kvp setExplicitlyIncluded: YES];
}
[result addObject: kvp];
}
}
END_FOR_IN(allKeys);
return result;
}
@end
// NSDictionary class implementation...
@implementation NSDictionaryController
+ (void) initialize
{
if (self == [NSDictionaryController class])
{
[self exposeBinding: NSContentDictionaryBinding];
[self exposeBinding: NSIncludedKeysBinding];
[self exposeBinding: NSExcludedKeysBinding];
[self exposeBinding: NSInitialKeyBinding];
[self exposeBinding: NSInitialValueBinding];
[self setKeys: [NSArray arrayWithObjects: NSContentBinding, NSContentObjectBinding,
NSExcludedKeysBinding, NSIncludedKeysBinding, nil]
triggerChangeNotificationsForDependentKey: @"arrangedObjects"];
}
}
- (void) _setup
{
_contentDictionary = [[NSMutableDictionary alloc] init];
_includedKeys = [[NSArray alloc] init];
_excludedKeys = [[NSArray alloc] init];
_initialKey = [[NSString alloc] initWithString: @"key"];
_initialValue = [[NSString alloc] initWithString: @"value"];
_count = 0;
}
- (instancetype) initWithContent: (id)content
{
self = [super initWithContent: content];
if (self != nil)
{
[self _setup];
}
return self;
}
- (void) dealloc
{
RELEASE(_contentDictionary);
RELEASE(_includedKeys);
RELEASE(_excludedKeys);
RELEASE(_initialKey);
RELEASE(_initialValue);
[super dealloc];
}
- (void) addObject: (id)obj
{
NSString *k = [obj key];
NSString *v = [obj value];
[super addObject: obj];
[_contentDictionary setObject: v
forKey: k];
[self rearrangeObjects];
}
- (void) addObjects: (NSArray *)array
{
[super addObjects: array];
FOR_IN(NSDictionaryControllerKeyValuePair*, kvp, array)
{
NSString *k = [kvp key];
id v = [kvp value];
[_contentDictionary setObject: v
forKey: k];
}
END_FOR_IN(array);
[self rearrangeObjects];
}
- (void) removeObject: (id)obj
{
NSString *k = [obj key];
[super removeObject: obj];
[_contentDictionary removeObjectForKey: k];
[self rearrangeObjects];
}
- (void) removeObjects: (NSArray *)array
{
[super removeObjects: array];
FOR_IN(NSDictionaryControllerKeyValuePair*, kvp, array)
{
NSString *k = [kvp key];
[_contentDictionary removeObjectForKey: k];
}
END_FOR_IN(array);
[self rearrangeObjects];
}
- (NSDictionaryControllerKeyValuePair *) newObject
{
NSDictionaryControllerKeyValuePair *kvp = [[NSDictionaryControllerKeyValuePair alloc] init];
NSString *k = nil;
if (_count > 0)
{
k = [NSString stringWithFormat: @"%@%lu", _initialKey, _count];
}
else
{
k = [_initialKey copy];
}
[kvp setKey: k];
[kvp setValue: _initialValue];
_count++;
AUTORELEASE(kvp);
return kvp;
}
- (void) rearrangeObjects
{
[self willChangeValueForKey: NSContentBinding];
DESTROY(_arranged_objects);
_arranged_objects = [[GSObservableArray alloc]
initWithArray: [self arrangeObjects:
[self _buildArray: _contentDictionary]]];
[self didChangeValueForKey: NSContentBinding];
}
- (NSString *) initialKey
{
return _initialKey;
}
- (void) setInitialKey: (NSString *)key
{
ASSIGNCOPY(_initialKey, key);
}
- (id) initialValue
{
return _initialValue;
}
- (void) setInitialValue: (id)value
{
ASSIGNCOPY(_initialValue, value);
}
- (NSArray *) includedKeys
{
return _includedKeys;
}
- (void) setIncludedKeys: (NSArray *)includedKeys
{
ASSIGNCOPY(_includedKeys, includedKeys);
[self rearrangeObjects];
}
- (NSArray *) excludedKeys
{
return _excludedKeys;
}
- (void) setExcludedKeys: (NSArray *)excludedKeys
{
ASSIGNCOPY(_excludedKeys, excludedKeys);
[self rearrangeObjects];
}
- (NSDictionary *) localizedKeyDictionary
{
return _localizedKeyDictionary;
}
- (void) setLocalizedKeyDictionary: (NSDictionary *)dict
{
NSString *strings = [dict _stringsFromDictionary];
ASSIGN(_localizedKeyTable, strings);
ASSIGNCOPY(_localizedKeyDictionary, dict);
[self rearrangeObjects];
}
- (NSString *) localizedKeyTable
{
return _localizedKeyTable;
}
- (void) setLocalizedKeyTable: (NSString *)keyTable
{
NSDictionary *dictionary = [keyTable _dictionaryFromStrings];
ASSIGN(_localizedKeyDictionary, dictionary);
ASSIGNCOPY(_localizedKeyTable, keyTable);
[self rearrangeObjects];
}
- (void) setContent: (id)content
{
ASSIGN(_contentDictionary, content);
[super setContent: [self _buildArray: content]];
}
- (void) observeValueForKeyPath: (NSString*)aPath
ofObject: (id)anObject
change: (NSDictionary*)aChange
context: (void*)aContext
{
[NSException raise: NSInvalidArgumentException
format: @"-%@ cannot be sent to %@ ..."
@" create an instance overriding this",
NSStringFromSelector(_cmd), NSStringFromClass([self class])];
}
- (void) bind: (NSString *)binding
toObject: (id)anObject
withKeyPath: (NSString *)keyPath
options: (NSDictionary *)options
{
if ([binding isEqual: NSContentDictionaryBinding])
{
GSKeyValueBinding *kvb;
[self unbind: binding];
kvb = [[GSKeyValueBinding alloc] initWithBinding: @"content"
withName: binding
toObject: anObject
withKeyPath: keyPath
options: options
fromObject: self];
// The binding will be retained in the binding table
RELEASE(kvb);
}
else
{
[super bind: binding
toObject: anObject
withKeyPath: keyPath
options: options];
}
}
- (Class) valueClassForBinding: (NSString *)binding
{
if ([binding isEqual: NSContentDictionaryBinding])
{
return [NSObject class];
}
else
{
return nil;
}
}
- (instancetype) initWithCoder: (NSCoder *)coder
{
self = [super initWithCoder: coder];
if (self != nil)
{
[self _setup];
}
return self;
}
@end
@implementation NSDictionaryControllerKeyValuePair
- (instancetype) init
{
self = [super init];
if (self != nil)
{
_key = nil;
_value = nil;
_localizedKey = nil;
_explicitlyIncluded = YES;
}
return self;
}
- (void) dealloc
{
RELEASE(_key);
RELEASE(_value);
RELEASE(_localizedKey);
[super dealloc];
}
/**
* Returns a copy of the key
*/
- (NSString *) key
{
return _key;
}
- (void) setKey: (NSString *)key
{
ASSIGNCOPY(_key, key);
}
/**
* Returns a strong reference to the value
*/
- (id) value
{
return _value;
}
- (void) setValue: (id)value
{
ASSIGNCOPY(_value, value);
}
- (NSString *) localizedKey
{
return _localizedKey;
}
- (void) setLocalizedKey: (NSString *)localizedKey
{
ASSIGNCOPY(_localizedKey, localizedKey);
}
- (BOOL) isExplicitlyIncluded
{
return _explicitlyIncluded;
}
- (void) setExplicitlyIncluded: (BOOL)flag
{
_explicitlyIncluded = flag;
}
@end

View file

@ -692,14 +692,20 @@ APPKIT_DECLARE NSString *NSValueTransformerBindingOption = @"NSValueTransformer"
APPKIT_DECLARE NSString *NSAlignmentBinding = @"alignment"; APPKIT_DECLARE NSString *NSAlignmentBinding = @"alignment";
APPKIT_DECLARE NSString *NSContentArrayBinding = @"contentArray"; APPKIT_DECLARE NSString *NSContentArrayBinding = @"contentArray";
APPKIT_DECLARE NSString *NSContentBinding = @"content"; APPKIT_DECLARE NSString *NSContentBinding = @"content";
APPKIT_DECLARE NSString *NSContentDictionaryBinding = @"contentDictionary";
APPKIT_DECLARE NSString *NSContentObjectBinding = @"contentObject"; APPKIT_DECLARE NSString *NSContentObjectBinding = @"contentObject";
APPKIT_DECLARE NSString *NSContentValuesBinding = @"contentValues"; APPKIT_DECLARE NSString *NSContentValuesBinding = @"contentValues";
APPKIT_DECLARE NSString *NSEditableBinding = @"editable"; APPKIT_DECLARE NSString *NSEditableBinding = @"editable";
APPKIT_DECLARE NSString *NSEnabledBinding = @"enabled"; APPKIT_DECLARE NSString *NSEnabledBinding = @"enabled";
APPKIT_DECLARE NSString *NSExcludedKeysBinding = @"excludedKeys";
APPKIT_DECLARE NSString *NSFontBinding = @"font"; APPKIT_DECLARE NSString *NSFontBinding = @"font";
APPKIT_DECLARE NSString *NSFontNameBinding = @"fontName"; APPKIT_DECLARE NSString *NSFontNameBinding = @"fontName";
APPKIT_DECLARE NSString *NSFontSizeBinding = @"fontSize"; APPKIT_DECLARE NSString *NSFontSizeBinding = @"fontSize";
APPKIT_DECLARE NSString *NSHiddenBinding = @"hidden"; APPKIT_DECLARE NSString *NSHiddenBinding = @"hidden";
APPKIT_DECLARE NSString *NSIncludedKeysBinding = @"includedKeys";
APPKIT_DECLARE NSString *NSInitialKeyBinding = @"initialKey";
APPKIT_DECLARE NSString *NSInitialValueBinding = @"initialValue";
APPKIT_DECLARE NSString *NSLocalizedKeyDictionaryBinding = @"localizedKeyDictionary";
APPKIT_DECLARE NSString *NSSelectedIndexBinding = @"selectedIndex"; APPKIT_DECLARE NSString *NSSelectedIndexBinding = @"selectedIndex";
APPKIT_DECLARE NSString *NSSelectedObjectBinding = @"selectedObject"; APPKIT_DECLARE NSString *NSSelectedObjectBinding = @"selectedObject";
APPKIT_DECLARE NSString *NSSelectedTagBinding = @"selectedTag"; APPKIT_DECLARE NSString *NSSelectedTagBinding = @"selectedTag";