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