// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.ui.swt; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuAdapter; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; import de.ugoe.cs.autoquest.eventcore.IEventTarget; import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement; import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance; import de.ugoe.cs.autoquest.tasktrees.treeifc.IMarkingTemporalRelationship; import de.ugoe.cs.autoquest.tasktrees.treeifc.IStructuringTemporalRelationship; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInfo; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel; import de.ugoe.cs.autoquest.tasktrees.treeifc.TaskMetric; /** *

* TODO comment *

* * @author Patrick Harms */ class VisualizationUtils { /** * */ static Tree createTaskDetailsTree(Composite parent, String firstColumnHeader, ITaskModel taskModel) { final Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.VIRTUAL); tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); tree.setHeaderVisible(true); TreeColumn taskColumn = new TreeColumn(tree, SWT.NONE); taskColumn.setText(firstColumnHeader); taskColumn.setAlignment(SWT.LEFT); TaskMetric[] metrics = taskModel.getAllMetrics(); for (TaskMetric metric : metrics) { TreeColumn metricColumn = new TreeColumn(tree, SWT.WRAP); metricColumn.setText(metric.getName().replace(' ', '\n')); metricColumn.setToolTipText(metric.getDescription()); metricColumn.setAlignment(SWT.CENTER); } // update the columns widths on expansion and collapse if (tree.getListeners(SWT.Expand).length == 0) { tree.addListener(SWT.Expand, new Listener() { public void handleEvent(final Event event) { ((TreeItem) event.item).setExpanded(true); updateColumnWidths(tree); } }); } if (tree.getListeners(SWT.Collapse).length == 0) { tree.addListener(SWT.Collapse, new Listener() { public void handleEvent(final Event event) { ((TreeItem) event.item).setExpanded(false); updateColumnWidths(tree); } }); } return tree; } /** * convenience method to create a tree item for a task */ static void createTreeItemFor(ITask task, Widget parent, ITaskModel taskModel, boolean createChildren) { ITaskInfo taskInfo = taskModel.getTaskInfo(task); TaskMetric[] metrics = taskModel.getAllMetrics(); String[] values = new String[metrics.length + 2]; values[0] = task.toString(); for (int i = 0; i < metrics.length; i++) { int contextValue = Integer.MIN_VALUE; if (parent.getData() instanceof ITask) { contextValue = taskInfo.getMeasureValue(metrics[i]); } if (contextValue > Integer.MIN_VALUE) { values[i + 1] = metrics[i].formatValue(contextValue) + "(" + metrics[i].formatValue(taskInfo.getMeasureValue(metrics[i])) + ")"; } else { values[i + 1] = metrics[i].formatValue(taskInfo.getMeasureValue(metrics[i])); } } values[values.length - 1] = Integer.toString(task.getId()); TreeItem item; if (parent instanceof TreeItem) { item = new TreeItem((TreeItem) parent, SWT.NULL); } else { item = new TreeItem((Tree) parent, SWT.NULL); } item.setText(values); item.setData(task); if (createChildren) { // simulate a child if ((task instanceof IStructuringTemporalRelationship) || (task instanceof IMarkingTemporalRelationship)) { new TreeItem(item, SWT.NULL); } } } /** * */ static Tree createTargetsTree(Composite parent, String name) { Tree tree = new Tree(parent, SWT.BORDER | SWT.MULTI); tree.setHeaderVisible(true); TreeColumn guiElementColumn = new TreeColumn(tree, SWT.NONE); guiElementColumn.setText(name); guiElementColumn.setAlignment(SWT.LEFT); return tree; } /** * */ static void updateColumnWidths(Tree tree) { TreeColumn firstColumn = tree.getColumn(0); firstColumn.pack(); if (tree.getColumnCount() > 1) { int availableWidth = tree.getBounds().width - firstColumn.getWidth(); int effectiveWidth = 0; for (int i = 1; i < tree.getColumnCount(); i++) { TreeColumn column = tree.getColumn(i); column.pack(); effectiveWidth += column.getWidth(); } if (effectiveWidth < availableWidth) { firstColumn.setWidth(firstColumn.getWidth() + availableWidth - effectiveWidth - 20); } } } /** * */ static void addItemSpecificContextMenu(final Tree tree, final Class selectedItemDataType, final String menuItemText, final SelectionAdapter menuItemSelectionAdapter) { Menu menu = tree.getMenu(); if (menu == null) { menu = new Menu(tree); tree.setMenu(menu); } final Menu finalMenu = menu; menu.addMenuListener(new MenuAdapter() { public void menuShown(MenuEvent e) { MenuItem[] items = finalMenu.getItems(); for (int i = 0; i < items.length; i++) { if (menuItemText.equals(items[i].getText())) { items[i].dispose(); } } if (selectedItemDataType.isInstance(tree.getSelection()[0].getData())) { MenuItem newItem = new MenuItem(finalMenu, SWT.NONE); newItem.setText(menuItemText); newItem.addSelectionListener(menuItemSelectionAdapter); } } }); } /** * */ static void addInvolvedTargets(Tree guiElementsTree, ITask task) { List targets = new ArrayList(); getInvolvedTargets(task, targets); addInvolvedTargets(guiElementsTree, targets); } /** * */ static void getInvolvedTargets(ITask task, List involvedTargets) { if (task instanceof IStructuringTemporalRelationship) { for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { getInvolvedTargets(child, involvedTargets); } } else if (task instanceof IMarkingTemporalRelationship) { getInvolvedTargets (((IMarkingTemporalRelationship) task).getMarkedTask(), involvedTargets); } else { involvedTargets.add (((IEventTaskInstance) task.getInstances().iterator().next()).getEvent().getTarget()); } } /** * */ static void addInvolvedTargets(Tree guiElementsTree, List targets) { for (IEventTarget target : targets) { List pathToIntegrate = new LinkedList(); while (target != null) { pathToIntegrate.add(0, target); if (target instanceof IGUIElement) { target = ((IGUIElement) target).getParent(); } else { target = null; } } TreeItem parent = null; while (pathToIntegrate.size() > 0) { TreeItem[] children; if (parent == null) { children = guiElementsTree.getItems(); } else { children = parent.getItems(); } TreeItem childItem = null; if (children != null) { for (TreeItem child : children) { if (pathToIntegrate.get(0).equals(child.getData())) { childItem = child; } } } if (childItem == null) { if (parent == null) { childItem = new TreeItem(guiElementsTree, SWT.NONE); } else { childItem = new TreeItem(parent, SWT.NONE); } childItem.setText(pathToIntegrate.get(0).toString()); childItem.setData(pathToIntegrate.get(0)); } pathToIntegrate.remove(0); parent = childItem; } } expandAll(guiElementsTree, true); updateColumnWidths(guiElementsTree); } /** * */ static void addInvolvedTargetsHighlighting(final Tree tasks, final Tree involvedTargetsTree) { tasks.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { TreeItem[] selectedItems = tasks.getSelection(); if ((selectedItems.length == 1) && (selectedItems[0].getData() instanceof ITask)) { highlightInvolvedTargets ((ITask) selectedItems[0].getData(), involvedTargetsTree); } } }); } /** * */ static void highlightInvolvedTargets(ITask task, Tree involvedTargetsTree) { List targets = new ArrayList(); getInvolvedTargets(task, targets); List itemsToSelect = new LinkedList(); List candidateItems = new LinkedList(); for (TreeItem item : involvedTargetsTree.getItems()) { candidateItems.add(item); } while (candidateItems.size() > 0) { TreeItem candidate = candidateItems.remove(0); if (targets.contains(candidate.getData())) { itemsToSelect.add(candidate); } for (TreeItem child : candidate.getItems()) { candidateItems.add(child); } } involvedTargetsTree.setSelection (itemsToSelect.toArray(new TreeItem[itemsToSelect.size()])); } /** * */ static void addExpansionListener(Tree tree, Listener listener) { Listener[] listeners = tree.getListeners(SWT.Expand); for (Listener existingListener : listeners) { if ((existingListener == listener) || (existingListener.equals(listener))) { return; } } tree.addListener(SWT.Expand, listener); } /** * expands all nodes in a tree */ static void expandAll(Tree tree, boolean expanded) { for (TreeItem item : tree.getItems()) { expandAll(item, expanded, Integer.MAX_VALUE); } } /** * expands all nodes in a tree up to a specific number of children */ static void expandAll(TreeItem item, boolean expanded, int maxChildrenToExpand) { if (item.getItems().length < maxChildrenToExpand) { Listener[] listeners = item.getParent().getListeners(SWT.Expand); if (listeners != null) { for (Listener listener : listeners) { Event event = new Event(); event.type = SWT.Expand; event.item = item; listener.handleEvent(event); } } item.setExpanded(expanded); for (TreeItem childItem : item.getItems()) { expandAll(childItem, expanded, maxChildrenToExpand); } } } /** * */ private VisualizationUtils() { // prevent instantiation } }