/******************************************************************************* * Copyright (c) 2008-2011 Chair for Applied Software Engineering, * Technische Universitaet Muenchen. * 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: ******************************************************************************/ package org.eclipse.emf.emfstore.internal.client.ui.views.historybrowserview; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import org.apache.commons.lang.StringUtils; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.provider.ComposedAdapterFactory; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.emf.emfstore.client.ESLocalProject; import org.eclipse.emf.emfstore.client.util.ESVoidCallable; import org.eclipse.emf.emfstore.internal.client.common.UnknownEMFStoreWorkloadCommand; import org.eclipse.emf.emfstore.internal.client.model.ESWorkspaceProviderImpl; import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace; import org.eclipse.emf.emfstore.internal.client.model.connectionmanager.ServerCall; import org.eclipse.emf.emfstore.internal.client.model.impl.api.ESWorkspaceImpl; import org.eclipse.emf.emfstore.internal.client.model.util.ProjectSpaceContainer; import org.eclipse.emf.emfstore.internal.client.observers.DeleteProjectSpaceObserver; import org.eclipse.emf.emfstore.internal.client.ui.Activator; import org.eclipse.emf.emfstore.internal.client.ui.common.RunInUI; import org.eclipse.emf.emfstore.internal.client.ui.controller.AbstractEMFStoreUIController; import org.eclipse.emf.emfstore.internal.client.ui.dialogs.EMFStoreMessageDialog; import org.eclipse.emf.emfstore.internal.client.ui.views.changes.ChangePackageVisualizationHelper; import org.eclipse.emf.emfstore.internal.client.ui.views.historybrowserview.graph.IPlotCommit; import org.eclipse.emf.emfstore.internal.client.ui.views.historybrowserview.graph.PlotCommitProvider; import org.eclipse.emf.emfstore.internal.client.ui.views.historybrowserview.graph.PlotLane; import org.eclipse.emf.emfstore.internal.client.ui.views.historybrowserview.graph.SWTPlotRenderer; import org.eclipse.emf.emfstore.internal.client.ui.views.scm.SCMContentProvider; import org.eclipse.emf.emfstore.internal.common.model.ModelElementId; import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil; import org.eclipse.emf.emfstore.internal.server.conflictDetection.ModelElementIdToEObjectMappingImpl; import org.eclipse.emf.emfstore.internal.server.model.impl.api.ESHistoryInfoImpl; import org.eclipse.emf.emfstore.internal.server.model.versioning.AbstractChangePackage; import org.eclipse.emf.emfstore.internal.server.model.versioning.HistoryInfo; import org.eclipse.emf.emfstore.internal.server.model.versioning.ModelElementQuery; import org.eclipse.emf.emfstore.internal.server.model.versioning.PrimaryVersionSpec; import org.eclipse.emf.emfstore.internal.server.model.versioning.RangeQuery; import org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec; import org.eclipse.emf.emfstore.internal.server.model.versioning.VersioningFactory; import org.eclipse.emf.emfstore.internal.server.model.versioning.Versions; import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation; import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.CompositeOperation; import org.eclipse.emf.emfstore.internal.server.model.versioning.util.HistoryQueryBuilder; import org.eclipse.emf.emfstore.server.ESCloseableIterable; import org.eclipse.emf.emfstore.server.exceptions.ESException; import org.eclipse.emf.emfstore.server.model.ESHistoryInfo; import org.eclipse.emf.emfstore.server.model.query.ESHistoryQuery; import org.eclipse.emf.emfstore.server.model.query.ESModelElementQuery; import org.eclipse.emf.emfstore.server.model.versionspec.ESVersionSpec; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.IActionBars; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementListSelectionDialog; import org.eclipse.ui.part.ViewPart; /** * This eclipse views displays the version history of EMFStore. * * @author wesendon * @author Aumann * @author Hodaie * @author Shterev * */ // TODO: review setInput methods public class HistoryBrowserView extends ViewPart implements ProjectSpaceContainer { // icons private static final String EXPAND_ALL_GIF = "icons/expandall.gif"; //$NON-NLS-1$ private static final String COLLAPSE_ALL_GIF = "icons/collapseall.gif"; //$NON-NLS-1$ // Config private static final int UPPER_LIMIT = 10; private static final int LOWER_LIMIT = 20; // model state private ProjectSpace projectSpace; private EObject modelElement; private List<HistoryInfo> infos; private PrimaryVersionSpec centerVersion; private boolean showAllVersions; // viewer private TreeViewerWithModelElementSelectionProvider viewer; private SWTPlotRenderer renderer; private Link noProjectHint; // Columns private TreeViewerColumn changeColumn; private TreeViewerColumn branchColumn; private TreeViewerColumn commitColumn; private TreeViewerColumn authorColumn; private static final int BRANCH_COLUMN = 1; // content/label provider private SCMContentProvider contentProvider; private PlotCommitProvider commitProvider; private AdapterFactoryLabelProvider adapterFactoryLabelProvider; private HistorySCMLabelProvider changeLabel; private LogMessageColumnLabelProvider commitLabel; // actions private ExpandCollapseAction expandAndCollapse; private boolean isUnlinkedFromNavigator; private Action showAllBranches; /** * {@inheritDoc} */ public ProjectSpace getProjectSpace() { return projectSpace; } @Override public void createPartControl(Composite parent) { GridLayoutFactory.fillDefaults().applyTo(parent); initNoProjectHint(parent); // init viewer viewer = new TreeViewerWithModelElementSelectionProvider(parent); GridDataFactory.fillDefaults().grab(true, true).applyTo(viewer.getControl()); final Tree tree = viewer.getTree(); tree.setHeaderVisible(true); ColumnViewerToolTipSupport.enableFor(viewer); getSite().setSelectionProvider(viewer); initMenuManager(); changeColumn = createColumn(Messages.HistoryBrowserView_Changes, 250); branchColumn = createColumn(Messages.HistoryBrowserView_Branches, 150); commitColumn = createColumn(Messages.HistoryBrowserView_CommitMessage, 250); authorColumn = createColumn(Messages.HistoryBrowserView_AuthorAndDate, 250); initContentAndLabelProvider(); initGraphRenderer(); initToolBar(); initProjectDeleteListener(); } private void initContentAndLabelProvider() { contentProvider = new SCMContentProvider(); commitProvider = new PlotCommitProvider(); viewer.setContentProvider(contentProvider); changeLabel = new HistorySCMLabelProvider(); changeColumn.setLabelProvider(changeLabel); branchColumn.setLabelProvider(new BranchGraphLabelProvider()); commitLabel = new LogMessageColumnLabelProvider(); commitColumn.setLabelProvider(commitLabel); authorColumn.setLabelProvider(new CommitInfoColumnLabelProvider()); adapterFactoryLabelProvider = new AdapterFactoryLabelProvider(new ComposedAdapterFactory( ComposedAdapterFactory.Descriptor.Registry.INSTANCE)); } private void initGraphRenderer() { renderer = new SWTPlotRenderer(viewer.getTree().getDisplay()); // XXX SWT.PaintItem is not available in RAP, so we are using the numerical constant here viewer.getTree().addListener(/* SWT.PaintItem */42, new Listener() { public void handleEvent(Event event) { doPaint(event); } }); } private void doPaint(Event event) { if (event.index != BRANCH_COLUMN) { return; } Object data; TreeItem currItem = (TreeItem) event.item; data = currItem.getData(); boolean isCommitItem = true; while (!(data instanceof HistoryInfo)) { isCommitItem = false; currItem = currItem.getParentItem(); if (currItem == null) { // no history info in parent hierarchy, do not draw. // Happens e.g. if the user deactivates showing the commits return; } data = currItem.getData(); } final IPlotCommit c = commitProvider.getCommitFor((HistoryInfo) data, !isCommitItem); final PlotLane lane = c.getLane(); if (lane != null && lane.getSaturatedColor().isDisposed()) { return; } // if (highlight != null && c.has(highlight)) // event.gc.setFont(hFont); // else event.gc.setFont(PlatformUI.getWorkbench().getDisplay().getSystemFont()); renderer.paint(event, c); } private TreeViewerColumn createColumn(String label, int width) { final TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.MULTI); column.getColumn().setText(label); column.getColumn().setWidth(width); return column; } // TODO review this stuff private void initMenuManager() { final MenuManager menuMgr = new MenuManager(); menuMgr.add(new Separator("additions")); //$NON-NLS-1$ getSite().registerContextMenu(menuMgr, viewer); final Control control = viewer.getControl(); final Menu menu = menuMgr.createContextMenu(control); control.setMenu(menu); getSite().registerContextMenu(menuMgr, viewer); } /** * Reloads the view with the current parameters. */ public void refresh() { RunInUI.run(new Callable<Void>() { public Void call() throws Exception { setDescription(); return null; } }); resetExpandCollapse(); if (projectSpace == null || modelElement == null) { RunInUI.run(new ESVoidCallable() { @Override public void run() { viewer.setInput(Collections.EMPTY_LIST); } }); return; } infos = getHistoryInfos(); addBaseVersionTag(infos); resetProviders(infos); viewer.setInput(infos); } private void addBaseVersionTag(List<HistoryInfo> infos) { final HistoryInfo historyInfo = getHistoryInfo(projectSpace.getBaseVersion()); if (historyInfo != null) { historyInfo.getTagSpecs().add(Versions.createTAG( ESVersionSpec.BASE, ESVersionSpec.GLOBAL)); } } private void resetExpandCollapse() { expandAndCollapse.setChecked(false); expandAndCollapse.setImage(true); } private void setDescription() { if (projectSpace == null) { setContentDescription(Messages.HistoryBrowserView_NoSelection); showNoProjectHint(true); return; } String label = Messages.HistoryBrowserView_HistoryFor; if (modelElement == projectSpace) { label += projectSpace.getProjectName() + " [" + projectSpace.getBaseVersion().getBranch() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } else { label += adapterFactoryLabelProvider.getText(modelElement); } showNoProjectHint(false); setContentDescription(label); } private List<HistoryInfo> getHistoryInfos() { final Shell shell = getViewSite().getShell(); final List<HistoryInfo> result = new AbstractEMFStoreUIController<List<HistoryInfo>>(shell, true, false) { @Override public List<HistoryInfo> doRun(final IProgressMonitor monitor) throws ESException { return new UnknownEMFStoreWorkloadCommand<List<HistoryInfo>>(monitor) { @Override public List<HistoryInfo> run(final IProgressMonitor monitor) throws ESException { final List<HistoryInfo> historyInfosFromServer = getHistoryInfosFromServer(monitor); return historyInfosFromServer; } }.execute(); // UnknownEMFStoreWorkloadCommand } }.execute(); // AbstractEMFStoreUIController return result != null ? result : new ArrayList<HistoryInfo>(); } private List<HistoryInfo> getHistoryInfosFromServer(final IProgressMonitor monitor) throws ESException { return new ServerCall<List<HistoryInfo>>(projectSpace) { @Override protected List<HistoryInfo> run() throws ESException { monitor.beginTask(Messages.HistoryBrowserView_FetchingHistory, 100); final List<HistoryInfo> historyInfos = getLocalChanges(); monitor.worked(10); if (projectSpace != modelElement) { final List<ESHistoryInfo> infos = modelElementQuery(); for (final ESHistoryInfo info : infos) { historyInfos.add(((ESHistoryInfoImpl) info).toInternalAPI()); } } else { // TODO monitor final List<ESHistoryInfo> infos = rangeQuery(); for (final ESHistoryInfo info : infos) { historyInfos.add(((ESHistoryInfoImpl) info).toInternalAPI()); } } monitor.worked(90); return historyInfos; } }.execute(); // ServerCall } private List<ESHistoryInfo> modelElementQuery() throws ESException { final ModelElementQuery query = HistoryQueryBuilder.modelelementQuery( centerVersion, Arrays.asList(ModelUtil.getModelElementId(modelElement)), UPPER_LIMIT, LOWER_LIMIT, showAllVersions, true); // TODO: proivde util method final ESHistoryQuery<ESModelElementQuery> api = query.toAPI(); final List<ESHistoryInfo> infos = projectSpace.toAPI().getHistoryInfos(api, new NullProgressMonitor()); return infos; } private List<ESHistoryInfo> rangeQuery() throws ESException { final RangeQuery<?> rangeQuery = HistoryQueryBuilder .rangeQuery( centerVersion, UPPER_LIMIT, LOWER_LIMIT, showAllVersions, true, true, true); final List<ESHistoryInfo> infos = projectSpace.toAPI().getHistoryInfos( rangeQuery.toAPI(), new NullProgressMonitor()); return infos; } private List<HistoryInfo> getLocalChanges() { final ArrayList<HistoryInfo> revisions = new ArrayList<HistoryInfo>(); if (projectSpace != null) { // TODO: add a feature "hide local revision" final HistoryInfo localHistoryInfo = VersioningFactory.eINSTANCE.createHistoryInfo(); final AbstractChangePackage changePackage = projectSpace.getLocalChangePackage(false); // filter for modelelement, do additional sanity check as the // project space could've been also selected if (modelElement != null && projectSpace.getProject().contains(modelElement)) { final Set<AbstractOperation> operationsToRemove = new LinkedHashSet<AbstractOperation>(); final ESCloseableIterable<AbstractOperation> operations = changePackage.operations(); try { for (final AbstractOperation operation : operations.iterable()) { if (!operation.getAllInvolvedModelElements().contains( ModelUtil.getProject(modelElement).getModelElementId(modelElement))) { operationsToRemove.add(operation); } } } finally { operations.close(); } // TODO: LCP - bummer.. // changePackage.getOperations().removeAll(operationsToRemove); } // TODO: LCP // localHistoryInfo.setChangePackage(changePackage); final PrimaryVersionSpec versionSpec = VersioningFactory.eINSTANCE.createPrimaryVersionSpec(); versionSpec.setIdentifier(-1); localHistoryInfo.setPrimarySpec(versionSpec); localHistoryInfo.setPreviousSpec(ModelUtil.clone(projectSpace.getBaseVersion())); revisions.add(localHistoryInfo); } return revisions; } private void resetProviders(List<HistoryInfo> infos) { // TODO: LCP final ArrayList<AbstractChangePackage> cps = new ArrayList<AbstractChangePackage>(); for (final HistoryInfo info : infos) { if (info.getChangePackage() != null) { cps.add(info.getChangePackage()); } } final ChangePackageVisualizationHelper newHelper = new ChangePackageVisualizationHelper( new ModelElementIdToEObjectMappingImpl(projectSpace.getProject(), cps)); changeLabel.setProject(projectSpace.getProject()); changeLabel.setChangePackageVisualizationHelper(newHelper); commitLabel.setProject(projectSpace.getProject()); commitLabel.setChangePackageVisualizationHelper(newHelper); commitProvider.reset(infos); } /** * Displays the history for the given input. * * @param input eobject in projectspace or projectspace itself */ public void setInput(EObject input) { try { if (input instanceof ProjectSpace) { projectSpace = (ProjectSpace) input; } else if (input != null) { final ESWorkspaceImpl workspace = ESWorkspaceProviderImpl.getInstance().getWorkspace(); projectSpace = workspace.toInternalAPI().getProjectSpace(ModelUtil.getProject(input)); } else { projectSpace = null; } modelElement = input; showAll(true); setCenterVersion(); refresh(); } catch (final ESException e) { } } /** * Sets a {@link ESLocalProject} as an input for the view. The history for the input will be shown. * * @param localProject the project to show the history for. */ public void setInput(ESLocalProject localProject) { setInput((EObject) localProject); } private void showAll(boolean show) { showAllVersions = show; showAllBranches.setChecked(show); } private void setCenterVersion() { if (projectSpace != null) { centerVersion = projectSpace.getBaseVersion(); } else { centerVersion = null; } } private void showNoProjectHint(boolean b) { noProjectHint.setVisible(b); noProjectHint.getParent().layout(); } private void initNoProjectHint(final Composite parent) { noProjectHint = new Link(parent, SWT.WRAP); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).grab(true, false).applyTo(noProjectHint); noProjectHint .setText(Messages.HistoryBrowserView_SelectProjectOrCallHistory); noProjectHint.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { final ElementListSelectionDialog elsd = new ElementListSelectionDialog(parent.getShell(), new ESBrowserLabelProvider()); final List<ProjectSpace> relevantProjectSpaces = new ArrayList<ProjectSpace>(); final ESWorkspaceImpl workspace = ESWorkspaceProviderImpl.getInstance().getWorkspace(); for (final ProjectSpace ps : workspace.toInternalAPI().getProjectSpaces()) { if (ps.getUsersession() != null) { relevantProjectSpaces.add(ps); } } elsd.setElements(relevantProjectSpaces.toArray()); elsd.setMultipleSelection(false); elsd.setTitle(Messages.HistoryBrowserView_SelectProjectTitle); elsd.setMessage(Messages.HistoryBrowserView_SelectProjectMsg); if (Window.OK == elsd.open()) { for (final Object o : elsd.getResult()) { final ProjectSpace resultSelection = (ProjectSpace) o; if (resultSelection != null) { setInput(resultSelection); } break; } } } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); } private void initProjectDeleteListener() { ESWorkspaceProviderImpl.getObserverBus().register(new DeleteProjectSpaceObserver() { public void projectSpaceDeleted(ProjectSpace projectSpace) { if (HistoryBrowserView.this.projectSpace == projectSpace) { setInput((EObject) null); } } }); } @Override public void dispose() { adapterFactoryLabelProvider.dispose(); changeLabel.dispose(); commitLabel.dispose(); super.dispose(); } @Override public void setFocus() { viewer.getControl().setFocus(); } /** * ==================================================================== * * TOOLBAR. * * ==================================================================== */ private void initToolBar() { final IActionBars bars = getViewSite().getActionBars(); final IToolBarManager menuManager = bars.getToolBarManager(); addRefreshAction(menuManager); addShowAllBranchesAction(menuManager); addExpandAllAndCollapseAllAction(menuManager); addNextAndPreviousAction(menuManager); addJumpToRevisionAction(menuManager); addLinkWithNavigatorAction(menuManager); } private void addRefreshAction(IToolBarManager menuManager) { final Action refresh = new Action() { @Override public void run() { refresh(); } }; refresh.setImageDescriptor(Activator.getImageDescriptor("/icons/refresh.png")); //$NON-NLS-1$ refresh.setToolTipText(Messages.HistoryBrowserView_Refresh); menuManager.add(refresh); } private void addNextAndPreviousAction(IToolBarManager menuManager) { final Action prev = new Action() { @Override public void run() { centerVersion = prevNextCenter(false); refresh(); } }; prev.setImageDescriptor(Activator.getImageDescriptor("/icons/prev.png")); //$NON-NLS-1$ prev.setToolTipText(Messages.HistoryBrowserView_PreviousItems); menuManager.add(prev); final Action next = new Action() { @Override public void run() { centerVersion = prevNextCenter(true); refresh(); } }; next.setImageDescriptor(Activator.getImageDescriptor("/icons/next.png")); //$NON-NLS-1$ next.setToolTipText(Messages.HistoryBrowserView_NextItems); menuManager.add(next); } private PrimaryVersionSpec prevNextCenter(boolean next) { if (projectSpace == null || centerVersion == null) { return null; } // all versions pages only based on version numbers if (showAllVersions) { return biggestOrSmallesInfo(next); } // if center is not on the selected branch (base version of ps) jump to base before paging if (!projectSpace.getBaseVersion().getBranch().equals(centerVersion.getBranch())) { return projectSpace.getBaseVersion(); } // search next or prev version on given branch HistoryInfo current = getHistoryInfo(centerVersion); while (current != null) { if (next) { if (current.getNextSpec().size() > 0) { final HistoryInfo nextInfo = getHistoryInfo(current.getNextSpec().get(0)); if (nextInfo == null) { return current.getPrimarySpec(); } current = nextInfo; } else { break; } } else { if (current.getPreviousSpec() != null && current.getPreviousSpec().getBranch().equals(projectSpace.getBaseVersion().getBranch())) { final HistoryInfo prevInfo = getHistoryInfo(current.getPreviousSpec()); if (prevInfo == null) { return current.getPrimarySpec(); } current = prevInfo; } else { break; } } } if (current == null) { return centerVersion; } return current.getPrimarySpec(); } private HistoryInfo getHistoryInfo(PrimaryVersionSpec version) { if (version == null) { return null; } for (final HistoryInfo info : infos) { if (version.equals(info.getPrimarySpec())) { return info; } } return null; } private PrimaryVersionSpec biggestOrSmallesInfo(boolean biggest) { @SuppressWarnings("unchecked") final List<HistoryInfo> input = (List<HistoryInfo>) viewer.getInput(); if (input == null) { return centerVersion; } final ArrayList<HistoryInfo> resultCandidates = new ArrayList<HistoryInfo>(input); PrimaryVersionSpec result = centerVersion; for (final HistoryInfo info : resultCandidates) { if (info.getPrimarySpec().getIdentifier() != -1 && (biggest && info.getPrimarySpec().compareTo(result) == 1 || !biggest && info.getPrimarySpec() .compareTo(result) == -1)) { result = info.getPrimarySpec(); } } return result; } private void addLinkWithNavigatorAction(IToolBarManager menuManager) { isUnlinkedFromNavigator = Activator.getDefault().getDialogSettings().getBoolean("LinkWithNavigator"); //$NON-NLS-1$ final Action linkWithNavigator = new Action(Messages.HistoryBrowserView_LinkWithNavigator, SWT.TOGGLE) { @Override public void run() { Activator.getDefault().getDialogSettings().put("LinkWithNavigator", !isChecked()); //$NON-NLS-1$ isUnlinkedFromNavigator = !isChecked(); } }; linkWithNavigator.setImageDescriptor(Activator.getImageDescriptor("icons/link_with_editor.gif")); //$NON-NLS-1$ linkWithNavigator.setToolTipText("Link with Navigator"); //$NON-NLS-1$ linkWithNavigator.setChecked(!isUnlinkedFromNavigator); menuManager.add(linkWithNavigator); } private void addShowAllBranchesAction(IToolBarManager menuManager) { showAllBranches = new Action("", SWT.TOGGLE) { //$NON-NLS-1$ @Override public void run() { showAllVersions = isChecked(); refresh(); } }; showAllBranches.setImageDescriptor(Activator.getImageDescriptor("icons/arrow_branch.png")); //$NON-NLS-1$ showAllBranches.setToolTipText(Messages.HistoryBrowserView_ShowAllBranches); showAllBranches.setChecked(true); menuManager.add(showAllBranches); } private void addJumpToRevisionAction(IToolBarManager menuManager) { final Action jumpTo = new Action() { @Override public void run() { final InputDialog inputDialog = new InputDialog(getSite().getShell(), Messages.HistoryBrowserView_GoToRevision, Messages.HistoryBrowserView_Revision, StringUtils.EMPTY, null); if (inputDialog.open() == Window.OK) { if (projectSpace != null) { final PrimaryVersionSpec versionSpec = resolveVersion(inputDialog.getValue()); if (versionSpec != null) { showAll(true); centerVersion = versionSpec; refresh(); } } } } }; jumpTo.setImageDescriptor(Activator.getImageDescriptor("/icons/magnifier.png")); //$NON-NLS-1$ jumpTo.setToolTipText(Messages.HistoryBrowserView_GoToRevisionToolTip); menuManager.add(jumpTo); } private PrimaryVersionSpec resolveVersion(final String value) { return new AbstractEMFStoreUIController<PrimaryVersionSpec>(getViewSite().getShell()) { @Override public PrimaryVersionSpec doRun(IProgressMonitor monitor) throws ESException { return new UnknownEMFStoreWorkloadCommand<PrimaryVersionSpec>(monitor) { @Override public PrimaryVersionSpec run(IProgressMonitor monitor) throws ESException { try { return projectSpace.resolveVersionSpec(Versions.createPRIMARY( VersionSpec.GLOBAL, Integer.parseInt(value)), new NullProgressMonitor()); } catch (final ESException e) { EMFStoreMessageDialog.showExceptionDialog( Messages.HistoryBrowserView_VersionDoesNotExist, e); } catch (final NumberFormatException e) { MessageDialog.openError(getSite().getShell(), Messages.HistoryBrowserView_Error, Messages.HistoryBrowserView_NumericValueExpected); } return null; } }.execute(); } }.execute(); } private void addExpandAllAndCollapseAllAction(IToolBarManager menuManager) { final ImageDescriptor expandImg = Activator.getImageDescriptor(EXPAND_ALL_GIF); final ImageDescriptor collapseImg = Activator.getImageDescriptor(COLLAPSE_ALL_GIF); expandAndCollapse = new ExpandCollapseAction(StringUtils.EMPTY, SWT.TOGGLE, expandImg, collapseImg); expandAndCollapse.setImageDescriptor(expandImg); expandAndCollapse.setToolTipText(Messages.HistoryBrowserView_ExpandCollapseToggle); menuManager.add(expandAndCollapse); } /** * Expand/Collapse action. * * @author wesendon */ private final class ExpandCollapseAction extends Action { private final ImageDescriptor expandImg; private final ImageDescriptor collapseImg; private ExpandCollapseAction(String text, int style, ImageDescriptor expandImg, ImageDescriptor collapseImg) { super(text, style); this.expandImg = expandImg; this.collapseImg = collapseImg; } @Override public void run() { if (!isChecked()) { setImage(true); viewer.collapseAll(); } else { setImage(false); viewer.expandToLevel(2); } } public void setImage(boolean expand) { setImageDescriptor(expand ? expandImg : collapseImg); } } /** * Treeviewer that provides a model element selection for selected * operations and mode element ids. * * @author koegel */ private final class TreeViewerWithModelElementSelectionProvider extends TreeViewer { private TreeViewerWithModelElementSelectionProvider(Composite parent) { super(parent, SWT.MULTI); } @Override protected Widget internalExpand(Object elementOrPath, boolean expand) { // TODO Auto-generated method stub return super.internalExpand(elementOrPath, expand); } /** * {@inheritDoc} * * @see org.eclipse.jface.viewers.AbstractTreeViewer#getSelection() */ @Override public ISelection getSelection() { final Control control = getControl(); if (control == null || control.isDisposed()) { return super.getSelection(); } final Widget[] items = getSelection(getControl()); if (items.length != 1) { return super.getSelection(); } final Widget item = items[0]; final Object data = item.getData(); if (data == null) { return super.getSelection(); } // TODO: remove assignment final Object element = data; EObject selectedModelElement = null; if (element instanceof CompositeOperation) { selectedModelElement = handleCompositeOperation((CompositeOperation) element); } else if (element instanceof AbstractOperation) { selectedModelElement = handleAbstractOperation((AbstractOperation) element); } else if (element instanceof ProjectSpace) { selectedModelElement = ((ProjectSpace) element).getProject(); } else if (element instanceof ModelElementId && projectSpace.getProject().contains((ModelElementId) element)) { selectedModelElement = projectSpace.getProject().getModelElement((ModelElementId) element); } else if (projectSpace.getProject().contains((EObject) element)) { selectedModelElement = (EObject) element; } if (selectedModelElement != null) { return new StructuredSelection(selectedModelElement); } return super.getSelection(); } private EObject handleCompositeOperation(CompositeOperation op) { final AbstractOperation mainOperation = op.getMainOperation(); if (mainOperation != null) { final ModelElementId modelElementId = mainOperation.getModelElementId(); final EObject modelElement = projectSpace.getProject().getModelElement(modelElementId); return modelElement; } return null; } private EObject handleAbstractOperation(AbstractOperation op) { final ModelElementId modelElementId = op.getModelElementId(); final EObject modelElement = projectSpace.getProject().getModelElement(modelElementId); return modelElement; } } }