1 19 20 package org.netbeans.modules.xml.schema.core.multiview; 21 22 import java.awt.event.ActionEvent ; 23 import java.awt.event.ActionListener ; 24 import java.awt.EventQueue ; 25 import java.io.IOException ; 26 import java.io.ObjectInput ; 27 import java.io.ObjectOutput ; 28 import java.util.List ; 29 import javax.swing.JComponent ; 30 import javax.swing.JEditorPane ; 31 import javax.swing.Timer ; 32 import javax.swing.event.CaretEvent ; 33 import javax.swing.event.CaretListener ; 34 import javax.swing.text.Document ; 35 import javax.swing.text.StyledDocument ; 36 import org.netbeans.core.spi.multiview.CloseOperationState; 37 import org.netbeans.core.spi.multiview.MultiViewElement; 38 import org.netbeans.core.spi.multiview.MultiViewElementCallback; 39 import org.netbeans.core.spi.multiview.MultiViewFactory; 40 import org.netbeans.modules.xml.schema.core.SchemaDataObject; 41 import org.netbeans.modules.xml.schema.core.SchemaEditorSupport; 42 import org.netbeans.modules.xml.schema.model.SchemaComponent; 43 import org.netbeans.modules.xml.schema.model.SchemaModel; 44 import org.netbeans.modules.xml.schema.ui.basic.UIUtilities; 45 import org.netbeans.modules.xml.schema.ui.nodes.StructuralSchemaNodeFactory; 46 import org.netbeans.modules.xml.validation.ShowCookie; 47 import org.netbeans.modules.xml.xam.Component; 48 import org.netbeans.modules.xml.xam.spi.Validator.ResultItem; 49 import org.openide.awt.UndoRedo; 50 import org.openide.nodes.Node; 51 import org.openide.nodes.NodeAdapter; 52 import org.openide.nodes.NodeEvent; 53 import org.openide.text.CloneableEditor; 54 import org.openide.text.NbDocument; 55 import org.openide.util.Lookup; 56 import org.openide.util.RequestProcessor; 57 import org.openide.util.lookup.Lookups; 58 59 65 public class SchemaSourceMultiViewElement extends CloneableEditor 66 implements MultiViewElement { 67 private static final long serialVersionUID = 4403502726950453345L; 68 private transient JComponent toolbar; 69 private transient MultiViewElementCallback multiViewCallback; 70 private SchemaDataObject schemaDataObject; 71 72 75 public SchemaSourceMultiViewElement() { 76 super(); 78 } 79 80 85 public SchemaSourceMultiViewElement(SchemaDataObject dobj) { 86 super(dobj.getSchemaEditorSupport()); 87 this.schemaDataObject = dobj; 88 89 dobj.getSchemaEditorSupport().initializeCloneableEditor(this); 100 initialize(); 101 } 102 103 106 private void initialize() { 107 ShowCookie showCookie = new ShowCookie() { 108 109 public void show(ResultItem resultItem) { 110 if(isActiveTC()) { 111 Component component = resultItem.getComponents(); 112 if(component instanceof SchemaComponent) { 113 int position = ((SchemaComponent)component).findPosition(); 114 getEditorPane().setCaretPosition(position); 115 } else { 116 int line = resultItem.getLineNumber(); 117 try { 118 int position = NbDocument.findLineOffset( 119 (StyledDocument )getEditorPane().getDocument(),line); 120 getEditorPane().setCaretPosition(position); 121 } catch (IndexOutOfBoundsException iob) { 122 } 124 } 125 } 126 } 127 }; 128 129 Node delegate = schemaDataObject.getNodeDelegate(); 131 SourceCookieProxyLookup lookup = new SourceCookieProxyLookup(new Lookup[] { 132 Lookups.fixed(new Object [] { 133 getActionMap(), 135 schemaDataObject, 139 showCookie, 141 }), 142 },delegate); 143 associateLookup(lookup); 144 addPropertyChangeListener("activatedNodes", lookup); 145 146 caretListener = new CaretListener () { 147 public void caretUpdate(CaretEvent e) { 148 timerSelNodes.restart(); 149 } 150 }; 151 152 timerSelNodes = new Timer (1, new ActionListener () { 153 public void actionPerformed(ActionEvent e) { 154 if (!isActiveTC() || getEditorPane() == null) { 155 return; 156 } 157 selectElementsAtOffset(); 158 } 159 }); 160 timerSelNodes.setRepeats(false); 161 } 162 163 public JComponent getToolbarRepresentation() { 164 Document doc = getEditorPane().getDocument(); 165 if (doc instanceof NbDocument.CustomToolbar) { 166 if (toolbar == null) { 167 toolbar = ((NbDocument.CustomToolbar) doc).createToolbar(getEditorPane()); 168 } 169 return toolbar; 170 } 171 return null; 172 } 173 174 public JComponent getVisualRepresentation() { 175 return this; 176 } 177 178 public void setMultiViewCallback(final MultiViewElementCallback callback) { 179 multiViewCallback = callback; 180 } 181 182 public void requestVisible() { 183 if (multiViewCallback != null) 184 multiViewCallback.requestVisible(); 185 else 186 super.requestVisible(); 187 } 188 189 public void requestActive() { 190 if (multiViewCallback != null) 191 multiViewCallback.requestActive(); 192 else 193 super.requestActive(); 194 } 195 196 protected String preferredID() { 197 return getClass().getName(); 198 } 199 200 201 public UndoRedo getUndoRedo() { 202 return schemaDataObject.getSchemaEditorSupport().getUndoManager(); 203 } 204 205 214 protected boolean closeLast() { 215 SchemaEditorSupport ses = schemaDataObject.getSchemaEditorSupport(); 216 JEditorPane [] editors = ses.getOpenedPanes(); 217 if (editors == null || editors.length == 0) { 218 return ses.silentClose(); 219 } 220 return false; 221 } 222 223 public CloseOperationState canCloseElement() { 224 if (!SchemaMultiViewSupport.isLastView(multiViewCallback.getTopComponent())) { 226 return CloseOperationState.STATE_OK; 227 } 228 return MultiViewFactory.createUnsafeCloseState( 230 "ID_TEXT_CLOSING", MultiViewFactory.NOOP_CLOSE_ACTION, 232 MultiViewFactory.NOOP_CLOSE_ACTION); 233 } 234 235 public void componentActivated() { 236 JEditorPane p = getEditorPane(); 237 if (p != null) { 238 p.addCaretListener(caretListener); 239 } 240 if(timerSelNodes!=null) { 241 timerSelNodes.restart(); 242 } 243 super.componentActivated(); 244 SchemaEditorSupport editor = schemaDataObject.getSchemaEditorSupport(); 245 editor.addUndoManagerToDocument(); 246 } 247 248 public void componentDeactivated() { 249 JEditorPane p = getEditorPane(); 253 if (p != null) { 254 p.removeCaretListener(caretListener); 255 } 256 synchronized (this) { 257 if (selectionTask != null) { 258 selectionTask.cancel(); 259 selectionTask = null; 260 } 261 } 262 if(timerSelNodes!=null) { 263 timerSelNodes.stop(); 264 } 265 super.componentDeactivated(); 266 SchemaEditorSupport editor = schemaDataObject.getSchemaEditorSupport(); 267 editor.syncModel(); 270 editor.removeUndoManagerFromDocument(); 271 } 272 273 public void componentOpened() { 274 super.componentOpened(); 275 } 276 277 public void componentClosed() { 278 super.componentClosed(); 279 } 280 281 public void componentShowing() { 282 super.componentShowing(); 283 SchemaEditorSupport editor = schemaDataObject.getSchemaEditorSupport(); 284 editor.addUndoManagerToDocument(); 285 } 286 287 public void componentHidden() { 288 super.componentHidden(); 289 SchemaEditorSupport editor = schemaDataObject.getSchemaEditorSupport(); 290 editor.syncModel(); 293 editor.removeUndoManagerFromDocument(); 294 } 295 296 public void writeExternal(ObjectOutput out) throws IOException { 297 super.writeExternal(out); 299 out.writeObject(schemaDataObject); 300 } 301 302 public void readExternal(ObjectInput in) 303 throws IOException , ClassNotFoundException { 304 super.readExternal(in); 305 Object firstObject = in.readObject(); 308 if (firstObject instanceof SchemaDataObject) { 309 schemaDataObject = (SchemaDataObject) firstObject; 310 } 311 initialize(); 312 } 313 314 316 private Node rootNode; 317 318 private Node selectedNode; 319 320 private NodeAdapter nl; 321 322 private Timer timerSelNodes; 323 324 private CaretListener caretListener; 325 326 private transient RequestProcessor.Task selectionTask = null; 327 328 void selectElementsAtOffset() 329 { 330 if(selectionTask!=null) 331 { 332 selectionTask.cancel(); 333 selectionTask = null; 334 } 335 RequestProcessor rp = new RequestProcessor("schema source view processor "+hashCode()); 336 selectionTask = rp.create(new Runnable () 337 { 338 public void run() 339 { 340 if (!isActiveTC() || schemaDataObject == null || 341 !schemaDataObject.isValid() || schemaDataObject.isTemplate()) 342 { 343 return; 344 } 345 Node n = findNode(getEditorPane().getCaret().getDot()); 346 if(n==null) 348 { 349 setActivatedNodes(new Node[] { 350 schemaDataObject.getNodeDelegate() }); 351 } 352 else 353 { 354 if(selectedNode!=n) 355 { 356 if(nl==null) 357 { 358 nl = new NodeAdapter() 359 { 360 public void nodeDestroyed(NodeEvent ev) 361 { 362 if(ev.getNode()==selectedNode) 363 { 364 selectElementsAtOffset(); 365 } 366 } 367 }; 368 } 369 else if(selectedNode!=null) 370 { 371 selectedNode.removeNodeListener(nl); 372 } 373 selectedNode = n; 374 selectedNode.addNodeListener(nl); 375 setActivatedNodes(new Node[] { selectedNode }); 376 } 377 } 378 } 379 }); 380 if(EventQueue.isDispatchThread()) { 381 selectionTask.run(); 382 } else { 383 EventQueue.invokeLater(selectionTask); 384 } 385 } 386 387 private Node findNode(int offset) 388 { 389 try 390 { 391 SchemaEditorSupport support = schemaDataObject.getSchemaEditorSupport(); 392 if(support==null) return null; 393 SchemaModel model = support.getModel(); 394 if(model==null||model.getState()!=SchemaModel.State.VALID) return null; 395 if(rootNode==null) 396 rootNode = new StructuralSchemaNodeFactory(support.getModel(), 397 schemaDataObject.getNodeDelegate().getLookup()).createRootNode(); 398 if(rootNode==null) return null; 399 SchemaComponent sc = (SchemaComponent) support.getModel(). 400 findComponent(offset); 401 if(sc==null) return null; 402 List <Node> path = UIUtilities.findPathFromRoot(rootNode,sc); 403 if(!path.isEmpty()) 404 return path.get(path.size()-1); 405 } 406 catch (IOException ioe) 407 { 408 } 409 return null; 410 } 411 412 protected boolean isActiveTC() 413 { 414 return getRegistry().getActivated() == multiViewCallback.getTopComponent(); 415 } 416 417 } 418 | Popular Tags |