]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.team.ui/src/org/simantics/team/ui/HistoryView.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.team.ui / src / org / simantics / team / ui / HistoryView.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.team.ui;\r
13 \r
14 import java.util.Collection;\r
15 import java.util.Iterator;\r
16 \r
17 import org.eclipse.jface.action.Action;\r
18 import org.eclipse.jface.action.GroupMarker;\r
19 import org.eclipse.jface.action.IMenuListener;\r
20 import org.eclipse.jface.action.IMenuManager;\r
21 import org.eclipse.jface.action.MenuManager;\r
22 import org.eclipse.jface.layout.TreeColumnLayout;\r
23 import org.eclipse.jface.resource.JFaceResources;\r
24 import org.eclipse.jface.resource.LocalResourceManager;\r
25 import org.eclipse.jface.viewers.ColumnWeightData;\r
26 import org.eclipse.jface.viewers.ISelection;\r
27 import org.eclipse.jface.viewers.TreeViewer;\r
28 import org.eclipse.jface.viewers.TreeViewerColumn;\r
29 import org.eclipse.swt.SWT;\r
30 import org.eclipse.swt.events.MouseAdapter;\r
31 import org.eclipse.swt.events.MouseEvent;\r
32 import org.eclipse.swt.graphics.Point;\r
33 import org.eclipse.swt.widgets.Composite;\r
34 import org.eclipse.swt.widgets.Menu;\r
35 import org.eclipse.swt.widgets.Tree;\r
36 import org.eclipse.swt.widgets.TreeItem;\r
37 import org.eclipse.ui.IWorkbenchActionConstants;\r
38 import org.eclipse.ui.IWorkbenchPartSite;\r
39 import org.eclipse.ui.PlatformUI;\r
40 import org.simantics.db.ChangeSetIdentifier;\r
41 import org.simantics.db.Resource;\r
42 import org.simantics.db.Session;\r
43 import org.simantics.db.WriteGraph;\r
44 import org.simantics.db.common.CommentMetadata;\r
45 import org.simantics.db.common.request.WriteRequest;\r
46 import org.simantics.db.common.utils.Logger;\r
47 import org.simantics.db.exception.DatabaseException;\r
48 import org.simantics.db.service.XSupport;\r
49 import org.simantics.layer0.Layer0;\r
50 import org.simantics.team.Activator;\r
51 import org.simantics.team.internal.DebugPolicy;\r
52 import org.simantics.team.internal.Images;\r
53 import org.simantics.ui.SimanticsUI;\r
54 import org.simantics.utils.ui.ExceptionUtils;\r
55 import org.simantics.utils.ui.dialogs.ShowError;\r
56 \r
57 \r
58 /**\r
59  * @author Kalle Kondelin\r
60  */\r
61 public class HistoryView extends TreeView {\r
62     public HistoryView() {\r
63     }\r
64     private void createPopupMenu() {\r
65         final MenuManager mm = new MenuManager("Graph History Popup", "#GraphHistoryPopup");\r
66         mm.setRemoveAllWhenShown(true);\r
67         mm.addMenuListener(new IMenuListener() {\r
68              @Override\r
69              public void menuAboutToShow(IMenuManager manager) {\r
70                  manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));\r
71              }\r
72          });\r
73         Menu menu = mm.createContextMenu(treeViewer.getControl());\r
74         treeViewer.getControl().setMenu(menu);\r
75         IWorkbenchPartSite site = getSite();\r
76         if (null != site)\r
77             site.registerContextMenu(mm.getId(), mm, treeViewer);\r
78         treeViewer.getControl().addMouseListener(new GraphHistoryMouseAdapter());\r
79         getSite().setSelectionProvider(treeViewer);\r
80     }\r
81     @Override\r
82     public void createPartControl(Composite parent) {\r
83         this.parent = parent;\r
84         this.treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.FULL_SELECTION);\r
85         this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), treeViewer.getTree());\r
86         Images.getInstance(JFaceResources.getResources());\r
87         TreeColumnLayout ad = new TreeColumnLayout();\r
88         parent.setLayout(ad);\r
89         treeViewer.getTree().setHeaderVisible(true);\r
90         //treeViewer.getTree().setLinesVisible(true);\r
91         //treeViewer.setUseHashlookup(true);\r
92         //treeViewer.setAutoExpandLevel(3);\r
93 \r
94         TreeViewerColumn idColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);\r
95         TreeViewerColumn dateColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);\r
96         TreeViewerColumn commentColumn = new TreeViewerColumn(treeViewer, SWT.LEFT);\r
97 \r
98         idColumn.setLabelProvider(new IdColumnLabelProvider());\r
99         dateColumn.setLabelProvider(new DateColumnLabelProvider());\r
100         commentColumn.setLabelProvider(new CommentColumnLabelProvider());\r
101 \r
102         idColumn.getColumn().setText("Id");\r
103         idColumn.getColumn().setWidth(20);\r
104         ad.setColumnData(idColumn.getColumn(), new ColumnWeightData(50, 20));\r
105         dateColumn.getColumn().setText("Date");\r
106         dateColumn.getColumn().setWidth(20);\r
107         ad.setColumnData(dateColumn.getColumn(), new ColumnWeightData(50, 40));\r
108         commentColumn.getColumn().setText("Comment");\r
109         commentColumn.getColumn().setWidth(20);\r
110         ad.setColumnData(commentColumn.getColumn(), new ColumnWeightData(50, 50));\r
111 \r
112         final HistoryContentProvider contentProvider = new HistoryContentProvider(SimanticsUI.getSession());\r
113           treeViewer.setContentProvider(contentProvider);\r
114           //viewer.setSorter(new ViewerSorter());\r
115           treeViewer.setInput(this);\r
116           \r
117           getViewSite().getActionBars().getToolBarManager().add(new Action("Previous", Activator.PREVIOUS_ICON) {\r
118               @Override\r
119               public void run() {\r
120                   contentProvider.previous();\r
121               }\r
122           });\r
123           getViewSite().getActionBars().getToolBarManager().add(new Action("Next", Activator.NEXT_ICON) {\r
124               @Override\r
125               public void run() {\r
126                   contentProvider.next();\r
127               }\r
128           });\r
129           getViewSite().getActionBars().getToolBarManager().add(new Action("Get Graph History", Activator.REFRESH_ICON) {\r
130               @Override\r
131               public void run() {\r
132                   contentProvider.refresh();\r
133               }\r
134           });\r
135           if (DebugPolicy.DEBUG) {\r
136           getViewSite().getActionBars().getToolBarManager().add(new Action("Debug", Activator.DEBUG_ICON) {\r
137               @Override\r
138               public void run() {\r
139                   Session s = SimanticsUI.getSession();\r
140                   try {\r
141                       s.sync(new WriteRequest() {\r
142                           @Override\r
143                           public void perform(WriteGraph graph) throws DatabaseException {\r
144                               for (DebugPolicy.Action da : DebugPolicy.actions) {\r
145                                   switch (da) {\r
146                                       default:\r
147                                           break;\r
148                                       case CorruptClusterAction:\r
149                                           corruptClusterAction(graph);\r
150                                           break;\r
151                                       case DebugCommitAction:\r
152                                           debugCommitAction(graph);\r
153                                           break;\r
154                                   }\r
155                               }\r
156                           }\r
157                       });\r
158                   } catch (DatabaseException e) {\r
159                       ShowError.showError("Debug Action Failed", e.getMessage(), e);\r
160                       Logger.defaultLogError("Debug action failed.", e);\r
161                   }\r
162               }\r
163           });\r
164           getViewSite().getActionBars().getToolBarManager().add(new Action("Exit", Activator.EXIT_ICON) {\r
165               @Override\r
166               public void run() {\r
167                   System.out.println("exit");\r
168                   PlatformUI.getWorkbench().close();\r
169                   System.exit(0);\r
170               }\r
171           });\r
172           }\r
173           new ItemDetailToolTip(treeViewer, treeViewer.getTree(), null);\r
174           createPopupMenu();\r
175     }\r
176     static class HistoryContentProvider extends ChangeSetProvider {\r
177         class HistoryElement extends ChangeSetElement {\r
178             HistoryElement(Session session, ChangeSetIdentifier cs) {\r
179                 super(session, cs);\r
180             }\r
181         }\r
182         private long topChangeSet; // Identifies first displayed change set. Zero if head.\r
183         private final int CS_LIMIT = 100; // Max number of change sets per page.\r
184         private HistoryElement[] changeSetIds;\r
185         HistoryContentProvider(Session session) {\r
186             super(session);\r
187             topChangeSet = 0; \r
188         }\r
189         @Override\r
190         public void refresh() {\r
191             topChangeSet = 0;\r
192             super.refresh();\r
193         }\r
194         @Override\r
195         public Object[] getElements(Object inputElement) {\r
196             try {\r
197                 if (0 != topChangeSet)\r
198                     return changeSetIds;\r
199                 changeSetIds = getElements(managementSupport.getHeadRevisionId());\r
200             } catch (DatabaseException e) {\r
201                 ExceptionUtils.logAndShowError(e);\r
202                 changeSetIds = new HistoryElement[0];\r
203             }\r
204             return changeSetIds;\r
205         }\r
206         private HistoryElement[] getElements(long head) {\r
207             try {\r
208                 if (head < 1)\r
209                     return new HistoryElement[0];\r
210                 Collection<ChangeSetIdentifier> cids;\r
211                 long min = Math.max(1, head - CS_LIMIT);\r
212                 cids = managementSupport.getChangeSetIdentifiers(min, head);\r
213                 if (null == cids)\r
214                     changeSetIds = new HistoryElement[0];\r
215                 else {\r
216                     changeSetIds = new HistoryElement[cids.size()];\r
217                     Iterator<ChangeSetIdentifier> it = cids.iterator();\r
218                     int i = cids.size();\r
219                     while (it.hasNext()) {\r
220                         changeSetIds[--i] = new HistoryElement(session, it.next());\r
221                     }\r
222                     assert(i == 0);\r
223                 }\r
224             } catch (DatabaseException e) {\r
225                 ExceptionUtils.logAndShowError(e);\r
226                 changeSetIds = new HistoryElement[0];\r
227             }\r
228             return changeSetIds;\r
229         }\r
230         void next() {\r
231             if (0 != topChangeSet) {\r
232                 long head = 0;\r
233                 try {\r
234                     head = managementSupport.getHeadRevisionId();\r
235                 } catch (DatabaseException e) {\r
236                     Logger.defaultLogError(e);\r
237                 }\r
238                 if (topChangeSet + CS_LIMIT > head)\r
239                     topChangeSet = 0;\r
240                 else\r
241                     topChangeSet += CS_LIMIT;\r
242                 changeSetIds = getElements(topChangeSet);\r
243             }\r
244             super.refresh();\r
245         }\r
246         void previous() {\r
247             long head = 0;\r
248             try {\r
249                 head = managementSupport.getHeadRevisionId();\r
250                 if (0 == topChangeSet)\r
251                     topChangeSet = head;\r
252                 if (topChangeSet > CS_LIMIT + 1)\r
253                     topChangeSet -= CS_LIMIT;\r
254                 changeSetIds = getElements(topChangeSet);\r
255             } catch (DatabaseException e) {\r
256                 Logger.defaultLogError(e);\r
257             }\r
258             super.refresh();\r
259         }\r
260     }\r
261     static class GraphHistoryMouseAdapter extends MouseAdapter {\r
262         final boolean DEBUG = false;\r
263         public GraphHistoryMouseAdapter() {\r
264         }\r
265         protected ISelection getClickedContext(MouseEvent e) {\r
266             final Tree tree = (Tree)e.getSource();\r
267             Point point = new Point(e.x, e.y);\r
268             TreeItem item = tree.getItem(point);\r
269             // No selectable item at point?\r
270             if (item == null)\r
271                 return null;\r
272             tree.select(item);\r
273             Object data = item.getData();\r
274             if (DEBUG)\r
275                 System.out.println("tree item data: " + data);\r
276             return null;\r
277         }\r
278         @Override\r
279         public void mouseUp(MouseEvent e) {\r
280             ISelection context = getClickedContext(e);\r
281             if (context == null)\r
282                 return;\r
283 //            Tree tree = (Tree)e.getSource();\r
284         }\r
285         @Override\r
286         public void mouseDoubleClick(MouseEvent e) {\r
287             ISelection context = getClickedContext(e);\r
288             if (context == null)\r
289                 return;\r
290 //            Tree tree = (Tree)e.getSource();\r
291         }\r
292     }\r
293     private static void corruptClusterAction(WriteGraph graph)\r
294     throws DatabaseException {\r
295         XSupport xs = graph.getService(XSupport.class);\r
296         // Layer0 l0 = Layer0.getInstance(graph);\r
297         Resource r = graph.newResource();\r
298         String msg = "Corrupt cluster r=" + r;\r
299         System.out.println(msg);\r
300         CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
301         cm.add(msg);\r
302         xs.corruptCluster(r);\r
303         Resource rr = graph.newResource();\r
304         msg = "Corrupt cluster rr=" + rr;\r
305         System.out.println(msg);\r
306         cm.add(msg);\r
307         xs.corruptCluster(rr);\r
308         graph.addMetadata(cm); // Add comment to change set.\r
309     }\r
310     private static void debugCommitAction(WriteGraph graph)\r
311     throws DatabaseException {\r
312         Layer0 l0 = Layer0.getInstance(graph);\r
313         CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
314         graph.addMetadata(cm.add("Debug commit."));\r
315         Resource root = graph.newResource();\r
316         graph.claim(root, l0.InstanceOf, l0.Entity);\r
317         graph.claimLiteral(root, l0.HasName, "Debug Resource Root");\r
318         Resource project = graph.getResource("http://Projects/Development%20Project");\r
319         graph.claim(root, l0.PartOf, project);\r
320         final int N = 1<<20;\r
321         int count = 1; \r
322         for (int i=0; i<N; ++i, ++count) {\r
323             Resource r = graph.newResource();\r
324             graph.claim(r, l0.InstanceOf, l0.Entity);\r
325             graph.claimLiteral(r, l0.HasName, "Debug Resource " + i);\r
326             if (count % 1000 == 0)\r
327                 root = r;\r
328             else\r
329                 graph.claim(r, l0.PartOf, l0.ConsistsOf, root);\r
330         }\r
331     }\r
332 }\r