package rtt.annotation.editor.ui; import java.io.IOException; import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Observable; import java.util.Observer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.layout.TreeColumnLayout; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnPixelData; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.part.FileEditorInput; import rtt.annotation.editor.AnnotationEditorPlugin; import rtt.annotation.editor.controller.ControllerRegistry; import rtt.annotation.editor.controller.IAnnotationController.Mode; import rtt.annotation.editor.data.AnnotationExporter; import rtt.annotation.editor.data.AnnotationImporter; import rtt.annotation.editor.data.ModelReader; import rtt.annotation.editor.data.ModelWriter; import rtt.annotation.editor.data.asm.ASMClassModelManager; import rtt.annotation.editor.data.jaxb.JAXBAnnotationManager; import rtt.annotation.editor.model.ClassElement; import rtt.annotation.editor.model.ClassModel; import rtt.annotation.editor.model.ModelElement; import rtt.annotation.editor.model.annotation.Annotatable; import rtt.annotation.editor.model.annotation.Annotation.AnnotationType; import rtt.annotation.editor.model.annotation.NodeAnnotation; import rtt.annotation.editor.ui.viewer.provider.EditableViewerItem; import rtt.annotation.editor.ui.viewer.provider.MemberViewerItemProvider; import rtt.annotation.editor.ui.viewer.provider.ModelElementViewerItem; import rtt.annotation.editor.ui.viewer.provider.NodeViewerItemProvider; import rtt.annotation.editor.ui.viewer.provider.PropertyViewerItemProvider; import rtt.annotation.editor.ui.viewer.provider.ViewerItem; import rtt.annotation.editor.ui.viewer.provider.ViewerItemProvider; import rtt.annotation.editor.ui.viewer.util.ViewerSelectionUtil; /** * The annotation editor. * * @author Christian Oelsner <C.Oelsner@web.de> * */ public class AnnotationEditor extends EditorPart implements Observer { private static class ViewerItemComparator extends ViewerComparator { public int compare(Viewer viewer, Object e1, Object e2) { if (e1 instanceof ViewerItem && e2 instanceof ViewerItem) { String e1Text = ((ViewerItem) e1).getColumnText(0); String e2Text = ((ViewerItem) e2).getColumnText(0); return e1Text.compareTo(e2Text); } return super.compare(viewer, e1, e2); } } private final class NodeFilter extends ViewerFilter { private boolean filterNodes = false; @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof ModelElementViewerItem<?>) { ClassElement classElement = ((ModelElementViewerItem<?>) element). getModelElement(ClassElement.class); if (classElement != null && filterNodes) { return classElement.hasAnnotation(AnnotationType.NODE) || classElement.hasExtendedAnnotation(); } } return true; } public void filterNodes(boolean filterNodes) { this.filterNodes = filterNodes; } } private final class ClassSearchFilter extends ViewerFilter { private String searchedClass = null; @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof ModelElementViewerItem<?>) { ClassElement classElement = ((ModelElementViewerItem<?>) element). getModelElement(ClassElement.class); if (classElement != null && searchedClass != null) { return classElement.getName().startsWith(searchedClass); } } return true; } public void searchClass(String searchedClass) { this.searchedClass = searchedClass; } } private abstract class SetAnnotationSelectionAdapter extends SelectionAdapter { private Mode mode; public SetAnnotationSelectionAdapter(Mode mode) { this.mode = mode; } @Override public void widgetSelected(SelectionEvent e) { Viewer viewer = getViewer(); ModelElement modelElement = ViewerSelectionUtil. getModelElement(viewer.getSelection()); if (modelElement instanceof Annotatable<?>) { ControllerRegistry.execute(mode, getAnnotation().getType(), (Annotatable<?>) modelElement); } nodeViewer.refresh(); memberViewer.refresh(); propertyViewer.refresh(); viewer.setSelection(viewer.getSelection(), true); } public abstract Viewer getViewer(); public abstract AnnotationType getAnnotation(); } private static final int MIN_COLUMN_WIDTH = 200; private static final int SECOND_LEVEL = 2; private TreeViewer propertyViewer; private TreeViewer memberViewer; private TreeViewer nodeViewer; private ViewerItemProvider nodeProvider; private ViewerItemProvider memberProvider; private ViewerItemProvider propertyProvider; private NodeFilter nodeFilter; private ClassSearchFilter searchFilter; private ClassModel model; private AnnotationType selectedAnnotation = AnnotationType.VALUE; private Button valueAnnotationButton; private Button initializeAnnotationButton; private Button setNodeButton; private Button setAnnotationButton; private Button removeAnnotationButton; private Button removeNodeButton; private Button filterButton; private boolean dirty = false; private IFile inputFile; private Text txtSearch; public AnnotationEditor() { nodeFilter = new NodeFilter(); searchFilter = new ClassSearchFilter(); } public AnnotationType getSelectedAnnotation() { return selectedAnnotation; } @Override public void doSave(IProgressMonitor monitor) { ModelWriter exporter = new ASMClassModelManager(); URI fileLocation = inputFile.getLocationURI(); try { exporter.exportModel(model, fileLocation); dirty = false; firePropertyChange(PROP_DIRTY); inputFile.refreshLocal(IResource.DEPTH_ZERO, monitor); } catch (IOException | CoreException e) { AnnotationEditorPlugin.logException( "Could not save file: " + fileLocation, e); } } @Override public void doSaveAs() { // if (Files.notExists(output, LinkOption.NOFOLLOW_LINKS)) { // Files.copy(origin, dest, StandardCopyOption.COPY_ATTRIBUTES); // } } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { if (input instanceof FileEditorInput) { FileEditorInput fileInput = (FileEditorInput) input; inputFile = fileInput.getFile(); if (inputFile == null) { throw new PartInitException("Input file was null."); } setPartName(getPartName() + " - " + inputFile.getName()); try { ModelReader importer = new ASMClassModelManager(); model = importer.importModel(inputFile.getLocationURI()); model.addObserver(this); } catch (IOException e) { throw new PartInitException( "Could not read input file.", e); } } super.setSite(site); super.setInput(input); } @Override public boolean isDirty() { return dirty; } @Override public boolean isSaveAsAllowed() { return false; } @Override public void createPartControl(Composite parent) { GridLayout gl_parent = new GridLayout(1, false); gl_parent.marginWidth = 2; gl_parent.marginHeight = 2; parent.setLayout(gl_parent); createAnnotationImportExportPanel(parent); SashForm verticalSash = new SashForm(parent, SWT.SMOOTH | SWT.VERTICAL); verticalSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); createEditorPanel(verticalSash); createDetailsPanel(verticalSash); verticalSash.setWeights(new int[] {2, 1}); } private void createAnnotationImportExportPanel(Composite composite) { Group annotationGroup = new Group(composite, SWT.NONE); FillLayout fl_annotationGroup = new FillLayout(SWT.HORIZONTAL); fl_annotationGroup.marginHeight = 2; fl_annotationGroup.spacing = 7; fl_annotationGroup.marginWidth = 2; annotationGroup.setLayout(fl_annotationGroup); annotationGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); annotationGroup.setText("Annotations"); Button importButton = new Button(annotationGroup, SWT.NONE); importButton.setText("Import"); importButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { AnnotationImporter importer = JAXBAnnotationManager.getInstance(); FileDialog dialog = new FileDialog(getSite().getShell(), SWT.OPEN); dialog.setFilterExtensions(new String[] {importer.getExtension()}); String result = dialog.open(); if (result != null) { Path importPath = Paths.get(result); importer.importAnnotations(model, importPath); } } }); Button exportButton = new Button(annotationGroup, SWT.NONE); exportButton.setText("Export"); exportButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { AnnotationExporter exporter = JAXBAnnotationManager.getInstance(); FileDialog dialog = new FileDialog(getSite().getShell(), SWT.SAVE); dialog.setFilterExtensions(new String[] {exporter.getExtension()}); dialog.setOverwrite(true); String result = dialog.open(); if (result != null) { Path exportPath = Paths.get(result); exporter.exportAnnotations(model, exportPath); } } }); } private void createEditorPanel(Composite composite) { SashForm sashForm = new SashForm(composite, SWT.SMOOTH); createLeftPanel(sashForm); createRightPanel(sashForm); sashForm.setWeights(new int[] {2, 3}); } private void createLeftPanel(Composite composite) { Group nodesGroup = new Group(composite, SWT.NONE); nodesGroup.setText("Nodes"); GridLayout gl_nodesGroup = new GridLayout(1, false); gl_nodesGroup.marginHeight = 2; gl_nodesGroup.horizontalSpacing = 3; gl_nodesGroup.verticalSpacing = 3; gl_nodesGroup.marginWidth = 3; nodesGroup.setLayout(gl_nodesGroup); Composite filterComposite = new Composite(nodesGroup, SWT.NONE); GridLayout gl_filterComposite = new GridLayout(3, false); gl_filterComposite.marginWidth = 0; gl_filterComposite.verticalSpacing = 3; gl_filterComposite.horizontalSpacing = 4; gl_filterComposite.marginHeight = 0; filterComposite.setLayout(gl_filterComposite); filterComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1)); Label searchLabel = new Label(filterComposite, SWT.NONE); searchLabel.setText("Filter:"); txtSearch = new Text(filterComposite, SWT.BORDER); txtSearch.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); txtSearch.addMouseListener(new MouseAdapter() { @Override public void mouseDown(MouseEvent e) { txtSearch.setText(""); } }); txtSearch.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { searchFilter.searchClass(txtSearch.getText()); nodeViewer.refresh(); } }); filterButton = new Button(filterComposite, SWT.CHECK); filterButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); filterButton.setText("Nodes only"); filterButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { nodeFilter.filterNodes(filterButton.getSelection()); nodeViewer.refresh(); } }); Composite nodeViewerComposite = new Composite(nodesGroup, SWT.NONE); nodeViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); createNodeViewer(nodeViewerComposite); Composite nodeButtonsComposite = new Composite(nodesGroup, SWT.NONE); FillLayout fl_nodeButtonsComposite = new FillLayout(SWT.HORIZONTAL); fl_nodeButtonsComposite.spacing = 2; nodeButtonsComposite.setLayout(fl_nodeButtonsComposite); nodeButtonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); createNodeButtons(nodeButtonsComposite); } private void createNodeViewer(Composite viewerComposite) { nodeProvider = new NodeViewerItemProvider(); nodeViewer = new TreeViewer(viewerComposite, SWT.BORDER | SWT.FULL_SELECTION); nodeViewer.setComparator(new ViewerItemComparator()); nodeViewer.setFilters(new ViewerFilter[] {nodeFilter, searchFilter}); nodeViewer.setContentProvider(nodeProvider.getContentProvider()); nodeViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { ModelElement element = ViewerSelectionUtil.getModelElement(event.getSelection()); setNodeButton.setEnabled(false); removeNodeButton.setEnabled(false); if (element instanceof Annotatable) { Annotatable<?> annotatable = (Annotatable<?>) element; setNodeButton.setEnabled(ControllerRegistry.canExecute( Mode.SET, NodeAnnotation.class, annotatable)); removeNodeButton.setEnabled(ControllerRegistry.canExecute( Mode.UNSET, NodeAnnotation.class, annotatable)); } propertyViewer.getControl().setEnabled(element != null); propertyViewer.setInput(element); propertyViewer.expandToLevel(TreeViewer.ALL_LEVELS); if (element instanceof ClassElement) { valueAnnotationButton.setEnabled(true); initializeAnnotationButton.setEnabled(true); memberViewer.getControl().setEnabled(true); memberViewer.setInput(element); memberViewer.expandToLevel(SECOND_LEVEL); } else { valueAnnotationButton.setEnabled(false); initializeAnnotationButton.setEnabled(false); memberViewer.getControl().setEnabled(false); memberViewer.setInput(null); } } }); Tree nodeTree = nodeViewer.getTree(); nodeTree.setHeaderVisible(true); nodeTree.setLinesVisible(true); TreeColumnLayout columnLayout = new TreeColumnLayout(); viewerComposite.setLayout(columnLayout); TreeViewerColumn nodeViewerColumn = new TreeViewerColumn(nodeViewer, SWT.NONE); nodeViewerColumn.setLabelProvider(nodeProvider.getLabelProvider(ViewerItemProvider.FIRST_COLUMN)); TreeColumn nodesColumn = nodeViewerColumn.getColumn(); columnLayout.setColumnData(nodesColumn, new ColumnWeightData(1, ColumnWeightData.MINIMUM_WIDTH, true)); nodesColumn.setText("Packages/Classes"); if (model != null) { nodeViewer.setInput(model); nodeViewer.expandToLevel(SECOND_LEVEL); } } private void createNodeButtons(Composite composite) { setNodeButton = new Button(composite, SWT.NONE); setNodeButton.setEnabled(false); setNodeButton.setText(AnnotationType.NODE.getName()); setNodeButton.addSelectionListener(new SetAnnotationSelectionAdapter(Mode.SET) { @Override public Viewer getViewer() { return nodeViewer; } @Override public AnnotationType getAnnotation() { return AnnotationType.NODE; } }); removeNodeButton = new Button(composite, SWT.NONE); removeNodeButton.setEnabled(false); removeNodeButton.setText("Remove"); removeNodeButton.addSelectionListener(new SetAnnotationSelectionAdapter(Mode.UNSET) { @Override public Viewer getViewer() { return nodeViewer; } @Override public AnnotationType getAnnotation() { return AnnotationType.NODE; } }); } private void createRightPanel(Composite composite) { Group membersGroup = new Group(composite, SWT.NONE); membersGroup.setText("Annotatable Members"); GridLayout gl_membersGroup = new GridLayout(1, false); gl_membersGroup.verticalSpacing = 3; gl_membersGroup.marginWidth = 3; gl_membersGroup.marginHeight = 2; gl_membersGroup.horizontalSpacing = 3; membersGroup.setLayout(gl_membersGroup); Composite annotationSelectionComposite = new Composite(membersGroup, SWT.NONE); GridLayout gl_annotationSelectionComposite = new GridLayout(3, false); gl_annotationSelectionComposite.verticalSpacing = 3; gl_annotationSelectionComposite.horizontalSpacing = 3; gl_annotationSelectionComposite.marginHeight = 2; annotationSelectionComposite.setLayout(gl_annotationSelectionComposite); annotationSelectionComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); createAnnotationSelection(annotationSelectionComposite); Composite memberViewerComposite = new Composite(membersGroup, SWT.NONE); memberViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); createMemberViewer(memberViewerComposite); Composite annotationComposite = new Composite(membersGroup, SWT.NONE); annotationComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); FillLayout fl_annotationComposite = new FillLayout(SWT.HORIZONTAL); fl_annotationComposite.spacing = 2; annotationComposite.setLayout(fl_annotationComposite); createAnnotationButtons(annotationComposite); } private void createAnnotationSelection(Composite annotationSelectionComposite) { Label annotationSelectionLabel = new Label(annotationSelectionComposite, SWT.NONE); annotationSelectionLabel.setText("Annotation:"); valueAnnotationButton = new Button(annotationSelectionComposite, SWT.RADIO); valueAnnotationButton.setEnabled(false); valueAnnotationButton.setText(AnnotationType.VALUE.getName()); valueAnnotationButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { selectedAnnotation = AnnotationType.VALUE; memberViewer.setInput(memberViewer.getInput()); memberViewer.expandToLevel(SECOND_LEVEL); setAnnotationButton.setText(selectedAnnotation.getName()); } }); valueAnnotationButton.setSelection(true); initializeAnnotationButton = new Button(annotationSelectionComposite, SWT.RADIO); initializeAnnotationButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); initializeAnnotationButton.setEnabled(false); initializeAnnotationButton.setText(AnnotationType.INITIALIZE.getName()); initializeAnnotationButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { selectedAnnotation = AnnotationType.INITIALIZE; memberViewer.setInput(memberViewer.getInput()); memberViewer.expandToLevel(SECOND_LEVEL); setAnnotationButton.setText(selectedAnnotation.getName()); } }); } private void createMemberViewer(Composite viewerComposite) { memberProvider = new MemberViewerItemProvider(this); memberViewer = new TreeViewer(viewerComposite, SWT.BORDER | SWT.FULL_SELECTION); memberViewer.setContentProvider(memberProvider.getContentProvider()); memberViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { setAnnotationButton.setEnabled(false); removeAnnotationButton.setEnabled(false); ModelElement selectedObject = ViewerSelectionUtil. getModelElement(event.getSelection()); propertyViewer.getControl().setEnabled(selectedObject != null); propertyViewer.setInput(selectedObject); propertyViewer.expandToLevel(TreeViewer.ALL_LEVELS); if (selectedObject instanceof Annotatable) { Annotatable<?> annotatable = (Annotatable<?>) selectedObject; setAnnotationButton.setEnabled(ControllerRegistry.canExecute( Mode.SET, selectedAnnotation.getType(), annotatable)); removeAnnotationButton.setEnabled(ControllerRegistry.canExecute( Mode.UNSET,selectedAnnotation.getType(), annotatable)); } } }); Tree memberTree = memberViewer.getTree(); memberTree.setHeaderVisible(true); memberTree.setLinesVisible(true); memberTree.setEnabled(false); TreeColumnLayout tcl_memberViewerComposite = new TreeColumnLayout(); viewerComposite.setLayout(tcl_memberViewerComposite); TreeViewerColumn nameViewerColumn = new TreeViewerColumn(memberViewer, SWT.NONE); nameViewerColumn.setLabelProvider(memberProvider.getLabelProvider(ViewerItemProvider.FIRST_COLUMN)); TreeColumn nameColumn = nameViewerColumn.getColumn(); tcl_memberViewerComposite.setColumnData(nameColumn, new ColumnWeightData(1, MIN_COLUMN_WIDTH, true)); nameColumn.setText("Name"); TreeViewerColumn typeViewerColumn = new TreeViewerColumn(memberViewer, SWT.NONE); typeViewerColumn.setLabelProvider(memberProvider.getLabelProvider(ViewerItemProvider.SECOND_COLUMN)); TreeColumn typeColumn = typeViewerColumn.getColumn(); tcl_memberViewerComposite.setColumnData(typeColumn, new ColumnWeightData(1, MIN_COLUMN_WIDTH, true)); typeColumn.setText("Type"); } private void createAnnotationButtons(Composite composite) { setAnnotationButton = new Button(composite, SWT.NONE); setAnnotationButton.setEnabled(false); setAnnotationButton.setText(selectedAnnotation.getName()); setAnnotationButton.addSelectionListener(new SetAnnotationSelectionAdapter(Mode.SET) { @Override public Viewer getViewer() { return memberViewer; } @Override public AnnotationType getAnnotation() { return selectedAnnotation; } }); removeAnnotationButton = new Button(composite, SWT.NONE); removeAnnotationButton.setEnabled(false); removeAnnotationButton.setText("Remove"); removeAnnotationButton.addSelectionListener(new SetAnnotationSelectionAdapter(Mode.UNSET) { @Override public Viewer getViewer() { return memberViewer; } @Override public AnnotationType getAnnotation() { return selectedAnnotation; } }); } private void createDetailsPanel(Composite composite) { Group propertiesGroup = new Group(composite, SWT.NONE); GridLayout gl_propertiesGroup = new GridLayout(1, false); gl_propertiesGroup.marginWidth = 3; gl_propertiesGroup.marginHeight = 2; propertiesGroup.setLayout(gl_propertiesGroup); propertiesGroup.setText("Details"); Composite propertyViewerComposite = new Composite(propertiesGroup, SWT.NONE); propertyViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); createPropertyViewer(propertyViewerComposite); } private void createPropertyViewer(Composite propertyViewerComposite) { propertyProvider = new PropertyViewerItemProvider(); propertyViewer = new TreeViewer(propertyViewerComposite, SWT.BORDER | SWT.FULL_SELECTION); propertyViewer.setContentProvider(propertyProvider.getContentProvider()); final Tree propertyTree = propertyViewer.getTree(); propertyTree.setHeaderVisible(true); propertyTree.setLinesVisible(true); propertyTree.setEnabled(false); TreeColumnLayout tcl_propertyViewerComposite = new TreeColumnLayout(); propertyViewerComposite.setLayout(tcl_propertyViewerComposite); TreeViewerColumn descriptionViewerColumn = new TreeViewerColumn(propertyViewer, SWT.NONE); descriptionViewerColumn.setLabelProvider(propertyProvider.getLabelProvider(ViewerItemProvider.FIRST_COLUMN)); TreeColumn descriptionColumn = descriptionViewerColumn.getColumn(); tcl_propertyViewerComposite.setColumnData(descriptionColumn, new ColumnPixelData(150, true, true)); descriptionColumn.setText("Description"); TreeViewerColumn valueViewerColumn = new TreeViewerColumn(propertyViewer, SWT.NONE); valueViewerColumn.setLabelProvider(propertyProvider.getLabelProvider(ViewerItemProvider.SECOND_COLUMN)); valueViewerColumn.setEditingSupport(new EditingSupport(propertyViewer) { @Override protected void setValue(Object element, Object value) { ((EditableViewerItem) element).setValue(value); propertyViewer.update(element, null); } @Override protected Object getValue(Object element) { return ((EditableViewerItem) element).getValue(); } @Override protected CellEditor getCellEditor(Object element) { return ((EditableViewerItem) element).getCellEditor(propertyTree); } @Override protected boolean canEdit(Object element) { return element instanceof EditableViewerItem; } }); TreeColumn valueColumn = valueViewerColumn.getColumn(); tcl_propertyViewerComposite.setColumnData(valueColumn, new ColumnWeightData(1, ColumnWeightData.MINIMUM_WIDTH, true)); valueColumn.setText("Value"); } @Override public void setFocus() { nodeViewer.getControl().setFocus(); } @Override public void dispose() { if (model != null) { model.deleteObserver(this); model = null; } if (nodeProvider != null) { nodeProvider.dispose(); nodeProvider = null; } if (memberProvider != null) { memberProvider.dispose(); memberProvider = null; } if (propertyProvider != null) { propertyProvider.dispose(); propertyProvider = null; } super.dispose(); } @Override public void update(Observable o, Object arg) { dirty = true; firePropertyChange(PROP_DIRTY); if (nodeViewer != null) { nodeViewer.refresh(); } if (memberViewer != null) { memberViewer.refresh(); } if (propertyViewer != null) { propertyViewer.refresh(); } } }