NSOutlineView autosaving of expanded/collapsed state
-
Hi,
is there a solution on Leopard to implement the autosaving of expanded/
collapsed state of an NSOutlineView (bound to Core Data via
NSTreeController).
I tried to implement outlineview:persistentObjectForItem; and
outlineView:itemForPersistentObject:. But it doesnt't work, because
NSTreeNode and NSManagedObject don't encode with NSKeyedArchiver.
Is there something I am missing, or couldn't state autosaving be done
in Leopard without 'hacks' like in Tiger?
Ralph. -
On 23 Feb 2008, at 01:58, Ralph Manns wrote:> Hi,
>
> is there a solution on Leopard to implement the autosaving of
> expanded/collapsed state of an NSOutlineView (bound to Core Data via
> NSTreeController).
> I tried to implement outlineview:persistentObjectForItem; and
> outlineView:itemForPersistentObject:. But it doesnt't work, because
> NSTreeNode and NSManagedObject don't encode with NSKeyedArchiver.
> Is there something I am missing, or couldn't state autosaving be
> done in Leopard without 'hacks' like in Tiger?
>
Hi Ralph,
I ran into this too in a non-Core Data app. I haven't found a
solution better than iterating through each row in the outlineView and
calling -isItemExpanded (I think that's the method) so I can use the
output from this to re-exapnd the rows when I restart my app (or open
the document in the case of a document-based app).
I'd welcome a better solution though!
Jon -
Am 23.02.2008 um 23:44 schrieb Jonathan Dann:> On 23 Feb 2008, at 01:58, Ralph Manns wrote:
>
>> Hi,
>>
>> is there a solution on Leopard to implement the autosaving of
>> expanded/collapsed state of an NSOutlineView (bound to Core Data
>> via NSTreeController).
>> I tried to implement outlineview:persistentObjectForItem; and
>> outlineView:itemForPersistentObject:. But it doesnt't work, because
>> NSTreeNode and NSManagedObject don't encode with NSKeyedArchiver.
>> Is there something I am missing, or couldn't state autosaving be
>> done in Leopard without 'hacks' like in Tiger?
>>
>
> Hi Ralph,
>
> I ran into this too in a non-Core Data app. I haven't found a
> solution better than iterating through each row in the outlineView
> and calling -isItemExpanded (I think that's the method) so I can use
> the output from this to re-exapnd the rows when I restart my app (or
> open the document in the case of a document-based app).
>
> I'd welcome a better solution though!
>
> Jon
Hi Jon,
I haven't found a solution up to now, although I tried everything. So
I have to do it like you explained.
Ralph. -
Hi Ralph,
Here's my code from an NSOutlineView subclass
- (NSArray *)expandedItems;
{
NSMutableArray *expandedItemsArray = [NSMutableArray array];
NSUInteger row, numberOfRows = [self numberOfRows];
for (row = 0 ; row < numberOfRows ; row++)
{
id item = [self itemAtRow:row];
if ([self isItemExpanded:item])
[expandedItemsArray addObject:[item representedObject]]; // create
an array of only the expanded items in the list
}
return [[expandedItemsArray copy] autorelease];
}
The returned array can then be archived.
It uses NSTreeNode and -representedObject, so is 10.5 only. For 10.4
there is an undocumented method for the private class that
NSTreeController used in 10.4 that does the same thing, can't remember
the method name but it's on Scott Stevenson's blog somewhere, just
Google theococoa.com and NSTreeController.
Passing the (now unarchived) array to the method below will expand
them again.
- (void)expandItems:(NSArray *)array;
{
NSUInteger row, numberOfRows = [self numberOfRows];
for (MyNode *savedItem in array) {
for (row = 0 ; row < numberOfRows ; row++) {
id item = [self itemAtRow:row];
MyNode *realObject = [item representedObject];
if ([realObject.nodeName isEqualToString:savedItem.nodeName]) {
[self expandItem:item];
numberOfRows = [self numberOfRows];
break;
}
}
}
}
Enjoy,
Jon -
Am 24.02.2008 um 23:37 schrieb Jonathan Dann:> Hi Ralph,
>
> Here's my code from an NSOutlineView subclass
>
> - (NSArray *)expandedItems;
> {
> NSMutableArray *expandedItemsArray = [NSMutableArray array];
> NSUInteger row, numberOfRows = [self numberOfRows];
>
> for (row = 0 ; row < numberOfRows ; row++)
> {
> id item = [self itemAtRow:row];
> if ([self isItemExpanded:item])
> [expandedItemsArray addObject:[item representedObject]]; //
> create an array of only the expanded items in the list
> }
>
> return [[expandedItemsArray copy] autorelease];
> }
>
> The returned array can then be archived.
>
> It uses NSTreeNode and -representedObject, so is 10.5 only. For 10.4
> there is an undocumented method for the private class that
> NSTreeController used in 10.4 that does the same thing, can't
> remember the method name but it's on Scott Stevenson's blog
> somewhere, just Google theococoa.com and NSTreeController.
>
> Passing the (now unarchived) array to the method below will expand
> them again.
>
> - (void)expandItems:(NSArray *)array;
> {
> NSUInteger row, numberOfRows = [self numberOfRows];
> for (MyNode *savedItem in array) {
> for (row = 0 ; row < numberOfRows ; row++) {
> id item = [self itemAtRow:row];
> MyNode *realObject = [item representedObject];
> if ([realObject.nodeName isEqualToString:savedItem.nodeName]) {
> [self expandItem:item];
> numberOfRows = [self numberOfRows];
> break;
> }
> }
> }
> }
>
> Enjoy,
>
> Jon
Hi Jon,
thanks for your response and providing your code. Works great.
Ralph. -
> is there a solution [...] to implement the autosaving of expanded/
> collapsed state of an NSOutlineView
I haven't done much work with Core Data so apologies if this won't/
doesn't work: I simply had a look at the headers.
Couldn't you return [[aManagedObject objectID] URIRepresentation] in
outlineView:persistentObjectForItem: to save the expanded state. Then
restore it by returning [aManagedObjectContext objectWithID:
[aPersistentStoreCoordinator managedObjectIDForURIRepresentation:URI]]
from outlineView:itemForPersistentObject:?
Keith -
> Couldn't you return [[aManagedObject objectID] URIRepresentation] in
> outlineView:persistentObjectForItem: to save the expanded state.
> Then restore it by returning [aManagedObjectContext objectWithID:
> [aPersistentStoreCoordinator
> managedObjectIDForURIRepresentation:URI]] from
> outlineView:itemForPersistentObject:?
You can't rely on the the URI representation the way you might
expect for any objects that haven't yet been saved. The
URIRepresentation is based on the objectID. From the documentation:
"If the receiver has not yet been saved, the object ID is a temporary
value that will change when the object is saved."
It's best to add an "expanded" attribute or something similarly
named and rely on it instead.
--
I.S. -
On 24 Feb 2008, at 22:45, Ralph Manns wrote:>
> Am 24.02.2008 um 23:37 schrieb Jonathan Dann:
>
> Hi Jon,
>
> thanks for your response and providing your code. Works great.
>
> Ralph.
You're welcome!
Jon


