mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-30 01:20:38 +00:00
Merge pull request #170 from gnustep/NSDictionaryController2_branch
This commit is contained in:
commit
e64d8d4b02
8 changed files with 745 additions and 67 deletions
|
@ -167,6 +167,7 @@
|
|||
#import <AppKit/NSDockTile.h>
|
||||
#import <AppKit/NSDocument.h>
|
||||
#import <AppKit/NSDocumentController.h>
|
||||
#import <AppKit/NSDictionaryController.h>
|
||||
#import <AppKit/NSDrawer.h>
|
||||
#import <AppKit/NSFileWrapperExtensions.h>
|
||||
#import <AppKit/NSFontAssetRequest.h>
|
||||
|
|
151
Headers/AppKit/NSDictionaryController.h
Normal file
151
Headers/AppKit/NSDictionaryController.h
Normal 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 */
|
|
@ -107,14 +107,20 @@ APPKIT_EXPORT id NSNotApplicableMarker;
|
|||
APPKIT_EXPORT NSString *NSAlignmentBinding;
|
||||
APPKIT_EXPORT NSString *NSContentArrayBinding;
|
||||
APPKIT_EXPORT NSString *NSContentBinding;
|
||||
APPKIT_EXPORT NSString *NSContentDictionaryBinding;
|
||||
APPKIT_EXPORT NSString *NSContentObjectBinding;
|
||||
APPKIT_EXPORT NSString *NSContentValuesBinding;
|
||||
APPKIT_EXPORT NSString *NSEditableBinding;
|
||||
APPKIT_EXPORT NSString *NSEnabledBinding;
|
||||
APPKIT_EXPORT NSString *NSExcludedKeysBinding;
|
||||
APPKIT_EXPORT NSString *NSFontBinding;
|
||||
APPKIT_EXPORT NSString *NSFontNameBinding;
|
||||
APPKIT_EXPORT NSString *NSFontSizeBinding;
|
||||
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 *NSSelectedObjectBinding;
|
||||
APPKIT_EXPORT NSString *NSSelectedTagBinding;
|
||||
|
|
1
MISSING
1
MISSING
|
@ -1,7 +1,6 @@
|
|||
MISSING HEADERS ( * = difficult, - = quick, + = placeholder, x = won't do )
|
||||
---
|
||||
> NSATSTypesetter.h +
|
||||
> NSDictionaryController.h -
|
||||
> NSDiffableDataSource.h *
|
||||
> NSDraggingItem.h -
|
||||
> NSDraggingSession.h -
|
||||
|
|
|
@ -103,6 +103,7 @@ NSDataLinkManager.m \
|
|||
NSDataLinkPanel.m \
|
||||
NSDatePicker.m \
|
||||
NSDatePickerCell.m \
|
||||
NSDictionaryController.m \
|
||||
NSDockTile.m \
|
||||
NSDocument.m \
|
||||
NSDocumentController.m \
|
||||
|
@ -435,6 +436,7 @@ NSDataLinkManager.h \
|
|||
NSDataLinkPanel.h \
|
||||
NSDatePicker.h \
|
||||
NSDatePickerCell.h \
|
||||
NSDictionaryController.h \
|
||||
NSDockTile.h \
|
||||
NSDocument.h \
|
||||
NSDocumentController.h \
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; see the file COPYING.LIB.
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
If not, see <http://www.gnu.org/licenses/> or write to the
|
||||
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
@ -79,7 +79,7 @@
|
|||
NSArray *result = [_array objectsAtIndexes: indexes];
|
||||
|
||||
return AUTORELEASE([[GSObservableArray alloc]
|
||||
initWithArray: result]);
|
||||
initWithArray: result]);
|
||||
}
|
||||
|
||||
- (id) valueForKey: (NSString*)key
|
||||
|
@ -93,7 +93,7 @@
|
|||
// object until this gets fixed.
|
||||
//return AUTORELEASE([[GSObservableArray alloc]
|
||||
return ([[GSObservableArray alloc]
|
||||
initWithArray: result]);
|
||||
initWithArray: result]);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -104,7 +104,7 @@
|
|||
NSArray * result = [_array arrayByAddingObject: anObject];
|
||||
|
||||
return AUTORELEASE([[GSObservableArray alloc]
|
||||
initWithArray: result]);
|
||||
initWithArray: result]);
|
||||
}
|
||||
|
||||
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray
|
||||
|
@ -112,7 +112,7 @@
|
|||
NSArray * result = [_array arrayByAddingObjectsFromArray: anotherArray];
|
||||
|
||||
return AUTORELEASE([[GSObservableArray alloc]
|
||||
initWithArray: result]);
|
||||
initWithArray: result]);
|
||||
}
|
||||
|
||||
- (void) addObserver: (NSObject*)anObserver
|
||||
|
@ -124,9 +124,9 @@
|
|||
|
||||
[self addObserver: anObserver
|
||||
toObjectsAtIndexes: indexes
|
||||
forKeyPath: aPath
|
||||
options: options
|
||||
context: aContext];
|
||||
forKeyPath: aPath
|
||||
options: options
|
||||
context: aContext];
|
||||
}
|
||||
|
||||
- (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath
|
||||
|
@ -135,7 +135,7 @@
|
|||
|
||||
[self removeObserver: anObserver
|
||||
fromObjectsAtIndexes: indexes
|
||||
forKeyPath: aPath];
|
||||
forKeyPath: aPath];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -147,8 +147,8 @@
|
|||
if (self == [NSArrayController class])
|
||||
{
|
||||
[self exposeBinding: NSContentArrayBinding];
|
||||
[self setKeys: [NSArray arrayWithObjects: NSContentBinding, NSContentObjectBinding, nil]
|
||||
triggerChangeNotificationsForDependentKey: @"arrangedObjects"];
|
||||
[self setKeys: [NSArray arrayWithObjects: NSContentBinding, NSContentObjectBinding, nil]
|
||||
triggerChangeNotificationsForDependentKey: @"arrangedObjects"];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@
|
|||
{
|
||||
[self rearrangeObjects];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
DESTROY(_arranged_objects);
|
||||
}
|
||||
|
@ -207,7 +207,7 @@
|
|||
{
|
||||
[self rearrangeObjects];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
DESTROY(_arranged_objects);
|
||||
}
|
||||
|
@ -227,7 +227,7 @@
|
|||
{
|
||||
[self rearrangeObjects];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
DESTROY(_arranged_objects);
|
||||
}
|
||||
|
@ -243,7 +243,7 @@
|
|||
{
|
||||
[self rearrangeObjects];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
DESTROY(_arranged_objects);
|
||||
}
|
||||
|
@ -279,7 +279,7 @@
|
|||
NSUInteger index = [_arranged_objects indexOfObject: obj];
|
||||
if (NSNotFound != index)
|
||||
{
|
||||
[tmp addIndex: index];
|
||||
[tmp addIndex: index];
|
||||
}
|
||||
}
|
||||
END_FOR_IN(enumerator)
|
||||
|
@ -307,8 +307,8 @@
|
|||
|
||||
- (BOOL) setSelectionIndex: (NSUInteger)idx
|
||||
{
|
||||
return [self setSelectionIndexes:
|
||||
[NSIndexSet indexSetWithIndex: idx]];
|
||||
return [self setSelectionIndexes:
|
||||
[NSIndexSet indexSetWithIndex: idx]];
|
||||
}
|
||||
|
||||
- (BOOL) setSelectionIndexes: (NSIndexSet*)idx
|
||||
|
@ -369,16 +369,16 @@
|
|||
{
|
||||
NSUInteger cur = [self selectionIndex];
|
||||
|
||||
[self setSelectionIndexes:
|
||||
[NSIndexSet indexSetWithIndex: cur + 1]];
|
||||
[self setSelectionIndexes:
|
||||
[NSIndexSet indexSetWithIndex: cur + 1]];
|
||||
}
|
||||
|
||||
- (void) selectPrevious: (id)sender
|
||||
{
|
||||
NSUInteger cur = [self selectionIndex];
|
||||
|
||||
[self setSelectionIndexes:
|
||||
[NSIndexSet indexSetWithIndex: cur - 1]];
|
||||
[self setSelectionIndexes:
|
||||
[NSIndexSet indexSetWithIndex: cur - 1]];
|
||||
}
|
||||
|
||||
- (NSArray*) selectedObjects
|
||||
|
@ -483,7 +483,7 @@
|
|||
[self willChangeValueForKey: @"arrangedObjects"];
|
||||
DESTROY(_arranged_objects);
|
||||
_arranged_objects = [[GSObservableArray alloc]
|
||||
initWithArray: [self arrangeObjects: _content]];
|
||||
initWithArray: [self arrangeObjects: _content]];
|
||||
[self didChangeValueForKey: @"arrangedObjects"];
|
||||
}
|
||||
|
||||
|
@ -507,14 +507,14 @@
|
|||
return _filter_predicate;
|
||||
}
|
||||
|
||||
- (void) insertObject: (id)obj
|
||||
- (void) insertObject: (id)obj
|
||||
atArrangedObjectIndex: (NSUInteger)idx
|
||||
{
|
||||
// FIXME
|
||||
[self addObject: obj];
|
||||
}
|
||||
|
||||
- (void) insertObjects: (NSArray*)obj
|
||||
- (void) insertObjects: (NSArray*)obj
|
||||
atArrangedObjectIndexes: (NSIndexSet*)idx
|
||||
{
|
||||
// FIXME
|
||||
|
@ -531,7 +531,7 @@ atArrangedObjectIndexes: (NSIndexSet*)idx
|
|||
[self removeObjects: [_arranged_objects objectsAtIndexes: idx]];
|
||||
}
|
||||
|
||||
- (void) bind: (NSString *)binding
|
||||
- (void) bind: (NSString *)binding
|
||||
toObject: (id)anObject
|
||||
withKeyPath: (NSString *)keyPath
|
||||
options: (NSDictionary *)options
|
||||
|
@ -541,21 +541,21 @@ atArrangedObjectIndexes: (NSIndexSet*)idx
|
|||
GSKeyValueBinding *kvb;
|
||||
|
||||
[self unbind: binding];
|
||||
kvb = [[GSKeyValueBinding alloc] initWithBinding: @"content"
|
||||
withName: binding
|
||||
toObject: anObject
|
||||
withKeyPath: keyPath
|
||||
options: options
|
||||
fromObject: self];
|
||||
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];
|
||||
[super bind: binding
|
||||
toObject: anObject
|
||||
withKeyPath: keyPath
|
||||
options: options];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,24 +572,44 @@ atArrangedObjectIndexes: (NSIndexSet*)idx
|
|||
}
|
||||
|
||||
- (void) encodeWithCoder: (NSCoder *)coder
|
||||
{
|
||||
{
|
||||
[super encodeWithCoder: coder];
|
||||
if ([coder allowsKeyedCoding])
|
||||
{
|
||||
[coder encodeBool: [self avoidsEmptySelection] forKey: @"NSAvoidsEmptySelection"];
|
||||
[coder encodeBool: [self preservesSelection] forKey: @"NSPreservesSelection"];
|
||||
[coder encodeBool: [self selectsInsertedObjects] forKey: @"NSSelectsInsertedObjects"];
|
||||
[coder encodeBool: [self clearsFilterPredicateOnInsertion] forKey:
|
||||
@"NSClearsFilterPredicateOnInsertion"];
|
||||
[coder encodeBool: [self automaticallyRearrangesObjects] forKey: @"NSAutomaticallyRearrangesObjects"];
|
||||
[coder encodeBool: [self avoidsEmptySelection]
|
||||
forKey: @"NSAvoidsEmptySelection"];
|
||||
[coder encodeBool: [self preservesSelection]
|
||||
forKey: @"NSPreservesSelection"];
|
||||
[coder encodeBool: [self selectsInsertedObjects]
|
||||
forKey: @"NSSelectsInsertedObjects"];
|
||||
[coder encodeBool: [self clearsFilterPredicateOnInsertion]
|
||||
forKey: @"NSClearsFilterPredicateOnInsertion"];
|
||||
[coder encodeBool: [self automaticallyRearrangesObjects]
|
||||
forKey: @"NSAutomaticallyRearrangesObjects"];
|
||||
}
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder *)coder
|
||||
{
|
||||
{
|
||||
if ((self = [super initWithCoder: coder]) == nil)
|
||||
{
|
||||
return nil;
|
||||
|
@ -598,36 +618,52 @@ atArrangedObjectIndexes: (NSIndexSet*)idx
|
|||
if ([coder allowsKeyedCoding])
|
||||
{
|
||||
if ([coder containsValueForKey: @"NSAvoidsEmptySelection"])
|
||||
{
|
||||
[self setAvoidsEmptySelection:
|
||||
[coder decodeBoolForKey: @"NSAvoidsEmptySelection"]];
|
||||
}
|
||||
{
|
||||
[self setAvoidsEmptySelection:
|
||||
[coder decodeBoolForKey: @"NSAvoidsEmptySelection"]];
|
||||
}
|
||||
if ([coder containsValueForKey: @"NSPreservesSelection"])
|
||||
{
|
||||
[self setPreservesSelection:
|
||||
[coder decodeBoolForKey: @"NSPreservesSelection"]];
|
||||
}
|
||||
{
|
||||
[self setPreservesSelection:
|
||||
[coder decodeBoolForKey: @"NSPreservesSelection"]];
|
||||
}
|
||||
if ([coder containsValueForKey: @"NSSelectsInsertedObjects"])
|
||||
{
|
||||
[self setSelectsInsertedObjects:
|
||||
[coder decodeBoolForKey: @"NSSelectsInsertedObjects"]];
|
||||
}
|
||||
{
|
||||
[self setSelectsInsertedObjects:
|
||||
[coder decodeBoolForKey: @"NSSelectsInsertedObjects"]];
|
||||
}
|
||||
if ([coder containsValueForKey: @"NSClearsFilterPredicateOnInsertion"])
|
||||
{
|
||||
[self setClearsFilterPredicateOnInsertion:
|
||||
[coder decodeBoolForKey: @"NSClearsFilterPredicateOnInsertion"]];
|
||||
}
|
||||
{
|
||||
[self setClearsFilterPredicateOnInsertion:
|
||||
[coder decodeBoolForKey: @"NSClearsFilterPredicateOnInsertion"]];
|
||||
}
|
||||
if ([coder containsValueForKey: @"NSAutomaticallyRearrangesObjects"])
|
||||
{
|
||||
[self setAutomaticallyRearrangesObjects:
|
||||
[coder decodeBoolForKey: @"NSAutomaticallyRearrangesObjects"]];
|
||||
}
|
||||
{
|
||||
[self setAutomaticallyRearrangesObjects:
|
||||
[coder decodeBoolForKey: @"NSAutomaticallyRearrangesObjects"]];
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
477
Source/NSDictionaryController.m
Normal file
477
Source/NSDictionaryController.m
Normal 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
|
|
@ -692,14 +692,20 @@ APPKIT_DECLARE NSString *NSValueTransformerBindingOption = @"NSValueTransformer"
|
|||
APPKIT_DECLARE NSString *NSAlignmentBinding = @"alignment";
|
||||
APPKIT_DECLARE NSString *NSContentArrayBinding = @"contentArray";
|
||||
APPKIT_DECLARE NSString *NSContentBinding = @"content";
|
||||
APPKIT_DECLARE NSString *NSContentDictionaryBinding = @"contentDictionary";
|
||||
APPKIT_DECLARE NSString *NSContentObjectBinding = @"contentObject";
|
||||
APPKIT_DECLARE NSString *NSContentValuesBinding = @"contentValues";
|
||||
APPKIT_DECLARE NSString *NSEditableBinding = @"editable";
|
||||
APPKIT_DECLARE NSString *NSEnabledBinding = @"enabled";
|
||||
APPKIT_DECLARE NSString *NSExcludedKeysBinding = @"excludedKeys";
|
||||
APPKIT_DECLARE NSString *NSFontBinding = @"font";
|
||||
APPKIT_DECLARE NSString *NSFontNameBinding = @"fontName";
|
||||
APPKIT_DECLARE NSString *NSFontSizeBinding = @"fontSize";
|
||||
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 *NSSelectedObjectBinding = @"selectedObject";
|
||||
APPKIT_DECLARE NSString *NSSelectedTagBinding = @"selectedTag";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue