$search
00001 00007 package org.best_of_robotics.model.datatypes.presentation; 00008 00009 00010 import java.io.IOException; 00011 import java.io.InputStream; 00012 00013 import java.util.ArrayList; 00014 import java.util.Collection; 00015 import java.util.Collections; 00016 import java.util.EventObject; 00017 import java.util.HashMap; 00018 import java.util.Iterator; 00019 import java.util.LinkedHashMap; 00020 import java.util.List; 00021 import java.util.Map; 00022 00023 import org.eclipse.core.resources.IFile; 00024 import org.eclipse.core.resources.IMarker; 00025 import org.eclipse.core.resources.IResource; 00026 import org.eclipse.core.resources.IResourceChangeEvent; 00027 import org.eclipse.core.resources.IResourceChangeListener; 00028 import org.eclipse.core.resources.IResourceDelta; 00029 import org.eclipse.core.resources.IResourceDeltaVisitor; 00030 import org.eclipse.core.resources.ResourcesPlugin; 00031 00032 import org.eclipse.core.runtime.CoreException; 00033 import org.eclipse.core.runtime.IPath; 00034 import org.eclipse.core.runtime.IProgressMonitor; 00035 import org.eclipse.core.runtime.NullProgressMonitor; 00036 00037 import org.eclipse.jface.action.IMenuListener; 00038 import org.eclipse.jface.action.IMenuManager; 00039 import org.eclipse.jface.action.IStatusLineManager; 00040 import org.eclipse.jface.action.IToolBarManager; 00041 import org.eclipse.jface.action.MenuManager; 00042 import org.eclipse.jface.action.Separator; 00043 00044 import org.eclipse.jface.dialogs.MessageDialog; 00045 import org.eclipse.jface.dialogs.ProgressMonitorDialog; 00046 00047 import org.eclipse.jface.viewers.ISelection; 00048 import org.eclipse.jface.viewers.ISelectionChangedListener; 00049 import org.eclipse.jface.viewers.ISelectionProvider; 00050 import org.eclipse.jface.viewers.IStructuredSelection; 00051 import org.eclipse.jface.viewers.SelectionChangedEvent; 00052 import org.eclipse.jface.viewers.StructuredSelection; 00053 import org.eclipse.jface.viewers.StructuredViewer; 00054 import org.eclipse.jface.viewers.TreeViewer; 00055 import org.eclipse.jface.viewers.Viewer; 00056 00057 import org.eclipse.swt.SWT; 00058 00059 import org.eclipse.swt.custom.CTabFolder; 00060 00061 import org.eclipse.swt.dnd.DND; 00062 import org.eclipse.swt.dnd.Transfer; 00063 00064 import org.eclipse.swt.events.ControlAdapter; 00065 import org.eclipse.swt.events.ControlEvent; 00066 00067 import org.eclipse.swt.graphics.Point; 00068 00069 import org.eclipse.swt.widgets.Composite; 00070 import org.eclipse.swt.widgets.Menu; 00071 import org.eclipse.swt.widgets.Tree; 00072 00073 import org.eclipse.ui.IActionBars; 00074 import org.eclipse.ui.IEditorInput; 00075 import org.eclipse.ui.IEditorPart; 00076 import org.eclipse.ui.IEditorSite; 00077 import org.eclipse.ui.IPartListener; 00078 import org.eclipse.ui.IWorkbenchPart; 00079 import org.eclipse.ui.PartInitException; 00080 00081 import org.eclipse.ui.dialogs.SaveAsDialog; 00082 00083 import org.eclipse.ui.ide.IGotoMarker; 00084 00085 import org.eclipse.ui.part.FileEditorInput; 00086 import org.eclipse.ui.part.MultiPageEditorPart; 00087 00088 import org.eclipse.ui.views.contentoutline.ContentOutline; 00089 import org.eclipse.ui.views.contentoutline.ContentOutlinePage; 00090 import org.eclipse.ui.views.contentoutline.IContentOutlinePage; 00091 00092 import org.eclipse.ui.views.properties.IPropertySheetPage; 00093 import org.eclipse.ui.views.properties.PropertySheet; 00094 import org.eclipse.ui.views.properties.PropertySheetPage; 00095 00096 import org.eclipse.emf.common.command.BasicCommandStack; 00097 import org.eclipse.emf.common.command.Command; 00098 import org.eclipse.emf.common.command.CommandStack; 00099 import org.eclipse.emf.common.command.CommandStackListener; 00100 00101 import org.eclipse.emf.common.notify.AdapterFactory; 00102 import org.eclipse.emf.common.notify.Notification; 00103 00104 import org.eclipse.emf.common.ui.MarkerHelper; 00105 00106 import org.eclipse.emf.common.ui.editor.ProblemEditorPart; 00107 00108 import org.eclipse.emf.common.ui.viewer.IViewerProvider; 00109 00110 import org.eclipse.emf.common.util.BasicDiagnostic; 00111 import org.eclipse.emf.common.util.Diagnostic; 00112 import org.eclipse.emf.common.util.URI; 00113 00114 import org.eclipse.emf.ecore.EObject; 00115 import org.eclipse.emf.ecore.EValidator; 00116 00117 import org.eclipse.emf.ecore.resource.Resource; 00118 import org.eclipse.emf.ecore.resource.ResourceSet; 00119 00120 import org.eclipse.emf.ecore.util.EContentAdapter; 00121 import org.eclipse.emf.ecore.util.EcoreUtil; 00122 00123 import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; 00124 import org.eclipse.emf.edit.domain.EditingDomain; 00125 import org.eclipse.emf.edit.domain.IEditingDomainProvider; 00126 00127 import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator; 00128 import org.eclipse.emf.edit.provider.ComposedAdapterFactory; 00129 import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; 00130 00131 import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory; 00132 00133 import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor; 00134 00135 import org.eclipse.emf.edit.ui.celleditor.AdapterFactoryTreeEditor; 00136 00137 import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter; 00138 import org.eclipse.emf.edit.ui.dnd.LocalTransfer; 00139 import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter; 00140 00141 import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; 00142 import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; 00143 import org.eclipse.emf.edit.ui.provider.UnwrappingSelectionProvider; 00144 00145 import org.eclipse.emf.edit.ui.util.EditUIMarkerHelper; 00146 import org.eclipse.emf.edit.ui.util.EditUIUtil; 00147 00148 import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage; 00149 00150 import org.best_of_robotics.model.datatypes.provider.DatatypesItemProviderAdapterFactory; 00151 00152 import org.eclipse.ui.actions.WorkspaceModifyOperation; 00153 00154 00161 public class DatatypesEditor 00162 extends MultiPageEditorPart 00163 implements IEditingDomainProvider, ISelectionProvider, IMenuListener, IViewerProvider, IGotoMarker { 00170 protected AdapterFactoryEditingDomain editingDomain; 00171 00178 protected ComposedAdapterFactory adapterFactory; 00179 00186 protected IContentOutlinePage contentOutlinePage; 00187 00194 protected IStatusLineManager contentOutlineStatusLineManager; 00195 00202 protected TreeViewer contentOutlineViewer; 00203 00210 protected PropertySheetPage propertySheetPage; 00211 00219 protected TreeViewer selectionViewer; 00220 00227 protected Viewer currentViewer; 00228 00235 protected ISelectionChangedListener selectionChangedListener; 00236 00243 protected Collection<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>(); 00244 00251 protected ISelection editorSelection = StructuredSelection.EMPTY; 00252 00260 protected MarkerHelper markerHelper = new EditUIMarkerHelper(); 00261 00268 protected IPartListener partListener = 00269 new IPartListener() { 00270 public void partActivated(IWorkbenchPart p) { 00271 if (p instanceof ContentOutline) { 00272 if (((ContentOutline)p).getCurrentPage() == contentOutlinePage) { 00273 getActionBarContributor().setActiveEditor(DatatypesEditor.this); 00274 00275 setCurrentViewer(contentOutlineViewer); 00276 } 00277 } 00278 else if (p instanceof PropertySheet) { 00279 if (((PropertySheet)p).getCurrentPage() == propertySheetPage) { 00280 getActionBarContributor().setActiveEditor(DatatypesEditor.this); 00281 handleActivate(); 00282 } 00283 } 00284 else if (p == DatatypesEditor.this) { 00285 handleActivate(); 00286 } 00287 } 00288 public void partBroughtToTop(IWorkbenchPart p) { 00289 // Ignore. 00290 } 00291 public void partClosed(IWorkbenchPart p) { 00292 // Ignore. 00293 } 00294 public void partDeactivated(IWorkbenchPart p) { 00295 // Ignore. 00296 } 00297 public void partOpened(IWorkbenchPart p) { 00298 // Ignore. 00299 } 00300 }; 00301 00308 protected Collection<Resource> removedResources = new ArrayList<Resource>(); 00309 00316 protected Collection<Resource> changedResources = new ArrayList<Resource>(); 00317 00324 protected Collection<Resource> savedResources = new ArrayList<Resource>(); 00325 00332 protected Map<Resource, Diagnostic> resourceToDiagnosticMap = new LinkedHashMap<Resource, Diagnostic>(); 00333 00340 protected boolean updateProblemIndication = true; 00341 00348 protected EContentAdapter problemIndicationAdapter = 00349 new EContentAdapter() { 00350 @Override 00351 public void notifyChanged(Notification notification) { 00352 if (notification.getNotifier() instanceof Resource) { 00353 switch (notification.getFeatureID(Resource.class)) { 00354 case Resource.RESOURCE__IS_LOADED: 00355 case Resource.RESOURCE__ERRORS: 00356 case Resource.RESOURCE__WARNINGS: { 00357 Resource resource = (Resource)notification.getNotifier(); 00358 Diagnostic diagnostic = analyzeResourceProblems(resource, null); 00359 if (diagnostic.getSeverity() != Diagnostic.OK) { 00360 resourceToDiagnosticMap.put(resource, diagnostic); 00361 } 00362 else { 00363 resourceToDiagnosticMap.remove(resource); 00364 } 00365 00366 if (updateProblemIndication) { 00367 getSite().getShell().getDisplay().asyncExec 00368 (new Runnable() { 00369 public void run() { 00370 updateProblemIndication(); 00371 } 00372 }); 00373 } 00374 break; 00375 } 00376 } 00377 } 00378 else { 00379 super.notifyChanged(notification); 00380 } 00381 } 00382 00383 @Override 00384 protected void setTarget(Resource target) { 00385 basicSetTarget(target); 00386 } 00387 00388 @Override 00389 protected void unsetTarget(Resource target) { 00390 basicUnsetTarget(target); 00391 } 00392 }; 00393 00400 protected IResourceChangeListener resourceChangeListener = 00401 new IResourceChangeListener() { 00402 public void resourceChanged(IResourceChangeEvent event) { 00403 IResourceDelta delta = event.getDelta(); 00404 try { 00405 class ResourceDeltaVisitor implements IResourceDeltaVisitor { 00406 protected ResourceSet resourceSet = editingDomain.getResourceSet(); 00407 protected Collection<Resource> changedResources = new ArrayList<Resource>(); 00408 protected Collection<Resource> removedResources = new ArrayList<Resource>(); 00409 00410 public boolean visit(IResourceDelta delta) { 00411 if (delta.getResource().getType() == IResource.FILE) { 00412 if (delta.getKind() == IResourceDelta.REMOVED || 00413 delta.getKind() == IResourceDelta.CHANGED && delta.getFlags() != IResourceDelta.MARKERS) { 00414 Resource resource = resourceSet.getResource(URI.createPlatformResourceURI(delta.getFullPath().toString(), true), false); 00415 if (resource != null) { 00416 if (delta.getKind() == IResourceDelta.REMOVED) { 00417 removedResources.add(resource); 00418 } 00419 else if (!savedResources.remove(resource)) { 00420 changedResources.add(resource); 00421 } 00422 } 00423 } 00424 } 00425 00426 return true; 00427 } 00428 00429 public Collection<Resource> getChangedResources() { 00430 return changedResources; 00431 } 00432 00433 public Collection<Resource> getRemovedResources() { 00434 return removedResources; 00435 } 00436 } 00437 00438 final ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(); 00439 delta.accept(visitor); 00440 00441 if (!visitor.getRemovedResources().isEmpty()) { 00442 getSite().getShell().getDisplay().asyncExec 00443 (new Runnable() { 00444 public void run() { 00445 removedResources.addAll(visitor.getRemovedResources()); 00446 if (!isDirty()) { 00447 getSite().getPage().closeEditor(DatatypesEditor.this, false); 00448 } 00449 } 00450 }); 00451 } 00452 00453 if (!visitor.getChangedResources().isEmpty()) { 00454 getSite().getShell().getDisplay().asyncExec 00455 (new Runnable() { 00456 public void run() { 00457 changedResources.addAll(visitor.getChangedResources()); 00458 if (getSite().getPage().getActiveEditor() == DatatypesEditor.this) { 00459 handleActivate(); 00460 } 00461 } 00462 }); 00463 } 00464 } 00465 catch (CoreException exception) { 00466 DataTypesEditorPlugin.INSTANCE.log(exception); 00467 } 00468 } 00469 }; 00470 00477 protected void handleActivate() { 00478 // Recompute the read only state. 00479 // 00480 if (editingDomain.getResourceToReadOnlyMap() != null) { 00481 editingDomain.getResourceToReadOnlyMap().clear(); 00482 00483 // Refresh any actions that may become enabled or disabled. 00484 // 00485 setSelection(getSelection()); 00486 } 00487 00488 if (!removedResources.isEmpty()) { 00489 if (handleDirtyConflict()) { 00490 getSite().getPage().closeEditor(DatatypesEditor.this, false); 00491 } 00492 else { 00493 removedResources.clear(); 00494 changedResources.clear(); 00495 savedResources.clear(); 00496 } 00497 } 00498 else if (!changedResources.isEmpty()) { 00499 changedResources.removeAll(savedResources); 00500 handleChangedResources(); 00501 changedResources.clear(); 00502 savedResources.clear(); 00503 } 00504 } 00505 00512 protected void handleChangedResources() { 00513 if (!changedResources.isEmpty() && (!isDirty() || handleDirtyConflict())) { 00514 if (isDirty()) { 00515 changedResources.addAll(editingDomain.getResourceSet().getResources()); 00516 } 00517 editingDomain.getCommandStack().flush(); 00518 00519 updateProblemIndication = false; 00520 for (Resource resource : changedResources) { 00521 if (resource.isLoaded()) { 00522 resource.unload(); 00523 try { 00524 resource.load(Collections.EMPTY_MAP); 00525 } 00526 catch (IOException exception) { 00527 if (!resourceToDiagnosticMap.containsKey(resource)) { 00528 resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception)); 00529 } 00530 } 00531 } 00532 } 00533 00534 if (AdapterFactoryEditingDomain.isStale(editorSelection)) { 00535 setSelection(StructuredSelection.EMPTY); 00536 } 00537 00538 updateProblemIndication = true; 00539 updateProblemIndication(); 00540 } 00541 } 00542 00549 protected void updateProblemIndication() { 00550 if (updateProblemIndication) { 00551 BasicDiagnostic diagnostic = 00552 new BasicDiagnostic 00553 (Diagnostic.OK, 00554 "org.best_of_robotics.model.datatypes.editor", 00555 0, 00556 null, 00557 new Object [] { editingDomain.getResourceSet() }); 00558 for (Diagnostic childDiagnostic : resourceToDiagnosticMap.values()) { 00559 if (childDiagnostic.getSeverity() != Diagnostic.OK) { 00560 diagnostic.add(childDiagnostic); 00561 } 00562 } 00563 00564 int lastEditorPage = getPageCount() - 1; 00565 if (lastEditorPage >= 0 && getEditor(lastEditorPage) instanceof ProblemEditorPart) { 00566 ((ProblemEditorPart)getEditor(lastEditorPage)).setDiagnostic(diagnostic); 00567 if (diagnostic.getSeverity() != Diagnostic.OK) { 00568 setActivePage(lastEditorPage); 00569 } 00570 } 00571 else if (diagnostic.getSeverity() != Diagnostic.OK) { 00572 ProblemEditorPart problemEditorPart = new ProblemEditorPart(); 00573 problemEditorPart.setDiagnostic(diagnostic); 00574 problemEditorPart.setMarkerHelper(markerHelper); 00575 try { 00576 addPage(++lastEditorPage, problemEditorPart, getEditorInput()); 00577 setPageText(lastEditorPage, problemEditorPart.getPartName()); 00578 setActivePage(lastEditorPage); 00579 showTabs(); 00580 } 00581 catch (PartInitException exception) { 00582 DataTypesEditorPlugin.INSTANCE.log(exception); 00583 } 00584 } 00585 00586 if (markerHelper.hasMarkers(editingDomain.getResourceSet())) { 00587 markerHelper.deleteMarkers(editingDomain.getResourceSet()); 00588 if (diagnostic.getSeverity() != Diagnostic.OK) { 00589 try { 00590 markerHelper.createMarkers(diagnostic); 00591 } 00592 catch (CoreException exception) { 00593 DataTypesEditorPlugin.INSTANCE.log(exception); 00594 } 00595 } 00596 } 00597 } 00598 } 00599 00606 protected boolean handleDirtyConflict() { 00607 return 00608 MessageDialog.openQuestion 00609 (getSite().getShell(), 00610 getString("_UI_FileConflict_label"), 00611 getString("_WARN_FileConflict")); 00612 } 00613 00620 public DatatypesEditor() { 00621 super(); 00622 initializeEditingDomain(); 00623 } 00624 00631 protected void initializeEditingDomain() { 00632 // Create an adapter factory that yields item providers. 00633 // 00634 adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); 00635 00636 adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory()); 00637 adapterFactory.addAdapterFactory(new DatatypesItemProviderAdapterFactory()); 00638 adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory()); 00639 00640 // Create the command stack that will notify this editor as commands are executed. 00641 // 00642 BasicCommandStack commandStack = new BasicCommandStack(); 00643 00644 // Add a listener to set the most recent command's affected objects to be the selection of the viewer with focus. 00645 // 00646 commandStack.addCommandStackListener 00647 (new CommandStackListener() { 00648 public void commandStackChanged(final EventObject event) { 00649 getContainer().getDisplay().asyncExec 00650 (new Runnable() { 00651 public void run() { 00652 firePropertyChange(IEditorPart.PROP_DIRTY); 00653 00654 // Try to select the affected objects. 00655 // 00656 Command mostRecentCommand = ((CommandStack)event.getSource()).getMostRecentCommand(); 00657 if (mostRecentCommand != null) { 00658 setSelectionToViewer(mostRecentCommand.getAffectedObjects()); 00659 } 00660 if (propertySheetPage != null && !propertySheetPage.getControl().isDisposed()) { 00661 propertySheetPage.refresh(); 00662 } 00663 } 00664 }); 00665 } 00666 }); 00667 00668 // Create the editing domain with a special command stack. 00669 // 00670 editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack, new HashMap<Resource, Boolean>()); 00671 } 00672 00679 @Override 00680 protected void firePropertyChange(int action) { 00681 super.firePropertyChange(action); 00682 } 00683 00690 public void setSelectionToViewer(Collection<?> collection) { 00691 final Collection<?> theSelection = collection; 00692 // Make sure it's okay. 00693 // 00694 if (theSelection != null && !theSelection.isEmpty()) { 00695 Runnable runnable = 00696 new Runnable() { 00697 public void run() { 00698 // Try to select the items in the current content viewer of the editor. 00699 // 00700 if (currentViewer != null) { 00701 currentViewer.setSelection(new StructuredSelection(theSelection.toArray()), true); 00702 } 00703 } 00704 }; 00705 getSite().getShell().getDisplay().asyncExec(runnable); 00706 } 00707 } 00708 00717 public EditingDomain getEditingDomain() { 00718 return editingDomain; 00719 } 00720 00726 public class ReverseAdapterFactoryContentProvider extends AdapterFactoryContentProvider { 00732 public ReverseAdapterFactoryContentProvider(AdapterFactory adapterFactory) { 00733 super(adapterFactory); 00734 } 00735 00741 @Override 00742 public Object [] getElements(Object object) { 00743 Object parent = super.getParent(object); 00744 return (parent == null ? Collections.EMPTY_SET : Collections.singleton(parent)).toArray(); 00745 } 00746 00752 @Override 00753 public Object [] getChildren(Object object) { 00754 Object parent = super.getParent(object); 00755 return (parent == null ? Collections.EMPTY_SET : Collections.singleton(parent)).toArray(); 00756 } 00757 00763 @Override 00764 public boolean hasChildren(Object object) { 00765 Object parent = super.getParent(object); 00766 return parent != null; 00767 } 00768 00774 @Override 00775 public Object getParent(Object object) { 00776 return null; 00777 } 00778 } 00779 00787 public void setCurrentViewer(Viewer viewer) { 00788 // If it is changing... 00789 // 00790 if (currentViewer != viewer) { 00791 if (selectionChangedListener == null) { 00792 // Create the listener on demand. 00793 // 00794 selectionChangedListener = 00795 new ISelectionChangedListener() { 00796 // This just notifies those things that are affected by the section. 00797 // 00798 public void selectionChanged(SelectionChangedEvent selectionChangedEvent) { 00799 setSelection(selectionChangedEvent.getSelection()); 00800 } 00801 }; 00802 } 00803 00804 // Stop listening to the old one. 00805 // 00806 if (currentViewer != null) { 00807 currentViewer.removeSelectionChangedListener(selectionChangedListener); 00808 } 00809 00810 // Start listening to the new one. 00811 // 00812 if (viewer != null) { 00813 viewer.addSelectionChangedListener(selectionChangedListener); 00814 } 00815 00816 // Remember it. 00817 // 00818 currentViewer = viewer; 00819 00820 // Set the editors selection based on the current viewer's selection. 00821 // 00822 setSelection(currentViewer == null ? StructuredSelection.EMPTY : currentViewer.getSelection()); 00823 } 00824 } 00825 00832 public Viewer getViewer() { 00833 return currentViewer; 00834 } 00835 00842 protected void createContextMenuFor(StructuredViewer viewer) { 00843 MenuManager contextMenu = new MenuManager("#PopUp"); 00844 contextMenu.add(new Separator("additions")); 00845 contextMenu.setRemoveAllWhenShown(true); 00846 contextMenu.addMenuListener(this); 00847 Menu menu= contextMenu.createContextMenu(viewer.getControl()); 00848 viewer.getControl().setMenu(menu); 00849 getSite().registerContextMenu(contextMenu, new UnwrappingSelectionProvider(viewer)); 00850 00851 int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; 00852 Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() }; 00853 viewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(viewer)); 00854 viewer.addDropSupport(dndOperations, transfers, new EditingDomainViewerDropAdapter(editingDomain, viewer)); 00855 } 00856 00863 public void createModel() { 00864 URI resourceURI = EditUIUtil.getURI(getEditorInput()); 00865 Exception exception = null; 00866 Resource resource = null; 00867 try { 00868 // Load the resource through the editing domain. 00869 // 00870 resource = editingDomain.getResourceSet().getResource(resourceURI, true); 00871 } 00872 catch (Exception e) { 00873 exception = e; 00874 resource = editingDomain.getResourceSet().getResource(resourceURI, false); 00875 } 00876 00877 Diagnostic diagnostic = analyzeResourceProblems(resource, exception); 00878 if (diagnostic.getSeverity() != Diagnostic.OK) { 00879 resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception)); 00880 } 00881 editingDomain.getResourceSet().eAdapters().add(problemIndicationAdapter); 00882 } 00883 00891 public Diagnostic analyzeResourceProblems(Resource resource, Exception exception) { 00892 if (!resource.getErrors().isEmpty() || !resource.getWarnings().isEmpty()) { 00893 BasicDiagnostic basicDiagnostic = 00894 new BasicDiagnostic 00895 (Diagnostic.ERROR, 00896 "org.best_of_robotics.model.datatypes.editor", 00897 0, 00898 getString("_UI_CreateModelError_message", resource.getURI()), 00899 new Object [] { exception == null ? (Object)resource : exception }); 00900 basicDiagnostic.merge(EcoreUtil.computeDiagnostic(resource, true)); 00901 return basicDiagnostic; 00902 } 00903 else if (exception != null) { 00904 return 00905 new BasicDiagnostic 00906 (Diagnostic.ERROR, 00907 "org.best_of_robotics.model.datatypes.editor", 00908 0, 00909 getString("_UI_CreateModelError_message", resource.getURI()), 00910 new Object[] { exception }); 00911 } 00912 else { 00913 return Diagnostic.OK_INSTANCE; 00914 } 00915 } 00916 00923 @Override 00924 public void createPages() { 00925 // Creates the model from the editor input 00926 // 00927 createModel(); 00928 00929 // Only creates the other pages if there is something that can be edited 00930 // 00931 if (!getEditingDomain().getResourceSet().getResources().isEmpty()) { 00932 // Create a page for the selection tree view. 00933 // 00934 Tree tree = new Tree(getContainer(), SWT.MULTI); 00935 selectionViewer = new TreeViewer(tree); 00936 setCurrentViewer(selectionViewer); 00937 00938 selectionViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory)); 00939 selectionViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory)); 00940 selectionViewer.setInput(editingDomain.getResourceSet()); 00941 selectionViewer.setSelection(new StructuredSelection(editingDomain.getResourceSet().getResources().get(0)), true); 00942 00943 new AdapterFactoryTreeEditor(selectionViewer.getTree(), adapterFactory); 00944 00945 createContextMenuFor(selectionViewer); 00946 int pageIndex = addPage(tree); 00947 setPageText(pageIndex, getString("_UI_SelectionPage_label")); 00948 00949 getSite().getShell().getDisplay().asyncExec 00950 (new Runnable() { 00951 public void run() { 00952 setActivePage(0); 00953 } 00954 }); 00955 } 00956 00957 // Ensures that this editor will only display the page's tab 00958 // area if there are more than one page 00959 // 00960 getContainer().addControlListener 00961 (new ControlAdapter() { 00962 boolean guard = false; 00963 @Override 00964 public void controlResized(ControlEvent event) { 00965 if (!guard) { 00966 guard = true; 00967 hideTabs(); 00968 guard = false; 00969 } 00970 } 00971 }); 00972 00973 getSite().getShell().getDisplay().asyncExec 00974 (new Runnable() { 00975 public void run() { 00976 updateProblemIndication(); 00977 } 00978 }); 00979 } 00980 00988 protected void hideTabs() { 00989 if (getPageCount() <= 1) { 00990 setPageText(0, ""); 00991 if (getContainer() instanceof CTabFolder) { 00992 ((CTabFolder)getContainer()).setTabHeight(1); 00993 Point point = getContainer().getSize(); 00994 getContainer().setSize(point.x, point.y + 6); 00995 } 00996 } 00997 } 00998 01006 protected void showTabs() { 01007 if (getPageCount() > 1) { 01008 setPageText(0, getString("_UI_SelectionPage_label")); 01009 if (getContainer() instanceof CTabFolder) { 01010 ((CTabFolder)getContainer()).setTabHeight(SWT.DEFAULT); 01011 Point point = getContainer().getSize(); 01012 getContainer().setSize(point.x, point.y - 6); 01013 } 01014 } 01015 } 01016 01023 @Override 01024 protected void pageChange(int pageIndex) { 01025 super.pageChange(pageIndex); 01026 01027 if (contentOutlinePage != null) { 01028 handleContentOutlineSelection(contentOutlinePage.getSelection()); 01029 } 01030 } 01031 01038 @SuppressWarnings("rawtypes") 01039 @Override 01040 public Object getAdapter(Class key) { 01041 if (key.equals(IContentOutlinePage.class)) { 01042 return showOutlineView() ? getContentOutlinePage() : null; 01043 } 01044 else if (key.equals(IPropertySheetPage.class)) { 01045 return getPropertySheetPage(); 01046 } 01047 else if (key.equals(IGotoMarker.class)) { 01048 return this; 01049 } 01050 else { 01051 return super.getAdapter(key); 01052 } 01053 } 01054 01061 public IContentOutlinePage getContentOutlinePage() { 01062 if (contentOutlinePage == null) { 01063 // The content outline is just a tree. 01064 // 01065 class MyContentOutlinePage extends ContentOutlinePage { 01066 @Override 01067 public void createControl(Composite parent) { 01068 super.createControl(parent); 01069 contentOutlineViewer = getTreeViewer(); 01070 contentOutlineViewer.addSelectionChangedListener(this); 01071 01072 // Set up the tree viewer. 01073 // 01074 contentOutlineViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory)); 01075 contentOutlineViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory)); 01076 contentOutlineViewer.setInput(editingDomain.getResourceSet()); 01077 01078 // Make sure our popups work. 01079 // 01080 createContextMenuFor(contentOutlineViewer); 01081 01082 if (!editingDomain.getResourceSet().getResources().isEmpty()) { 01083 // Select the root object in the view. 01084 // 01085 contentOutlineViewer.setSelection(new StructuredSelection(editingDomain.getResourceSet().getResources().get(0)), true); 01086 } 01087 } 01088 01089 @Override 01090 public void makeContributions(IMenuManager menuManager, IToolBarManager toolBarManager, IStatusLineManager statusLineManager) { 01091 super.makeContributions(menuManager, toolBarManager, statusLineManager); 01092 contentOutlineStatusLineManager = statusLineManager; 01093 } 01094 01095 @Override 01096 public void setActionBars(IActionBars actionBars) { 01097 super.setActionBars(actionBars); 01098 getActionBarContributor().shareGlobalActions(this, actionBars); 01099 } 01100 } 01101 01102 contentOutlinePage = new MyContentOutlinePage(); 01103 01104 // Listen to selection so that we can handle it is a special way. 01105 // 01106 contentOutlinePage.addSelectionChangedListener 01107 (new ISelectionChangedListener() { 01108 // This ensures that we handle selections correctly. 01109 // 01110 public void selectionChanged(SelectionChangedEvent event) { 01111 handleContentOutlineSelection(event.getSelection()); 01112 } 01113 }); 01114 } 01115 01116 return contentOutlinePage; 01117 } 01118 01125 public IPropertySheetPage getPropertySheetPage() { 01126 if (propertySheetPage == null) { 01127 propertySheetPage = 01128 new ExtendedPropertySheetPage(editingDomain) { 01129 @Override 01130 public void setSelectionToViewer(List<?> selection) { 01131 DatatypesEditor.this.setSelectionToViewer(selection); 01132 DatatypesEditor.this.setFocus(); 01133 } 01134 01135 @Override 01136 public void setActionBars(IActionBars actionBars) { 01137 super.setActionBars(actionBars); 01138 getActionBarContributor().shareGlobalActions(this, actionBars); 01139 } 01140 }; 01141 propertySheetPage.setPropertySourceProvider(new AdapterFactoryContentProvider(adapterFactory)); 01142 } 01143 01144 return propertySheetPage; 01145 } 01146 01153 public void handleContentOutlineSelection(ISelection selection) { 01154 if (selectionViewer != null && !selection.isEmpty() && selection instanceof IStructuredSelection) { 01155 Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator(); 01156 if (selectedElements.hasNext()) { 01157 // Get the first selected element. 01158 // 01159 Object selectedElement = selectedElements.next(); 01160 01161 ArrayList<Object> selectionList = new ArrayList<Object>(); 01162 selectionList.add(selectedElement); 01163 while (selectedElements.hasNext()) { 01164 selectionList.add(selectedElements.next()); 01165 } 01166 01167 // Set the selection to the widget. 01168 // 01169 selectionViewer.setSelection(new StructuredSelection(selectionList)); 01170 } 01171 } 01172 } 01173 01180 @Override 01181 public boolean isDirty() { 01182 return ((BasicCommandStack)editingDomain.getCommandStack()).isSaveNeeded(); 01183 } 01184 01191 @Override 01192 public void doSave(IProgressMonitor progressMonitor) { 01193 // Save only resources that have actually changed. 01194 // 01195 final Map<Object, Object> saveOptions = new HashMap<Object, Object>(); 01196 saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER); 01197 01198 // Do the work within an operation because this is a long running activity that modifies the workbench. 01199 // 01200 WorkspaceModifyOperation operation = 01201 new WorkspaceModifyOperation() { 01202 // This is the method that gets invoked when the operation runs. 01203 // 01204 @Override 01205 public void execute(IProgressMonitor monitor) { 01206 // Save the resources to the file system. 01207 // 01208 boolean first = true; 01209 for (Resource resource : editingDomain.getResourceSet().getResources()) { 01210 if ((first || !resource.getContents().isEmpty() || isPersisted(resource)) && !editingDomain.isReadOnly(resource)) { 01211 try { 01212 long timeStamp = resource.getTimeStamp(); 01213 resource.save(saveOptions); 01214 if (resource.getTimeStamp() != timeStamp) { 01215 savedResources.add(resource); 01216 } 01217 } 01218 catch (Exception exception) { 01219 resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception)); 01220 } 01221 first = false; 01222 } 01223 } 01224 } 01225 }; 01226 01227 updateProblemIndication = false; 01228 try { 01229 // This runs the options, and shows progress. 01230 // 01231 new ProgressMonitorDialog(getSite().getShell()).run(true, false, operation); 01232 01233 // Refresh the necessary state. 01234 // 01235 ((BasicCommandStack)editingDomain.getCommandStack()).saveIsDone(); 01236 firePropertyChange(IEditorPart.PROP_DIRTY); 01237 } 01238 catch (Exception exception) { 01239 // Something went wrong that shouldn't. 01240 // 01241 DataTypesEditorPlugin.INSTANCE.log(exception); 01242 } 01243 updateProblemIndication = true; 01244 updateProblemIndication(); 01245 } 01246 01254 protected boolean isPersisted(Resource resource) { 01255 boolean result = false; 01256 try { 01257 InputStream stream = editingDomain.getResourceSet().getURIConverter().createInputStream(resource.getURI()); 01258 if (stream != null) { 01259 result = true; 01260 stream.close(); 01261 } 01262 } 01263 catch (IOException e) { 01264 // Ignore 01265 } 01266 return result; 01267 } 01268 01275 @Override 01276 public boolean isSaveAsAllowed() { 01277 return true; 01278 } 01279 01286 @Override 01287 public void doSaveAs() { 01288 SaveAsDialog saveAsDialog = new SaveAsDialog(getSite().getShell()); 01289 saveAsDialog.open(); 01290 IPath path = saveAsDialog.getResult(); 01291 if (path != null) { 01292 IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path); 01293 if (file != null) { 01294 doSaveAs(URI.createPlatformResourceURI(file.getFullPath().toString(), true), new FileEditorInput(file)); 01295 } 01296 } 01297 } 01298 01304 protected void doSaveAs(URI uri, IEditorInput editorInput) { 01305 (editingDomain.getResourceSet().getResources().get(0)).setURI(uri); 01306 setInputWithNotify(editorInput); 01307 setPartName(editorInput.getName()); 01308 IProgressMonitor progressMonitor = 01309 getActionBars().getStatusLineManager() != null ? 01310 getActionBars().getStatusLineManager().getProgressMonitor() : 01311 new NullProgressMonitor(); 01312 doSave(progressMonitor); 01313 } 01314 01320 public void gotoMarker(IMarker marker) { 01321 try { 01322 if (marker.getType().equals(EValidator.MARKER)) { 01323 String uriAttribute = marker.getAttribute(EValidator.URI_ATTRIBUTE, null); 01324 if (uriAttribute != null) { 01325 URI uri = URI.createURI(uriAttribute); 01326 EObject eObject = editingDomain.getResourceSet().getEObject(uri, true); 01327 if (eObject != null) { 01328 setSelectionToViewer(Collections.singleton(editingDomain.getWrapper(eObject))); 01329 } 01330 } 01331 } 01332 } 01333 catch (CoreException exception) { 01334 DataTypesEditorPlugin.INSTANCE.log(exception); 01335 } 01336 } 01337 01344 @Override 01345 public void init(IEditorSite site, IEditorInput editorInput) { 01346 setSite(site); 01347 setInputWithNotify(editorInput); 01348 setPartName(editorInput.getName()); 01349 site.setSelectionProvider(this); 01350 site.getPage().addPartListener(partListener); 01351 ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener, IResourceChangeEvent.POST_CHANGE); 01352 } 01353 01359 @Override 01360 public void setFocus() { 01361 getControl(getActivePage()).setFocus(); 01362 } 01363 01370 public void addSelectionChangedListener(ISelectionChangedListener listener) { 01371 selectionChangedListeners.add(listener); 01372 } 01373 01380 public void removeSelectionChangedListener(ISelectionChangedListener listener) { 01381 selectionChangedListeners.remove(listener); 01382 } 01383 01390 public ISelection getSelection() { 01391 return editorSelection; 01392 } 01393 01401 public void setSelection(ISelection selection) { 01402 editorSelection = selection; 01403 01404 for (ISelectionChangedListener listener : selectionChangedListeners) { 01405 listener.selectionChanged(new SelectionChangedEvent(this, selection)); 01406 } 01407 setStatusLineManager(selection); 01408 } 01409 01415 public void setStatusLineManager(ISelection selection) { 01416 IStatusLineManager statusLineManager = currentViewer != null && currentViewer == contentOutlineViewer ? 01417 contentOutlineStatusLineManager : getActionBars().getStatusLineManager(); 01418 01419 if (statusLineManager != null) { 01420 if (selection instanceof IStructuredSelection) { 01421 Collection<?> collection = ((IStructuredSelection)selection).toList(); 01422 switch (collection.size()) { 01423 case 0: { 01424 statusLineManager.setMessage(getString("_UI_NoObjectSelected")); 01425 break; 01426 } 01427 case 1: { 01428 String text = new AdapterFactoryItemDelegator(adapterFactory).getText(collection.iterator().next()); 01429 statusLineManager.setMessage(getString("_UI_SingleObjectSelected", text)); 01430 break; 01431 } 01432 default: { 01433 statusLineManager.setMessage(getString("_UI_MultiObjectSelected", Integer.toString(collection.size()))); 01434 break; 01435 } 01436 } 01437 } 01438 else { 01439 statusLineManager.setMessage(""); 01440 } 01441 } 01442 } 01443 01450 private static String getString(String key) { 01451 return DataTypesEditorPlugin.INSTANCE.getString(key); 01452 } 01453 01460 private static String getString(String key, Object s1) { 01461 return DataTypesEditorPlugin.INSTANCE.getString(key, new Object [] { s1 }); 01462 } 01463 01470 public void menuAboutToShow(IMenuManager menuManager) { 01471 ((IMenuListener)getEditorSite().getActionBarContributor()).menuAboutToShow(menuManager); 01472 } 01473 01479 public EditingDomainActionBarContributor getActionBarContributor() { 01480 return (EditingDomainActionBarContributor)getEditorSite().getActionBarContributor(); 01481 } 01482 01488 public IActionBars getActionBars() { 01489 return getActionBarContributor().getActionBars(); 01490 } 01491 01497 public AdapterFactory getAdapterFactory() { 01498 return adapterFactory; 01499 } 01500 01506 @Override 01507 public void dispose() { 01508 updateProblemIndication = false; 01509 01510 ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener); 01511 01512 getSite().getPage().removePartListener(partListener); 01513 01514 adapterFactory.dispose(); 01515 01516 if (getActionBarContributor().getActiveEditor() == this) { 01517 getActionBarContributor().setActiveEditor(null); 01518 } 01519 01520 if (propertySheetPage != null) { 01521 propertySheetPage.dispose(); 01522 } 01523 01524 if (contentOutlinePage != null) { 01525 contentOutlinePage.dispose(); 01526 } 01527 01528 super.dispose(); 01529 } 01530 01537 protected boolean showOutlineView() { 01538 return false; 01539 } 01540 }