/******************************************************************************* * Copyright (c) 2011 Bundlemaker project team. * 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: * Bundlemaker project team - initial API and implementation ******************************************************************************/ package org.bundlemaker.core.ui.view.dependencytable; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.bundlemaker.core.analysis.AnalysisModelQueries; import org.bundlemaker.core.analysis.IBundleMakerArtifact; import org.bundlemaker.core.analysis.IDependency; import org.bundlemaker.core.analysis.IResourceArtifact; import org.bundlemaker.core.jtype.ITypeArtifact; import org.bundlemaker.core.selection.IDependencySelection; import org.bundlemaker.core.selection.IDependencySelectionListener; import org.bundlemaker.core.selection.Selection; import org.bundlemaker.core.ui.artifact.tree.EditorHelper; import org.bundlemaker.core.ui.event.selection.workbench.view.AbstractDependencySelectionAwareViewPart; import org.bundlemaker.core.ui.operations.CreateModuleWithArtifactsOperation; import org.bundlemaker.core.ui.view.dependencytable.internal.Activator; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnLayoutData; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.IActionBars; /** * <p> * </p> * * @author Nils Hartmann (nils@nilshartmann.net) * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class DependencyTableView extends AbstractDependencySelectionAwareViewPart implements IDependencySelectionListener { /** - */ public static String ID = DependencyTableView.class.getName(); public static String PROVIDER_ID = "org.bundlemaker.core.ui.view.dependencytable"; private static final String VIEW_SETTINGS_SECTION = "DependencyTableView"; /** - */ private TableViewer _viewer; private LabelPresentationModeAction[] _labelPresentationModeActions; /** Comparator used to sort the columns */ private DependencyComparator _dependencyComparator; /** - */ private ArtifactPathLabelGenerator _fromLabelGenerator = new ArtifactPathLabelGenerator(); /** - */ private ArtifactPathLabelGenerator _toLabelGenerator = new ArtifactPathLabelGenerator(); /** * {@inheritDoc} */ @Override public void createPartControl(Composite parent) { FillLayout fillLayout = new FillLayout(); fillLayout.type = SWT.VERTICAL; parent.setLayout(fillLayout); Composite tableComposite = new Composite(parent, SWT.NONE); tableComposite.setLayout(new TableColumnLayout()); _dependencyComparator = new DependencyComparator(_fromLabelGenerator, _toLabelGenerator); _viewer = new TableViewer(tableComposite, SWT.VIRTUAL | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI); final Table table = _viewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); _viewer.setContentProvider(new LazyDependencyProvider(_viewer)); createColumns(tableComposite, _viewer); // open editor on double click _viewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { openDependenciesInEditor(); } }); _viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection structuredSelection = (IStructuredSelection) event.getSelection(); // Collection<IDependency> dependencies = new LinkedList<IDependency>(); // for (Iterator<?> iterator = structuredSelection.iterator(); iterator.hasNext();) { dependencies.add((IDependency) iterator.next()); } // Selection.instance().getDependencySelectionService() .setSelection(Selection.DETAIL_DEPENDENCY_SELECTION_ID, PROVIDER_ID, dependencies); } }); loadViewSettings(); // Popup menu MenuManager menuMgr = new MenuManager(); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { DependencyTableView.this.fillContextMenu(manager); } }); Menu menu = menuMgr.createContextMenu(_viewer.getControl()); _viewer.getControl().setMenu(menu); // getSite().registerContextMenu(menuMgr, _viewer); contributeToActionBars(); // init the dependencies initDependencies(); } /** * @param manager */ protected void fillContextMenu(IMenuManager manager) { final List<IDependency> selectedDependencies = getSelectedDependencies(); Action action = new Action("Open in Editor") { @Override public void run() { openDependenciesInEditor(); } }; action.setEnabled(selectedDependencies.isEmpty() == false); manager.add(action); action = new Action("Copy to Clipboard") { @Override public void run() { copyDependenciesToClipboard(); } }; action.setEnabled(selectedDependencies.isEmpty() == false); manager.add(action); action = new Action("Create Module from referenced Artifacts") { @Override public void run() { List<IBundleMakerArtifact> artifacts = new LinkedList<IBundleMakerArtifact>(); List<IDependency> currentSelectedDependencies = getSelectedDependencies(); for (IDependency iDependency : currentSelectedDependencies) { IBundleMakerArtifact to = iDependency.getTo(); if (to instanceof ITypeArtifact) { if (!artifacts.contains(to)) { artifacts.add(to); } } } createModuleFromSelectedTypes(artifacts); _viewer.refresh(); } }; manager.add(action); action = new Action("Create Module from referencing Artifacts") { @Override public void run() { List<IBundleMakerArtifact> artifacts = new LinkedList<IBundleMakerArtifact>(); List<IDependency> currentSelectedDependencies = getSelectedDependencies(); for (IDependency iDependency : currentSelectedDependencies) { IBundleMakerArtifact from = iDependency.getFrom(); if (from instanceof ITypeArtifact) { if (!artifacts.contains(from)) { artifacts.add(from); } } } createModuleFromSelectedTypes(artifacts); _viewer.refresh(); } }; manager.add(action); } private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); // fillLocalToolBar(bars.getToolBarManager()); } class LabelPresentationModeAction extends Action { private final LabelPresentationMode _labelPresentationMode; public LabelPresentationModeAction(LabelPresentationMode labelPresentationMode) { super(labelPresentationMode.getLabel(), IAction.AS_CHECK_BOX); _labelPresentationMode = labelPresentationMode; setToolTipText(labelPresentationMode.getTooltip()); update(); } @Override public void run() { setLabelPresentationMode(_labelPresentationMode); } public void update() { setChecked(_fromLabelGenerator.getLabelPresentationMode() == _labelPresentationMode); } } protected void setLabelPresentationMode(LabelPresentationMode newLabelPresentationMode) { _fromLabelGenerator.setLabelPresentationMode(newLabelPresentationMode); _toLabelGenerator.setLabelPresentationMode(newLabelPresentationMode); saveViewSettings(); _viewer.refresh(); if (_labelPresentationModeActions != null) { for (LabelPresentationModeAction action : _labelPresentationModeActions) { action.update(); } } } private IDialogSettings getViewSettings() { IDialogSettings settings = Activator.getDefault().getDialogSettings(); IDialogSettings section = settings.getSection(VIEW_SETTINGS_SECTION); if (section == null) { section = settings.addNewSection(VIEW_SETTINGS_SECTION); } return section; } private void saveViewSettings() { IDialogSettings dialogSettings = getViewSettings(); dialogSettings.put("labelPresentationModel", _fromLabelGenerator.getLabelPresentationMode().name()); } private void loadViewSettings() { IDialogSettings dialogSettings = getViewSettings(); String labelPresentationModeName = dialogSettings.get("labelPresentationModel"); if (labelPresentationModeName != null) { LabelPresentationMode labelPresentationMode = LabelPresentationMode.valueOf(labelPresentationModeName); _fromLabelGenerator.setLabelPresentationMode(labelPresentationMode); _toLabelGenerator.setLabelPresentationMode(labelPresentationMode); } } private void fillLocalPullDown(IMenuManager menuManager) { if (_labelPresentationModeActions == null) { // Create one action for each label presentation mode LabelPresentationMode[] values = LabelPresentationMode.values(); _labelPresentationModeActions = new LabelPresentationModeAction[values.length]; for (int i = 0;i<values.length;i++) { _labelPresentationModeActions[i] = new LabelPresentationModeAction(values[i]); } } for (int i = 0;i<_labelPresentationModeActions.length;i++) { menuManager.add(_labelPresentationModeActions[i]); } } /** * Returns the dependencies that are currently selected inside the viewer. Returns an empty list if there are now * dependencies selected. * * @return */ public List<IDependency> getSelectedDependencies() { StructuredSelection structuredSelection = (StructuredSelection) _viewer.getSelection(); List<IDependency> result = new LinkedList<IDependency>(); Iterator<?> it = structuredSelection.iterator(); while (it.hasNext()) { IDependency selectedDependency = (IDependency) it.next(); result.add(selectedDependency); } return result; } /** * Open the selected dependency in the editor of the 'from' reference, marking the 'to' reference */ protected void openDependenciesInEditor() { List<IDependency> selectedDependencies = getSelectedDependencies(); for (IDependency dependency : selectedDependencies) { IBundleMakerArtifact artifact = (IBundleMakerArtifact) dependency.getFrom(); if (artifact != null) { try { EditorHelper.openArtifactInEditor(artifact instanceof IResourceArtifact ? ((IResourceArtifact) artifact) : artifact.getParent(IResourceArtifact.class)); } catch (Exception e) { MessageDialog.openError(getSite().getShell(), "Error", e.getMessage()); } } } } /** * Copies the selected dependencies into the clipboard. * * <p> * One line for each dependency with "from", "kind" and "to" in comma-separated columns * */ protected void copyDependenciesToClipboard() { List<IDependency> selectedDependencies = getSelectedDependencies(); // Build the content to be copied StringBuilder builder = new StringBuilder(); for (IDependency dependency : selectedDependencies) { String from = _fromLabelGenerator.getLabel(dependency.getFrom()); String to = _toLabelGenerator.getLabel(dependency.getTo()); builder .append(String.format("%s,%s,%s%n", from, String.valueOf(dependency.getDependencyKind()).toLowerCase(), to)); } // copy to clipboard final Clipboard cb = new Clipboard(getSite().getShell().getDisplay()); TextTransfer textTransfer = TextTransfer.getInstance(); cb.setContents(new Object[] { builder.toString() }, new Transfer[] { textTransfer }); } protected void createModuleFromSelectedTypes(List<IBundleMakerArtifact> types) { CreateModuleWithArtifactsOperation operation = new CreateModuleWithArtifactsOperation(getViewSite().getShell(), types); operation.run(); } /** * {@inheritDoc} */ @Override public void setFocus() { // } /** * {@inheritDoc} */ @Override protected void onSetDependencySelection(IDependencySelection selection) { // init dependencies initDependencies(); } /** * <p> * </p> */ private void initDependencies() { if (_viewer == null || _viewer.getTable().isDisposed()) { return; } IDependencySelection currentDependencySelection = getCurrentDependencySelection(); if (currentDependencySelection == null || !currentDependencySelection.hasDependencies()) { setColumnTitles("From", "To"); _viewer.setInput(new IDependency[0]); _viewer.getTable().redraw(); return; } else { IBundleMakerArtifact toBaseArtifact = currentDependencySelection.getFirstDependency().getTo(); IBundleMakerArtifact fromBaseArtifact = currentDependencySelection.getFirstDependency().getFrom(); if (currentDependencySelection.getSelectedDependencies().size()!=1) { // TODO determine deepest common base of all dependencies toBaseArtifact = toBaseArtifact.getRoot(); fromBaseArtifact = fromBaseArtifact.getRoot(); } System.out.println("ToArtifact: " + toBaseArtifact); System.out.println("FromArtifact: " + fromBaseArtifact); _fromLabelGenerator.setBaseArtifact(fromBaseArtifact); _toLabelGenerator.setBaseArtifact(toBaseArtifact); // String fromColumnTitle = "From " + _fromLabelGenerator.getTitle(); String toColumnTitle = "To " + _toLabelGenerator.getTitle(); setColumnTitles(fromColumnTitle, toColumnTitle); List<IDependency> leafDependencies = AnalysisModelQueries.getCoreDependencies(currentDependencySelection .getSelectedDependencies()); IDependency[] dependencies = leafDependencies.toArray(new IDependency[0]); setOrderedDependencies(dependencies); } } private void setOrderedDependencies(IDependency[] dependencies) { _dependencyComparator.sortDependencies(dependencies); _viewer.setInput(dependencies); _viewer.setItemCount(dependencies.length); // This is the difference when using a ILazyContentProvider _viewer.getTable().redraw(); } /** * {@inheritDoc} */ @Override public void analysisModelModified() { // TODO Auto-generated method stub } /** * <p> * </p> * * @return */ @Override protected String getSelectionId() { return Selection.MAIN_DEPENDENCY_SELECTION_ID; } private void createColumns(Composite parent, TableViewer viewer) { createTableViewerColumn(parent, viewer, 0,"From", 45, new DependencyColumnLabelProvider(_fromLabelGenerator) { @Override protected IBundleMakerArtifact getArtifactElement(IDependency element) { return element.getFrom(); } }); // createTableViewerColumn(parent, viewer, 1, "Usage", 10, new ColumnLabelProvider() { @Override public String getText(Object element) { if (element instanceof IDependency) { IDependency dependency = (IDependency) element; return String.valueOf(dependency.getDependencyKind()).toLowerCase(); } return super.getText(element); } }); createTableViewerColumn(parent, viewer, 2, "To", 45, new DependencyColumnLabelProvider(_toLabelGenerator) { @Override public IBundleMakerArtifact getArtifactElement(IDependency element) { return element.getTo(); } }); } private TableViewerColumn createTableViewerColumn(Composite tableComposite, TableViewer viewer, int index, String title, int weight, CellLabelProvider labelProvider) { final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE); final TableColumn column = viewerColumn.getColumn(); column.setText(title); column.setResizable(true); column.setMoveable(false); TableColumnLayout tableLayout = (TableColumnLayout) tableComposite.getLayout(); ColumnLayoutData columnLayoutData = new ColumnWeightData(weight); tableLayout.setColumnData(column, columnLayoutData); if (labelProvider != null) { viewerColumn.setLabelProvider(labelProvider); } column.addSelectionListener(getSelectionAdapter(column, index)); return viewerColumn; } private SelectionAdapter getSelectionAdapter(final TableColumn column, final int index) { SelectionAdapter selectionAdapter = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { _dependencyComparator.setColumn(index); int dir = _dependencyComparator.getDirection(); _viewer.getTable().setSortDirection(dir); _viewer.getTable().setSortColumn(column); IDependency[] currentDependencies = (IDependency[]) _viewer.getInput(); setOrderedDependencies(currentDependencies); _viewer.refresh(); } }; return selectionAdapter; } private void setColumnTitles(String fromColumnTitle, String toColumnTitle) { Table table = _viewer.getTable(); table.getColumn(0).setText(fromColumnTitle); table.getColumn(2).setText(toColumnTitle); } }