X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2FdiagramEditor%2FDiagramLayersPage.java;h=1632f32caa5c0d6e58d2d9ff15992ea2a7ab01bb;hb=d924aa9e2691606e0bc8044cce01aff4abcc7bc9;hp=ba7ed78366357d88f0c85b5c32305b80b147257d;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramLayersPage.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramLayersPage.java index ba7ed7836..1632f32ca 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramLayersPage.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramLayersPage.java @@ -1,848 +1,848 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.modeling.ui.diagramEditor; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Set; - -import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.layout.GridLayoutFactory; -import org.eclipse.jface.viewers.CellLabelProvider; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ICheckStateProvider; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.TreeEditor; -import org.eclipse.swt.events.KeyAdapter; -import org.eclipse.swt.events.KeyEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; -import org.eclipse.swt.widgets.TreeItem; -import org.eclipse.ui.part.Page; -import org.simantics.diagram.layer.ILayersViewPage; -import org.simantics.g2d.canvas.ICanvasContext; -import org.simantics.g2d.diagram.DiagramHints; -import org.simantics.g2d.diagram.IDiagram; -import org.simantics.g2d.diagram.participant.Selection; -import org.simantics.g2d.element.ElementClass; -import org.simantics.g2d.element.IElement; -import org.simantics.g2d.element.handler.ElementLayers; -import org.simantics.g2d.layers.IEditableLayer; -import org.simantics.g2d.layers.ILayer; -import org.simantics.g2d.layers.ILayers; -import org.simantics.g2d.layers.ILayersEditor; -import org.simantics.g2d.layers.SimpleLayer; -import org.simantics.g2d.layers.ILayersEditor.ILayersEditorListener; -import org.simantics.utils.datastructures.Arrays; -import org.simantics.utils.datastructures.hints.HintListenerAdapter; -import org.simantics.utils.datastructures.hints.IHintListener; -import org.simantics.utils.datastructures.hints.IHintObservable; -import org.simantics.utils.datastructures.hints.IHintContext.Key; -import org.simantics.utils.ui.ISelectionUtils; - -public class DiagramLayersPage extends Page implements ILayersViewPage { - - private static final String TEXT_APPLY_FOCUS_SETTINGS = "Focus Active"; - private static final String TOOLTIP_APPLY_FOCUS_SETTINGS = "Only Focus Diagram Elements For Active Roles"; - private static final String TEXT_IGNORE_FOCUS_SETTINGS = "Focus All"; - private static final String TOOLTIP_IGNORE_FOCUS_SETTINGS = "Focus All Diagram Elements Regardless Of Active Roles"; - - private static final String TEXT_APPLY_VISIBILITY_SETTINGS = "Show Active"; - private static final String TOOLTIP_APPLY_VISIBILITY_SETTINGS = "Only Show Diagram Elements For Active Roles"; - private static final String TEXT_IGNORE_VISIBILITY_SETTINGS = "Show All"; - private static final String TOOLTIP_IGNORE_VISIBILITY_SETTINGS = "Show All Diagram Elements Regardless Of Active Roles"; - - final private ICanvasContext context; - final private IDiagram diagram; - private CheckboxTreeViewer viewer; - private Composite composite; - private TreeEditor editor; - - private Collection elements = Collections.emptySet(); - - enum Attribute { - Visible, - Focusable - } - - enum Tristate { - True, - False, - Both; - - static Tristate to(Boolean b) { - return b == null ? null : b ? True : False; - } - boolean toBoolean() { - switch (this) { - case Both: - throw new IllegalStateException("cannot convert Tristate Both to boolean"); - case False: - return false; - case True: - return true; - default: - return false; - } - } - Tristate toggle() { - switch (this) { - case Both: - case False: - return True; - case True: - return False; - default: - return False; - } - } - Tristate merge(Tristate state) { - if (state == null) - return this; - switch (this) { - case Both: - return Both; - case False: - switch (state) { - case False: - return False; - case Both: - case True: - return Both; - } - case True: - switch (state) { - case True: - return True; - case False: - case Both: - return Both; - } - } - return this; - } - } - - Boolean getAttribute(IElement e, ILayer layer, Attribute attribute) { - ElementClass ec = e.getElementClass(); - for (ElementLayers el : ec.getItemsByClass(ElementLayers.class)) { - switch (attribute) { - case Visible: - return Boolean.valueOf(el.isVisible(e, layer)); - case Focusable: - return Boolean.valueOf(el.isFocusable(e, layer)); - } - } - return null; - } - - boolean setAttribute(IElement e, ILayer layer, Attribute attribute, boolean value) { - ElementClass ec = e.getElementClass(); - for (ElementLayers el : ec.getItemsByClass(ElementLayers.class)) { - switch (attribute) { - case Visible: - return el.setVisibility(e, layer, value); - case Focusable: - return el.setFocusability(e, layer, value); - } - } - return false; - } - - Tristate getJointAttribute(Collection elements, ILayer layer, Attribute attribute) { - Tristate state = null; - for (IElement e : elements) { - Boolean attr = getAttribute(e, layer, attribute); - if (attr == null) - continue; - - if (state == null) { - state = Tristate.to(attr); - } else { - state = state.merge(Tristate.to(attr)); - } - } - return state; - } - - int setAttribute(Collection elements, ILayer layer, Attribute attribute, boolean value) { - int result = 0; - for (IElement e : elements) { - if (setAttribute(e, layer, attribute, value)) - ++result; - } - return result; - } - - - final private IHintListener selectionListener = new HintListenerAdapter() { - - @Override - public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { - Collection es = Collections.emptySet(); - if (newValue instanceof Collection) { - Collection coll = (Collection)newValue; - es = new ArrayList(coll.size()); - for (Object o : coll) { - if (!(o instanceof IElement)) - return; - es.add((IElement) o); - } - if (es.isEmpty()) - es = Collections.emptySet(); - } - elements = es; - redraw(); - } - - private void redraw() { - viewer.getControl().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (viewer.getControl().isDisposed()) - return; - viewer.getControl().redraw(); - } - }); - } - }; - - public DiagramLayersPage(IDiagram diagram, ICanvasContext context) { - - assert(diagram != null); - - this.diagram = diagram; - this.context = context; - - context.getDefaultHintContext().addKeyHintListener(Selection.SELECTION0, selectionListener); - } - - @Override - public void dispose() { - - context.getDefaultHintContext().removeKeyHintListener(Selection.SELECTION0, selectionListener); - - super.dispose(); - - } - - @Override - public void createControl(Composite parent) { - - final ILayersEditor layers = diagram.getHint(DiagramHints.KEY_LAYERS_EDITOR); - layers.addListener(new ILayersEditorListener() { - - @Override - public void layerRemoved(ILayer layer) { - scheduleRefresh(); - } - - @Override - public void layerAdded(ILayer layer) { - scheduleRefresh(); - } - - @Override - public void layerActivated(ILayer layer) { - scheduleRefresh(); - } - - @Override - public void layerDeactivated(ILayer layer) { - scheduleRefresh(); - } - - @Override - public void ignoreFocusChanged(boolean value) { - } - - @Override - public void ignoreVisibilityChanged(boolean value) { - } - - void scheduleRefresh() { - viewer.getControl().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - viewer.refresh(); - } - }); - } - }); - - composite = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(4).applyTo(composite); - - Button addButton = new Button(composite, SWT.NONE); - addButton.setText("New"); - addButton.setToolTipText("Create New Diagram Role"); - addButton.addSelectionListener(new SelectionListener() { - - String findFreshName(ILayers layers, String proposal) { - Set all = layers.getLayers(); - String name = proposal; - int i = 1; - while (true) { - boolean match = false; - for (ILayer layer : all) { - if (name.equals(layer.getName())) { - match = true; - break; - } - } - if (!match) - return name; - ++i; - name = proposal + " " + i; - } - } - - @Override - public void widgetSelected(SelectionEvent e) { - String name = findFreshName(layers, "New Role"); - SimpleLayer layer = new SimpleLayer(name); - layers.addLayer(layer); - layers.activate(layer); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - - }); - - final Button removeButton = new Button(composite, SWT.NONE); - removeButton.setText("Remove"); - removeButton.setToolTipText("Remove Selected Diagram Role"); - removeButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - TreeItem[] items = viewer.getTree().getSelection(); - if (items.length == 0) - return; - - TreeItem[] all = viewer.getTree().getItems(); - int firstIndex = Arrays.indexOf(all, items[0]); - for (TreeItem item : items) { - int index = Arrays.indexOf(all, item); - all[index] = null; - ILayer layer = (ILayer)item.getData(); - layers.removeLayer(layer); - } - int selectIndex = firstIndex - 1; - if (firstIndex == 0) { - for (int i = firstIndex; i < all.length; ++i) - if (all[i] != null) { - selectIndex = i; - break; - } - } - if (selectIndex >= 0) { - viewer.getTree().select(all[selectIndex]); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - }); - - String ignoreVisibilityText = TEXT_IGNORE_VISIBILITY_SETTINGS; - String ignoreVisibilityTooltip = TOOLTIP_IGNORE_VISIBILITY_SETTINGS; - boolean ignoreVisibility = layers.getIgnoreVisibilitySettings(); - if (ignoreVisibility) { - ignoreVisibilityText = TEXT_APPLY_VISIBILITY_SETTINGS; - ignoreVisibilityTooltip = TOOLTIP_APPLY_VISIBILITY_SETTINGS; - } - - final Button ignoreVisibilityButton = new Button(composite, SWT.NONE); - ignoreVisibilityButton.setText(ignoreVisibilityText); - ignoreVisibilityButton.setToolTipText(ignoreVisibilityTooltip); - ignoreVisibilityButton.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - String ignoreText = TEXT_IGNORE_VISIBILITY_SETTINGS; - String ignoreTooltip= TOOLTIP_IGNORE_VISIBILITY_SETTINGS; - boolean ignore = layers.getIgnoreVisibilitySettings(); - if(!ignore) { - ignoreText = TEXT_APPLY_VISIBILITY_SETTINGS; - ignoreTooltip = TOOLTIP_APPLY_VISIBILITY_SETTINGS; - layers.setIgnoreVisibilitySettings(true); - } else { - layers.setIgnoreVisibilitySettings(false); - } - ignoreVisibilityButton.setText(ignoreText); - ignoreVisibilityButton.setToolTipText(ignoreTooltip); - composite.layout(); - context.getThreadAccess().asyncExec(new Runnable() { - - @Override - public void run() { - if(context.isDisposed()) return; - context.getContentContext().setDirty(); - } - - }); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - - }); - - String ignoreFocusText = TEXT_IGNORE_FOCUS_SETTINGS; - String ignoreFocusTooltip = TOOLTIP_IGNORE_FOCUS_SETTINGS; - boolean ignoreFocus = layers.getIgnoreFocusSettings(); - if(ignoreFocus) { - ignoreFocusText = TEXT_APPLY_FOCUS_SETTINGS; - ignoreFocusTooltip = TOOLTIP_APPLY_FOCUS_SETTINGS; - } - - final Button ignoreFocusButton = new Button(composite, SWT.NONE); - ignoreFocusButton.setText(ignoreFocusText); - ignoreFocusButton.setToolTipText(ignoreFocusTooltip); - ignoreFocusButton.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - String ignoreText = TEXT_IGNORE_FOCUS_SETTINGS; - String ignoreTooltip = TOOLTIP_IGNORE_FOCUS_SETTINGS; - boolean ignore = layers.getIgnoreFocusSettings(); - if(!ignore) { - ignoreText = TEXT_APPLY_FOCUS_SETTINGS; - ignoreTooltip = TOOLTIP_APPLY_FOCUS_SETTINGS; - layers.setIgnoreFocusSettings(true); - } else { - layers.setIgnoreFocusSettings(false); - } - ignoreFocusButton.setText(ignoreText); - ignoreFocusButton.setToolTipText(ignoreTooltip); - composite.layout(); - context.getThreadAccess().asyncExec(new Runnable() { - - @Override - public void run() { - if(context.isDisposed()) return; - context.getContentContext().setDirty(); - } - - }); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - widgetSelected(e); - } - - }); - - viewer = new CheckboxTreeViewer(composite, SWT.BORDER | SWT.FULL_SELECTION ); - - GridDataFactory.fillDefaults().grab(true, true).span(4, 1).applyTo(viewer.getControl()); - viewer.getControl().setToolTipText("Selects the diagram to include in the exported document."); - viewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS); - viewer.getTree().setHeaderVisible(true); - editor = new TreeEditor(viewer.getTree()); - - final TreeColumn column1 = new TreeColumn(viewer.getTree(), SWT.LEFT); - column1.setText("Role"); - column1.setWidth(100); - final TreeColumn column2 = new TreeColumn(viewer.getTree(), SWT.LEFT); - column2.setText("Show"); - column2.setWidth(50); - final TreeColumn column3 = new TreeColumn(viewer.getTree(), SWT.LEFT); - column3.setText("Focus"); - column3.setWidth(50); - viewer.getTree().addListener(SWT.Resize, new Listener() { - @Override - public void handleEvent(Event event) { - Tree tree = viewer.getTree(); - Point size = tree.getSize(); - int w = Math.max(size.x - 100 - tree.getBorderWidth() * 2, 30); - column1.setWidth(w); - } - }); - - viewer.getTree().addListener(SWT.PaintItem, new Listener() { - public void handleEvent(Event event) { - if ((event.index == 1 || event.index == 2) && !elements.isEmpty()) { - ILayer[] lz = layers.getLayers().toArray(new ILayer[0]); - - TreeItem item = (TreeItem)event.item; - int index = viewer.getTree().indexOf(item); - - int width = 0; - if (event.index == 1) - width = (column2.getWidth() - 1); - if (event.index == 2) - width = (column3.getWidth() - 1); - - Attribute attribute = Attribute.Visible; - if (event.index == 2) - attribute = Attribute.Focusable; - Tristate state = getJointAttribute(elements, lz[index], attribute); - - Color color = null; - switch (state) { - case False: - color = viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_RED); - break; - case True: - color = viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_GREEN); - break; - case Both: - color = viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_GRAY); - break; - } - - GC gc = event.gc; - Color foreground = gc.getForeground(); - Color background = gc.getBackground(); - gc.setBackground(color); - gc.setForeground(viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_BLACK)); - gc.fillRectangle(event.x, event.y, width-1, event.height-1); - Rectangle rect2 = new Rectangle(event.x, event.y, width-1, event.height-1); - gc.drawRectangle(rect2); - gc.setForeground(background); - gc.setBackground(foreground); - } - } - }); - viewer.getTree().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent event) { - if (event.keyCode == SWT.F2) { - // FIXME: Eclipse currently eats F2 presses. This should be - // implemented as a command handler or find some way to - // force these listeners to have priority... - System.out.println("startediting"); - - TreeItem[] items = viewer.getTree().getSelection(); - if(items.length != 1) - return; - - TreeItem item = items[0]; - - ILayer layer = ISelectionUtils.filterSingleSelection(viewer.getSelection(), ILayer.class); - if (layer == null) - return; - - startEditing(layer, item); - } - } - }); - viewer.getTree().addListener(SWT.MouseDown, new Listener() { - public void handleEvent(Event event) { - if (viewer.getControl().isDisposed()) - return; - - Point pt = new Point(event.x, event.y); - TreeItem item = viewer.getTree().getItem(pt); - if (item == null) - return; - - int index = viewer.getTree().indexOf(item); - ILayer[] lz = layers.getLayers().toArray(new ILayer[0]); - ILayer layer = lz[index]; - - Rectangle rect = item.getBounds(0); - if (event.count == 2 && rect.contains(pt)) { - startEditing(layer, item); - return; - } - - // Cannot adjust visibility/focusability if no elements are selected. - if (elements.isEmpty()) - return; - - rect = item.getBounds(1); - if (rect.contains(pt)) { - Tristate state = getJointAttribute(elements, layer, Attribute.Visible); - if (setAttribute(elements, layer, Attribute.Visible, state.toggle().toBoolean()) > 0) { - refresh(); - } - return; - } - - Rectangle rect2 = item.getBounds(2); - if (rect2.contains(pt)) { - Tristate state = getJointAttribute(elements, layer, Attribute.Focusable); - if (setAttribute(elements, layer, Attribute.Focusable, state.toggle().toBoolean()) > 0) { - refresh(); - } - return; - } - } - - private void refresh() { - viewer.getControl().redraw(); - context.getThreadAccess().asyncExec(new Runnable() { - @Override - public void run() { - if (context.isDisposed()) - return; - context.getContentContext().setDirty(); - } - }); - } - }); - - viewer.addCheckStateListener(new ICheckStateListener(){ - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - ILayer layer = (ILayer)event.getElement(); - if(event.getChecked()) layers.activate(layer); - else layers.deactivate(layer); - viewer.setSubtreeChecked(event.getElement(), event.getChecked()); - context.getThreadAccess().asyncExec(new Runnable() { - - @Override - public void run() { - if(context.isDisposed()) return; - context.getContentContext().setDirty(); - } - - }); - } - }); - - viewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - ISelection s = event.getSelection(); - if (s.isEmpty()) { - removeButton.setEnabled(false); - } else { - removeButton.setEnabled(true); - } - } - }); - - viewer.setContentProvider(new ITreeContentProvider(){ - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - @Override - public void dispose() { - } - @Override - public Object[] getElements(Object inputElement) { - return layers.getLayers().toArray(); - } - @Override - public boolean hasChildren(Object element) { - return false; - } - @Override - public Object getParent(Object element) { - return null; - } - @Override - public Object[] getChildren(Object parentElement) { - return new Object[0]; - } - }); - viewer.setLabelProvider(new CellLabelProvider() { - @Override - public void update(ViewerCell cell) { - if(cell.getColumnIndex() == 0) { - ILayer layer = (ILayer)cell.getElement(); - cell.setText(layer.getName()); - } else { - cell.setText(""); - } - } - }); - viewer.setCheckStateProvider(new ICheckStateProvider() { - @Override - public boolean isChecked(Object element) { - ILayer layer = (ILayer)element; - final boolean isActive = layers.isActive(layer); - return isActive; - } - @Override - public boolean isGrayed(Object element) { - return false; - } - }); - - viewer.setInput(this); - - for(ILayer layer : layers.getVisibleLayers()) { - viewer.setSubtreeChecked(layer, true); - } - } - - @Override - public Control getControl() { - return composite; - } - - @Override - public void setFocus() { - } - - @Override - public void addSelectionChangedListener(ISelectionChangedListener listener) { - } - - @Override - public ISelection getSelection() { - return null; - } - - @Override - public void removeSelectionChangedListener(ISelectionChangedListener listener) { - } - - @Override - public void setSelection(ISelection selection) { - } - - private boolean startEditing(final ILayer layer, final TreeItem item/*, final int columnIndex*/) { - - // Column column = columns[columnIndex]; - - String initialText = layer.getName(); - - final Composite composite = new Composite(viewer.getTree(), SWT.NONE); - final Text text = new Text(composite, SWT.BORDER); - final int insetX = 0; - final int insetY = 0; - composite.addListener(SWT.Resize, new Listener() { - public void handleEvent(Event e) { - Rectangle rect = composite.getClientArea(); - text.setBounds(rect.x + insetX, rect.y + insetY, rect.width - insetX * 2, rect.height - - insetY * 2); - } - }); - Listener textListener = new Listener() { - public void handleEvent(final Event e) { - //String error; - String newText; - switch (e.type) { - case SWT.FocusOut: - if(layer instanceof IEditableLayer) { - IEditableLayer l = (IEditableLayer)layer; - l.setName(text.getText()); - System.out.println("renamed layer to " + text.getText()); - viewer.refresh(); - } - - // // Item may be disposed if the tree gets reset after a previous editing. - // if (!item.isDisposed()) { - // item.setText(columnIndex, text.getText()); - // queueSelectionRefresh(context); - // } - // } else { - // // System.out.println("validation error: " + error); - // } - composite.dispose(); - break; - case SWT.Modify: - // newText = text.getText(); - // error = modifier.isValid(newText); - // if (error != null) { - // text.setBackground(invalidModificationColor); - // // System.out.println("validation error: " + error); - // } else { - // text.setBackground(null); - // } - break; - case SWT.Verify: - newText = text.getText(); - String leftText = newText.substring(0, e.start); - String rightText = newText.substring(e.end, newText.length()); - GC gc = new GC(text); - Point size = gc.textExtent(leftText + e.text + rightText); - gc.dispose(); - size = text.computeSize(size.x, SWT.DEFAULT); - editor.horizontalAlignment = SWT.LEFT; - Rectangle itemRect = item.getBounds(0), - rect = viewer.getTree().getClientArea(); - editor.minimumWidth = Math.max(size.x, itemRect.width) + insetX * 2; - int left = itemRect.x, - right = rect.x + rect.width; - editor.minimumWidth = Math.min(editor.minimumWidth, right - left); - editor.minimumHeight = size.y + insetY * 2; - editor.layout(); - break; - case SWT.Traverse: - switch (e.detail) { - case SWT.TRAVERSE_RETURN: - if(layer instanceof IEditableLayer) { - IEditableLayer l = (IEditableLayer)layer; - l.setName(text.getText()); - //System.out.println("renamed layer to " + text.getText()); - viewer.refresh(); - } - // error = modifier.isValid(text.getText()); - // if (error == null) { - // modifier.modify(text.getText()); - // if (!item.isDisposed()) { - // item.setText(columnIndex, text.getText()); - // queueSelectionRefresh(context); - // } - // } - // FALL THROUGH - case SWT.TRAVERSE_ESCAPE: - composite.dispose(); - e.doit = false; - break; - default: - //System.out.println("unhandled traversal: " + e.detail); - break; - } - break; - } - } - }; - text.addListener(SWT.FocusOut, textListener); - text.addListener(SWT.Traverse, textListener); - text.addListener(SWT.Verify, textListener); - text.addListener(SWT.Modify, textListener); - editor.setEditor(composite, item, 0); - text.setText(initialText); - text.selectAll(); - text.setFocus(); - // lastItem[0] = item; - return true; - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling.ui.diagramEditor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTreeViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.ICheckStateProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TreeEditor; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.part.Page; +import org.simantics.diagram.layer.ILayersViewPage; +import org.simantics.g2d.canvas.ICanvasContext; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.participant.Selection; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.IElement; +import org.simantics.g2d.element.handler.ElementLayers; +import org.simantics.g2d.layers.IEditableLayer; +import org.simantics.g2d.layers.ILayer; +import org.simantics.g2d.layers.ILayers; +import org.simantics.g2d.layers.ILayersEditor; +import org.simantics.g2d.layers.SimpleLayer; +import org.simantics.g2d.layers.ILayersEditor.ILayersEditorListener; +import org.simantics.utils.datastructures.Arrays; +import org.simantics.utils.datastructures.hints.HintListenerAdapter; +import org.simantics.utils.datastructures.hints.IHintListener; +import org.simantics.utils.datastructures.hints.IHintObservable; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.ui.ISelectionUtils; + +public class DiagramLayersPage extends Page implements ILayersViewPage { + + private static final String TEXT_APPLY_FOCUS_SETTINGS = "Focus Active"; + private static final String TOOLTIP_APPLY_FOCUS_SETTINGS = "Only Focus Diagram Elements For Active Roles"; + private static final String TEXT_IGNORE_FOCUS_SETTINGS = "Focus All"; + private static final String TOOLTIP_IGNORE_FOCUS_SETTINGS = "Focus All Diagram Elements Regardless Of Active Roles"; + + private static final String TEXT_APPLY_VISIBILITY_SETTINGS = "Show Active"; + private static final String TOOLTIP_APPLY_VISIBILITY_SETTINGS = "Only Show Diagram Elements For Active Roles"; + private static final String TEXT_IGNORE_VISIBILITY_SETTINGS = "Show All"; + private static final String TOOLTIP_IGNORE_VISIBILITY_SETTINGS = "Show All Diagram Elements Regardless Of Active Roles"; + + final private ICanvasContext context; + final private IDiagram diagram; + private CheckboxTreeViewer viewer; + private Composite composite; + private TreeEditor editor; + + private Collection elements = Collections.emptySet(); + + enum Attribute { + Visible, + Focusable + } + + enum Tristate { + True, + False, + Both; + + static Tristate to(Boolean b) { + return b == null ? null : b ? True : False; + } + boolean toBoolean() { + switch (this) { + case Both: + throw new IllegalStateException("cannot convert Tristate Both to boolean"); + case False: + return false; + case True: + return true; + default: + return false; + } + } + Tristate toggle() { + switch (this) { + case Both: + case False: + return True; + case True: + return False; + default: + return False; + } + } + Tristate merge(Tristate state) { + if (state == null) + return this; + switch (this) { + case Both: + return Both; + case False: + switch (state) { + case False: + return False; + case Both: + case True: + return Both; + } + case True: + switch (state) { + case True: + return True; + case False: + case Both: + return Both; + } + } + return this; + } + } + + Boolean getAttribute(IElement e, ILayer layer, Attribute attribute) { + ElementClass ec = e.getElementClass(); + for (ElementLayers el : ec.getItemsByClass(ElementLayers.class)) { + switch (attribute) { + case Visible: + return Boolean.valueOf(el.isVisible(e, layer)); + case Focusable: + return Boolean.valueOf(el.isFocusable(e, layer)); + } + } + return null; + } + + boolean setAttribute(IElement e, ILayer layer, Attribute attribute, boolean value) { + ElementClass ec = e.getElementClass(); + for (ElementLayers el : ec.getItemsByClass(ElementLayers.class)) { + switch (attribute) { + case Visible: + return el.setVisibility(e, layer, value); + case Focusable: + return el.setFocusability(e, layer, value); + } + } + return false; + } + + Tristate getJointAttribute(Collection elements, ILayer layer, Attribute attribute) { + Tristate state = null; + for (IElement e : elements) { + Boolean attr = getAttribute(e, layer, attribute); + if (attr == null) + continue; + + if (state == null) { + state = Tristate.to(attr); + } else { + state = state.merge(Tristate.to(attr)); + } + } + return state; + } + + int setAttribute(Collection elements, ILayer layer, Attribute attribute, boolean value) { + int result = 0; + for (IElement e : elements) { + if (setAttribute(e, layer, attribute, value)) + ++result; + } + return result; + } + + + final private IHintListener selectionListener = new HintListenerAdapter() { + + @Override + public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) { + Collection es = Collections.emptySet(); + if (newValue instanceof Collection) { + Collection coll = (Collection)newValue; + es = new ArrayList(coll.size()); + for (Object o : coll) { + if (!(o instanceof IElement)) + return; + es.add((IElement) o); + } + if (es.isEmpty()) + es = Collections.emptySet(); + } + elements = es; + redraw(); + } + + private void redraw() { + viewer.getControl().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + if (viewer.getControl().isDisposed()) + return; + viewer.getControl().redraw(); + } + }); + } + }; + + public DiagramLayersPage(IDiagram diagram, ICanvasContext context) { + + assert(diagram != null); + + this.diagram = diagram; + this.context = context; + + context.getDefaultHintContext().addKeyHintListener(Selection.SELECTION0, selectionListener); + } + + @Override + public void dispose() { + + context.getDefaultHintContext().removeKeyHintListener(Selection.SELECTION0, selectionListener); + + super.dispose(); + + } + + @Override + public void createControl(Composite parent) { + + final ILayersEditor layers = diagram.getHint(DiagramHints.KEY_LAYERS_EDITOR); + layers.addListener(new ILayersEditorListener() { + + @Override + public void layerRemoved(ILayer layer) { + scheduleRefresh(); + } + + @Override + public void layerAdded(ILayer layer) { + scheduleRefresh(); + } + + @Override + public void layerActivated(ILayer layer) { + scheduleRefresh(); + } + + @Override + public void layerDeactivated(ILayer layer) { + scheduleRefresh(); + } + + @Override + public void ignoreFocusChanged(boolean value) { + } + + @Override + public void ignoreVisibilityChanged(boolean value) { + } + + void scheduleRefresh() { + viewer.getControl().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + viewer.refresh(); + } + }); + } + }); + + composite = new Composite(parent, SWT.NONE); + GridLayoutFactory.fillDefaults().numColumns(4).applyTo(composite); + + Button addButton = new Button(composite, SWT.NONE); + addButton.setText("New"); + addButton.setToolTipText("Create New Diagram Role"); + addButton.addSelectionListener(new SelectionListener() { + + String findFreshName(ILayers layers, String proposal) { + Set all = layers.getLayers(); + String name = proposal; + int i = 1; + while (true) { + boolean match = false; + for (ILayer layer : all) { + if (name.equals(layer.getName())) { + match = true; + break; + } + } + if (!match) + return name; + ++i; + name = proposal + " " + i; + } + } + + @Override + public void widgetSelected(SelectionEvent e) { + String name = findFreshName(layers, "New Role"); + SimpleLayer layer = new SimpleLayer(name); + layers.addLayer(layer); + layers.activate(layer); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + + }); + + final Button removeButton = new Button(composite, SWT.NONE); + removeButton.setText("Remove"); + removeButton.setToolTipText("Remove Selected Diagram Role"); + removeButton.addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + TreeItem[] items = viewer.getTree().getSelection(); + if (items.length == 0) + return; + + TreeItem[] all = viewer.getTree().getItems(); + int firstIndex = Arrays.indexOf(all, items[0]); + for (TreeItem item : items) { + int index = Arrays.indexOf(all, item); + all[index] = null; + ILayer layer = (ILayer)item.getData(); + layers.removeLayer(layer); + } + int selectIndex = firstIndex - 1; + if (firstIndex == 0) { + for (int i = firstIndex; i < all.length; ++i) + if (all[i] != null) { + selectIndex = i; + break; + } + } + if (selectIndex >= 0) { + viewer.getTree().select(all[selectIndex]); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + }); + + String ignoreVisibilityText = TEXT_IGNORE_VISIBILITY_SETTINGS; + String ignoreVisibilityTooltip = TOOLTIP_IGNORE_VISIBILITY_SETTINGS; + boolean ignoreVisibility = layers.getIgnoreVisibilitySettings(); + if (ignoreVisibility) { + ignoreVisibilityText = TEXT_APPLY_VISIBILITY_SETTINGS; + ignoreVisibilityTooltip = TOOLTIP_APPLY_VISIBILITY_SETTINGS; + } + + final Button ignoreVisibilityButton = new Button(composite, SWT.NONE); + ignoreVisibilityButton.setText(ignoreVisibilityText); + ignoreVisibilityButton.setToolTipText(ignoreVisibilityTooltip); + ignoreVisibilityButton.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + String ignoreText = TEXT_IGNORE_VISIBILITY_SETTINGS; + String ignoreTooltip= TOOLTIP_IGNORE_VISIBILITY_SETTINGS; + boolean ignore = layers.getIgnoreVisibilitySettings(); + if(!ignore) { + ignoreText = TEXT_APPLY_VISIBILITY_SETTINGS; + ignoreTooltip = TOOLTIP_APPLY_VISIBILITY_SETTINGS; + layers.setIgnoreVisibilitySettings(true); + } else { + layers.setIgnoreVisibilitySettings(false); + } + ignoreVisibilityButton.setText(ignoreText); + ignoreVisibilityButton.setToolTipText(ignoreTooltip); + composite.layout(); + context.getThreadAccess().asyncExec(new Runnable() { + + @Override + public void run() { + if(context.isDisposed()) return; + context.getContentContext().setDirty(); + } + + }); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + + }); + + String ignoreFocusText = TEXT_IGNORE_FOCUS_SETTINGS; + String ignoreFocusTooltip = TOOLTIP_IGNORE_FOCUS_SETTINGS; + boolean ignoreFocus = layers.getIgnoreFocusSettings(); + if(ignoreFocus) { + ignoreFocusText = TEXT_APPLY_FOCUS_SETTINGS; + ignoreFocusTooltip = TOOLTIP_APPLY_FOCUS_SETTINGS; + } + + final Button ignoreFocusButton = new Button(composite, SWT.NONE); + ignoreFocusButton.setText(ignoreFocusText); + ignoreFocusButton.setToolTipText(ignoreFocusTooltip); + ignoreFocusButton.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + String ignoreText = TEXT_IGNORE_FOCUS_SETTINGS; + String ignoreTooltip = TOOLTIP_IGNORE_FOCUS_SETTINGS; + boolean ignore = layers.getIgnoreFocusSettings(); + if(!ignore) { + ignoreText = TEXT_APPLY_FOCUS_SETTINGS; + ignoreTooltip = TOOLTIP_APPLY_FOCUS_SETTINGS; + layers.setIgnoreFocusSettings(true); + } else { + layers.setIgnoreFocusSettings(false); + } + ignoreFocusButton.setText(ignoreText); + ignoreFocusButton.setToolTipText(ignoreTooltip); + composite.layout(); + context.getThreadAccess().asyncExec(new Runnable() { + + @Override + public void run() { + if(context.isDisposed()) return; + context.getContentContext().setDirty(); + } + + }); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + widgetSelected(e); + } + + }); + + viewer = new CheckboxTreeViewer(composite, SWT.BORDER | SWT.FULL_SELECTION ); + + GridDataFactory.fillDefaults().grab(true, true).span(4, 1).applyTo(viewer.getControl()); + viewer.getControl().setToolTipText("Selects the diagram to include in the exported document."); + viewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS); + viewer.getTree().setHeaderVisible(true); + editor = new TreeEditor(viewer.getTree()); + + final TreeColumn column1 = new TreeColumn(viewer.getTree(), SWT.LEFT); + column1.setText("Role"); + column1.setWidth(100); + final TreeColumn column2 = new TreeColumn(viewer.getTree(), SWT.LEFT); + column2.setText("Show"); + column2.setWidth(50); + final TreeColumn column3 = new TreeColumn(viewer.getTree(), SWT.LEFT); + column3.setText("Focus"); + column3.setWidth(50); + viewer.getTree().addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(Event event) { + Tree tree = viewer.getTree(); + Point size = tree.getSize(); + int w = Math.max(size.x - 100 - tree.getBorderWidth() * 2, 30); + column1.setWidth(w); + } + }); + + viewer.getTree().addListener(SWT.PaintItem, new Listener() { + public void handleEvent(Event event) { + if ((event.index == 1 || event.index == 2) && !elements.isEmpty()) { + ILayer[] lz = layers.getLayers().toArray(new ILayer[0]); + + TreeItem item = (TreeItem)event.item; + int index = viewer.getTree().indexOf(item); + + int width = 0; + if (event.index == 1) + width = (column2.getWidth() - 1); + if (event.index == 2) + width = (column3.getWidth() - 1); + + Attribute attribute = Attribute.Visible; + if (event.index == 2) + attribute = Attribute.Focusable; + Tristate state = getJointAttribute(elements, lz[index], attribute); + + Color color = null; + switch (state) { + case False: + color = viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_RED); + break; + case True: + color = viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_GREEN); + break; + case Both: + color = viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_GRAY); + break; + } + + GC gc = event.gc; + Color foreground = gc.getForeground(); + Color background = gc.getBackground(); + gc.setBackground(color); + gc.setForeground(viewer.getTree().getDisplay().getSystemColor(SWT.COLOR_BLACK)); + gc.fillRectangle(event.x, event.y, width-1, event.height-1); + Rectangle rect2 = new Rectangle(event.x, event.y, width-1, event.height-1); + gc.drawRectangle(rect2); + gc.setForeground(background); + gc.setBackground(foreground); + } + } + }); + viewer.getTree().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent event) { + if (event.keyCode == SWT.F2) { + // FIXME: Eclipse currently eats F2 presses. This should be + // implemented as a command handler or find some way to + // force these listeners to have priority... + System.out.println("startediting"); + + TreeItem[] items = viewer.getTree().getSelection(); + if(items.length != 1) + return; + + TreeItem item = items[0]; + + ILayer layer = ISelectionUtils.filterSingleSelection(viewer.getSelection(), ILayer.class); + if (layer == null) + return; + + startEditing(layer, item); + } + } + }); + viewer.getTree().addListener(SWT.MouseDown, new Listener() { + public void handleEvent(Event event) { + if (viewer.getControl().isDisposed()) + return; + + Point pt = new Point(event.x, event.y); + TreeItem item = viewer.getTree().getItem(pt); + if (item == null) + return; + + int index = viewer.getTree().indexOf(item); + ILayer[] lz = layers.getLayers().toArray(new ILayer[0]); + ILayer layer = lz[index]; + + Rectangle rect = item.getBounds(0); + if (event.count == 2 && rect.contains(pt)) { + startEditing(layer, item); + return; + } + + // Cannot adjust visibility/focusability if no elements are selected. + if (elements.isEmpty()) + return; + + rect = item.getBounds(1); + if (rect.contains(pt)) { + Tristate state = getJointAttribute(elements, layer, Attribute.Visible); + if (setAttribute(elements, layer, Attribute.Visible, state.toggle().toBoolean()) > 0) { + refresh(); + } + return; + } + + Rectangle rect2 = item.getBounds(2); + if (rect2.contains(pt)) { + Tristate state = getJointAttribute(elements, layer, Attribute.Focusable); + if (setAttribute(elements, layer, Attribute.Focusable, state.toggle().toBoolean()) > 0) { + refresh(); + } + return; + } + } + + private void refresh() { + viewer.getControl().redraw(); + context.getThreadAccess().asyncExec(new Runnable() { + @Override + public void run() { + if (context.isDisposed()) + return; + context.getContentContext().setDirty(); + } + }); + } + }); + + viewer.addCheckStateListener(new ICheckStateListener(){ + @Override + public void checkStateChanged(CheckStateChangedEvent event) { + ILayer layer = (ILayer)event.getElement(); + if(event.getChecked()) layers.activate(layer); + else layers.deactivate(layer); + viewer.setSubtreeChecked(event.getElement(), event.getChecked()); + context.getThreadAccess().asyncExec(new Runnable() { + + @Override + public void run() { + if(context.isDisposed()) return; + context.getContentContext().setDirty(); + } + + }); + } + }); + + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + ISelection s = event.getSelection(); + if (s.isEmpty()) { + removeButton.setEnabled(false); + } else { + removeButton.setEnabled(true); + } + } + }); + + viewer.setContentProvider(new ITreeContentProvider(){ + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + @Override + public void dispose() { + } + @Override + public Object[] getElements(Object inputElement) { + return layers.getLayers().toArray(); + } + @Override + public boolean hasChildren(Object element) { + return false; + } + @Override + public Object getParent(Object element) { + return null; + } + @Override + public Object[] getChildren(Object parentElement) { + return new Object[0]; + } + }); + viewer.setLabelProvider(new CellLabelProvider() { + @Override + public void update(ViewerCell cell) { + if(cell.getColumnIndex() == 0) { + ILayer layer = (ILayer)cell.getElement(); + cell.setText(layer.getName()); + } else { + cell.setText(""); + } + } + }); + viewer.setCheckStateProvider(new ICheckStateProvider() { + @Override + public boolean isChecked(Object element) { + ILayer layer = (ILayer)element; + final boolean isActive = layers.isActive(layer); + return isActive; + } + @Override + public boolean isGrayed(Object element) { + return false; + } + }); + + viewer.setInput(this); + + for(ILayer layer : layers.getVisibleLayers()) { + viewer.setSubtreeChecked(layer, true); + } + } + + @Override + public Control getControl() { + return composite; + } + + @Override + public void setFocus() { + } + + @Override + public void addSelectionChangedListener(ISelectionChangedListener listener) { + } + + @Override + public ISelection getSelection() { + return null; + } + + @Override + public void removeSelectionChangedListener(ISelectionChangedListener listener) { + } + + @Override + public void setSelection(ISelection selection) { + } + + private boolean startEditing(final ILayer layer, final TreeItem item/*, final int columnIndex*/) { + + // Column column = columns[columnIndex]; + + String initialText = layer.getName(); + + final Composite composite = new Composite(viewer.getTree(), SWT.NONE); + final Text text = new Text(composite, SWT.BORDER); + final int insetX = 0; + final int insetY = 0; + composite.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event e) { + Rectangle rect = composite.getClientArea(); + text.setBounds(rect.x + insetX, rect.y + insetY, rect.width - insetX * 2, rect.height + - insetY * 2); + } + }); + Listener textListener = new Listener() { + public void handleEvent(final Event e) { + //String error; + String newText; + switch (e.type) { + case SWT.FocusOut: + if(layer instanceof IEditableLayer) { + IEditableLayer l = (IEditableLayer)layer; + l.setName(text.getText()); + System.out.println("renamed layer to " + text.getText()); + viewer.refresh(); + } + + // // Item may be disposed if the tree gets reset after a previous editing. + // if (!item.isDisposed()) { + // item.setText(columnIndex, text.getText()); + // queueSelectionRefresh(context); + // } + // } else { + // // System.out.println("validation error: " + error); + // } + composite.dispose(); + break; + case SWT.Modify: + // newText = text.getText(); + // error = modifier.isValid(newText); + // if (error != null) { + // text.setBackground(invalidModificationColor); + // // System.out.println("validation error: " + error); + // } else { + // text.setBackground(null); + // } + break; + case SWT.Verify: + newText = text.getText(); + String leftText = newText.substring(0, e.start); + String rightText = newText.substring(e.end, newText.length()); + GC gc = new GC(text); + Point size = gc.textExtent(leftText + e.text + rightText); + gc.dispose(); + size = text.computeSize(size.x, SWT.DEFAULT); + editor.horizontalAlignment = SWT.LEFT; + Rectangle itemRect = item.getBounds(0), + rect = viewer.getTree().getClientArea(); + editor.minimumWidth = Math.max(size.x, itemRect.width) + insetX * 2; + int left = itemRect.x, + right = rect.x + rect.width; + editor.minimumWidth = Math.min(editor.minimumWidth, right - left); + editor.minimumHeight = size.y + insetY * 2; + editor.layout(); + break; + case SWT.Traverse: + switch (e.detail) { + case SWT.TRAVERSE_RETURN: + if(layer instanceof IEditableLayer) { + IEditableLayer l = (IEditableLayer)layer; + l.setName(text.getText()); + //System.out.println("renamed layer to " + text.getText()); + viewer.refresh(); + } + // error = modifier.isValid(text.getText()); + // if (error == null) { + // modifier.modify(text.getText()); + // if (!item.isDisposed()) { + // item.setText(columnIndex, text.getText()); + // queueSelectionRefresh(context); + // } + // } + // FALL THROUGH + case SWT.TRAVERSE_ESCAPE: + composite.dispose(); + e.doit = false; + break; + default: + //System.out.println("unhandled traversal: " + e.detail); + break; + } + break; + } + } + }; + text.addListener(SWT.FocusOut, textListener); + text.addListener(SWT.Traverse, textListener); + text.addListener(SWT.Verify, textListener); + text.addListener(SWT.Modify, textListener); + editor.setEditor(composite, item, 0); + text.setText(initialText); + text.selectAll(); + text.setFocus(); + // lastItem[0] = item; + return true; + } + +}