1 package org.simantics.team.ui;
3 import java.lang.ref.WeakReference;
4 import java.nio.ByteBuffer;
5 import java.nio.CharBuffer;
6 import java.nio.charset.CharacterCodingException;
7 import java.nio.charset.Charset;
8 import java.nio.charset.CharsetDecoder;
9 import java.nio.charset.CodingErrorAction;
10 import java.util.Collection;
11 import java.util.Iterator;
12 import java.util.Vector;
14 import org.eclipse.jface.action.Action;
15 import org.eclipse.jface.layout.TreeColumnLayout;
16 import org.eclipse.jface.resource.JFaceResources;
17 import org.eclipse.jface.resource.LocalResourceManager;
18 import org.eclipse.jface.viewers.ColumnWeightData;
19 import org.eclipse.jface.viewers.TreeViewer;
20 import org.eclipse.jface.viewers.TreeViewerColumn;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.graphics.Image;
23 import org.eclipse.swt.widgets.Composite;
24 import org.simantics.Simantics;
25 import org.simantics.db.Operation;
26 import org.simantics.db.Session;
27 import org.simantics.db.UndoContext;
28 import org.simantics.db.common.utils.Logger;
29 import org.simantics.db.exception.DatabaseException;
30 import org.simantics.db.service.UndoRedoSupport;
31 import org.simantics.db.service.UndoRedoSupport.ChangeListener;
32 import org.simantics.team.Activator;
33 import org.simantics.team.internal.Images;
34 import org.simantics.utils.ui.dialogs.ShowError;
37 * @author Kalle Kondelin
39 public class UndoView extends TreeView {
41 public void createPartControl(Composite parent) {
43 this.treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.FULL_SELECTION);
44 this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), treeViewer.getTree());
45 Images.getInstance(JFaceResources.getResources());
46 TreeColumnLayout ad = new TreeColumnLayout();
48 treeViewer.getTree().setHeaderVisible(true);
49 //treeViewer.getTree().setLinesVisible(true);
50 //treeViewer.setUseHashlookup(true);
51 //treeViewer.setAutoExpandLevel(3);
53 TreeViewerColumn idColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
54 TreeViewerColumn dateColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
55 TreeViewerColumn commentColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);
57 idColumn.setLabelProvider(new IdColumnLabelProvider());
58 dateColumn.setLabelProvider(new DateColumnLabelProvider());
59 commentColumn.setLabelProvider(new CommentColumnLabelProvider());
61 idColumn.getColumn().setText("Id");
62 idColumn.getColumn().setWidth(20);
63 ad.setColumnData(idColumn.getColumn(), new ColumnWeightData(50, 20));
64 dateColumn.getColumn().setText("Date");
65 dateColumn.getColumn().setWidth(20);
66 ad.setColumnData(dateColumn.getColumn(), new ColumnWeightData(50, 40));
67 commentColumn.getColumn().setText("Comment");
68 commentColumn.getColumn().setWidth(20);
69 ad.setColumnData(commentColumn.getColumn(), new ColumnWeightData(50, 50));
71 final UndoContentProvider contentProvider = new UndoContentProvider(Simantics.getSession());
72 treeViewer.setContentProvider(contentProvider);
73 treeViewer.setInput(this);
74 getViewSite().getActionBars().getToolBarManager().add(new Action("Remove All", Activator.REMOVE_ALL_ICON) {
77 contentProvider.removeAll();
80 getViewSite().getActionBars().getToolBarManager().add(new Action("Get Undo History", Activator.REFRESH_ICON) {
83 treeViewer.setContentProvider(contentProvider);
86 new ItemDetailToolTip(treeViewer, treeViewer.getTree(), null);
90 abstract class UndoViewElement extends TreeElement {
91 protected Session session;
92 UndoViewElement(Session session) {
93 this.session = session;
95 protected static final Charset UTF8 = Charset.forName("UTF-8");
96 protected String toString(byte[] data) {
99 CharsetDecoder decoder = UTF8.newDecoder();
100 ByteBuffer bbuf = ByteBuffer.wrap(data);
104 cbuf = decoder.decode(bbuf);
106 } catch (CharacterCodingException e) {
111 .onMalformedInput(CodingErrorAction.REPLACE)
112 .onUnmappableCharacter(CodingErrorAction.REPLACE)
115 } catch (CharacterCodingException e1) {
116 return "String conversion error.";
122 boolean hasChildren() {
126 Object[] getChildren() {
127 return new Object[0];
131 class UndoContextElement extends UndoViewElement {
132 protected String name = "Undo";
133 protected WeakReference<UndoContext> contextRef;
134 UndoContextElement(Session session, UndoContext context) {
136 this.contextRef = new WeakReference<UndoContext>(context);
139 protected Image getIdImage() {
140 return Images.getInstance().OTHER_IMAGE;
143 protected String getIdText() {
144 String s = toString();
145 return s.substring(0, Math.min(10, s.length()));
148 boolean hasChildren() {
149 UndoContext c = contextRef.get();
153 return c.getAll().size() > 0;
154 } catch (DatabaseException e) {
155 Logger.defaultLogError(e);
160 public String toString() {
161 UndoContext c = contextRef.get();
163 return name + "@no context";
164 return name + "@" + c;
167 Object[] getChildren() {
168 UndoContext c = contextRef.get();
170 return new Object[0];
171 Collection<Operation> operations;
173 operations = c.getAll();
174 } catch (DatabaseException e) {
175 Logger.defaultLogError(e);
176 return new Object[0];
178 if (operations.size() < 1)
179 return new Object[0];
180 Object[] objects = new Object[operations.size()];
181 Iterator<Operation> it = operations.iterator();
182 int i = operations.size();
183 while (it.hasNext()) {
184 Operation op = it.next();
185 objects[--i] = new UndoCombinedElement(session, op);
192 class RedoContextElement extends UndoContextElement {
193 RedoContextElement(Session session, UndoContext context) {
194 super(session, context);
198 boolean hasChildren() {
199 UndoContext c = contextRef.get();
203 return c.getRedoList().size() > 0;
204 } catch (DatabaseException e) {
205 Logger.defaultLogError(e);
210 Object[] getChildren() {
211 UndoContext c = contextRef.get();
213 return new Object[0];
214 Collection<Operation> operations;
216 operations = c.getRedoList();
217 } catch (DatabaseException e) {
218 Logger.defaultLogError(e);
221 if (operations.size() < 1)
222 return new Object[0];
223 Object[] objects = new Object[operations.size()];
224 Iterator<Operation> it = operations.iterator();
225 int i = operations.size();
226 while (it.hasNext()) {
227 Operation op = it.next();
228 objects[--i] = new UndoCombinedElement(session, op);
235 class UndoCombinedElement extends UndoViewElement {
236 private final Operation operation;
237 private final Vector<ChangeSetElement> elements = new Vector<ChangeSetElement>();
238 private String comment = null;
239 UndoCombinedElement(Session session, Operation op) {
244 protected Image getIdImage() {
245 return Images.getInstance().UNDO_IMAGE;
248 protected String getIdText() {
249 return "" + operation.getId();
252 protected String getDateText() {
253 if (elements.size() == 0)
255 if (elements.size() > 0)
256 return elements.firstElement().getDateText();
261 protected String getCommentText() {
262 if (elements.size() == 0)
264 if (elements.size() > 0)
265 return elements.firstElement().getCommentText();
270 boolean hasChildren() {
271 return operation.getOperations().size() > 0;
274 Object[] getChildren() {
275 Collection<Operation> ops = operation.getOperations();
276 final int SIZE = ops.size();
278 return new Object[0];
280 Iterator<Operation> it = ops.iterator();
281 for (int i=0; i<SIZE; ++i) {
282 Operation op = it.next();
283 ChangeSetElement e = new ChangeSetElement(session, op.getCSId());
286 if (elements.size() == 1)
287 return elements.firstElement().getChildren();
288 return elements.toArray();
291 public String toString() {
292 getChildren(); // This initializes elements vector.
293 for (ChangeSetElement e : elements) {
294 comment = e.toString();
302 class UndoContentProvider extends ChangeSetProvider implements ChangeListener {
303 private UndoContextElement uce;
304 protected UndoRedoSupport undoRedoSupport;
305 private boolean subscribed = false;
306 UndoContentProvider(Session session) {
308 undoRedoSupport = session.getService(UndoRedoSupport.class);
312 public Object[] getElements(Object inputElement) {
313 return getElements(session);
316 public void dispose() {
317 managementSupport.cancel(this);
318 this.subscribed = false;
322 public void onChanged() {
326 protected Object[] getElements(Session session) {
328 UndoRedoSupport undoSupport = session.getService(UndoRedoSupport.class);
329 UndoContext undoContext = undoSupport.getUndoContext(session);
330 if (null != undoContext) {
331 uce = new UndoContextElement(session, undoContext);
332 return uce.getChildren();
334 } catch (Exception e) {
335 Logger.defaultLogError(e);
337 ShowError.showError("Error", e.getMessage(), e);
339 return new Object[0];
341 protected void subscribe() {
345 if (null == undoRedoSupport)
346 undoRedoSupport = session.getService(UndoRedoSupport.class);
347 undoRedoSupport.subscribe(this);
348 this.subscribed = true;
351 UndoRedoSupport us = session.getService(UndoRedoSupport.class);
352 UndoContext uc = us.getUndoContext(session);
360 class RedoContentProvider extends UndoContentProvider {
361 private RedoContextElement rce;
362 RedoContentProvider(Session session) {
366 protected Object[] getElements(Session session) {
368 UndoRedoSupport undoSupport = session.getService(UndoRedoSupport.class);
369 UndoContext undoContext = undoSupport.getUndoContext(session);
370 if (null != undoContext) {
371 rce = new RedoContextElement(session, undoContext);
372 return rce.getChildren();
374 } catch (Exception e) {
375 Logger.defaultLogError(e);
377 ShowError.showError("Error", e.getMessage(), e);
379 return new Object[0];