|
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.pi.memory; |
|
19 |
|
20 import java.awt.Toolkit; |
|
21 import java.awt.datatransfer.Clipboard; |
|
22 import java.awt.datatransfer.StringSelection; |
|
23 import java.awt.event.ActionEvent; |
|
24 import java.awt.event.FocusEvent; |
|
25 import java.awt.event.MouseEvent; |
|
26 import java.text.DecimalFormat; |
|
27 import java.util.ArrayList; |
|
28 import java.util.HashSet; |
|
29 import java.util.Iterator; |
|
30 import java.util.Vector; |
|
31 |
|
32 import org.eclipse.jface.action.Action; |
|
33 import org.eclipse.jface.action.ActionContributionItem; |
|
34 import org.eclipse.jface.action.IAction; |
|
35 import org.eclipse.jface.action.IContributionManager; |
|
36 import org.eclipse.jface.action.IMenuManager; |
|
37 import org.eclipse.jface.action.SubMenuManager; |
|
38 import org.eclipse.jface.viewers.CheckStateChangedEvent; |
|
39 import org.eclipse.jface.viewers.CheckboxTableViewer; |
|
40 import org.eclipse.jface.viewers.ICheckStateListener; |
|
41 import org.eclipse.jface.viewers.IStructuredContentProvider; |
|
42 import org.eclipse.jface.viewers.ITableLabelProvider; |
|
43 import org.eclipse.jface.viewers.LabelProvider; |
|
44 import org.eclipse.jface.viewers.Viewer; |
|
45 import org.eclipse.jface.viewers.ViewerSorter; |
|
46 import org.eclipse.swt.SWT; |
|
47 import org.eclipse.swt.events.FocusListener; |
|
48 import org.eclipse.swt.events.MouseListener; |
|
49 import org.eclipse.swt.events.SelectionAdapter; |
|
50 import org.eclipse.swt.events.SelectionEvent; |
|
51 import org.eclipse.swt.graphics.Image; |
|
52 import org.eclipse.swt.layout.GridData; |
|
53 import org.eclipse.swt.widgets.Composite; |
|
54 import org.eclipse.swt.widgets.Display; |
|
55 import org.eclipse.swt.widgets.Menu; |
|
56 import org.eclipse.swt.widgets.MenuItem; |
|
57 import org.eclipse.swt.widgets.Table; |
|
58 import org.eclipse.swt.widgets.TableColumn; |
|
59 import org.eclipse.swt.widgets.TableItem; |
|
60 import org.eclipse.ui.IActionBars; |
|
61 import org.eclipse.ui.actions.ActionFactory; |
|
62 import org.eclipse.ui.ide.IIDEActionConstants; |
|
63 |
|
64 import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples; |
|
65 import com.nokia.carbide.cpp.internal.pi.memory.actions.MemoryStatisticsDialog; |
|
66 import com.nokia.carbide.cpp.internal.pi.visual.GenericTable; |
|
67 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent; |
|
68 import com.nokia.carbide.cpp.pi.editors.PIPageEditor; |
|
69 |
|
70 |
|
71 public class MemThreadTable extends GenericTable |
|
72 { |
|
73 private static final int COLUMN_ID_MEMORY_CHUNKS = 14; |
|
74 private static final int COLUMN_ID_MEMORY_STACK = 15; |
|
75 private static final int COLUMN_ID_MEMORY_TOTAL = 16; |
|
76 private static final int COLUMN_ID_MEMORY_NAME = 17; |
|
77 |
|
78 // sort direction |
|
79 private boolean sortAscending = true; |
|
80 |
|
81 // trace associated with this display |
|
82 // private MemTrace myTrace; |
|
83 private MemTraceGraph myGraph; |
|
84 private Composite parent; |
|
85 |
|
86 // override |
|
87 protected Vector<MemThread> tableItemData; |
|
88 |
|
89 // menu items |
|
90 private Action selectAllAction; |
|
91 private Action copyTableAction; |
|
92 private Action copyAction; |
|
93 private Action saveTableAction; |
|
94 |
|
95 // class to pass sample data to the save wizard |
|
96 public class SaveSampleString implements ISaveSamples { |
|
97 boolean done = false; |
|
98 |
|
99 public SaveSampleString() { |
|
100 } |
|
101 |
|
102 public String getData() { |
|
103 if (done) |
|
104 return null; |
|
105 |
|
106 String returnString = getSampleString(); |
|
107 done = true; |
|
108 return returnString; |
|
109 } |
|
110 |
|
111 public String getData(int size) { |
|
112 return getData(); |
|
113 } |
|
114 |
|
115 public int getIndex() { |
|
116 return done ? 1 : 0; |
|
117 } |
|
118 |
|
119 public void clear() { |
|
120 done = false; |
|
121 } |
|
122 } |
|
123 |
|
124 /* |
|
125 * return the memory samples selected in the interval |
|
126 */ |
|
127 protected String getSampleString() |
|
128 { |
|
129 int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0 + 0.0005); |
|
130 int endTime = (int) (PIPageEditor.currentPageEditor().getEndTime() * 1000.0 + 0.0005); |
|
131 |
|
132 MemTrace trace = this.myGraph.getMemTrace(); |
|
133 ArrayList<MemSampleByTime> drawDataByTime = trace.getDrawDataByTime(); |
|
134 |
|
135 if (drawDataByTime == null || drawDataByTime.size() == 0) |
|
136 return ""; // should have been checked so this never happens //$NON-NLS-1$ |
|
137 |
|
138 String returnString = Messages.getString("MemThreadTable.saveSamplesHeading"); //$NON-NLS-1$ |
|
139 |
|
140 if (drawDataByTime.get(0).getTime() > startTime) { |
|
141 int graphIndex = this.myGraph.getGraphIndex(); |
|
142 TableItem[] items = this.table.getItems(); |
|
143 |
|
144 for (int i = 0; i < items.length; i++) { |
|
145 Object data = items[i].getData(); |
|
146 |
|
147 if (!(data instanceof MemThread)) |
|
148 continue; |
|
149 |
|
150 MemThread pmt = (MemThread) data; |
|
151 |
|
152 if (!pmt.enabled[graphIndex]) |
|
153 continue; |
|
154 |
|
155 returnString += Messages.getString("MemThreadTable.notRecorded1") + items[i].getText() + Messages.getString("MemThreadTable.notRecorded2"); //$NON-NLS-1$ //$NON-NLS-2$ |
|
156 } |
|
157 } |
|
158 |
|
159 // find least sampling time greater than or equal to the start time |
|
160 int i = 0; |
|
161 long sampleTime = 0; |
|
162 for ( ; i < drawDataByTime.size(); i++) { |
|
163 sampleTime = drawDataByTime.get(i).getTime(); |
|
164 if (sampleTime > startTime) |
|
165 break; |
|
166 } |
|
167 |
|
168 if (i != 0) |
|
169 i--; |
|
170 |
|
171 int graphIndex = myGraph.getGraphIndex(); |
|
172 for ( ; i < drawDataByTime.size() && drawDataByTime.get(i).getTime() <= endTime; i++) { |
|
173 ArrayList<MemSample> samples = drawDataByTime.get(i).getSamples(); |
|
174 for (MemSample sample : samples) { |
|
175 if (!sample.thread.enabled[graphIndex]) |
|
176 continue; |
|
177 |
|
178 returnString += sample.sampleSynchTime + Messages.getString("MemThreadTable.comma") + sample.thread.fullName //$NON-NLS-1$ |
|
179 + Messages.getString("MemThreadTable.comma") + (sample.heapSize / 1024) + Messages.getString("MemThreadTable.comma") + (sample.stackSize / 1024) + "\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
|
180 } |
|
181 } |
|
182 |
|
183 return returnString; |
|
184 } |
|
185 |
|
186 protected MenuItem getSaveSamplesItem(Menu menu, boolean enabled) { |
|
187 MenuItem saveSamplesItem = new MenuItem(menu, SWT.PUSH); |
|
188 |
|
189 saveSamplesItem.setText(Messages.getString("MemThreadTable.saveCheckedSamples")); //$NON-NLS-1$ |
|
190 saveSamplesItem.setEnabled(enabled); |
|
191 |
|
192 if (enabled) { |
|
193 saveSamplesItem.addSelectionListener(new SelectionAdapter() { |
|
194 public void widgetSelected(SelectionEvent e) { |
|
195 action("saveSamples"); //$NON-NLS-1$ |
|
196 } |
|
197 }); |
|
198 } |
|
199 |
|
200 return saveSamplesItem; |
|
201 } |
|
202 |
|
203 public MemThreadTable(MemTraceGraph myGraph, Composite parent) |
|
204 { |
|
205 this.myGraph = myGraph; |
|
206 this.parent = parent; |
|
207 |
|
208 this.tableViewer = CheckboxTableViewer.newCheckList(parent, |
|
209 SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); |
|
210 this.table = this.tableViewer.getTable(); |
|
211 this.table.setLayoutData(new GridData(GridData.FILL_BOTH)); |
|
212 |
|
213 // add the check state handler, label provider and content provider |
|
214 this.tableViewer.addCheckStateListener(new CheckHandler()); |
|
215 this.tableViewer.setLabelProvider(new SharedLabelProvider(this.table)); |
|
216 this.tableViewer.setContentProvider(new MemoryTableContentProvider()); |
|
217 this.tableViewer.setSorter(new SharedSorter()); |
|
218 |
|
219 // give the table a heading for possible use in copying and exported |
|
220 this.table.setData(Messages.getString("MemThreadTable.memory")); //$NON-NLS-1$ |
|
221 |
|
222 // create the columns |
|
223 TableColumn column; |
|
224 |
|
225 // data associated with the TableViewer will note which columns contain hex values |
|
226 // Keep this in the order in which columns have been created |
|
227 boolean[] isHex = {false, false, false, false}; |
|
228 this.table.setData("isHex", isHex); //$NON-NLS-1$ |
|
229 |
|
230 // select/deselect column |
|
231 column = new TableColumn(this.table, SWT.CENTER); |
|
232 column.setText(COLUMN_HEAD_MEMORY_NAME); |
|
233 column.setWidth(COLUMN_WIDTH_MEMORY_NAME + 15); // extra space for the checkbox |
|
234 column.setData(new Integer(COLUMN_ID_MEMORY_NAME)); |
|
235 column.setMoveable(true); |
|
236 column.setResizable(true); |
|
237 column.addSelectionListener(new ColumnSelectionHandler()); |
|
238 |
|
239 column = new TableColumn(tableViewer.getTable(), SWT.RIGHT); |
|
240 column.setText(COLUMN_HEAD_MEMORY_CHUNKS); |
|
241 column.setWidth(COLUMN_WIDTH_MEMORY_CHUNKS); |
|
242 column.setData(new Integer(COLUMN_ID_MEMORY_CHUNKS)); |
|
243 column.setMoveable(true); |
|
244 column.setResizable(true); |
|
245 column.addSelectionListener(new ColumnSelectionHandler()); |
|
246 |
|
247 column = new TableColumn(tableViewer.getTable(), SWT.RIGHT); |
|
248 column.setText(COLUMN_HEAD_MEMORY_STACK); |
|
249 column.setWidth(COLUMN_WIDTH_MEMORY_STACK); |
|
250 column.setData(new Integer(COLUMN_ID_MEMORY_STACK)); |
|
251 column.setMoveable(true); |
|
252 column.setResizable(true); |
|
253 column.addSelectionListener(new ColumnSelectionHandler()); |
|
254 |
|
255 column = new TableColumn(tableViewer.getTable(), SWT.RIGHT); |
|
256 column.setText(COLUMN_HEAD_MEMORY_TOTAL); |
|
257 column.setWidth(COLUMN_WIDTH_MEMORY_TOTAL); |
|
258 column.setData(new Integer(COLUMN_ID_MEMORY_TOTAL)); |
|
259 column.setMoveable(true); |
|
260 column.setResizable(true); |
|
261 column.addSelectionListener(new ColumnSelectionHandler()); |
|
262 |
|
263 // initially, all rows are checked |
|
264 this.tableViewer.setAllChecked(true); |
|
265 |
|
266 this.table.addMouseListener(new TableMouseListener()); |
|
267 this.table.setHeaderVisible(true); |
|
268 this.table.setLinesVisible(true); |
|
269 this.table.setRedraw(true); |
|
270 |
|
271 updateItemData(true); |
|
272 ((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_MEMORY_NAME); |
|
273 |
|
274 // initially, all rows are checked |
|
275 this.tableViewer.setAllChecked(true); |
|
276 |
|
277 createDefaultActions(); |
|
278 |
|
279 // listen for key sequences such as Ctrl-A and Ctrl-C |
|
280 table.addKeyListener(new TableKeyListener()); |
|
281 |
|
282 table.addFocusListener(new FocusListener() { |
|
283 IAction oldSelectAllAction = null; |
|
284 IAction oldCopyAction = null; |
|
285 |
|
286 public void focusGained(org.eclipse.swt.events.FocusEvent arg0) { |
|
287 IActionBars bars = PIPageEditor.getActionBars(); |
|
288 |
|
289 oldSelectAllAction = PIPageEditor.getActionBars().getGlobalActionHandler(ActionFactory.SELECT_ALL.getId()); |
|
290 oldCopyAction = PIPageEditor.getActionBars().getGlobalActionHandler(ActionFactory.COPY.getId()); |
|
291 |
|
292 bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction); |
|
293 bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllAction); |
|
294 |
|
295 copyAction.setEnabled(table.getSelectionCount() > 0); |
|
296 selectAllAction.setEnabled(table.getItemCount() > 0); |
|
297 bars.updateActionBars(); |
|
298 |
|
299 // add to the Edit menu |
|
300 IMenuManager editMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_EDIT); |
|
301 |
|
302 if (editMenuManager instanceof SubMenuManager) |
|
303 { |
|
304 IContributionManager editManager = ((SubMenuManager)editMenuManager).getParent(); |
|
305 ActionContributionItem item; |
|
306 |
|
307 editMenuManager.remove("PICopyTable"); //$NON-NLS-1$ |
|
308 copyTableAction.setEnabled(table.getItemCount() > 0); |
|
309 item = new ActionContributionItem(copyTableAction); |
|
310 item.setVisible(true); |
|
311 editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item); |
|
312 } |
|
313 |
|
314 // add to the File menu |
|
315 IMenuManager fileMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_FILE); |
|
316 |
|
317 if (fileMenuManager instanceof SubMenuManager) |
|
318 { |
|
319 IContributionManager fileManager = ((SubMenuManager)fileMenuManager).getParent(); |
|
320 ActionContributionItem item; |
|
321 |
|
322 fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$ |
|
323 saveTableAction.setEnabled(table.getItemCount() > 0); |
|
324 item = new ActionContributionItem(saveTableAction); |
|
325 item.setVisible(true); |
|
326 fileManager.insertAfter("saveAll", item); //$NON-NLS-1$ |
|
327 } |
|
328 } |
|
329 |
|
330 public void focusLost(org.eclipse.swt.events.FocusEvent arg0) { |
|
331 IActionBars bars = PIPageEditor.getActionBars(); |
|
332 bars.setGlobalActionHandler(ActionFactory.COPY.getId(), oldCopyAction); |
|
333 bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), oldSelectAllAction); |
|
334 bars.updateActionBars(); |
|
335 |
|
336 SubMenuManager editMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_EDIT); |
|
337 editMenuManager.remove("PICopyTable"); //$NON-NLS-1$ |
|
338 editMenuManager.update(); |
|
339 |
|
340 SubMenuManager fileMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_FILE); |
|
341 fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$ |
|
342 fileMenuManager.update(); |
|
343 } |
|
344 }); |
|
345 |
|
346 tableViewer.refresh(); |
|
347 table.redraw(); |
|
348 } |
|
349 |
|
350 private class TableMouseListener implements MouseListener |
|
351 { |
|
352 public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) { |
|
353 if (e.button == MouseEvent.BUTTON1) |
|
354 { |
|
355 TableItem[] selectedItems = table.getSelection(); |
|
356 if (selectedItems.length == 0) |
|
357 return; |
|
358 |
|
359 if (selectedItems[0].getData() instanceof MemThread) |
|
360 { |
|
361 MemThread pMemThread = (MemThread)(selectedItems[0].getData()); |
|
362 if (pMemThread.isEnabled(myGraph.getGraphIndex())) |
|
363 action("remove"); //$NON-NLS-1$ |
|
364 else |
|
365 action("add"); //$NON-NLS-1$ |
|
366 } |
|
367 } |
|
368 selectAllAction.setEnabled(table.getItemCount() > 0); |
|
369 copyAction.setEnabled(table.getSelectionCount() > 0); |
|
370 copyTableAction.setEnabled(table.getItemCount() > 0); |
|
371 } |
|
372 |
|
373 public void mouseDown(org.eclipse.swt.events.MouseEvent e) { |
|
374 } |
|
375 |
|
376 public void mouseUp(org.eclipse.swt.events.MouseEvent e) { |
|
377 |
|
378 selectAllAction.setEnabled(table.getItemCount() > 0); |
|
379 copyAction.setEnabled(table.getSelectionCount() > 0); |
|
380 copyTableAction.setEnabled(table.getItemCount() > 0); |
|
381 |
|
382 if (e.button == MouseEvent.BUTTON3) { |
|
383 // get rid of last Menu created so we don't have double menu |
|
384 // on click |
|
385 if (contextMenu != null) { |
|
386 contextMenu.dispose(); |
|
387 } |
|
388 |
|
389 contextMenu = new Menu(table.getShell(), SWT.POP_UP); |
|
390 getCheckRows(contextMenu, table.getSelectionCount() > 0); |
|
391 |
|
392 // select all, copy, and copy all |
|
393 new MenuItem(contextMenu, SWT.SEPARATOR); |
|
394 getSelectAllItem(contextMenu, table.getItemCount() > 0); |
|
395 getCopyItem(contextMenu, table.getSelectionCount() > 0); |
|
396 getCopyTableItem(contextMenu, table.getItemCount() > 0); |
|
397 selectAllAction.setEnabled(table.getItemCount() > 0); |
|
398 copyAction.setEnabled(table.getSelectionCount() > 0); |
|
399 copyTableAction.setEnabled(table.getItemCount() > 0); |
|
400 |
|
401 // save all |
|
402 new MenuItem(contextMenu, SWT.SEPARATOR); |
|
403 getSaveTableItem(contextMenu, table.getItemCount() > 0); |
|
404 saveTableAction.setEnabled(table.getItemCount() > 0); |
|
405 |
|
406 // save samples |
|
407 int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0f); |
|
408 int endTime = (int) (PIPageEditor.currentPageEditor().getEndTime() * 1000.0f); |
|
409 |
|
410 getSaveSamplesItem(contextMenu, |
|
411 myGraph.haveEnabled() && (startTime != -1) && (endTime != -1) && (startTime != endTime)); |
|
412 |
|
413 contextMenu.setLocation(parent.toDisplay(e.x + table.getLocation().x, e.y + table.getLocation().y)); |
|
414 contextMenu.setVisible(true); |
|
415 |
|
416 new MenuItem(contextMenu, SWT.SEPARATOR); |
|
417 |
|
418 MenuItem memoryStatsItem = new MenuItem(contextMenu, SWT.PUSH); |
|
419 memoryStatsItem.setText(Messages.getString("MemoryPlugin.memoryStats")); //$NON-NLS-1$ |
|
420 memoryStatsItem.addSelectionListener(new SelectionAdapter() { |
|
421 public void widgetSelected(SelectionEvent e) { |
|
422 new MemoryStatisticsDialog(Display.getCurrent()); |
|
423 } |
|
424 }); |
|
425 |
|
426 table.setMenu(contextMenu); |
|
427 } |
|
428 } |
|
429 } |
|
430 |
|
431 private static class MemoryTableContentProvider implements IStructuredContentProvider { |
|
432 |
|
433 public MemoryTableContentProvider() { |
|
434 super(); |
|
435 } |
|
436 |
|
437 public Object[] getElements(Object inputElement) { |
|
438 return ((Vector<MemThread>) inputElement).toArray(); |
|
439 } |
|
440 |
|
441 public void dispose() { |
|
442 } |
|
443 |
|
444 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
|
445 } |
|
446 } |
|
447 |
|
448 private class CheckHandler implements ICheckStateListener |
|
449 { |
|
450 public void checkStateChanged(CheckStateChangedEvent event) { |
|
451 |
|
452 if (!(event.getElement() instanceof MemThread)) |
|
453 return; |
|
454 |
|
455 // set the stored value to the checkbox value |
|
456 MemThread pMemThread = (MemThread)event.getElement(); |
|
457 pMemThread.setEnabled(myGraph.getGraphIndex(), event.getChecked()); |
|
458 |
|
459 selectionChangeNotify(); |
|
460 |
|
461 table.deselectAll(); |
|
462 } |
|
463 } |
|
464 |
|
465 void selectionChangeNotify() { |
|
466 this.tableViewer.refresh(); |
|
467 this.table.redraw(); |
|
468 PIEvent be = new PIEvent(null, PIEvent.CHANGED_MEMORY_TABLE); |
|
469 myGraph.piEventReceived(be); |
|
470 } |
|
471 |
|
472 private class SharedLabelProvider extends LabelProvider implements ITableLabelProvider { |
|
473 |
|
474 private DecimalFormat decimalFormat = new DecimalFormat(Messages.getString("MemThreadTable.kbFormat")); //$NON-NLS-1$ |
|
475 |
|
476 Table table; |
|
477 |
|
478 public SharedLabelProvider(Table table) { |
|
479 super(); |
|
480 this.table = table; |
|
481 } |
|
482 |
|
483 public String getColumnText(Object element, int columnIndex) { |
|
484 int columnId = ((Integer) table.getColumn(columnIndex).getData()).intValue(); |
|
485 |
|
486 if (!(element instanceof MemThread)) |
|
487 return ""; //$NON-NLS-1$ |
|
488 |
|
489 MemThread profiledItem = (MemThread) element; |
|
490 |
|
491 switch (columnId) |
|
492 { |
|
493 case COLUMN_ID_MEMORY_NAME: |
|
494 { |
|
495 return profiledItem.fullName; |
|
496 } |
|
497 case COLUMN_ID_MEMORY_CHUNKS: |
|
498 { |
|
499 double startTime = PIPageEditor.currentPageEditor().getStartTime(); |
|
500 double endTime = PIPageEditor.currentPageEditor().getEndTime(); |
|
501 |
|
502 if ((startTime == -1) || (endTime == -1) || (startTime == endTime)) |
|
503 return ""; //$NON-NLS-1$ |
|
504 |
|
505 return decimalFormat.format((profiledItem.maxMemoryItem.maxChunks + 512)/1024); |
|
506 } |
|
507 case COLUMN_ID_MEMORY_STACK: |
|
508 { |
|
509 double startTime = PIPageEditor.currentPageEditor().getStartTime(); |
|
510 double endTime = PIPageEditor.currentPageEditor().getEndTime(); |
|
511 |
|
512 if ((startTime == -1) || (endTime == -1) || (startTime == endTime)) |
|
513 return ""; //$NON-NLS-1$ |
|
514 |
|
515 return decimalFormat.format((profiledItem.maxMemoryItem.maxStackHeap + 512)/1024); |
|
516 } |
|
517 case COLUMN_ID_MEMORY_TOTAL: |
|
518 { |
|
519 double startTime = PIPageEditor.currentPageEditor().getStartTime(); |
|
520 double endTime = PIPageEditor.currentPageEditor().getEndTime(); |
|
521 |
|
522 if ((startTime == -1) || (endTime == -1) || (startTime == endTime)) |
|
523 return ""; //$NON-NLS-1$ |
|
524 |
|
525 return decimalFormat.format((profiledItem.maxMemoryItem.maxTotal + 512)/1024); |
|
526 } |
|
527 default: |
|
528 { |
|
529 break; |
|
530 } |
|
531 } |
|
532 // should never get here |
|
533 return ""; //$NON-NLS-1$ |
|
534 } |
|
535 |
|
536 public Image getColumnImage(Object element, int columnIndex) { |
|
537 return null; |
|
538 } |
|
539 } |
|
540 |
|
541 |
|
542 /* |
|
543 * TableViewer sorter for the called-by and called function tableviewers |
|
544 */ |
|
545 private class SharedSorter extends ViewerSorter { |
|
546 // last column sorted |
|
547 private int column = -1; |
|
548 |
|
549 /* |
|
550 * decide on which column to sort by, and the sort ordering |
|
551 */ |
|
552 public void doSort(int column) { |
|
553 // ignore the column passed in and use the id set by the column selection handler |
|
554 if (column == this.column) { |
|
555 // sort in other order |
|
556 sortAscending = !sortAscending; |
|
557 } else { |
|
558 // changed columns, so sort in the default order |
|
559 switch (column) { |
|
560 case COLUMN_ID_MEMORY_NAME: |
|
561 { |
|
562 // sort in ascending order |
|
563 sortAscending = true; |
|
564 break; |
|
565 } |
|
566 case COLUMN_ID_MEMORY_CHUNKS: |
|
567 case COLUMN_ID_MEMORY_STACK: |
|
568 case COLUMN_ID_MEMORY_TOTAL: |
|
569 { |
|
570 // sort in descending order |
|
571 sortAscending = false; |
|
572 break; |
|
573 } |
|
574 default: |
|
575 { |
|
576 // ignore the column |
|
577 return; |
|
578 } |
|
579 } |
|
580 this.column = column; |
|
581 } |
|
582 |
|
583 // find the TableColumn corresponding to column, and give it a column direction |
|
584 TableColumn sortByColumn = null; |
|
585 for (int i = 0; i < table.getColumnCount(); i++) { |
|
586 if (table.getColumn(i).getData() instanceof Integer) { |
|
587 if (((Integer)table.getColumn(i).getData()) == column) { |
|
588 sortByColumn = table.getColumn(i); |
|
589 break; |
|
590 } |
|
591 } |
|
592 } |
|
593 |
|
594 if (sortByColumn != null) { |
|
595 table.setSortColumn(sortByColumn); |
|
596 table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN); |
|
597 } |
|
598 } |
|
599 |
|
600 /* |
|
601 * compare two items from a table column |
|
602 */ |
|
603 public int compare(Viewer viewer, Object e1, Object e2) { |
|
604 int returnCode = 0; |
|
605 |
|
606 MemThread elem1 = (MemThread)e1; |
|
607 MemThread elem2 = (MemThread)e2; |
|
608 |
|
609 // find the memory information for the two threads |
|
610 |
|
611 // compare based on the memory information |
|
612 switch (column) { |
|
613 case COLUMN_ID_MEMORY_CHUNKS: |
|
614 |
|
615 returnCode = elem1.maxMemoryItem.maxChunks > |
|
616 elem2.maxMemoryItem.maxChunks ? 1 : -1; |
|
617 break; |
|
618 case COLUMN_ID_MEMORY_STACK: |
|
619 returnCode = elem1.maxMemoryItem.maxStackHeap > |
|
620 elem2.maxMemoryItem.maxStackHeap ? 1 : -1; |
|
621 break; |
|
622 case COLUMN_ID_MEMORY_TOTAL: |
|
623 returnCode = elem1.maxMemoryItem.maxTotal > |
|
624 elem2.maxMemoryItem.maxTotal ? 1 : -1; |
|
625 break; |
|
626 case COLUMN_ID_MEMORY_NAME: |
|
627 { |
|
628 returnCode = this.getComparator().compare(elem1.fullName, elem2.fullName); |
|
629 break; |
|
630 } |
|
631 default: |
|
632 break; |
|
633 } |
|
634 |
|
635 // for descending order, reverse the sense of the compare |
|
636 if (!sortAscending) |
|
637 returnCode = -returnCode; |
|
638 |
|
639 return returnCode; |
|
640 } |
|
641 } |
|
642 |
|
643 public void actionPerformed(ActionEvent e) {} |
|
644 |
|
645 public void action(String actionString) |
|
646 { |
|
647 int graphIndex = this.myGraph.getGraphIndex(); |
|
648 |
|
649 if ( actionString.equals("add") //$NON-NLS-1$ |
|
650 || actionString.equals("remove")) //$NON-NLS-1$ |
|
651 { |
|
652 actionAddRemove(actionString, graphIndex); |
|
653 } |
|
654 else if ( actionString.equals("addall") //$NON-NLS-1$ |
|
655 || actionString.equals("removeall")) //$NON-NLS-1$ |
|
656 { |
|
657 actionAddRemoveAll(actionString, graphIndex); |
|
658 } |
|
659 else if (actionString.equals("copy")) //$NON-NLS-1$ |
|
660 { |
|
661 actionCopyOrSave(true, this.table, CHECKBOX_TEXT, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
|
662 return; // no redraw needed |
|
663 } |
|
664 else if (actionString.equals("copyTable")) //$NON-NLS-1$ |
|
665 { |
|
666 actionCopyOrSave(true, this.table, CHECKBOX_TEXT, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
|
667 return; // no redraw needed |
|
668 } |
|
669 else if (actionString.equals("selectAll")) //$NON-NLS-1$ |
|
670 { |
|
671 actionSelectAll(); |
|
672 return; |
|
673 } |
|
674 else if (actionString.equals("saveTable")) //$NON-NLS-1$ |
|
675 { |
|
676 actionCopyOrSave(false, this.table, CHECKBOX_TEXT, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
|
677 return; // no redraw needed |
|
678 } |
|
679 else if (actionString.equals("saveSamples")) //$NON-NLS-1$ |
|
680 { |
|
681 SaveSampleString saveSampleString = new SaveSampleString(); |
|
682 actionSaveSamples(saveSampleString); //$NON-NLS-1$ |
|
683 return; |
|
684 } |
|
685 else if (actionString.equals("saveTableTest")) //$NON-NLS-1$ |
|
686 { |
|
687 // copy save file contents to the clipboard for easy viewing |
|
688 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); |
|
689 SaveTableString getString = new SaveTableString(this.table, CHECKBOX_TEXT, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
|
690 String copyString = getString.getData(); |
|
691 StringSelection contents = new StringSelection(copyString); |
|
692 cb.setContents(contents, contents); |
|
693 return; |
|
694 } |
|
695 |
|
696 tableViewer.refresh(); |
|
697 table.redraw(); |
|
698 this.myGraph.repaint(); |
|
699 } |
|
700 |
|
701 private void actionAddRemove(String actionString, int graphIndex) |
|
702 { |
|
703 MemThread memThread; |
|
704 |
|
705 // true for "add", false for "remove" |
|
706 boolean addIt = actionString.equals("add"); //$NON-NLS-1$ |
|
707 |
|
708 TableItem[] selectedItems = this.table.getSelection(); |
|
709 for (int i = 0; i < selectedItems.length; i++) |
|
710 { |
|
711 selectedItems[i].setChecked(addIt); |
|
712 memThread = (MemThread)((TableItem)selectedItems[i]).getData(); |
|
713 memThread.setEnabled(graphIndex, addIt); |
|
714 } |
|
715 |
|
716 // this table's set of checkbox-selected rows has changed, |
|
717 // so propagate that information |
|
718 if (selectedItems.length != 0) |
|
719 selectionChangeNotify(); |
|
720 |
|
721 this.table.deselectAll(); |
|
722 } |
|
723 |
|
724 private void actionAddRemoveAll(String actionString, int graphIndex) |
|
725 { |
|
726 MemThread memThread; |
|
727 |
|
728 // true for "add", false for "remove" |
|
729 boolean addIt = actionString.equals("addall"); //$NON-NLS-1$ |
|
730 |
|
731 TableItem[] selectedItems = this.table.getItems(); |
|
732 for (int i = 0; i < selectedItems.length; i++) |
|
733 { |
|
734 selectedItems[i].setChecked(addIt); |
|
735 memThread = (MemThread)((TableItem)selectedItems[i]).getData(); |
|
736 memThread.setEnabled(graphIndex, addIt); |
|
737 } |
|
738 |
|
739 // this table's set of checkbox-selected rows has changed, |
|
740 // so propagate that information |
|
741 selectionChangeNotify(); |
|
742 |
|
743 this.table.deselectAll(); |
|
744 } |
|
745 |
|
746 public void focusGained(FocusEvent e) {} |
|
747 |
|
748 public void focusLost(FocusEvent e) {} |
|
749 |
|
750 public void piEventReceived(PIEvent be) |
|
751 { |
|
752 if (be.getType() == PIEvent.SELECTION_AREA_CHANGED2) |
|
753 { |
|
754 this.tableViewer.refresh(); |
|
755 this.table.redraw(); |
|
756 } |
|
757 else if (be.getType() == PIEvent.CHANGED_MEMORY_TABLE) |
|
758 { |
|
759 // this.tableViewer.refresh(); |
|
760 // this.table.redraw(); |
|
761 } |
|
762 } |
|
763 |
|
764 public void updateItemData(boolean setInput) |
|
765 { |
|
766 HashSet<MemThread> noDuplicateMemThreads = myGraph.getMemTrace().getNoDuplicateMemThreads(); |
|
767 if (tableItemData == null) |
|
768 tableItemData = new Vector<MemThread>(noDuplicateMemThreads.size()); |
|
769 else |
|
770 tableItemData.clear(); |
|
771 |
|
772 // tableItemData contains one entry per table row |
|
773 // the first profiled thread is the system-wide total memory information |
|
774 for (Iterator<MemThread> iter = noDuplicateMemThreads.iterator(); iter.hasNext(); ) |
|
775 { |
|
776 MemThread memThread = iter.next(); |
|
777 if ( (memThread.threadId != 0xffffffffbabbeaaaL) |
|
778 && (memThread.threadId != 0xffffffffbabbea20L)) |
|
779 { |
|
780 tableItemData.add(memThread); |
|
781 } |
|
782 } |
|
783 |
|
784 // refresh the table, if needed |
|
785 if (setInput) |
|
786 refreshTableViewer(); |
|
787 } |
|
788 |
|
789 public void refreshTableViewer() |
|
790 { |
|
791 this.tableViewer.setInput(tableItemData); |
|
792 } |
|
793 |
|
794 public void sortOnColumnSelection(TableColumn tableColumn) { |
|
795 int columnID = ((Integer) tableColumn.getData()).intValue(); |
|
796 ((SharedSorter) tableViewer.getSorter()).doSort(columnID); |
|
797 |
|
798 tableViewer.refresh(); |
|
799 table.redraw(); |
|
800 } |
|
801 |
|
802 private class ColumnSelectionHandler extends SelectionAdapter |
|
803 { |
|
804 public void widgetSelected(SelectionEvent e) |
|
805 { |
|
806 if (!(e.widget instanceof TableColumn)) |
|
807 return; |
|
808 |
|
809 sortOnColumnSelection((TableColumn) e.widget); |
|
810 } |
|
811 } |
|
812 |
|
813 public CheckboxTableViewer getTableViewer() |
|
814 { |
|
815 return this.tableViewer; |
|
816 } |
|
817 |
|
818 protected void createDefaultActions() |
|
819 { |
|
820 selectAllAction = new Action("SelectAll") { //$NON-NLS-1$ |
|
821 public void run() { |
|
822 action("selectAll"); //$NON-NLS-1$ |
|
823 } |
|
824 }; |
|
825 selectAllAction.setEnabled(true); |
|
826 |
|
827 copyAction = new Action("Copy") { //$NON-NLS-1$ |
|
828 public void run() { |
|
829 action("copy"); //$NON-NLS-1$ |
|
830 } |
|
831 }; |
|
832 copyAction.setEnabled(false); |
|
833 |
|
834 copyTableAction = new Action("CopyTable") { //$NON-NLS-1$ |
|
835 public void run() { |
|
836 action("copyTable"); //$NON-NLS-1$ |
|
837 } |
|
838 }; |
|
839 copyTableAction.setEnabled(true); |
|
840 copyTableAction.setId("PICopyTable"); //$NON-NLS-1$ |
|
841 copyTableAction.setText(Messages.getString("MemThreadTable.copyTable")); //$NON-NLS-1$ |
|
842 |
|
843 saveTableAction = new Action("SaveTable") { //$NON-NLS-1$ |
|
844 public void run() { |
|
845 action("saveTable"); //$NON-NLS-1$ |
|
846 } |
|
847 }; |
|
848 saveTableAction.setEnabled(true); |
|
849 saveTableAction.setId("PISaveTable"); //$NON-NLS-1$ |
|
850 saveTableAction.setText(Messages.getString("MemThreadTable.SaveTable")); //$NON-NLS-1$ |
|
851 } |
|
852 } |