Repository: realm/realm-swift
File: tools/RealmBrowser/RealmBrowser/Classes/RLMTypeOutlineViewController.m (Objective-C)

Code before:
@end

@implementation RLMTypeOutlineViewController

#pragma mark - RLMViewController overrides

-(void)realmDidLoad
{
    [self.classesOutlineView reloadData];
    // Expand the root item representing the selected realm.
    RLMRealmNode *firstItem = self.parentWindowController.modelDocument.presentedRealm;
    if (firstItem != nil) {
        // We want the class outline to be expanded as default
        [self.classesOutlineView expandItem:firstItem expandChildren:YES];
    }
}

- (void)performUpdateUsingState:(RLMNavigationState *)newState oldState:(RLMNavigationState *)oldState
{
    [super performUpdateUsingState:newState oldState:oldState];
 
    if ([oldState isMemberOfClass:[RLMArrayNavigationState class]] || [oldState isMemberOfClass:[RLMQueryNavigationState class]]) {
        RLMClassNode *parentNode = (RLMClassNode *)oldState.selectedType;
        [parentNode removeAllChildNodes];
        [self.tableView reloadData];
    }
    
    if ([newState isMemberOfClass:[RLMNavigationState class]]) {
        if ([oldState isMemberOfClass:[RLMQueryNavigationState class]] || newState.selectedType != oldState.selectedType) {
            NSInteger typeIndex = [self.classesOutlineView rowForItem:newState.selectedType];
            
            [self setSelectionIndex:typeIndex];
        }
    }
    else if ([newState isMemberOfClass:[RLMArrayNavigationState class]]) {
        RLMArrayNavigationState *arrayState = (RLMArrayNavigationState *)newState;
        
        RLMClassNode *parentClassNode = (RLMClassNode *)arrayState.selectedType;
        NSInteger selectionIndex = arrayState.selectedInstanceIndex;
        RLMObject *selectedInstance = [parentClassNode instanceAtIndex:selectionIndex];
        
        RLMObjectNode *objectNode = [parentClassNode displayChildObject:selectedInstance];
        
        RLMArrayNode *arrayNode = [objectNode displayChildArrayFromProperty:arrayState.property object:selectedInstance];
        objectNode.childNode = arrayNode;

        [self.classesOutlineView reloadData];
        [self.classesOutlineView expandItem:parentClassNode];
        [self.classesOutlineView expandItem:objectNode];
        
        NSInteger index = [self.classesOutlineView rowForItem:arrayNode];

Review comment (suggestion):
This is done in order to handle the case where you type in a query, and then follow an array link from there. The navigationState system is not really built to handle this, and in general I think we should definitely get rid of it as soon as possible.


Code after:
@end

@implementation RLMTypeOutlineViewController

#pragma mark - RLMViewController overrides

-(void)realmDidLoad
{
    [self.classesOutlineView reloadData];
    // Expand the root item representing the selected realm.
    RLMRealmNode *firstItem = self.parentWindowController.modelDocument.presentedRealm;
    if (firstItem != nil) {
        // We want the class outline to be expanded as default
        [self.classesOutlineView expandItem:firstItem expandChildren:YES];
    }
}

- (void)performUpdateUsingState:(RLMNavigationState *)newState oldState:(RLMNavigationState *)oldState
{
    [super performUpdateUsingState:newState oldState:oldState];
 
    if ([oldState isMemberOfClass:[RLMArrayNavigationState class]] || [oldState isMemberOfClass:[RLMQueryNavigationState class]]) {
        if ([oldState.selectedType isMemberOfClass:[RLMClassNode class]] && ![newState.selectedType isMemberOfClass:[RLMArrayNode class]]) {
            [(RLMClassNode *)oldState.selectedType removeAllChildNodes];
        }
        [self.tableView reloadData];
    }
    
    if ([newState isMemberOfClass:[RLMNavigationState class]]) {
        if ([oldState isMemberOfClass:[RLMQueryNavigationState class]] || newState.selectedType != oldState.selectedType) {
            NSInteger typeIndex = [self.classesOutlineView rowForItem:newState.selectedType];
            
            [self setSelectionIndex:typeIndex];
        }
    }
    else if ([newState isMemberOfClass:[RLMArrayNavigationState class]]) {
        RLMArrayNavigationState *arrayState = (RLMArrayNavigationState *)newState;
        
        RLMClassNode *parentClassNode = (RLMClassNode *)arrayState.selectedType;
        NSInteger selectionIndex = arrayState.selectedInstanceIndex;

        RLMObject *selectedInstance = [parentClassNode instanceAtIndex:selectionIndex];
        
        RLMObjectNode *objectNode;
        
        if ([oldState isMemberOfClass:[RLMQueryNavigationState class]]) {
            objectNode = [(RLMClassNode *)oldState.selectedType displayChildObject:selectedInstance];
        }
        else {
            objectNode = [parentClassNode displayChildObject:selectedInstance];
        }