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