001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ 004 package graphlab.plugins.main.core.actions; 005 006 import graphlab.graph.atributeset.*; 007 import graphlab.graph.event.EdgeEvent; 008 import graphlab.graph.event.GraphSelectData; 009 import graphlab.graph.event.VertexEvent; 010 import graphlab.graph.graph.EdgeModel; 011 import graphlab.graph.graph.GraphModel; 012 import graphlab.graph.graph.VertexModel; 013 import graphlab.graph.old.GStroke; 014 import static graphlab.graph.old.GStroke.*; 015 import graphlab.platform.attribute.*; 016 import graphlab.platform.core.AbstractAction; 017 import graphlab.platform.core.BlackBoard; 018 import graphlab.plugins.main.select.Select; 019 import graphlab.plugins.main.select.SelectPluginMethods; 020 import graphlab.plugins.main.ui.GStrokeEditor; 021 import graphlab.ui.AttributeSetView; 022 import graphlab.ui.PortableNotifiableAttributeSetImpl; 023 import graphlab.ui.UIUtils; 024 import graphlab.ui.components.gpropertyeditor.GPropertyEditor; 025 026 import java.util.HashSet; 027 028 /** 029 * the left side property editor of graphlab gui 030 * 031 * @author Azin Azadi 032 */ 033 public class GraphPropertyEditor extends AbstractAction implements AttributeListener { 034 public GPropertyEditor getPropertyEditor() { 035 return prosheet; 036 } 037 038 private GPropertyEditor prosheet; 039 040 public NotifiableAttributeSet NotifiableAttributeSet; 041 042 public AttributeSetView viewer; 043 044 VertexModel lastVertex; 045 046 EdgeModel lastEdge; 047 048 private TimeLimitedNotifiableAttrSet target; 049 050 AttributeSetView edgeView = new AttributeSetView(); 051 052 AttributeSetView vertexView = new AttributeSetView(); 053 054 AttributeSetView graphView = new AttributeSetView(); 055 056 AttributeSetView selectView = new AttributeSetView(); 057 058 HashSet<String> hiddenVertexAttributes = new HashSet<String>(); 059 060 HashSet<String> hiddenEdgeAttributes = new HashSet<String>(); 061 062 PortableNotifiableAttributeSetImpl xx = new PortableNotifiableAttributeSetImpl(); 063 064 TimeLimitedNotifiableAttrSet selectionAttributes = new TimeLimitedNotifiableAttrSet(new AttributeSetImpl()); 065 066 SelectPluginMethods spm; 067 068 /** 069 * constructor 070 * 071 * @param bb the blackboard of the action 072 */ 073 public GraphPropertyEditor(BlackBoard bb) { 074 super(bb); 075 spm = new SelectPluginMethods(blackboard); 076 prosheet = new GPropertyEditor(); 077 prosheet.setSize(150, 100); 078 UIUtils.setComponent(blackboard, "property editor", prosheet); 079 listen4Event(EdgeEvent.EVENT_KEY); 080 listen4Event(VertexEvent.EVENT_KEY); 081 listen4Event(Select.EVENT_KEY); 082 listen4Event(GraphSelectData.EVENT_KEY); 083 084 // graphView.setVisible(GraphAttrSet.CENTERX, false); 085 // graphView.setVisible(GraphAttrSet.CENTERY, false); 086 // graphView.setVisible(GraphAttrSet.DIRECTED, false); 087 // graphView.setVisible(GraphAttrSet.ZOOM, false); 088 graphView.setIndex(GraphAttrSet.LABEL, 0); 089 graphView.setIndex(GraphAttrSet.DIRECTED, 1); 090 graphView.setIndex(GraphAttrSet.DRAW_VERTEX_LABELS, 5); 091 graphView.setIndex(GraphAttrSet.DRAW_EDGE_LABELS, 6); 092 graphView.setEditable(GraphAttrSet.DIRECTED, false); 093 graphView.setEditable(GraphAttrSet.LABEL, true); 094 095 // graphView.setIndex(EdgeAttrSet.SHOW_EDGE_LABELS, 3); 096 097 //Storing Id in vertex is deprecated 098 // vertexView.setVisible(VertexModel.ID, false); 099 // vertexView.setVisible(VertexModel.XPOS, false); 100 // vertexView.setVisible(VertexModel.YPOS, false); 101 vertexView.setIndex(VertexAttrSet.LABEL, 0); 102 vertexView.setIndex(VertexAttrSet.COLOR, 2); 103 vertexView.setIndex(VertexAttrSet.SHAPE, 4); 104 vertexView.setIndex(VertexAttrSet.BORDER, 6); 105 vertexView.setVisible(VertexAttrSet.SELECTED, false); 106 vertexView.setEditor(VertexAttrSet.BORDER, new GStrokeEditor() { 107 public Object[] getValues() { 108 return new GStroke[]{ 109 GStroke.empty, 110 simple, 111 solid, 112 strong, 113 dashed, 114 dotted, 115 dashed_dotted, 116 dashed_dotted_dotted, 117 dashed_dashed_dotted 118 }; 119 } 120 }); 121 vertexView.setEditor(VertexAttrSet.COLOR, new GMergedColorEditor(true)); 122 vertexView.setrenderer(VertexAttrSet.COLOR, new GMergedColorRenderer(true)); 123 124 // edgeView.setVisible(EdgeAttrSet.DIRECTED, false); 125 // edgeView.setVisible(EdgeAttrSet.LABEL, false); 126 edgeView.setEditable(EdgeAttrSet.SOURCE, false); 127 edgeView.setEditable(EdgeAttrSet.TARGET, false); 128 edgeView.setIndex(EdgeAttrSet.LABEL, 0); 129 edgeView.setIndex(EdgeAttrSet.WEIGHT, 1); 130 edgeView.setIndex(EdgeAttrSet.ARROW, 4); 131 edgeView.setEditor(EdgeAttrSet.COLOR, new GMergedColorEditor(false)); 132 edgeView.setrenderer(EdgeAttrSet.COLOR, new GMergedColorRenderer(false)); 133 // updateSelectView(); 134 135 } 136 137 138 private VertexModel lastVertex() { 139 VertexEvent x = blackboard.getData(VertexEvent.EVENT_KEY); 140 return (x == null ? null : x.v); 141 } 142 143 private EdgeModel lastEdge() { 144 EdgeEvent x = blackboard.getData(EdgeEvent.EVENT_KEY); 145 return (x == null ? null : x.e); 146 } 147 148 private GraphModel lastGraph() { 149 GraphSelectData x = blackboard.getData(GraphSelectData.EVENT_KEY); 150 return (x == null ? null : x.g); 151 } 152 153 public void performAction(String eventName, Object value) { 154 prosheet = (GPropertyEditor) UIUtils.getComponent(blackboard, 155 "property editor"); 156 if (getTarget() != null) 157 if (eventName == Select.EVENT_KEY) { 158 if (!spm.isSelectionEmpty()) { 159 updatePropertyEditor_selected(); 160 // viewer = selectView; 161 } else { 162 setTarget(new GraphNotifiableAttrSet(lastGraph())); 163 viewer = graphView; 164 } 165 } 166 // if (eventName ==VertexEvent.name)) { 167 // VertexEvent ve = blackboard.get(VertexEvent.name); 168 // if (ve.eventType == VertexEvent.PRESSED) { 169 // if (spm.isSelectionEmpty()) { 170 // setTarget(new VertexNotifiableAttrSet(lastVertex())); 171 // viewer = vertexView; 172 // } 173 // } 174 // } 175 // if (eventName ==EdgeEvent.name)) { 176 // EdgeEvent ve = blackboard.get(EdgeEvent.name); 177 // if (ve.eventType == EdgeEvent.PRESSED) { 178 // if (spm.isSelectionEmpty()) { 179 // setTarget(new EdgeNotifiableAttrSet(lastEdge())); 180 // viewer = edgeView; 181 // } 182 // } 183 // } 184 if (eventName == GraphSelectData.EVENT_KEY) { 185 setTarget(new GraphNotifiableAttrSet(lastGraph())); 186 viewer = graphView; 187 } 188 updateTarget(); 189 } 190 191 private void updateTarget() { 192 if (prosheet != null && getTarget() != null) { 193 xx.setView(viewer); 194 xx.setModel(getTarget()); 195 prosheet.connect(xx); 196 } 197 } 198 199 public void attributeUpdated(String name, Object oldVal, Object newVal) { 200 //occurs whenever one attribute in selection attribute changed by user 201 //note that the vertex and edge attributes are updates directly, not from here 202 if (!iChangedTheAttribute) { 203 String key = name.substring(1); //the original name of attribute 204 if (name.startsWith("v")) { //it was a vertex attribute 205 for (VertexModel v : spm.getSelectedVertices()) { 206 VertexAttrSet _v = new VertexAttrSet(v); 207 _v.put(key, newVal); 208 } 209 } 210 if (name.startsWith("e")) { //it was an edge attribute 211 for (EdgeModel e : spm.getSelectedEdges()) { 212 EdgeAttrSet _e = new EdgeAttrSet(e); 213 _e.put(key, newVal); 214 215 } 216 } 217 } 218 } 219 220 boolean iChangedTheAttribute = false; 221 222 private void updatePropertyEditor_selected() { 223 HashSet<VertexModel> selectedVertices = spm.getSelectedVertices(); 224 HashSet<EdgeModel> selectedEdges = spm.getSelectedEdges(); 225 226 int numOfSelectedVertices = selectedVertices.size(); 227 int numOfSelectedEdges = selectedEdges.size(); 228 229 //if there was only 1 selected vertex(edge) show the classic editor for it 230 if (numOfSelectedVertices + numOfSelectedEdges == 1) { 231 if (numOfSelectedVertices == 1) { 232 setTarget(new VertexNotifiableAttrSet(selectedVertices.iterator().next())); 233 viewer = vertexView; 234 } else { 235 setTarget(new EdgeNotifiableAttrSet(selectedEdges.iterator().next())); 236 viewer = edgeView; 237 } 238 } else { 239 viewer = selectView; 240 241 iChangedTheAttribute = true; 242 TimeLimitedNotifiableAttrSet retAtrs = new TimeLimitedNotifiableAttrSet(new AttributeSetImpl()); 243 retAtrs.removeAttributeListener(this); 244 245 //adding each Vertex/Edge attribute to selectionAttributes 246 int i = 0; 247 retAtrs.put("Vertices", numOfSelectedVertices); 248 selectView.setEditable("Vertices", false); 249 selectView.setIndex("Vertices", i++); 250 for (VertexModel v : selectedVertices) { 251 if (i < 500) { 252 AttributeSet vAtrs = new VertexAttrSet(v); 253 vertexView.setAttribute(vAtrs); 254 for (String atrName : vertexView.getNames()) { 255 String key = vertexAtrName(atrName); 256 insertAttributeToSelectionAtrs(retAtrs, key, vAtrs, atrName); 257 selectView.setDisplayName(key, atrName); 258 selectView.setIndex(key, i++); 259 } 260 } 261 } 262 263 retAtrs.put(" ", ""); 264 selectView.setEditable(" ", false); 265 retAtrs.put("Edges", numOfSelectedEdges); 266 selectView.setIndex(" ", i++); 267 selectView.setIndex("Edges", i++); 268 selectView.setEditable("Edges", false); 269 for (EdgeModel e : selectedEdges) { 270 if (i < 1000) { 271 AttributeSet eAtrs = new EdgeAttrSet(e); 272 for (String atrName : eAtrs.getAttrs().keySet()) { 273 String key = edgeAtrName(atrName); 274 insertAttributeToSelectionAtrs(retAtrs, key, eAtrs, atrName); 275 selectView.setDisplayName(key, atrName); 276 selectView.setIndex(key, i++); 277 } 278 } 279 } 280 selectView.setVisible("v" + VertexAttrSet.LOCATION, false); 281 selectView.setVisible("v" + VertexAttrSet.SELECTED, false); 282 selectView.setEditor("v" + VertexAttrSet.BORDER, new GStrokeEditor() { 283 public Object[] getValues() { 284 return new GStroke[]{ 285 GStroke.empty, 286 simple, 287 solid, 288 strong, 289 dashed, 290 dotted, 291 dashed_dotted, 292 dashed_dotted_dotted, 293 dashed_dashed_dotted 294 }; 295 } 296 }); 297 selectView.setEditor("v" + VertexAttrSet.COLOR, new GMergedColorEditor()); 298 selectView.setrenderer("v" + VertexAttrSet.COLOR, new GMergedColorRenderer()); 299 300 selectView.setEditor("e" + VertexAttrSet.COLOR, new GMergedColorEditor()); 301 selectView.setrenderer("e" + VertexAttrSet.COLOR, new GMergedColorRenderer()); 302 303 viewer = selectView; 304 retAtrs.addAttributeListener(this); 305 // updateSelectView(); 306 iChangedTheAttribute = false; 307 308 setTarget(retAtrs); 309 } 310 311 } 312 313 /** 314 * adds the given atr from source to dest, and if there was some values 315 * on the place before, invalidate the place 316 * 317 * @param dest 318 * @param key reffers to the atr name in dest 319 * @param source 320 * @param atrName reffers to the atr name in source that should be inserted to dest 321 */ 322 private void insertAttributeToSelectionAtrs(AttributeSet dest, String key, AttributeSet source, String atrName) { 323 if (dest.getAttrs().containsKey(key)) { 324 Object oldVal = dest.get(key); 325 if (oldVal == null) 326 return; 327 Object newVal = source.get(atrName); 328 if (!oldVal.equals(newVal)) { 329 selectView.setValid(key, false); 330 } 331 } else { 332 selectView.setValid(key, true); //it is valid default (in first time) 333 } 334 dest.put(key, source.get(atrName)); 335 } 336 337 // private void updateSelectView() { 338 // //selectView is the union of vertexView and edgeView 339 //// int maxIndex = Integer.MIN_VALUE; 340 //// selectView.setIndex("Vertices", 0); 341 // for (String key : selectionAttributes.getAttrs().keySet()) { 342 // String name = key.substring(1); //the original name of attribute 343 // if (key.startsWith("v")) { 344 // selectView.setVisible(key, vertexView.isVisible(name)); 345 //// selectView.setDisplayName(key, name); 346 //// selectView.setCategory(key, vertexAtrName(vertexView.getCategory(name))); 347 // selectView.setDescription(key, vertexView.getDescription(name)); 348 // selectView.setEditable(key, vertexView.isEditable(name)); 349 //// selectView.setIndex(key, vertexView.getIndex(name)); 350 //// maxIndex = Math.max(maxIndex, vertexView.getIndex(name)); 351 // } 352 //// selectView.setIndex("Edges", maxIndex + 1); 353 // if (key.startsWith("e")) { 354 // selectView.setVisible(key, edgeView.isVisible(name)); 355 //// selectView.setDisplayName(key, name); 356 //// selectView.setCategory(key, vertexAtrName(edgeView.getCategory(name))); 357 // selectView.setDescription(key, edgeView.getDescription(name)); 358 // selectView.setEditable(key, edgeView.isEditable(name)); 359 //// selectView.setIndex(key, maxIndex + edgeView.getIndex(name)); 360 // } 361 // } 362 // } 363 364 /** 365 * suggests a name for the given vertex attribute to be used in selection attributed 366 */ 367 private String vertexAtrName(String name) { 368 return "v" + name; 369 } 370 371 /** 372 * suggests a name for the given edge attribute to be used in selection attributed 373 */ 374 private String edgeAtrName(String name) { 375 return "e" + name; 376 } 377 378 379 private TimeLimitedNotifiableAttrSet getTarget() { 380 return target; 381 } 382 383 private void setTarget(TimeLimitedNotifiableAttrSet target) { 384 if (this.target != null) { 385 this.target.stop(); 386 } 387 this.target = target; 388 this.target.stop(); 389 } 390 }