tmf: Drop generics from ITmfTrace and TmfExperiment
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / rawviewer / TmfRawEventViewer.java
CommitLineData
c76c54bb 1/*******************************************************************************\r
2f2265e2 2 * Copyright (c) 2010, 2012 Ericsson\r
6256d8ad 3 *\r
c76c54bb
FC
4 * All rights reserved. This program and the accompanying materials are\r
5 * made available under the terms of the Eclipse Public License v1.0 which\r
6 * accompanies this distribution, and is available at\r
7 * http://www.eclipse.org/legal/epl-v10.html\r
6256d8ad 8 *\r
c76c54bb
FC
9 * Contributors:\r
10 * Patrick Tasse - Initial API and implementation\r
11 ******************************************************************************/\r
12\r
3770bc6a 13package org.eclipse.linuxtools.tmf.ui.widgets.rawviewer;\r
c76c54bb
FC
14\r
15import java.util.ArrayList;\r
9fa32496 16import java.util.List;\r
c76c54bb 17\r
72f1e62a 18import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;\r
34ccf9a9 19import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;\r
6c13869b
FC
20import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;\r
21import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;\r
c76c54bb
FC
22import org.eclipse.swt.SWT;\r
23import org.eclipse.swt.custom.CaretEvent;\r
24import org.eclipse.swt.custom.CaretListener;\r
25import org.eclipse.swt.custom.ScrolledComposite;\r
26import org.eclipse.swt.custom.StyledText;\r
27import org.eclipse.swt.events.ControlEvent;\r
28import org.eclipse.swt.events.ControlListener;\r
29import org.eclipse.swt.events.KeyEvent;\r
30import org.eclipse.swt.events.KeyListener;\r
31import org.eclipse.swt.events.MouseAdapter;\r
32import org.eclipse.swt.events.MouseEvent;\r
33import org.eclipse.swt.events.MouseMoveListener;\r
34import org.eclipse.swt.events.MouseTrackListener;\r
35import org.eclipse.swt.events.MouseWheelListener;\r
36import org.eclipse.swt.events.SelectionEvent;\r
37import org.eclipse.swt.events.SelectionListener;\r
38import org.eclipse.swt.graphics.Color;\r
39import org.eclipse.swt.graphics.Font;\r
40import org.eclipse.swt.graphics.FontData;\r
41import org.eclipse.swt.graphics.Point;\r
42import org.eclipse.swt.layout.GridData;\r
43import org.eclipse.swt.layout.GridLayout;\r
44import org.eclipse.swt.widgets.Composite;\r
45import org.eclipse.swt.widgets.Control;\r
46import org.eclipse.swt.widgets.Display;\r
47import org.eclipse.swt.widgets.Event;\r
48import org.eclipse.swt.widgets.Listener;\r
49import org.eclipse.swt.widgets.Menu;\r
50import org.eclipse.swt.widgets.Slider;\r
c76c54bb
FC
51\r
52/**\r
c76c54bb
FC
53 * TmfRawEventViewer allows for the display of the raw data for an arbitrarily\r
54 * large number of TMF events.\r
6256d8ad 55 *\r
c76c54bb
FC
56 * It is essentially a Composite of a StyledText area and a Slider, where the number\r
57 * of visible lines in the StyledText control is set to fill the viewer display area.\r
58 * An underlying data model is used to store a cache of event raw text line data.\r
3770bc6a 59 * The slider is ratio-based.\r
abbdd66a 60 *\r
2f2265e2
BH
61 * @version 1.0\r
62 * @author Patrick Tasse\r
c76c54bb
FC
63 */\r
64public class TmfRawEventViewer extends Composite implements ControlListener, SelectionListener,\r
65 KeyListener, CaretListener, MouseMoveListener, MouseTrackListener, MouseWheelListener {\r
66\r
67 private static final Color COLOR_BACKGROUND_ODD = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);\r
68 private static final Color COLOR_BACKGROUND_EVEN = new Color(Display.getDefault(), 242, 242, 242);\r
69 private static final Color COLOR_BACKGROUND_SELECTED = new Color(Display.getDefault(), 231, 246, 254);\r
70 private static final Color COLOR_BACKGROUND_HIGHLIGHTED = new Color(Display.getDefault(), 246, 252, 255);\r
71 private static final int MAX_LINE_DATA_SIZE = 1000;\r
72 private static final int SLIDER_MAX = 1000000;\r
73\r
6256d8ad 74 private ITmfTrace fTrace;\r
34ccf9a9 75 private ITmfContext fBottomContext;\r
6256d8ad 76\r
c76c54bb
FC
77 private ScrolledComposite fScrolledComposite;\r
78 private Composite fTextArea;\r
79 private StyledText fStyledText;\r
80 private Font fFixedFont;\r
81 private Slider fSlider;\r
82\r
6256d8ad 83 private final List<LineData> fLines = new ArrayList<LineData>();\r
c76c54bb
FC
84 private boolean fActualRanks = false;\r
85 private int fTopLineIndex;\r
86 private int fLastTopLineIndex;\r
6256d8ad 87 private final CaretPosition[] fStoredCaretPosition = new CaretPosition[]\r
c76c54bb
FC
88 { new CaretPosition(0, 0), new CaretPosition(0,0)};\r
89 private int fNumVisibleLines;\r
90 private ITmfLocation<?> fSelectedLocation = null;\r
91 private long fHighlightedRank = Long.MIN_VALUE;\r
92 private int fCursorYCoordinate = -1;\r
93 private int fHoldSelection = 0;\r
94\r
5a5c2fc7 95 private static class LineData {\r
c76c54bb
FC
96 long rank;\r
97 ITmfLocation<?> location;\r
98 String string;\r
99 public LineData(long rank, ITmfLocation<?> location, String string) {\r
100 this.rank = rank;\r
101 this.location = location;\r
102 if (string.length() == 0) {\r
103 this.string = " "; // workaround for setLineBackground has no effect on empty line //$NON-NLS-1$\r
104 } else {\r
105 this.string = string;\r
106 }\r
107 }\r
108 @Override\r
109 public String toString() {\r
110 return rank + " [" + location + "]: " + string; //$NON-NLS-1$ //$NON-NLS-2$\r
111 }\r
112 }\r
113\r
5a5c2fc7 114 private static class CaretPosition {\r
c76c54bb
FC
115 int time;\r
116 int caretOffset;\r
117 public CaretPosition(int time, int caretOffset) {\r
118 this.time = time;\r
119 this.caretOffset = caretOffset;\r
120 }\r
121 }\r
6256d8ad 122\r
c76c54bb
FC
123 // ------------------------------------------------------------------------\r
124 // Constructor\r
125 // ------------------------------------------------------------------------\r
126\r
127 /**\r
2f2265e2
BH
128 * Constructor\r
129 * @param parent The parent composite\r
130 * @param style The style bits\r
c76c54bb
FC
131 */\r
132 public TmfRawEventViewer(Composite parent, int style) {\r
133 super(parent, style & (~SWT.H_SCROLL) & (~SWT.V_SCROLL));\r
134\r
135 // Set the layout\r
136 GridLayout gridLayout = new GridLayout();\r
137 gridLayout.numColumns = 2;\r
138 gridLayout.horizontalSpacing = 0;\r
139 gridLayout.verticalSpacing = 0;\r
140 gridLayout.marginWidth = 0;\r
141 gridLayout.marginHeight = 0;\r
142 setLayout(gridLayout);\r
6256d8ad 143\r
c76c54bb
FC
144 // Create the controls\r
145 createTextArea(style & SWT.H_SCROLL);\r
146 createSlider(style & SWT.V_SCROLL);\r
6256d8ad 147\r
c76c54bb
FC
148 // Prevent the slider from being traversed\r
149 setTabList(new Control[] { fScrolledComposite });\r
150 }\r
6256d8ad 151\r
c76c54bb
FC
152 @Override\r
153 public void dispose() {\r
154 if (fFixedFont != null) {\r
155 fFixedFont.dispose();\r
156 fFixedFont = null;\r
157 }\r
158 super.dispose();\r
159 }\r
160\r
161 // ------------------------------------------------------------------------\r
162 // Text area handling\r
163 // ------------------------------------------------------------------------\r
164\r
165 /**\r
166 * Create the text area and add listeners\r
167 */\r
168 private void createTextArea(int style) {\r
169 fScrolledComposite = new ScrolledComposite(this, style);\r
170 fScrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
171 fTextArea = new Composite(fScrolledComposite, SWT.NONE);\r
172 fTextArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
173 fScrolledComposite.setContent(fTextArea);\r
174 fScrolledComposite.setExpandHorizontal(true);\r
175 fScrolledComposite.setExpandVertical(true);\r
176 fScrolledComposite.setAlwaysShowScrollBars(true);\r
177 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
178 fScrolledComposite.addControlListener(this);\r
179\r
180 GridLayout textAreaGridLayout = new GridLayout();\r
181 textAreaGridLayout.marginHeight = 0;\r
182 textAreaGridLayout.marginWidth = 0;\r
183 fTextArea.setLayout(textAreaGridLayout);\r
184\r
185 if (fFixedFont == null) {\r
186 if (System.getProperty("os.name").contains("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$\r
187 fFixedFont = new Font(Display.getCurrent(), new FontData("Courier New", 10, SWT.NORMAL)); //$NON-NLS-1$\r
188 } else {\r
189 fFixedFont = new Font(Display.getCurrent(), new FontData("Monospace", 10, SWT.NORMAL)); //$NON-NLS-1$\r
190 }\r
191 }\r
6256d8ad 192\r
c76c54bb
FC
193 fStyledText = new StyledText(fTextArea, SWT.READ_ONLY);\r
194 fStyledText.setFont(fFixedFont);\r
195 fStyledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));\r
6256d8ad 196\r
c76c54bb
FC
197 fStyledText.addCaretListener(this);\r
198 fStyledText.addMouseMoveListener(this);\r
199 fStyledText.addMouseTrackListener(this);\r
200 fStyledText.addMouseWheelListener(this);\r
201 fStyledText.addListener(SWT.MouseWheel, new Listener() { // disable mouse scroll of horizontal scroll bar\r
202 @Override\r
203 public void handleEvent(Event event) { event.doit = false; }});\r
204 fStyledText.addKeyListener(this);\r
6256d8ad 205\r
c76c54bb
FC
206 fTextArea.setBackground(fStyledText.getBackground());\r
207 fTextArea.addMouseListener(new MouseAdapter() {\r
208 @Override\r
209 public void mouseDown(MouseEvent e) {\r
210 fTextArea.setFocus();\r
211 }});\r
6256d8ad 212 }\r
c76c54bb
FC
213\r
214 // ------------------------------------------------------------------------\r
215 // Slider handling\r
216 // ------------------------------------------------------------------------\r
217\r
218 private void createSlider(int style) {\r
219 fSlider = new Slider(this, SWT.VERTICAL);\r
220 fSlider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));\r
221 fSlider.setValues(0, 0, SLIDER_MAX, SLIDER_MAX, 1, 1);\r
222 fSlider.addSelectionListener(this);\r
223 if ((style & SWT.V_SCROLL) == 0) {\r
224 fSlider.setVisible(false);\r
225 }\r
226 }\r
227\r
228 // ------------------------------------------------------------------------\r
229 // Controls interactions\r
230 // ------------------------------------------------------------------------\r
231\r
232 @Override\r
233 public boolean setFocus() {\r
234 boolean isVisible = isVisible();\r
235 if (isVisible) {\r
236 fTextArea.setFocus();\r
237 }\r
238 return isVisible;\r
239 }\r
6256d8ad 240\r
c76c54bb
FC
241 @Override\r
242 public void setMenu(Menu menu) {\r
243 fStyledText.setMenu(menu);\r
244 }\r
245\r
2f2265e2
BH
246 /**\r
247 * Sets the trace and updates the content\r
248 * @param trace The trace to set\r
249 */\r
6256d8ad 250 public void setTrace(ITmfTrace trace) {\r
c76c54bb
FC
251 fTrace = trace;\r
252 fTopLineIndex = 0;\r
253 fLines.clear();\r
254 refreshEventCount();\r
255 }\r
256\r
2f2265e2
BH
257 /**\r
258 * Refreshes the event count, updates the slider thumb and loads display\r
259 */\r
c76c54bb
FC
260 public void refreshEventCount() {\r
261 if (fTrace != null) {\r
262 if (fTrace.getNbEvents() > 0) {\r
263 fSlider.setThumb((int) Math.max(SLIDER_MAX / fTrace.getNbEvents(), 1));\r
264 } else {\r
265 fSlider.setThumb(SLIDER_MAX);\r
266 }\r
d86b9d98 267\r
6256d8ad
AM
268 if (!isVisible()) {\r
269 return;\r
270 }\r
271\r
d86b9d98 272 if (fLines.size() == 0) {\r
c76c54bb
FC
273 setTopRank(0);\r
274 } else if (fLines.size() < fNumVisibleLines) {\r
275 fBottomContext = null;\r
276 loadLineData();\r
277 fillTextArea();\r
278 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
279 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
280 }\r
281 }\r
282 }\r
6256d8ad 283\r
2f2265e2
BH
284 /**\r
285 * Selects the event of given rank and makes it visible.\r
286 * @param rank The rank of event\r
287 */\r
c76c54bb
FC
288 public void selectAndReveal(long rank) {\r
289 if (fTrace == null || !isVisible()) {\r
290 return;\r
291 }\r
292 if (fActualRanks && fTopLineIndex < fLines.size() && rank >= fLines.get(fTopLineIndex).rank) {\r
293 int lastVisibleIndex = Math.min(fTopLineIndex + fNumVisibleLines, fLines.size()) - 1;\r
294 if (rank <= fLines.get(lastVisibleIndex).rank) {\r
295 for (int i = fTopLineIndex; i < fLines.size(); i++) {\r
296 if (fLines.get(i).rank == rank) {\r
297 fSelectedLocation = fLines.get(i).location;\r
298 break;\r
299 }\r
300 }\r
301 refreshLineBackgrounds();\r
302 return;\r
303 }\r
304 }\r
305 setTopRank(rank);\r
306 if (fLines.size() > 0 && fHoldSelection == 0) {\r
307 fSelectedLocation = fLines.get(0).location;\r
308 refreshLineBackgrounds();\r
309 }\r
310 }\r
6256d8ad 311\r
2f2265e2
BH
312 /**\r
313 * Add a selection listener\r
314 * @param listener A listener to add\r
315 */\r
828e5592 316 public void addSelectionListener(Listener listener) {\r
c76c54bb 317 checkWidget();\r
6256d8ad
AM
318 if (listener == null) {\r
319 SWT.error (SWT.ERROR_NULL_ARGUMENT);\r
320 }\r
828e5592 321 addListener (SWT.Selection, listener);\r
c76c54bb
FC
322 }\r
323\r
2f2265e2
BH
324 /**\r
325 * Remove selection listener\r
326 * @param listener A listener to remove\r
327 */\r
828e5592 328 public void removeSelectionListener(Listener listener) {\r
c76c54bb 329 checkWidget();\r
6256d8ad
AM
330 if (listener == null) {\r
331 SWT.error (SWT.ERROR_NULL_ARGUMENT);\r
332 }\r
c76c54bb
FC
333 removeListener(SWT.Selection, listener);\r
334 }\r
335\r
336 private void sendSelectionEvent(LineData lineData) {\r
337 Event event = new Event();\r
338 if (fActualRanks) {\r
5a5c2fc7 339 event.data = Long.valueOf(lineData.rank);\r
c76c54bb
FC
340 } else {\r
341 event.data = lineData.location;\r
342 }\r
343 notifyListeners(SWT.Selection, event);\r
344 }\r
6256d8ad 345\r
c76c54bb
FC
346 private void setTopRank(long rank) {\r
347 fBottomContext = fTrace.seekEvent(rank);\r
348 if (fBottomContext == null) {\r
349 return;\r
350 }\r
351 fLines.clear();\r
352 fActualRanks = true;\r
353 fTopLineIndex = 0;\r
354 loadLineData();\r
355 refreshTextArea();\r
356 if (fLines.size() == 0) {\r
357 fSlider.setSelection(0);\r
358 } else {\r
359 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
360 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
361 }\r
362 }\r
6256d8ad 363\r
c76c54bb 364 private void setTopPosition(double ratio) {\r
7e6347b0 365 fBottomContext = fTrace.seekEvent(ratio);\r
c76c54bb
FC
366 if (fBottomContext == null) {\r
367 return;\r
368 }\r
369 fBottomContext.setRank(0);\r
370 fLines.clear();\r
371 fActualRanks = false;\r
372 fTopLineIndex = 0;\r
373 loadLineData();\r
374 refreshTextArea();\r
375 }\r
6256d8ad 376\r
c76c54bb
FC
377 private void loadLineData() {\r
378 if (fTopLineIndex < 0) {\r
379 //if (fLines.size() > 0 && fLines.get(0).rank > 0) {\r
380 //long endRank = fLines.get(0).rank;\r
381 //long startRank = Math.max(0, endRank - fNumVisibleLines);\r
382 //TmfContext context = fTrace.seekEvent(startRank);\r
383 //int index = 0;\r
384 //while (context.getRank() < endRank) {\r
385 //long rank = context.getRank();\r
386 //ITmfLocation<?> location = context.getLocation();\r
387 //TmfEvent event = fTrace.getNextEvent(context);\r
388 //String[] lines = event.getRawText().split("\r?\n");\r
389 //for (int i = 0; i < lines.length; i++) {\r
390 //String line = lines[i];\r
6256d8ad 391 //LineData lineData = new LineData(rank, location, line);\r
c76c54bb
FC
392 //fLines.add(index++, lineData);\r
393 //fTopLineIndex++;\r
394 //fLastTopLineIndex++;\r
395 //}\r
396 //}\r
397 //}\r
398 if (fLines.size() > 0 && fTrace.getLocationRatio(fLines.get(0).location) > 0) {\r
399 double lastRatio = fTrace.getLocationRatio(fLines.get(fLines.size() - 1).location);\r
400 double firstRatio = fTrace.getLocationRatio(fLines.get(0).location);\r
401 double delta;\r
402 boolean singleEvent = false;\r
403 if (firstRatio != lastRatio) {\r
404 // approximate ratio of at least 20 items\r
405 delta = Math.max(20, fNumVisibleLines) * (lastRatio - firstRatio) / (fLines.size() - 1);\r
406 } else {\r
407 delta = Math.pow(10, -15);\r
408 singleEvent = true;\r
409 }\r
410 while (fTopLineIndex < 0) {\r
411 ITmfLocation<?> endLocation = fLines.get(0).location;\r
412 firstRatio = Math.max(0, firstRatio - delta);\r
7e6347b0 413 ITmfContext context = fTrace.seekEvent(firstRatio);\r
478e04a4 414 ITmfLocation<?> location;\r
c76c54bb
FC
415 int index = 0;\r
416 long rank = 0;\r
417 while (!context.getLocation().equals(endLocation)) {\r
478e04a4 418 location = context.getLocation().clone();\r
c32744d6 419 ITmfEvent event = fTrace.getNext(context);\r
c76c54bb
FC
420 if (event == null) {\r
421 break;\r
422 }\r
d6e600c3
PT
423 if (event.getContent() != null && event.getContent().getValue() != null) {\r
424 String[] lines = event.getContent().getValue().toString().split("\r?\n"); //$NON-NLS-1$\r
425 for (int i = 0; i < lines.length; i++) {\r
426 String line = lines[i];\r
6256d8ad 427 LineData lineData = new LineData(rank, location, line);\r
d6e600c3
PT
428 fLines.add(index++, lineData);\r
429 fTopLineIndex++;\r
430 fLastTopLineIndex++;\r
431 }\r
c9d507c4
PT
432 } else {\r
433 LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$\r
434 fLines.add(index++, lineData);\r
435 fTopLineIndex++;\r
436 fLastTopLineIndex++;\r
c76c54bb
FC
437 }\r
438 rank++;\r
439 }\r
440 long rankOffset = fLines.get(index).rank - rank;\r
441 for (int i = 0; i < index; i++) {\r
442 fLines.get(i).rank += rankOffset;\r
443 }\r
444 if (firstRatio == 0) {\r
445 break;\r
446 }\r
447 if (singleEvent) {\r
448 delta = Math.min(delta * 10, 0.1);\r
449 }\r
450 }\r
451 }\r
452 if (fTopLineIndex < 0) {\r
453 fTopLineIndex = 0;\r
454 }\r
455 }\r
6256d8ad 456\r
c76c54bb
FC
457 while (fLines.size() - fTopLineIndex < fNumVisibleLines) {\r
458 if (fBottomContext == null) {\r
459 if (fLines.size() == 0) {\r
460 fBottomContext = fTrace.seekEvent(0);\r
461 } else {\r
462 //fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).rank + 1);\r
7e6347b0 463 fBottomContext = fTrace.seekEvent(fLines.get(fLines.size() - 1).location);\r
c32744d6 464 fTrace.getNext(fBottomContext);\r
c76c54bb
FC
465 }\r
466 if (fBottomContext == null) {\r
467 break;\r
468 }\r
469 }\r
470 long rank = fBottomContext.getRank();\r
478e04a4 471 ITmfLocation<?> location = fBottomContext.getLocation() != null ? fBottomContext.getLocation().clone() : null;\r
c32744d6 472 ITmfEvent event = fTrace.getNext(fBottomContext);\r
c76c54bb
FC
473 if (event == null) {\r
474 break;\r
475 }\r
d6e600c3
PT
476 if (event.getContent() != null && event.getContent().getValue() != null) {\r
477 for (String line : event.getContent().getValue().toString().split("\r?\n")) { //$NON-NLS-1$\r
478 int crPos;\r
479 if ((crPos = line.indexOf('\r')) != -1) {\r
480 line = line.substring(0, crPos);\r
481 }\r
6256d8ad 482 LineData lineData = new LineData(rank, location, line);\r
d6e600c3 483 fLines.add(lineData);\r
c76c54bb 484 }\r
c9d507c4
PT
485 } else {\r
486 LineData lineData = new LineData(rank, location, ""); //$NON-NLS-1$\r
487 fLines.add(lineData);\r
c76c54bb
FC
488 }\r
489 }\r
490 fTopLineIndex = Math.max(0, Math.min(fTopLineIndex, fLines.size() - 1));\r
6256d8ad 491\r
c76c54bb
FC
492 if (fLines.size() > MAX_LINE_DATA_SIZE) {\r
493 if (fTopLineIndex < MAX_LINE_DATA_SIZE / 2) {\r
494 long rank = fLines.get(MAX_LINE_DATA_SIZE - 1).rank;\r
495 for (int i = MAX_LINE_DATA_SIZE; i < fLines.size(); i++) {\r
496 if (fLines.get(i).rank > rank) {\r
497 fLines.subList(i, fLines.size()).clear();\r
498 fBottomContext = null;\r
499 break;\r
500 }\r
501 }\r
502 } else {\r
503 long rank = fLines.get(fLines.size() - MAX_LINE_DATA_SIZE).rank;\r
504 for (int i = fLines.size() - MAX_LINE_DATA_SIZE - 1; i >= 0; i--) {\r
505 if (fLines.get(i).rank < rank) {\r
506 fLines.subList(0, i + 1).clear();\r
507 fTopLineIndex -= (i + 1);\r
508 fLastTopLineIndex -= (i + 1);\r
509 break;\r
510 }\r
511 }\r
512 }\r
513 }\r
514 }\r
6256d8ad 515\r
c76c54bb
FC
516 private void refreshTextArea() {\r
517 fStyledText.setText(""); //$NON-NLS-1$\r
518 for (int i = 0; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {\r
6256d8ad
AM
519 if (i > 0)\r
520 {\r
521 fStyledText.append("\n"); //$NON-NLS-1$\r
522 }\r
c76c54bb
FC
523 LineData lineData = fLines.get(fTopLineIndex + i);\r
524 fStyledText.append(lineData.string);\r
525 setLineBackground(i, lineData);\r
526 }\r
527 fTextArea.layout();\r
528 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
529 fLastTopLineIndex = fTopLineIndex;\r
530 }\r
531\r
532 private void fillTextArea() {\r
533 int nextLine = fStyledText.getCharCount() == 0 ? 0 : fStyledText.getLineCount();\r
534 for (int i = nextLine; i < fLines.size() - fTopLineIndex && i < fNumVisibleLines; i++) {\r
6256d8ad
AM
535 if (i > 0)\r
536 {\r
537 fStyledText.append("\n"); //$NON-NLS-1$\r
538 }\r
c76c54bb
FC
539 LineData lineData = fLines.get(fTopLineIndex + i);\r
540 fStyledText.append(lineData.string);\r
541 setLineBackground(i, lineData);\r
542 }\r
543 int endLine = Math.min(fNumVisibleLines, fLines.size());\r
544 if (endLine < fStyledText.getLineCount()) {\r
545 int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;\r
546 if (endOffset > fStyledText.getCharCount()) {\r
547 fHoldSelection++;\r
548 fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$\r
549 fHoldSelection--;\r
550 }\r
551 }\r
552 fTextArea.layout();\r
553 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
554 }\r
555\r
556 private void updateTextArea() {\r
557 if (fTopLineIndex < fLastTopLineIndex) {\r
558 StringBuffer insertedText = new StringBuffer();\r
559 for (int i = fTopLineIndex; i < fLastTopLineIndex; i++) {\r
560 insertedText.append(fLines.get(i).string + "\n"); //$NON-NLS-1$\r
561 }\r
562 fStyledText.replaceTextRange(0, 0, insertedText.toString());\r
563 for (int i = 0; i < fLastTopLineIndex - fTopLineIndex; i++) {\r
564 LineData lineData = fLines.get(fTopLineIndex + i);\r
565 setLineBackground(i, lineData);\r
566 }\r
567 fLastTopLineIndex = fTopLineIndex;\r
568 } else if (fTopLineIndex > fLastTopLineIndex) {\r
569 int length = 0;\r
570 for (int i = 0; i < fTopLineIndex - fLastTopLineIndex && i < fNumVisibleLines; i++) {\r
571 length += fLines.get(i + fLastTopLineIndex).string.length();\r
6256d8ad
AM
572 if (i < fStyledText.getLineCount()) {\r
573 length += 1;\r
574 }\r
c76c54bb
FC
575 }\r
576 fStyledText.replaceTextRange(0, length, ""); //$NON-NLS-1$\r
577 fLastTopLineIndex = fTopLineIndex;\r
578 fillTextArea();\r
579 }\r
580 int endLine = Math.min(fNumVisibleLines, fLines.size());\r
581 if (endLine < fStyledText.getLineCount()) {\r
582 int endOffset = fStyledText.getOffsetAtLine(endLine) - 1;\r
583 if (endOffset > fStyledText.getCharCount()) {\r
584 fStyledText.replaceTextRange(endOffset, fStyledText.getCharCount() - endOffset, ""); //$NON-NLS-1$\r
585 }\r
586 }\r
587 fTextArea.layout();\r
588 fScrolledComposite.setMinSize(fTextArea.computeSize(SWT.DEFAULT, SWT.DEFAULT));\r
589 }\r
6256d8ad 590\r
c76c54bb
FC
591 private void refreshLineBackgrounds() {\r
592 for (int i = 0; (i < fStyledText.getLineCount()) && (i < fNumVisibleLines) && (i < fLines.size() - fTopLineIndex); i++) {\r
593 LineData lineData = fLines.get(fTopLineIndex + i);\r
594 setLineBackground(i, lineData);\r
595 }\r
596 }\r
597\r
598 private void setLineBackground(int index, LineData lineData) {\r
599 if (lineData.location.equals(fSelectedLocation)) {\r
600 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_SELECTED);\r
601 } else if (lineData.rank == fHighlightedRank) {\r
602 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_HIGHLIGHTED);\r
603 } else if (lineData.rank % 2 == 0) {\r
604 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_EVEN);\r
605 } else {\r
606 fStyledText.setLineBackground(index, 1, COLOR_BACKGROUND_ODD);\r
607 }\r
608 }\r
609\r
610 private void storeCaretPosition(int time, int caretOffset) {\r
611 if (fStoredCaretPosition[0].time == time) {\r
612 fStoredCaretPosition[0].caretOffset = caretOffset;\r
613 } else {\r
614 fStoredCaretPosition[1] = fStoredCaretPosition[0];\r
615 fStoredCaretPosition[0] = new CaretPosition(time, caretOffset);\r
616 }\r
617 }\r
6256d8ad 618\r
c76c54bb
FC
619 private int getPreviousCaretOffset(int time) {\r
620 if (fStoredCaretPosition[0].time == time) {\r
621 return fStoredCaretPosition[1].caretOffset;\r
c76c54bb 622 }\r
abbdd66a 623 return fStoredCaretPosition[0].caretOffset;\r
c76c54bb
FC
624 }\r
625\r
626 private void updateHighlightedRank() {\r
627 if (fCursorYCoordinate < 0 || fCursorYCoordinate > fStyledText.getSize().y) {\r
628 if (fHighlightedRank != Long.MIN_VALUE) {\r
629 fHighlightedRank = Long.MIN_VALUE;\r
630 refreshLineBackgrounds();\r
631 }\r
632 return;\r
633 }\r
634 int offset = fStyledText.getOffsetAtLocation(new Point(0, fCursorYCoordinate));\r
635 int line = fStyledText.getLineAtOffset(offset);\r
636 if (line < fLines.size() - fTopLineIndex) {\r
637 LineData lineData = fLines.get(fTopLineIndex + line);\r
638 if (fHighlightedRank != lineData.rank) {\r
639 fHighlightedRank = lineData.rank;\r
640 refreshLineBackgrounds();\r
641 }\r
642 } else {\r
643 if (fHighlightedRank != Long.MIN_VALUE) {\r
644 fHighlightedRank = Long.MIN_VALUE;\r
645 refreshLineBackgrounds();\r
646 }\r
647 }\r
648 }\r
6256d8ad 649\r
c76c54bb
FC
650 // ------------------------------------------------------------------------\r
651 // ControlListener (ScrolledComposite)\r
652 // ------------------------------------------------------------------------\r
6256d8ad 653\r
c76c54bb
FC
654 @Override\r
655 public void controlResized(ControlEvent event) {\r
656 int areaHeight = fScrolledComposite.getSize().y;\r
657 if (fScrolledComposite.getHorizontalBar() != null) {\r
658 areaHeight -= fScrolledComposite.getHorizontalBar().getSize().y;\r
659 }\r
660 int lineHeight = fStyledText.getLineHeight();\r
661 fNumVisibleLines = Math.max((areaHeight + lineHeight - 1) / lineHeight, 1);\r
662\r
663 if (fBottomContext != null) {\r
664 loadLineData();\r
665 fillTextArea();\r
666 }\r
667 }\r
668\r
669 @Override\r
670 public void controlMoved(ControlEvent e) {\r
671 }\r
6256d8ad 672\r
c76c54bb
FC
673 // ------------------------------------------------------------------------\r
674 // SelectionListener (Slider)\r
675 // ------------------------------------------------------------------------\r
6256d8ad 676\r
c76c54bb
FC
677 @Override\r
678 public void widgetSelected(SelectionEvent e) {\r
679 fTextArea.setFocus();\r
680 if (fLines.size() == 0) {\r
681 return;\r
682 }\r
683 if (e.detail == SWT.DRAG) {\r
684 return;\r
685 }\r
686 fHoldSelection++;\r
687 switch (e.detail) {\r
688 case SWT.NONE: {\r
689 //long rank = (long) (fTrace.getNbEvents() * ((double) fSlider.getSelection() / SLIDER_MAX));\r
690 //setTopRank(rank);\r
691 if (fSlider.getSelection() == 0 || fSlider.getThumb() == SLIDER_MAX) {\r
692 fLines.clear();\r
693 setTopPosition(0.0);\r
694 break;\r
695 }\r
696 double ratio = (double) fSlider.getSelection() / (SLIDER_MAX - fSlider.getThumb());\r
697 double delta = Math.pow(10, -15);\r
698 fLines.clear();\r
699 while (fLines.size() == 0) {\r
700 setTopPosition(ratio);\r
6256d8ad
AM
701 if (ratio == 0.0) {\r
702 break;\r
703 }\r
c76c54bb
FC
704 delta = Math.min(delta * 10, 0.1);\r
705 ratio = Math.max(ratio - delta, 0.0);\r
706 }\r
707 break;\r
708 }\r
709 case SWT.ARROW_DOWN: {\r
710 if (fTopLineIndex >= fLines.size()) {\r
711 break;\r
712 }\r
713 fTopLineIndex++;\r
714 loadLineData();\r
715 updateTextArea();\r
716 break;\r
717 }\r
718 case SWT.PAGE_DOWN: {\r
719 fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);\r
720 loadLineData();\r
721 updateTextArea();\r
722 break;\r
723 }\r
724 case SWT.ARROW_UP: {\r
725 //if (fLines.size() == 0 || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
726 if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
727 break;\r
728 }\r
729 fTopLineIndex--;\r
730 loadLineData();\r
731 updateTextArea();\r
732 break;\r
733 }\r
734 case SWT.PAGE_UP: {\r
735 fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);\r
736 loadLineData();\r
737 updateTextArea();\r
738 break;\r
739 }\r
740 case SWT.HOME: {\r
741 //selectAndReveal(0);\r
742 setTopPosition(0.0);\r
743 break;\r
744 }\r
745 case SWT.END: {\r
746 //if (fTrace.getNbEvents() > 0) {\r
747 //selectAndReveal(fTrace.getNbEvents() - 1);\r
748 //}\r
749 double ratio = 1.0;\r
750 double delta = Math.pow(10, -15);\r
751 fLines.clear();\r
752 while (fLines.size() == 0) {\r
753 setTopPosition(ratio);\r
6256d8ad
AM
754 if (ratio == 0.0) {\r
755 break;\r
756 }\r
c76c54bb
FC
757 delta = Math.min(delta * 10, 0.1);\r
758 ratio = Math.max(ratio - delta, 0.0);\r
759 }\r
760 break;\r
761 }\r
abbdd66a
AM
762 default:\r
763 break;\r
c76c54bb
FC
764 }\r
765 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
766 if (e.detail != SWT.NONE) {\r
767 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
768 }\r
6256d8ad 769\r
c76c54bb
FC
770 fHoldSelection = 0;\r
771 }\r
772\r
773 @Override\r
774 public void widgetDefaultSelected(SelectionEvent e) {\r
775 }\r
776\r
777 // ------------------------------------------------------------------------\r
778 // KeyListener (StyledText)\r
779 // ------------------------------------------------------------------------\r
6256d8ad 780\r
c76c54bb
FC
781 @Override\r
782 public void keyPressed(KeyEvent e) {\r
783 if (fLines.size() == 0) {\r
784 return;\r
785 }\r
786 int caretOffset = fStyledText.getCaretOffset();\r
787 int previousCaretOffset = getPreviousCaretOffset(e.time);\r
788 int previousLineAtCaretPosition = fStyledText.getLineAtOffset(previousCaretOffset);\r
789 int previousColumnAtCaretPosition = getPreviousCaretOffset(e.time) - fStyledText.getOffsetAtLine(previousLineAtCaretPosition);\r
790 switch (e.keyCode) {\r
791 case SWT.ARROW_DOWN: {\r
792 if (previousLineAtCaretPosition < (fNumVisibleLines - 2)) {\r
793 break;\r
794 }\r
795 fHoldSelection++;\r
796 fTopLineIndex++;\r
797 loadLineData();\r
798 updateTextArea();\r
799 fHoldSelection--;\r
800 LineData lineData = fLines.get(fTopLineIndex + fStyledText.getLineAtOffset(fStyledText.getCaretOffset()));\r
801 if (!lineData.location.equals(fSelectedLocation)) {\r
802 fSelectedLocation = lineData.location;\r
803 refreshLineBackgrounds();\r
804 sendSelectionEvent(lineData);\r
805 }\r
806 break;\r
807 }\r
808 case SWT.PAGE_DOWN: {\r
809 if (previousLineAtCaretPosition >= (fNumVisibleLines - 1)) {\r
810 fHoldSelection++;\r
811 if (fLines.get(fTopLineIndex + previousLineAtCaretPosition).rank % 2 == 0) {\r
812 fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_EVEN);\r
813 } else {\r
814 fStyledText.setLineBackground(previousLineAtCaretPosition, 1, COLOR_BACKGROUND_ODD);\r
815 }\r
816 fSelectedLocation = null;\r
817 fTopLineIndex += Math.max(fNumVisibleLines - 1, 1);\r
818 loadLineData();\r
819 updateTextArea();\r
820 fHoldSelection--;\r
821 }\r
822 int line = Math.min(fNumVisibleLines - 1, fStyledText.getLineCount() - 1);\r
823 int offset = fStyledText.getOffsetAtLine(line);\r
824 fStyledText.setSelection(offset + Math.min(previousColumnAtCaretPosition, fLines.get(fTopLineIndex + line).string.length()));\r
825 break;\r
826 }\r
827 case SWT.ARROW_RIGHT: {\r
828 if (previousCaretOffset < fStyledText.getCharCount() || previousLineAtCaretPosition < (fNumVisibleLines - 2)) {\r
829 break;\r
830 }\r
831 fHoldSelection++;\r
832 fTopLineIndex++;\r
833 loadLineData();\r
834 updateTextArea();\r
835 fHoldSelection--;\r
836 fStyledText.setSelection(fStyledText.getCaretOffset() + 1);\r
837 break;\r
838 }\r
839 case SWT.ARROW_UP: {\r
840 if (previousLineAtCaretPosition > 0) {\r
841 break;\r
842 }\r
843 if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
844 break;\r
845 }\r
846 fHoldSelection++;\r
847 fTopLineIndex--;\r
848 loadLineData();\r
849 updateTextArea();\r
850 fHoldSelection--;\r
851 LineData lineData = fLines.get(fTopLineIndex);\r
852 if (!lineData.location.equals(fSelectedLocation)) {\r
853 fSelectedLocation = lineData.location;\r
854 refreshLineBackgrounds();\r
855 sendSelectionEvent(lineData);\r
856 }\r
857 fStyledText.setSelection(caretOffset);\r
858 break;\r
859 }\r
860 case SWT.PAGE_UP: {\r
861 if (previousLineAtCaretPosition > 0) {\r
862 break;\r
863 }\r
864 fHoldSelection++;\r
865 fTopLineIndex -= Math.max(fNumVisibleLines - 1, 1);\r
866 loadLineData();\r
867 updateTextArea();\r
868 fHoldSelection--;\r
869 LineData lineData = fLines.get(fTopLineIndex);\r
870 if (!lineData.location.equals(fSelectedLocation)) {\r
871 fSelectedLocation = lineData.location;\r
872 refreshLineBackgrounds();\r
873 sendSelectionEvent(lineData);\r
874 }\r
875 fStyledText.setSelection(caretOffset);\r
876 break;\r
877 }\r
878 case SWT.ARROW_LEFT: {\r
879 if (previousCaretOffset > 0) {\r
880 break;\r
881 }\r
882 if (fLines.size() == 0) {// || (fTopLineIndex == 0 && fLines.get(0).rank == 0)) {\r
883 break;\r
884 }\r
885 long topRank = fLines.get(fTopLineIndex).rank;\r
886 fHoldSelection++;\r
887 fTopLineIndex--;\r
888 loadLineData();\r
889 updateTextArea();\r
890 fHoldSelection--;\r
891 LineData lineData = fLines.get(fTopLineIndex);\r
892 if (!lineData.location.equals(fSelectedLocation)) {\r
893 fSelectedLocation = lineData.location;\r
894 refreshLineBackgrounds();\r
895 sendSelectionEvent(lineData);\r
896 }\r
897 if (topRank != fLines.get(fTopLineIndex).rank) {\r
898 fStyledText.setSelection(fLines.get(fTopLineIndex).string.length());\r
899 }\r
900 break;\r
901 }\r
902 case SWT.HOME: {\r
903 if ((e.stateMask & SWT.CTRL) == 0) {\r
904 break;\r
905 }\r
906 //selectAndReveal(0);\r
907 setTopPosition(0.0);\r
908 LineData lineData = fLines.get(fTopLineIndex);\r
909 if (!lineData.location.equals(fSelectedLocation)) {\r
910 fSelectedLocation = lineData.location;\r
911 refreshLineBackgrounds();\r
912 sendSelectionEvent(lineData);\r
913 }\r
914 break;\r
915 }\r
916 case SWT.END: {\r
917 if ((e.stateMask & SWT.CTRL) == 0) {\r
918 break;\r
919 }\r
920 //if (fTrace.getNbEvents() > 0) {\r
921 //selectAndReveal(fTrace.getNbEvents() - 1);\r
922 //}\r
923 double ratio = 1.0;\r
924 double delta = Math.pow(10, -15);\r
925 fLines.clear();\r
926 while (fLines.size() == 0) {\r
927 setTopPosition(ratio);\r
6256d8ad
AM
928 if (ratio == 0.0) {\r
929 break;\r
930 }\r
c76c54bb
FC
931 delta = Math.min(delta * 10, 0.1);\r
932 ratio = Math.max(ratio - delta, 0.0);\r
933 }\r
934 LineData lineData = fLines.get(fTopLineIndex);\r
935 if (!lineData.location.equals(fSelectedLocation)) {\r
936 fSelectedLocation = lineData.location;\r
937 refreshLineBackgrounds();\r
938 sendSelectionEvent(lineData);\r
939 }\r
940 break;\r
941 }\r
abbdd66a
AM
942 default:\r
943 break;\r
c76c54bb
FC
944 }\r
945 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
946 updateHighlightedRank();\r
947 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
948 }\r
949\r
950 @Override\r
951 public void keyReleased(KeyEvent e) {\r
952 }\r
953\r
954 // ------------------------------------------------------------------------\r
955 // CaretListener (StyledText)\r
956 // ------------------------------------------------------------------------\r
6256d8ad 957\r
c76c54bb
FC
958 @Override\r
959 public void caretMoved(CaretEvent event) {\r
960 if (fHoldSelection == 0) {\r
961 int line = fStyledText.getLineAtOffset(event.caretOffset);\r
962 if (fTopLineIndex + line < fLines.size()) {\r
963 LineData lineData = fLines.get(fTopLineIndex + line);\r
964 if (!lineData.location.equals(fSelectedLocation)) {\r
965 fSelectedLocation = lineData.location;\r
966 refreshLineBackgrounds();\r
967 sendSelectionEvent(lineData);\r
968 }\r
969 }\r
970 }\r
971 storeCaretPosition(event.time, event.caretOffset);\r
972 if (fHoldSelection == 0) {\r
973 Point caret = fStyledText.getLocationAtOffset(fStyledText.getCaretOffset());\r
974 Point origin = fScrolledComposite.getOrigin();\r
975 if (origin.x > caret.x) {\r
976 origin.x = caret.x;\r
977 } else if (caret.x - origin.x > fScrolledComposite.getSize().x) {\r
978 origin.x = caret.x - fScrolledComposite.getSize().x + 1;\r
979 }\r
980 fScrolledComposite.setOrigin(origin);\r
981 }\r
982 }\r
983\r
984 // ------------------------------------------------------------------------\r
985 // MouseMoveListener (StyledText)\r
986 // ------------------------------------------------------------------------\r
6256d8ad 987\r
c76c54bb
FC
988 @Override\r
989 public void mouseMove(MouseEvent e) {\r
990 fCursorYCoordinate = e.y;\r
991 if (e.y < 0 || e.y > fStyledText.getSize().y) {\r
992 if (fHighlightedRank != Long.MIN_VALUE) {\r
993 fHighlightedRank = Long.MIN_VALUE;\r
994 refreshLineBackgrounds();\r
995 }\r
996 return;\r
997 }\r
998 int offset = fStyledText.getOffsetAtLocation(new Point(0, e.y));\r
999 int line = fStyledText.getLineAtOffset(offset);\r
1000 if (line < fLines.size() - fTopLineIndex) {\r
1001 LineData lineData = fLines.get(fTopLineIndex + line);\r
1002 if (fHighlightedRank != lineData.rank) {\r
1003 fHighlightedRank = lineData.rank;\r
1004 refreshLineBackgrounds();\r
1005 }\r
1006 } else {\r
1007 if (fHighlightedRank != Long.MIN_VALUE) {\r
1008 fHighlightedRank = Long.MIN_VALUE;\r
1009 refreshLineBackgrounds();\r
1010 }\r
1011 }\r
1012 }\r
1013\r
1014 // ------------------------------------------------------------------------\r
1015 // MouseTrackListener (StyledText)\r
1016 // ------------------------------------------------------------------------\r
6256d8ad 1017\r
c76c54bb
FC
1018 @Override\r
1019 public void mouseExit(MouseEvent e) {\r
1020 fCursorYCoordinate = -1;\r
1021 if (fHighlightedRank != Long.MIN_VALUE) {\r
1022 fHighlightedRank = Long.MIN_VALUE;\r
1023 refreshLineBackgrounds();\r
1024 }\r
1025 }\r
1026\r
1027 @Override\r
1028 public void mouseEnter(MouseEvent e) {\r
1029 fCursorYCoordinate = e.y;\r
1030 }\r
1031\r
1032 @Override\r
1033 public void mouseHover(MouseEvent e) {\r
1034 }\r
1035\r
1036 // ------------------------------------------------------------------------\r
1037 // MouseWheelListener (StyledText)\r
1038 // ------------------------------------------------------------------------\r
6256d8ad 1039\r
c76c54bb
FC
1040 @Override\r
1041 public void mouseScrolled(MouseEvent e) {\r
1042 if (fLines.size() == 0) {\r
1043 return;\r
1044 }\r
1045 fHoldSelection++;\r
1046 fTopLineIndex -= e.count;\r
1047 loadLineData();\r
1048 updateTextArea();\r
1049 fHoldSelection = 0;\r
1050 //fSlider.setSelection((int) (SLIDER_MAX * ((double) fLines.get(fTopLineIndex).rank / fTrace.getNbEvents())));\r
1051 updateHighlightedRank();\r
1052 fSlider.setSelection((int) (SLIDER_MAX * fTrace.getLocationRatio(fLines.get(fTopLineIndex).location)));\r
1053 }\r
6256d8ad 1054\r
c76c54bb 1055}\r
This page took 0.080794 seconds and 5 git commands to generate.