GVAttributeInspectorController.m 6.36 KB
Newer Older
1 2 3
/* $Id$ $Revision$ */
/* vim:set shiftwidth=4 ts=8: */

ellson's avatar
ellson committed
4 5 6 7 8 9 10 11 12
/*************************************************************************
 * Copyright (c) 2011 AT&T Intellectual Property 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors: See CVS logs. Details at http://www.graphviz.org/
 *************************************************************************/
13 14 15

#import "GVAttributeInspectorController.h"
#import "GVAttributeSchema.h"
16
#import "GVDocument.h"
17 18 19 20 21 22 23 24 25 26
#import "GVGraph.h"
#import "GVWindowController.h"

@implementation GVAttributeInspectorController

- (id)init
{
	if (self = [super initWithWindowNibName: @"Attributes"]) {
		_allSchemas = nil;
		_allAttributes = [[NSMutableDictionary alloc] init];
27
		_inspectedDocument = nil;
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
		_otherChangedGraph = YES;
	}
	return self;
}

- (void)awakeFromNib
{
	/* set component toolbar */
	[_allSchemas release];
	_allSchemas = [[NSDictionary alloc] initWithObjectsAndKeys:
		[GVAttributeSchema attributeSchemasWithComponent:@"graph"], [graphToolbarItem itemIdentifier],
		[GVAttributeSchema attributeSchemasWithComponent:@"node"], [nodeDefaultToolbarItem itemIdentifier],
		[GVAttributeSchema attributeSchemasWithComponent:@"edge"], [edgeDefaultToolbarItem itemIdentifier],
		nil];
	[componentToolbar setSelectedItemIdentifier:[graphToolbarItem itemIdentifier]];
	[self toolbarItemDidSelect:nil];
		
	/* start observing whenever a window becomes main */
	[self graphWindowDidBecomeMain:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(graphWindowDidBecomeMain:) name:NSWindowDidBecomeMainNotification object:nil];
}

- (IBAction)toolbarItemDidSelect:(id)sender
{
	/* reload the table */
	[attributeTable reloadData];
}

- (void)graphWindowDidBecomeMain:(NSNotification *)notification
{
	NSWindow* mainWindow = notification ? [notification object] : [NSApp mainWindow];
59
	GVDocument* mainWindowDocument = [[mainWindow windowController] document];
60
		
61
	/* update and observe referenced document */
62
			NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
63 64 65 66 67 68
	if (_inspectedDocument)
		[defaultCenter removeObserver:self name:@"GVGraphDocumentDidChange" object:_inspectedDocument];
	_inspectedDocument = mainWindowDocument;
	[defaultCenter addObserver:self selector:@selector(graphDocumentDidChange:) name:@"GVGraphDocumentDidChange" object:mainWindowDocument];

	[self reloadAttributes];
69 70 71 72 73 74
		
			/* update the UI */
			[[self window] setTitle:[NSString stringWithFormat:@"%@ Attributes", [mainWindow title]]];
			[attributeTable reloadData];
}

75
- (void)graphDocumentDidChange:(NSNotification *)notification
76 77
{
	/* if we didn't instigate the change, update the UI */
78 79
	if (_otherChangedGraph) {
		[self reloadAttributes];
80
		[attributeTable reloadData];
81 82 83 84 85 86 87 88 89 90 91 92 93
	}
}

- (void)reloadAttributes
{
	/* reload the attributes from the inspected document's graph */
	[_allAttributes removeAllObjects];
	if ([_inspectedDocument respondsToSelector:@selector(graph)]) {
		GVGraph *graph = [_inspectedDocument graph];
		[_allAttributes setObject:graph.graphAttributes forKey:[graphToolbarItem itemIdentifier]];
		[_allAttributes setObject:graph.defaultNodeAttributes forKey:[nodeDefaultToolbarItem itemIdentifier]];
		[_allAttributes setObject:graph.defaultEdgeAttributes forKey:[edgeDefaultToolbarItem itemIdentifier]];
	}
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
}

- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
{
	/* which toolbar items are selectable */
	return [NSArray arrayWithObjects:
		[graphToolbarItem itemIdentifier],
		[nodeDefaultToolbarItem itemIdentifier],
		[edgeDefaultToolbarItem itemIdentifier],
		nil];
}

- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
	if ([[tableColumn identifier] isEqualToString:@"value"]) {
		/* use the row's schema's cell */
		NSCell *cell = [[[_allSchemas objectForKey:[componentToolbar selectedItemIdentifier]] objectAtIndex:row] cell];
		[cell setEnabled:[_allAttributes count] > 0];
		return cell;
	}
	else
		/* use the default cell (usually a text field) for other columns */
		return nil;
}

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
{
	int selectedRow = [[aNotification object] selectedRow];
	NSString* documentation = selectedRow == -1 ? nil : [[[_allSchemas objectForKey:[componentToolbar selectedItemIdentifier]] objectAtIndex: selectedRow] documentation];
	[[documentationWeb mainFrame] loadHTMLString:documentation baseURL:[NSURL URLWithString:@"http://www.graphviz.org/"]];
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
	return [[_allSchemas objectForKey:[componentToolbar selectedItemIdentifier]] count];
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
	NSString *selectedComponentIdentifier = [componentToolbar selectedItemIdentifier];
	NSString *attributeName = [[[_allSchemas objectForKey:selectedComponentIdentifier] objectAtIndex:rowIndex] name];
	if ([[tableColumn identifier] isEqualToString:@"key"])
		return attributeName;
	else if ([[tableColumn identifier] isEqualToString:@"value"])
		/* return the inspected graph's attribute value, if any */
		return [[_allAttributes objectForKey:selectedComponentIdentifier] valueForKey:attributeName];
	else
		return nil;
}

- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
	if ([[tableColumn identifier] isEqualToString:@"value"])
		{
			NSString *selectedComponentIdentifier = [componentToolbar selectedItemIdentifier];
			NSString *attributeName = [[[_allSchemas objectForKey:selectedComponentIdentifier] objectAtIndex:rowIndex] name];
			
			/* set or remove the key-value on the selected attributes */
152
			/* NOTE: to avoid needlessly reloading the table in graphDocumentDidChange:, we fence this change with _otherChangedGraph = NO */
153 154 155 156 157 158 159 160 161 162 163 164 165 166
			_otherChangedGraph = NO;
			@try {
				[[_allAttributes objectForKey:selectedComponentIdentifier] setValue:anObject forKey:attributeName];
			}
			@finally {
				_otherChangedGraph = YES;
			}
		}

}


- (void)dealloc
{
167
	[[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidBecomeMainNotification object:nil];
168 169
	[_allSchemas release];
	[_allAttributes release];
170
	[super dealloc];
171 172 173
}

@end