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%2FUndoView.java;fp=bundles%2Forg.simantics.team.ui%2Fsrc%2Forg%2Fsimantics%2Fteam%2Fui%2FUndoView.java;h=0e87bf612ff1dd62abd2e6e7d792e9cb7c74e6ab;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.team.ui/src/org/simantics/team/ui/UndoView.java b/bundles/org.simantics.team.ui/src/org/simantics/team/ui/UndoView.java new file mode 100644 index 000000000..0e87bf612 --- /dev/null +++ b/bundles/org.simantics.team.ui/src/org/simantics/team/ui/UndoView.java @@ -0,0 +1,381 @@ +package org.simantics.team.ui; + +import java.lang.ref.WeakReference; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.util.Collection; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.jface.action.Action; +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.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.simantics.db.Operation; +import org.simantics.db.Session; +import org.simantics.db.UndoContext; +import org.simantics.db.common.utils.Logger; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.UndoRedoSupport; +import org.simantics.db.service.UndoRedoSupport.ChangeListener; +import org.simantics.team.Activator; +import org.simantics.team.internal.Images; +import org.simantics.ui.SimanticsUI; +import org.simantics.utils.ui.dialogs.ShowError; + +/** + * @author Kalle Kondelin + */ +public class UndoView extends TreeView { + @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 UndoContentProvider contentProvider = new UndoContentProvider(SimanticsUI.getSession()); + treeViewer.setContentProvider(contentProvider); + treeViewer.setInput(this); + getViewSite().getActionBars().getToolBarManager().add(new Action("Remove All", Activator.REMOVE_ALL_ICON) { + @Override + public void run() { + contentProvider.removeAll(); + } + }); + getViewSite().getActionBars().getToolBarManager().add(new Action("Get Undo History", Activator.REFRESH_ICON) { + @Override + public void run() { + treeViewer.setContentProvider(contentProvider); + } + }); + new ItemDetailToolTip(treeViewer, treeViewer.getTree(), null); + } +} + +abstract class UndoViewElement extends TreeElement { + protected Session session; + UndoViewElement(Session session) { + this.session = session; + } + protected static final Charset UTF8 = Charset.forName("UTF-8"); + protected String toString(byte[] data) { + if (data == null) + return "null"; + CharsetDecoder decoder = UTF8.newDecoder(); + ByteBuffer bbuf = ByteBuffer.wrap(data); + CharBuffer cbuf; + String s = null; + try { + cbuf = decoder.decode(bbuf); + s = cbuf.toString(); + } catch (CharacterCodingException e) { + bbuf.rewind(); + try { + cbuf = UTF8 + .newDecoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE) + .decode(bbuf); + s = cbuf.toString(); + } catch (CharacterCodingException e1) { + return "String conversion error."; + } + } + return s; + } + @Override + boolean hasChildren() { + return false; + } + @Override + Object[] getChildren() { + return new Object[0]; + } +} + +class UndoContextElement extends UndoViewElement { + protected String name = "Undo"; + protected WeakReference contextRef; + UndoContextElement(Session session, UndoContext context) { + super(session); + this.contextRef = new WeakReference(context); + } + @Override + protected Image getIdImage() { + return Images.getInstance().OTHER_IMAGE; + } + @Override + protected String getIdText() { + String s = toString(); + return s.substring(0, Math.min(10, s.length())); + } + @Override + boolean hasChildren() { + UndoContext c = contextRef.get(); + if (null == c) + return false; + try { + return c.getAll().size() > 0; + } catch (DatabaseException e) { + Logger.defaultLogError(e); + return false; + } + } + @Override + public String toString() { + UndoContext c = contextRef.get(); + if (null == c) + return name + "@no context"; + return name + "@" + c; + } + @Override + Object[] getChildren() { + UndoContext c = contextRef.get(); + if (null == c) + return new Object[0]; + Collection operations; + try { + operations = c.getAll(); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + return new Object[0]; + } + if (operations.size() < 1) + return new Object[0]; + Object[] objects = new Object[operations.size()]; + Iterator it = operations.iterator(); + int i = operations.size(); + while (it.hasNext()) { + Operation op = it.next(); + objects[--i] = new UndoCombinedElement(session, op); + } + assert(0==i); + return objects; + } +} + +class RedoContextElement extends UndoContextElement { + RedoContextElement(Session session, UndoContext context) { + super(session, context); + this.name = "Redo"; + } + @Override + boolean hasChildren() { + UndoContext c = contextRef.get(); + if (null == c) + return false; + try { + return c.getRedoList().size() > 0; + } catch (DatabaseException e) { + Logger.defaultLogError(e); + return false; + } + } + @Override + Object[] getChildren() { + UndoContext c = contextRef.get(); + if (null == c) + return new Object[0]; + Collection operations; + try { + operations = c.getRedoList(); + } catch (DatabaseException e) { + Logger.defaultLogError(e); + operations = null; + } + if (operations.size() < 1) + return new Object[0]; + Object[] objects = new Object[operations.size()]; + Iterator it = operations.iterator(); + int i = operations.size(); + while (it.hasNext()) { + Operation op = it.next(); + objects[--i] = new UndoCombinedElement(session, op); + } + assert(0 == i); + return objects; + } +} + +class UndoCombinedElement extends UndoViewElement { + private final Operation operation; + private final Vector elements = new Vector(); + private String comment = null; + UndoCombinedElement(Session session, Operation op) { + super(session); + operation = op; + } + @Override + protected Image getIdImage() { + return Images.getInstance().UNDO_IMAGE; + } + @Override + protected String getIdText() { + return "" + operation.getId(); + } + @Override + protected String getDateText() { + if (elements.size() == 0) + getChildren(); + if (elements.size() > 0) + return elements.firstElement().getDateText(); + else + return null; + } + @Override + protected String getCommentText() { + if (elements.size() == 0) + getChildren(); + if (elements.size() > 0) + return elements.firstElement().getCommentText(); + else + return null; + } + @Override + boolean hasChildren() { + return operation.getOperations().size() > 0; + } + @Override + Object[] getChildren() { + Collection ops = operation.getOperations(); + final int SIZE = ops.size(); + if (SIZE < 1) + return new Object[0]; + elements.clear(); + Iterator it = ops.iterator(); + for (int i=0; i