GVAttributeInspectorController.m 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at http://www.graphviz.org/
  9. *************************************************************************/
  10. #import "GVAttributeInspectorController.h"
  11. #import "GVAttributeSchema.h"
  12. #import "GVDocument.h"
  13. #import "GVZGraph.h"
  14. #import "GVWindowController.h"
  15. @implementation GVAttributeInspectorController
  16. - (id)init
  17. {
  18. if (self = [super initWithWindowNibName: @"Attributes"]) {
  19. _allSchemas = nil;
  20. _allAttributes = [[NSMutableDictionary alloc] init];
  21. _inspectedDocument = nil;
  22. _otherChangedGraph = YES;
  23. }
  24. return self;
  25. }
  26. - (void)awakeFromNib
  27. {
  28. /* set component toolbar */
  29. [_allSchemas release];
  30. _allSchemas = [[NSDictionary alloc] initWithObjectsAndKeys:
  31. [GVAttributeSchema attributeSchemasWithComponent:@"graph"], [graphToolbarItem itemIdentifier],
  32. [GVAttributeSchema attributeSchemasWithComponent:@"node"], [nodeDefaultToolbarItem itemIdentifier],
  33. [GVAttributeSchema attributeSchemasWithComponent:@"edge"], [edgeDefaultToolbarItem itemIdentifier],
  34. nil];
  35. [componentToolbar setSelectedItemIdentifier:[graphToolbarItem itemIdentifier]];
  36. [self toolbarItemDidSelect:nil];
  37. /* start observing whenever a window becomes main */
  38. [self graphWindowDidBecomeMain:nil];
  39. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(graphWindowDidBecomeMain:) name:NSWindowDidBecomeMainNotification object:nil];
  40. }
  41. - (IBAction)toolbarItemDidSelect:(id)sender
  42. {
  43. /* reload the table */
  44. [attributeTable reloadData];
  45. }
  46. - (void)graphWindowDidBecomeMain:(NSNotification *)notification
  47. {
  48. NSWindow* mainWindow = notification ? [notification object] : [NSApp mainWindow];
  49. GVDocument* mainWindowDocument = [[mainWindow windowController] document];
  50. /* update and observe referenced document */
  51. NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
  52. if (_inspectedDocument)
  53. [defaultCenter removeObserver:self name:@"GVGraphDocumentDidChange" object:_inspectedDocument];
  54. _inspectedDocument = mainWindowDocument;
  55. [defaultCenter addObserver:self selector:@selector(graphDocumentDidChange:) name:@"GVGraphDocumentDidChange" object:mainWindowDocument];
  56. [self reloadAttributes];
  57. /* update the UI */
  58. [[self window] setTitle:[NSString stringWithFormat:@"%@ Attributes", [mainWindow title]]];
  59. [attributeTable reloadData];
  60. }
  61. - (void)graphDocumentDidChange:(NSNotification *)notification
  62. {
  63. /* if we didn't instigate the change, update the UI */
  64. if (_otherChangedGraph) {
  65. [self reloadAttributes];
  66. [attributeTable reloadData];
  67. }
  68. }
  69. - (void)reloadAttributes
  70. {
  71. /* reload the attributes from the inspected document's graph */
  72. [_allAttributes removeAllObjects];
  73. if ([_inspectedDocument respondsToSelector:@selector(graph)]) {
  74. GVZGraph *graph = [_inspectedDocument graph];
  75. [_allAttributes setObject:graph.graphAttributes forKey:[graphToolbarItem itemIdentifier]];
  76. [_allAttributes setObject:graph.defaultNodeAttributes forKey:[nodeDefaultToolbarItem itemIdentifier]];
  77. [_allAttributes setObject:graph.defaultEdgeAttributes forKey:[edgeDefaultToolbarItem itemIdentifier]];
  78. }
  79. }
  80. - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
  81. {
  82. /* which toolbar items are selectable */
  83. return [NSArray arrayWithObjects:
  84. [graphToolbarItem itemIdentifier],
  85. [nodeDefaultToolbarItem itemIdentifier],
  86. [edgeDefaultToolbarItem itemIdentifier],
  87. nil];
  88. }
  89. - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
  90. {
  91. if ([[tableColumn identifier] isEqualToString:@"value"]) {
  92. /* use the row's schema's cell */
  93. NSCell *cell = [[[_allSchemas objectForKey:[componentToolbar selectedItemIdentifier]] objectAtIndex:row] cell];
  94. [cell setEnabled:[_allAttributes count] > 0];
  95. return cell;
  96. }
  97. else
  98. /* use the default cell (usually a text field) for other columns */
  99. return nil;
  100. }
  101. - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
  102. {
  103. NSInteger selectedRow = [[aNotification object] selectedRow];
  104. NSString* documentation = selectedRow == -1 ? nil : [[[_allSchemas objectForKey:[componentToolbar selectedItemIdentifier]] objectAtIndex: selectedRow] documentation];
  105. [[documentationWeb mainFrame] loadHTMLString:documentation baseURL:[NSURL URLWithString:@"http://www.graphviz.org/"]];
  106. }
  107. - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
  108. {
  109. return [[_allSchemas objectForKey:[componentToolbar selectedItemIdentifier]] count];
  110. }
  111. - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
  112. {
  113. NSString *selectedComponentIdentifier = [componentToolbar selectedItemIdentifier];
  114. NSString *attributeName = [[[_allSchemas objectForKey:selectedComponentIdentifier] objectAtIndex:rowIndex] name];
  115. if ([[tableColumn identifier] isEqualToString:@"key"])
  116. return attributeName;
  117. else if ([[tableColumn identifier] isEqualToString:@"value"])
  118. /* return the inspected graph's attribute value, if any */
  119. return [[_allAttributes objectForKey:selectedComponentIdentifier] valueForKey:attributeName];
  120. else
  121. return nil;
  122. }
  123. - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
  124. {
  125. if ([[tableColumn identifier] isEqualToString:@"value"])
  126. {
  127. NSString *selectedComponentIdentifier = [componentToolbar selectedItemIdentifier];
  128. NSString *attributeName = [[[_allSchemas objectForKey:selectedComponentIdentifier] objectAtIndex:rowIndex] name];
  129. /* set or remove the key-value on the selected attributes */
  130. /* NOTE: to avoid needlessly reloading the table in graphDocumentDidChange:, we fence this change with _otherChangedGraph = NO */
  131. _otherChangedGraph = NO;
  132. @try {
  133. [[_allAttributes objectForKey:selectedComponentIdentifier] setValue:anObject forKey:attributeName];
  134. }
  135. @finally {
  136. _otherChangedGraph = YES;
  137. }
  138. }
  139. }
  140. - (void)dealloc
  141. {
  142. [[NSNotificationCenter defaultCenter] removeObserver:self name:NSWindowDidBecomeMainNotification object:nil];
  143. [_allSchemas release];
  144. [_allAttributes release];
  145. [super dealloc];
  146. }
  147. @end