|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 package com.nokia.carbide.cpp.internal.pi.analyser; |
|
19 |
|
20 import java.awt.Component; |
|
21 import java.io.File; |
|
22 import java.io.IOException; |
|
23 import java.text.DecimalFormat; |
|
24 |
|
25 import org.eclipse.swt.SWT; |
|
26 import org.eclipse.swt.custom.SashForm; |
|
27 import org.eclipse.swt.events.SelectionAdapter; |
|
28 import org.eclipse.swt.events.SelectionEvent; |
|
29 import org.eclipse.swt.layout.FormAttachment; |
|
30 import org.eclipse.swt.layout.FormData; |
|
31 import org.eclipse.swt.layout.FormLayout; |
|
32 import org.eclipse.swt.widgets.Composite; |
|
33 import org.eclipse.swt.widgets.Display; |
|
34 import org.eclipse.swt.widgets.Label; |
|
35 import org.eclipse.swt.widgets.Sash; |
|
36 |
|
37 import com.nokia.carbide.cpp.internal.pi.utils.PIUtilities; |
|
38 import com.nokia.carbide.cpp.internal.pi.visual.PICompositePanel; |
|
39 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent; |
|
40 import com.nokia.carbide.cpp.pi.editors.PIPageEditor; |
|
41 |
|
42 |
|
43 public class ProfileVisualiser { |
|
44 // rather than abitrary topologies, we will support pages containing: |
|
45 // only a top composite |
|
46 // a top composite and a bottom composite separated by a sash |
|
47 public static final int TOP_ONLY = 1; |
|
48 public static final int TOP_AND_BOTTOM = 2; |
|
49 |
|
50 private ProfileVisualiser thisVisualiser; |
|
51 |
|
52 // page for this visualiser |
|
53 private Composite page; |
|
54 |
|
55 // title |
|
56 private Label title; |
|
57 |
|
58 // secondary title |
|
59 private Label title2; |
|
60 |
|
61 // current time selection string |
|
62 private Label timeInterval; |
|
63 private static final String noInterval = Messages.getString("ProfileVisualiser.noInterval"); //$NON-NLS-1$ |
|
64 |
|
65 public static final DecimalFormat timeFormat = new DecimalFormat(Messages.getString("ProfileVisualiser.decimalFormat")); //$NON-NLS-1$ |
|
66 |
|
67 // composite at the top of the page |
|
68 private PICompositePanel topComposite; |
|
69 |
|
70 // composite at the bottom of the page (optional) |
|
71 private SashForm bottomComposite; |
|
72 |
|
73 private Component currentInfoComponent; |
|
74 private ParserRepository parserRepository; |
|
75 private String pageName = null; |
|
76 |
|
77 public boolean visualiserEnabled = true; |
|
78 |
|
79 // public ProfileVisualiser(int topology, Composite parent, AnalyseTab tab) |
|
80 // { |
|
81 // initialize(parent, tab, ""); |
|
82 // } |
|
83 |
|
84 public ProfileVisualiser(int topology, Composite parent, String pageName) |
|
85 { |
|
86 this.thisVisualiser = this; |
|
87 this.pageName = pageName; |
|
88 this.page = new Composite(parent, SWT.NONE); |
|
89 |
|
90 initialize(topology, page); |
|
91 } |
|
92 |
|
93 private void initialize(int topology, Composite newPage) |
|
94 { |
|
95 // newPage (Composite) |
|
96 // titleBar (Composite) |
|
97 // holder (Composite) |
|
98 FormData formData; |
|
99 |
|
100 if ( (topology != TOP_ONLY) |
|
101 && (topology != TOP_AND_BOTTOM)) { |
|
102 return; |
|
103 } |
|
104 |
|
105 this.parserRepository = new ParserRepository(); |
|
106 |
|
107 |
|
108 // add the title bar at the top |
|
109 Composite titleBar = addTitleBar(newPage); |
|
110 |
|
111 // all graphs and tables go into a composite below the title |
|
112 Composite holder = new Composite(newPage, SWT.NONE); |
|
113 |
|
114 // FormData for the title bar |
|
115 formData = new FormData(); |
|
116 formData.top = new FormAttachment(0); |
|
117 formData.left = new FormAttachment(0); |
|
118 formData.right = new FormAttachment(100); |
|
119 titleBar.setLayoutData(formData); |
|
120 titleBar.setLayout(new FormLayout()); |
|
121 |
|
122 // FormData for the overall holder composite |
|
123 formData = new FormData(); |
|
124 formData.top = new FormAttachment(titleBar); |
|
125 formData.bottom = new FormAttachment(100); |
|
126 formData.left = new FormAttachment(0); |
|
127 formData.right = new FormAttachment(100); |
|
128 holder.setLayoutData(formData); |
|
129 holder.setLayout(new FormLayout()); |
|
130 |
|
131 newPage.setLayout(new FormLayout()); |
|
132 |
|
133 setGraphsAndTablesHolder(holder, topology, formData); |
|
134 } |
|
135 |
|
136 private Composite addTitleBar(Composite newPage) |
|
137 { |
|
138 // titleBar (Composite) |
|
139 // title2 (Label) title (Label) timeInterval (Label) |
|
140 |
|
141 FormData formData; |
|
142 Composite titleBar = new Composite(newPage, SWT.NONE); |
|
143 |
|
144 title2 = new Label(titleBar, SWT.LEFT); |
|
145 title2.setBackground(newPage.getDisplay().getSystemColor(SWT.COLOR_YELLOW)); |
|
146 title2.setFont(PIPageEditor.helvetica_9); |
|
147 |
|
148 title = new Label(titleBar, SWT.CENTER); |
|
149 title.setBackground(newPage.getDisplay().getSystemColor(SWT.COLOR_YELLOW)); |
|
150 title.setFont(PIPageEditor.helvetica_9); |
|
151 |
|
152 timeInterval = new Label(titleBar, SWT.RIGHT); |
|
153 timeInterval.setBackground(newPage.getDisplay().getSystemColor(SWT.COLOR_YELLOW)); |
|
154 timeInterval.setText(noInterval); |
|
155 timeInterval.setFont(PIPageEditor.helvetica_9); |
|
156 |
|
157 formData = new FormData(); |
|
158 formData.left = new FormAttachment(0); |
|
159 formData.right = new FormAttachment(30); |
|
160 title2.setLayoutData(formData); |
|
161 |
|
162 formData = new FormData(); |
|
163 formData.left = new FormAttachment(30); |
|
164 formData.right = new FormAttachment(70); |
|
165 title.setLayoutData(formData); |
|
166 |
|
167 formData = new FormData(); |
|
168 formData.left = new FormAttachment(70); |
|
169 formData.right = new FormAttachment(100); |
|
170 timeInterval.setLayoutData(formData); |
|
171 |
|
172 return titleBar; |
|
173 } |
|
174 |
|
175 private void setGraphsAndTablesHolder(Composite holder, int topology, FormData formData) |
|
176 { |
|
177 // holder (Composite) |
|
178 // topComposite (PICompositePanel/ScrolledComposite/SashForm) |
|
179 // bottomComposite (SashForm) |
|
180 |
|
181 // create a top composite that can hold graphs and/or tables |
|
182 // NOTE: Sometimes we really only need a Composite(newPage, SWT.NONE) |
|
183 this.topComposite = new PICompositePanel(holder, thisVisualiser); |
|
184 |
|
185 if (topology == TOP_ONLY) { |
|
186 formData.left = new FormAttachment(0); |
|
187 formData.right = new FormAttachment(100); |
|
188 this.topComposite.getSashForm().setLayoutData(formData); |
|
189 this.topComposite.getSashForm().setLayout(new FormLayout()); |
|
190 return; |
|
191 } |
|
192 |
|
193 // create a bottom composite only suitable for holding tables |
|
194 this.bottomComposite = new SashForm(holder, SWT.VERTICAL); |
|
195 |
|
196 // A sash separates top composite from bottom composite |
|
197 final Sash acrossSash = new Sash(holder, SWT.HORIZONTAL); |
|
198 |
|
199 // FormData for top |
|
200 formData = new FormData(); |
|
201 formData.top = new FormAttachment(0); |
|
202 formData.bottom = new FormAttachment(acrossSash); |
|
203 formData.left = new FormAttachment(0); |
|
204 formData.right = new FormAttachment(100); |
|
205 this.topComposite.getSashForm().setLayoutData(formData); |
|
206 this.topComposite.getSashForm().setLayout(new FormLayout()); |
|
207 |
|
208 // FormData for bottom |
|
209 formData = new FormData(); |
|
210 formData.top = new FormAttachment(acrossSash); |
|
211 formData.bottom = new FormAttachment(100); |
|
212 formData.left = new FormAttachment(0); |
|
213 formData.right = new FormAttachment(100); |
|
214 bottomComposite.setLayoutData(formData); |
|
215 bottomComposite.setLayout(new FormLayout()); |
|
216 |
|
217 // FormData for acrossSash |
|
218 // Put it initially in the middle |
|
219 formData = new FormData(); |
|
220 formData.top = new FormAttachment(50); |
|
221 formData.left = new FormAttachment(0); |
|
222 formData.right = new FormAttachment(100); |
|
223 acrossSash.setLayoutData(formData); |
|
224 |
|
225 final FormData acrossSashData = formData; |
|
226 final Composite parentFinal = acrossSash.getParent(); |
|
227 acrossSash.addSelectionListener(new SelectionAdapter() { |
|
228 public void widgetSelected(SelectionEvent event) { |
|
229 if (event.detail != SWT.DRAG) { |
|
230 acrossSashData.top = new FormAttachment(0, event.y); |
|
231 parentFinal.layout(); |
|
232 } |
|
233 } |
|
234 }); |
|
235 } |
|
236 |
|
237 public void setTimeInterval(final double start, final double end) |
|
238 { |
|
239 Display.getDefault().syncExec(new Runnable() { |
|
240 public void run() { |
|
241 PIPageEditor.currentPageEditor().setLocalTime(start, end); |
|
242 } |
|
243 }); |
|
244 } |
|
245 |
|
246 public void fetchSelection() |
|
247 { |
|
248 double start = this.topComposite.getSelectionStart() / 1000; |
|
249 double end = this.topComposite.getSelectionEnd() / 1000; |
|
250 PIPageEditor.currentPageEditor().setLocalTime(start, end); |
|
251 } |
|
252 |
|
253 public String getPageName() |
|
254 { |
|
255 return this.pageName; |
|
256 } |
|
257 |
|
258 public void setPageName(String pageName) |
|
259 { |
|
260 this.pageName = pageName; |
|
261 } |
|
262 |
|
263 public void saveScreenshot() throws IOException |
|
264 { |
|
265 File filePath = null; |
|
266 |
|
267 try |
|
268 { |
|
269 filePath = PIUtilities.getAFile(true, "jpg"); //$NON-NLS-1$ |
|
270 } |
|
271 catch (Exception e) |
|
272 { |
|
273 return; |
|
274 } |
|
275 |
|
276 if (filePath == null) |
|
277 { |
|
278 System.out.println(Messages.getString("ProfileVisualiser.noPath")); //$NON-NLS-1$ |
|
279 return; |
|
280 } |
|
281 System.out.println(Messages.getString("ProfileVisualiser.savingScreenshot")); //$NON-NLS-1$ |
|
282 } |
|
283 |
|
284 public void saveListScreenshot() throws IOException |
|
285 { |
|
286 if (this.currentInfoComponent == null) return; |
|
287 |
|
288 File filePath = null; |
|
289 |
|
290 try |
|
291 { |
|
292 filePath = PIUtilities.getAFile(true, "jpg"); //$NON-NLS-1$ |
|
293 } |
|
294 catch (Exception e) |
|
295 { |
|
296 return; |
|
297 } |
|
298 |
|
299 if (filePath == null) |
|
300 { |
|
301 System.out.println(Messages.getString("ProfileVisualiser.noPath")); //$NON-NLS-1$ |
|
302 return; |
|
303 } |
|
304 System.out.println(Messages.getString("ProfileVisualiser.savingScreenshot")); //$NON-NLS-1$ |
|
305 } |
|
306 |
|
307 public void action(String actionString) |
|
308 { |
|
309 // if there is any action that is applicable for panel without |
|
310 // a graph put it here |
|
311 |
|
312 // below actions are only applicable for panels that have a graph |
|
313 if (this.topComposite.getActiveGraph() == null) |
|
314 return; |
|
315 |
|
316 if (actionString.equals("screenshot")) //$NON-NLS-1$ |
|
317 { |
|
318 try |
|
319 { |
|
320 this.saveScreenshot(); |
|
321 } |
|
322 catch (Exception e) |
|
323 { |
|
324 e.printStackTrace(); |
|
325 } |
|
326 } |
|
327 else if (actionString.equals("listscreenshot")) //$NON-NLS-1$ |
|
328 { |
|
329 try |
|
330 { |
|
331 this.saveListScreenshot(); |
|
332 } |
|
333 catch (Exception e) |
|
334 { |
|
335 e.printStackTrace(); |
|
336 } |
|
337 } |
|
338 else if (actionString.equals("+")) //$NON-NLS-1$ |
|
339 { |
|
340 this.topComposite.performZoomCommand("+"); //$NON-NLS-1$ |
|
341 } |
|
342 else if (actionString.equals("-")) //$NON-NLS-1$ |
|
343 { |
|
344 this.topComposite.performZoomCommand("-"); //$NON-NLS-1$ |
|
345 } |
|
346 else if (actionString.equals("++")) //$NON-NLS-1$ |
|
347 { |
|
348 this.topComposite.performZoomCommand("++"); //$NON-NLS-1$ |
|
349 } |
|
350 else if (actionString.equals("--")) //$NON-NLS-1$ |
|
351 { |
|
352 this.topComposite.performZoomCommand("--"); //$NON-NLS-1$ |
|
353 } |
|
354 else if (actionString.equals("changeSelection")) //$NON-NLS-1$ |
|
355 { |
|
356 // change the time interval selected |
|
357 this.topComposite.selectionChanged(); |
|
358 } |
|
359 else if (actionString.equals("changeInterval")) //$NON-NLS-1$ |
|
360 { |
|
361 // change the time interval displayed |
|
362 double startTime = PIPageEditor.currentPageEditor().getStartTime(); |
|
363 double endTime = PIPageEditor.currentPageEditor().getEndTime(); |
|
364 |
|
365 if (startTime == -1 || endTime == -1) |
|
366 { |
|
367 this.timeInterval.setText(noInterval); |
|
368 } |
|
369 else |
|
370 { |
|
371 this.timeInterval.setText(ProfileVisualiser.getTimeInterval(startTime, endTime)); |
|
372 } |
|
373 // now the data are updated, let the zoomCommand of the panel |
|
374 // handle the selection centering and refresh |
|
375 this.topComposite.performZoomCommand("changeInterval"); //$NON-NLS-1$ |
|
376 } |
|
377 else if (actionString.equals("stretch")) //$NON-NLS-1$ |
|
378 { |
|
379 } |
|
380 else if (actionString.equals("changeResolution")) //$NON-NLS-1$ |
|
381 { |
|
382 } |
|
383 else if (actionString.equals("fetchSelection")) //$NON-NLS-1$ |
|
384 { |
|
385 this.fetchSelection(); |
|
386 } |
|
387 else if (actionString.equals("changeThresholdThread")) //$NON-NLS-1$ |
|
388 { |
|
389 PIEvent be = new PIEvent( |
|
390 null, PIEvent.THRESHOLD_THREAD_CHANGED); |
|
391 this.topComposite.piEventReceived(be); |
|
392 } |
|
393 else if (actionString.equals("changeThresholdBinary")) //$NON-NLS-1$ |
|
394 { |
|
395 PIEvent be = new PIEvent( |
|
396 null, PIEvent.THRESHOLD_BINARY_CHANGED); |
|
397 this.topComposite.piEventReceived(be); |
|
398 } |
|
399 else if (actionString.equals("changeThresholdFunction")) //$NON-NLS-1$ |
|
400 { |
|
401 PIEvent be = new PIEvent( |
|
402 null, PIEvent.THRESHOLD_FUNCTION_CHANGED); |
|
403 this.topComposite.piEventReceived(be); |
|
404 } |
|
405 } |
|
406 |
|
407 public Composite getContentPane() |
|
408 { |
|
409 return this.page; |
|
410 } |
|
411 |
|
412 public ParserRepository getParserRepository() |
|
413 { |
|
414 return this.parserRepository; |
|
415 } |
|
416 |
|
417 public int getLastSampleX() |
|
418 { |
|
419 return this.topComposite.lastSampleX; |
|
420 } |
|
421 |
|
422 public void setLastSampleX(int aksa) |
|
423 { |
|
424 if (this.topComposite.lastSampleX < aksa) |
|
425 this.topComposite.lastSampleX = aksa; |
|
426 |
|
427 // do the set even if nothing has changed except that a new graph was added to the tab |
|
428 this.topComposite.setSizeX(true); |
|
429 } |
|
430 |
|
431 public void vPanelRepaint(Component infoComponent) |
|
432 { |
|
433 //make this |
|
434 if (infoComponent != null && infoComponent != this.currentInfoComponent) |
|
435 { |
|
436 this.currentInfoComponent = infoComponent; |
|
437 } |
|
438 } |
|
439 |
|
440 public SashForm getBottomComposite() |
|
441 { |
|
442 return this.bottomComposite; |
|
443 } |
|
444 |
|
445 public PICompositePanel getTopComposite() |
|
446 { |
|
447 return this.topComposite; |
|
448 } |
|
449 |
|
450 public Label getTitle() |
|
451 { |
|
452 return this.title; |
|
453 } |
|
454 |
|
455 public Label getTitle2() |
|
456 { |
|
457 return this.title2; |
|
458 } |
|
459 |
|
460 public Label getTimeString() |
|
461 { |
|
462 return this.timeInterval; |
|
463 } |
|
464 |
|
465 public static String getTimeInterval(double startTime, double endTime) |
|
466 { |
|
467 return Messages.getString("ProfileVisualiser.interval1") + timeFormat.format(startTime) //$NON-NLS-1$ |
|
468 + Messages.getString("ProfileVisualiser.interval2") + timeFormat.format(endTime) //$NON-NLS-1$ |
|
469 + Messages.getString("ProfileVisualiser.interval3") + timeFormat.format(endTime - startTime) //$NON-NLS-1$ |
|
470 + Messages.getString("ProfileVisualiser.interval4"); //$NON-NLS-1$ |
|
471 } |
|
472 } |