X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.team.ui%2Fsrc%2Forg%2Fsimantics%2Fteam%2Fui%2FHistoryView.java;fp=bundles%2Forg.simantics.team.ui%2Fsrc%2Forg%2Fsimantics%2Fteam%2Fui%2FHistoryView.java;h=75ad0bb01ad40077a4a0aa3019751c01fe33981c;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.team.ui/src/org/simantics/team/ui/HistoryView.java b/bundles/org.simantics.team.ui/src/org/simantics/team/ui/HistoryView.java new file mode 100644 index 000000000..75ad0bb01 --- /dev/null +++ b/bundles/org.simantics.team.ui/src/org/simantics/team/ui/HistoryView.java @@ -0,0 +1,332 @@ +/******************************************************************************* + * 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.team.ui; + +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.layout.TreeColumnLayout; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.resource.LocalResourceManager; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PlatformUI; +import org.simantics.db.ChangeSetIdentifier; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.CommentMetadata; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.XSupport; +import org.simantics.layer0.Layer0; +import org.simantics.team.Activator; +import org.simantics.team.internal.DebugPolicy; +import org.simantics.team.internal.Images; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.ExceptionUtils; +import org.simantics.utils.ui.dialogs.ShowError; + + +/** + * @author Kalle Kondelin + */ +public class HistoryView extends TreeView { + public HistoryView() { + } + private void createPopupMenu() { + final MenuManager mm = new MenuManager("Graph History Popup", "#GraphHistoryPopup"); + mm.setRemoveAllWhenShown(true); + mm.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + } + }); + Menu menu = mm.createContextMenu(treeViewer.getControl()); + treeViewer.getControl().setMenu(menu); + IWorkbenchPartSite site = getSite(); + if (null != site) + site.registerContextMenu(mm.getId(), mm, treeViewer); + treeViewer.getControl().addMouseListener(new GraphHistoryMouseAdapter()); + getSite().setSelectionProvider(treeViewer); + } + @Override + public void createPartControl(Composite parent) { + this.parent = parent; + this.treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.FULL_SELECTION); + this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), treeViewer.getTree()); + Images.getInstance(JFaceResources.getResources()); + TreeColumnLayout ad = new TreeColumnLayout(); + parent.setLayout(ad); + treeViewer.getTree().setHeaderVisible(true); + //treeViewer.getTree().setLinesVisible(true); + //treeViewer.setUseHashlookup(true); + //treeViewer.setAutoExpandLevel(3); + + TreeViewerColumn idColumn = new TreeViewerColumn(treeViewer, SWT.LEFT); + TreeViewerColumn dateColumn = new TreeViewerColumn(treeViewer, SWT.LEFT); + TreeViewerColumn commentColumn = new TreeViewerColumn(treeViewer, SWT.LEFT); + + idColumn.setLabelProvider(new IdColumnLabelProvider()); + dateColumn.setLabelProvider(new DateColumnLabelProvider()); + commentColumn.setLabelProvider(new CommentColumnLabelProvider()); + + idColumn.getColumn().setText("Id"); + idColumn.getColumn().setWidth(20); + ad.setColumnData(idColumn.getColumn(), new ColumnWeightData(50, 20)); + dateColumn.getColumn().setText("Date"); + dateColumn.getColumn().setWidth(20); + ad.setColumnData(dateColumn.getColumn(), new ColumnWeightData(50, 40)); + commentColumn.getColumn().setText("Comment"); + commentColumn.getColumn().setWidth(20); + ad.setColumnData(commentColumn.getColumn(), new ColumnWeightData(50, 50)); + + final HistoryContentProvider contentProvider = new HistoryContentProvider(SimanticsUI.getSession()); + treeViewer.setContentProvider(contentProvider); + //viewer.setSorter(new ViewerSorter()); + treeViewer.setInput(this); + + getViewSite().getActionBars().getToolBarManager().add(new Action("Previous", Activator.PREVIOUS_ICON) { + @Override + public void run() { + contentProvider.previous(); + } + }); + getViewSite().getActionBars().getToolBarManager().add(new Action("Next", Activator.NEXT_ICON) { + @Override + public void run() { + contentProvider.next(); + } + }); + getViewSite().getActionBars().getToolBarManager().add(new Action("Get Graph History", Activator.REFRESH_ICON) { + @Override + public void run() { + contentProvider.refresh(); + } + }); + if (DebugPolicy.DEBUG) { + getViewSite().getActionBars().getToolBarManager().add(new Action("Debug", Activator.DEBUG_ICON) { + @Override + public void run() { + Session s = SimanticsUI.getSession(); + try { + s.sync(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + for (DebugPolicy.Action da : DebugPolicy.actions) { + switch (da) { + default: + break; + case CorruptClusterAction: + corruptClusterAction(graph); + break; + case DebugCommitAction: + debugCommitAction(graph); + break; + } + } + } + }); + } catch (DatabaseException e) { + ShowError.showError("Debug Action Failed", e.getMessage(), e); + Logger.defaultLogError("Debug action failed.", e); + } + } + }); + getViewSite().getActionBars().getToolBarManager().add(new Action("Exit", Activator.EXIT_ICON) { + @Override + public void run() { + System.out.println("exit"); + PlatformUI.getWorkbench().close(); + System.exit(0); + } + }); + } + new ItemDetailToolTip(treeViewer, treeViewer.getTree(), null); + createPopupMenu(); + } + static class HistoryContentProvider extends ChangeSetProvider { + class HistoryElement extends ChangeSetElement { + HistoryElement(Session session, ChangeSetIdentifier cs) { + super(session, cs); + } + } + private long topChangeSet; // Identifies first displayed change set. Zero if head. + private final int CS_LIMIT = 100; // Max number of change sets per page. + private HistoryElement[] changeSetIds; + HistoryContentProvider(Session session) { + super(session); + topChangeSet = 0; + } + @Override + public void refresh() { + topChangeSet = 0; + super.refresh(); + } + @Override + public Object[] getElements(Object inputElement) { + try { + if (0 != topChangeSet) + return changeSetIds; + changeSetIds = getElements(managementSupport.getHeadRevisionId()); + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + changeSetIds = new HistoryElement[0]; + } + return changeSetIds; + } + private HistoryElement[] getElements(long head) { + try { + if (head < 1) + return new HistoryElement[0]; + Collection cids; + long min = Math.max(1, head - CS_LIMIT); + cids = managementSupport.getChangeSetIdentifiers(min, head); + if (null == cids) + changeSetIds = new HistoryElement[0]; + else { + changeSetIds = new HistoryElement[cids.size()]; + Iterator it = cids.iterator(); + int i = cids.size(); + while (it.hasNext()) { + changeSetIds[--i] = new HistoryElement(session, it.next()); + } + assert(i == 0); + } + } catch (DatabaseException e) { + ExceptionUtils.logAndShowError(e); + changeSetIds = new HistoryElement[0]; + } + return changeSetIds; + } + void next() { + if (0 != topChangeSet) { + long head = 0; + try { + head = managementSupport.getHeadRevisionId(); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + if (topChangeSet + CS_LIMIT > head) + topChangeSet = 0; + else + topChangeSet += CS_LIMIT; + changeSetIds = getElements(topChangeSet); + } + super.refresh(); + } + void previous() { + long head = 0; + try { + head = managementSupport.getHeadRevisionId(); + if (0 == topChangeSet) + topChangeSet = head; + if (topChangeSet > CS_LIMIT + 1) + topChangeSet -= CS_LIMIT; + changeSetIds = getElements(topChangeSet); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + } + super.refresh(); + } + } + static class GraphHistoryMouseAdapter extends MouseAdapter { + final boolean DEBUG = false; + public GraphHistoryMouseAdapter() { + } + protected ISelection getClickedContext(MouseEvent e) { + final Tree tree = (Tree)e.getSource(); + Point point = new Point(e.x, e.y); + TreeItem item = tree.getItem(point); + // No selectable item at point? + if (item == null) + return null; + tree.select(item); + Object data = item.getData(); + if (DEBUG) + System.out.println("tree item data: " + data); + return null; + } + @Override + public void mouseUp(MouseEvent e) { + ISelection context = getClickedContext(e); + if (context == null) + return; +// Tree tree = (Tree)e.getSource(); + } + @Override + public void mouseDoubleClick(MouseEvent e) { + ISelection context = getClickedContext(e); + if (context == null) + return; +// Tree tree = (Tree)e.getSource(); + } + } + private static void corruptClusterAction(WriteGraph graph) + throws DatabaseException { + XSupport xs = graph.getService(XSupport.class); + // Layer0 l0 = Layer0.getInstance(graph); + Resource r = graph.newResource(); + String msg = "Corrupt cluster r=" + r; + System.out.println(msg); + CommentMetadata cm = graph.getMetadata(CommentMetadata.class); + cm.add(msg); + xs.corruptCluster(r); + Resource rr = graph.newResource(); + msg = "Corrupt cluster rr=" + rr; + System.out.println(msg); + cm.add(msg); + xs.corruptCluster(rr); + graph.addMetadata(cm); // Add comment to change set. + } + private static void debugCommitAction(WriteGraph graph) + throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + CommentMetadata cm = graph.getMetadata(CommentMetadata.class); + graph.addMetadata(cm.add("Debug commit.")); + Resource root = graph.newResource(); + graph.claim(root, l0.InstanceOf, l0.Entity); + graph.claimLiteral(root, l0.HasName, "Debug Resource Root"); + Resource project = graph.getResource("http://Projects/Development%20Project"); + graph.claim(root, l0.PartOf, project); + final int N = 1<<20; + int count = 1; + for (int i=0; i