|
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 "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 |
|
19 |
|
20 package com.nokia.s60tools.memspy.ui.wizards; |
|
21 import java.io.File; |
|
22 import java.lang.reflect.InvocationTargetException; |
|
23 import java.text.SimpleDateFormat; |
|
24 import java.util.ArrayList; |
|
25 import java.util.Date; |
|
26 |
|
27 import org.eclipse.core.runtime.IProgressMonitor; |
|
28 import org.eclipse.core.runtime.IStatus; |
|
29 import org.eclipse.core.runtime.Status; |
|
30 import org.eclipse.jface.dialogs.ErrorDialog; |
|
31 import org.eclipse.jface.dialogs.MessageDialog; |
|
32 import org.eclipse.jface.operation.IRunnableWithProgress; |
|
33 import org.eclipse.swt.SWT; |
|
34 import org.eclipse.swt.events.SelectionEvent; |
|
35 import org.eclipse.swt.events.SelectionListener; |
|
36 import org.eclipse.swt.layout.GridData; |
|
37 import org.eclipse.swt.layout.GridLayout; |
|
38 import org.eclipse.swt.widgets.Button; |
|
39 import org.eclipse.swt.widgets.Combo; |
|
40 import org.eclipse.swt.widgets.Composite; |
|
41 import org.eclipse.swt.widgets.DirectoryDialog; |
|
42 import org.eclipse.swt.widgets.Display; |
|
43 import org.eclipse.swt.widgets.FileDialog; |
|
44 import org.eclipse.swt.widgets.Group; |
|
45 import org.eclipse.swt.widgets.Label; |
|
46 import org.eclipse.swt.widgets.Shell; |
|
47 import org.eclipse.swt.widgets.Table; |
|
48 import org.eclipse.swt.widgets.TableColumn; |
|
49 import org.eclipse.swt.widgets.TableItem; |
|
50 import org.eclipse.ui.PlatformUI; |
|
51 |
|
52 import com.nokia.s60tools.memspy.containers.SWMTLogInfo; |
|
53 import com.nokia.s60tools.memspy.containers.SWMTLogInfo.SWMTLogType; |
|
54 import com.nokia.s60tools.memspy.interfaces.IMemSpyTraceListener; |
|
55 import com.nokia.s60tools.memspy.model.MemSpyFileOperations; |
|
56 import com.nokia.s60tools.memspy.model.MemSpyLogParserEngine; |
|
57 import com.nokia.s60tools.memspy.model.TraceCoreEngine; |
|
58 import com.nokia.s60tools.memspy.model.UserEnteredData; |
|
59 import com.nokia.s60tools.memspy.model.UserEnteredData.ValueTypes; |
|
60 import com.nokia.s60tools.memspy.plugin.MemSpyPlugin; |
|
61 import com.nokia.s60tools.memspy.preferences.MemSpyPreferences; |
|
62 import com.nokia.s60tools.memspy.resources.HelpContextIDs; |
|
63 import com.nokia.s60tools.memspy.ui.UiUtils; |
|
64 import com.nokia.s60tools.ui.preferences.PreferenceUtils; |
|
65 import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage; |
|
66 import com.nokia.s60tools.util.debug.DbgUtility; |
|
67 |
|
68 /** |
|
69 * SWMT-log import page is used for importing SWMT-logs from file system or from device. |
|
70 */ |
|
71 |
|
72 public class SWMTLogPage extends S60ToolsWizardPage implements SelectionListener, IMemSpyTraceListener, SWMTCategorySelectionMediator{ |
|
73 |
|
74 /** |
|
75 * Selection index for import from device via TraceViewer radio button |
|
76 */ |
|
77 private static final int DEVICE_RADIO_BUTTON_SELECTION_INDEX = 2; |
|
78 |
|
79 // Array list of logs that are imported |
|
80 // from files: |
|
81 private ArrayList<SWMTLogInfo> fileLogList; |
|
82 // from device: |
|
83 private ArrayList<SWMTLogInfo> deviceLogList; |
|
84 |
|
85 // SWMT-log that is currently received |
|
86 SWMTLogInfo receivedLog; |
|
87 |
|
88 // TraceCore engine |
|
89 private TraceCoreEngine traceEngine; |
|
90 |
|
91 // Cycle Number for SMWT-log file name |
|
92 private int cycleNumber; |
|
93 |
|
94 // Error message |
|
95 String errorMessage; |
|
96 |
|
97 // boolean value stating that error has been occurred and logs cannot be requested before removing |
|
98 // all items and restarting from cycle 1. |
|
99 boolean missedLogs; |
|
100 |
|
101 //UI-components: |
|
102 private Group radioButtonGroup; |
|
103 private Button fileRadioButton; |
|
104 private Button deviceRadioButton; |
|
105 |
|
106 // Components for importing file from device |
|
107 private Table fileLogsTable; |
|
108 private Composite fileSelectionButtonComposite; |
|
109 private Button addFileButton; |
|
110 private Button addDirectoryButton; |
|
111 private Button removeOneButton; |
|
112 private Button removeAllButton; |
|
113 |
|
114 private Group fileSelectionGroup; |
|
115 private Group deviceGroup; |
|
116 |
|
117 private GridData fileSelectionGridData; |
|
118 private GridData deviceGridData; |
|
119 |
|
120 |
|
121 // components for importing log from device |
|
122 private Table deviceLogsTable; |
|
123 private Composite loggingComposite; |
|
124 private Button connectionSettingsButton; |
|
125 private Button getLogNowButton; |
|
126 private Button removeReceivedLogsButton; |
|
127 private Label connectionNameInUseLabel; |
|
128 |
|
129 // Timer related components |
|
130 private Label intervalLabel; |
|
131 private Label secondLabel; |
|
132 private Button startTimerButton; |
|
133 private Combo timerCombo; |
|
134 |
|
135 /** |
|
136 * UI composite for SWMT Category group |
|
137 */ |
|
138 private SWMTCategoryGroupComposite categoryGroupComposite; |
|
139 |
|
140 // boolean variable, which is set to true if some MemSpy operation is running. |
|
141 boolean memSpyOperationRunning; |
|
142 boolean memSpyStopping; |
|
143 boolean memSpyTimerRunning; |
|
144 |
|
145 // MemSpy operation processes: |
|
146 // receive SWMT-log manually |
|
147 IRunnableWithProgress receiveSWMTLogProcess; |
|
148 |
|
149 private final static String GET_LOG_FROM_RADIO_BUTTON = "Get SWMT Log"; |
|
150 private final static String GET_FROM_FROM_FILE_RADIO_BUTTON = "From File System"; |
|
151 private final static String GET_LOG_FROM_DEVICE_RADIO_BUTTON = "From Device via TraceViewer"; |
|
152 private final static String LOG_FILES = "Log files:"; |
|
153 private final static String LOG_TYPE = "Type"; |
|
154 private final static String ADD_FILE = "Add File"; |
|
155 private final static String ADD_DIRECTORY = "Add Directory"; |
|
156 private final static String REMOVE_ONE = "Remove"; |
|
157 private final static String REMOVE_ALL = "Remove All"; |
|
158 private final static String ADD_FILE_TEXT = "Define Location of SWMT Log file:"; |
|
159 private final static String ADD_DIRECTORY_TEXT = "Define Location of directory that contains SWMT Logs:"; |
|
160 private final static String LOG_TYPE_FILE = "File"; |
|
161 private final static String LOG_TYPE_DIRECTORY = "Directory"; |
|
162 |
|
163 private final static String CONNECTION_SETTINGS_BUTTON = "Connection Settings..."; |
|
164 private final static String CURRENTLY_USING_TEXT = "Currently using:"; |
|
165 private final static String GET_LOG_NOW_BUTTON = "Get SWMT Log Now"; |
|
166 private final static String LOGS = "Logs"; |
|
167 private final static String RECEIVED = "Received"; |
|
168 |
|
169 private final static String RECEIVING_SWMT_LOG = "Receiving SWMT Log: "; |
|
170 private final static String WAITING_FOR_TIMER = "Waiting for timer to expire: "; |
|
171 private final static String STOPPING_TIMER = "Stopping timer: "; |
|
172 |
|
173 private final static String TEXT_GET_LOG_WITH_TIMER = "Get Log with Timer"; |
|
174 private final static String TEXT_INTERVAL = "Interval:"; |
|
175 private final static String START_TIMER = "Start Timer"; |
|
176 private final static String TEXT_SECOND = "Seconds"; |
|
177 |
|
178 private final static String ERROR_INTERVAL = "Time interval needs to be integer and more than zero."; |
|
179 |
|
180 /** |
|
181 * Constructor. |
|
182 * @param pageName name of the page |
|
183 * @param traceEngine TraceCore engine that is used when requesting data from TC |
|
184 */ |
|
185 protected SWMTLogPage(String pageName, TraceCoreEngine traceEngine) { |
|
186 super(pageName); |
|
187 setTitle("System Wide Memory Tracking Wizard"); |
|
188 setDescription("Define Source For SWMT logs that are imported. Logs can be imported from already existing files or from device via TraceViewer."); |
|
189 this.fileLogList = new ArrayList<SWMTLogInfo>(); |
|
190 this.deviceLogList = new ArrayList<SWMTLogInfo>(); |
|
191 this.traceEngine = traceEngine; |
|
192 this.createMemSpyProcesses(); |
|
193 |
|
194 this.memSpyTimerRunning = false; |
|
195 this.memSpyOperationRunning = false; |
|
196 this.memSpyStopping = false; |
|
197 this.cycleNumber = 0; |
|
198 |
|
199 this.missedLogs = false; |
|
200 } |
|
201 |
|
202 @Override |
|
203 public void recalculateButtonStates() { |
|
204 // no implementation needed |
|
205 } |
|
206 |
|
207 @Override |
|
208 public void setInitialFocus() { |
|
209 timerCombo.setFocus(); |
|
210 } |
|
211 |
|
212 /* |
|
213 * (non-Javadoc) |
|
214 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent) |
|
215 */ |
|
216 public void widgetDefaultSelected(SelectionEvent e) { |
|
217 // Not needed in this case |
|
218 } |
|
219 |
|
220 /* |
|
221 * (non-Javadoc) |
|
222 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
|
223 */ |
|
224 public void widgetSelected(SelectionEvent e) { |
|
225 // Update controls after radio buttons state changes to false |
|
226 if ( ( e.widget == deviceRadioButton && deviceRadioButton.getSelection() == false ) || |
|
227 ( e.widget == fileRadioButton && fileRadioButton.getSelection() == false ) ){ |
|
228 //When selection is changed, we clear the previous results. |
|
229 removeReceivedLogs(); |
|
230 this.hideAndRevealItems(); |
|
231 } |
|
232 |
|
233 // open file dialog |
|
234 else if (e.widget == addFileButton) { |
|
235 // open file dialog for selecting a crash file |
|
236 FileDialog dialog = new FileDialog(this.getShell(), SWT.MULTI); |
|
237 dialog.setText(ADD_FILE_TEXT); |
|
238 String[] filterExt = { "*.txt", "*.log", "*.*" }; |
|
239 dialog.setFilterExtensions(filterExt); |
|
240 |
|
241 if (dialog.open() != null ){ |
|
242 String[] files = dialog.getFileNames(); |
|
243 String directory = dialog.getFilterPath(); |
|
244 directory = MemSpyFileOperations.addSlashToEnd( directory ); |
|
245 |
|
246 boolean noLogFound = false; |
|
247 |
|
248 for( String item : files ){ |
|
249 |
|
250 // confirm that file is smwt log |
|
251 if( MemSpyLogParserEngine.isFileSWMTLog( new File(directory + item)) ){ |
|
252 this.addFileLog( directory + item ); |
|
253 } |
|
254 |
|
255 else{ |
|
256 noLogFound = true; |
|
257 } |
|
258 } |
|
259 |
|
260 // if some of the selected files is not swmt-file show error message. |
|
261 if( noLogFound ){ |
|
262 Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "Some of the selected files is not SWMT-log file.", null); |
|
263 // Display the dialog |
|
264 ErrorDialog.openError(Display.getCurrent().getActiveShell(),ERROR_MEMSPY, null, status); |
|
265 } |
|
266 } |
|
267 |
|
268 |
|
269 } |
|
270 |
|
271 // open directory dialog |
|
272 else if (e.widget == addDirectoryButton) { |
|
273 // open file dialog for selecting a crash file |
|
274 DirectoryDialog dialog = new DirectoryDialog(this.getShell()); |
|
275 dialog.setText(ADD_DIRECTORY_TEXT); |
|
276 String result = dialog.open(); |
|
277 if (result != null ){ |
|
278 |
|
279 File[] allFiles = MemSpyFileOperations.getFilesFromDirectory( new File( result ) ); |
|
280 |
|
281 int swmtFileCount = 0; |
|
282 |
|
283 for ( File item : allFiles ){ |
|
284 if( MemSpyLogParserEngine.isFileSWMTLog( item ) ){ |
|
285 swmtFileCount++; |
|
286 this.addFileLog( item.toString() ); |
|
287 } |
|
288 } |
|
289 // if no SWMT-log files were found from selected directory, show error message. |
|
290 if(swmtFileCount == 0){ |
|
291 Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, "No SWMT-logs were found from selected directory.", null); |
|
292 // Display the dialog |
|
293 ErrorDialog.openError(Display.getCurrent().getActiveShell(),ERROR_MEMSPY, null, status); |
|
294 |
|
295 |
|
296 } |
|
297 } |
|
298 } |
|
299 |
|
300 // remove selected log file |
|
301 else if (e.widget == removeOneButton ){ |
|
302 if( fileLogsTable.getSelectionCount() == 1 ){ |
|
303 fileLogList.remove( fileLogsTable.getSelectionIndex() ); |
|
304 this.refreshFileLogTable(); |
|
305 } |
|
306 } |
|
307 |
|
308 // remove all log files |
|
309 else if (e.widget == removeAllButton ){ |
|
310 fileLogList.clear(); |
|
311 this.refreshFileLogTable(); |
|
312 } |
|
313 |
|
314 // open connection settings |
|
315 else if ( e.widget == connectionSettingsButton ){ |
|
316 // Open connection Trace viewers connection settings. |
|
317 Shell shell = MemSpyPlugin.getCurrentlyActiveWbWindowShell(); |
|
318 PreferenceUtils.openPreferencePage(MemSpyPlugin.getTraceProvider().getTraceSourcePreferencePageId(), shell); |
|
319 |
|
320 // Disconnect trace source so that new settings are used when sending next request |
|
321 MemSpyPlugin.getTraceProvider().disconnectTraceSource(); |
|
322 |
|
323 // get wizard pointer and cast it to MemSpyWizard |
|
324 MemSpyWizard wizard = (MemSpyWizard) this.getWizard(); |
|
325 // update new settings to each wizard page. |
|
326 wizard.updateConnectionSettings(); |
|
327 } |
|
328 |
|
329 // get log now from TC |
|
330 else if (e.widget == getLogNowButton ){ |
|
331 this.getLogNowPressed(); |
|
332 } |
|
333 |
|
334 // Remove all log received from device-button |
|
335 else if( e.widget == removeReceivedLogsButton ){ |
|
336 this.removeReceivedLogs(); |
|
337 } |
|
338 |
|
339 // SWMT timer started |
|
340 else if( e.widget == startTimerButton ){ |
|
341 this.getLogWithTimerPressed(); |
|
342 } |
|
343 |
|
344 |
|
345 // if file logs table selection changes or button is pressed, enable and disable buttons |
|
346 if( e.widget == this.fileLogsTable || |
|
347 e.widget == this.removeAllButton || |
|
348 e.widget == this.removeOneButton || |
|
349 e.widget == this.addFileButton || |
|
350 e.widget == this.addDirectoryButton ){ |
|
351 this.enableAndDisableFileButtons(); |
|
352 } |
|
353 getWizard().getContainer().updateButtons(); |
|
354 |
|
355 } |
|
356 |
|
357 /** |
|
358 * Checks if wizard can be finished or not. |
|
359 * @return boolean value if wizard can finish |
|
360 */ |
|
361 public boolean canFinish(){ |
|
362 |
|
363 // if traceEngines taskList is not empty, return false |
|
364 if( traceEngine.getFirstTask() != null ){ |
|
365 return false; |
|
366 } |
|
367 |
|
368 // if file or device log lists are not empty(depending on radiobutton selection) return true |
|
369 if( fileRadioButton.getSelection() ){ |
|
370 if( fileLogList.size() > 0 ){ |
|
371 return true; |
|
372 } |
|
373 } |
|
374 else{ |
|
375 if( deviceLogList.size() > 0 ){ |
|
376 return true; |
|
377 } |
|
378 } |
|
379 return false; |
|
380 } |
|
381 |
|
382 |
|
383 /** |
|
384 * Hides and reveals controls according to radio button states. |
|
385 */ |
|
386 private void hideAndRevealItems() { |
|
387 |
|
388 boolean fileSelected = true; |
|
389 |
|
390 if( fileRadioButton.getSelection() == false ){ |
|
391 fileSelected = false; |
|
392 } |
|
393 |
|
394 // exclude/include needed controls |
|
395 fileSelectionGridData.exclude = !fileSelected; |
|
396 deviceGridData.exclude = fileSelected; |
|
397 |
|
398 if( !fileSelected ){ |
|
399 // Since excluded groups size and location are not updated, do it now |
|
400 deviceGroup.setSize( fileSelectionGroup.getSize() ); |
|
401 deviceGroup.setLocation(fileSelectionGroup.getLocation()); |
|
402 } |
|
403 else{ |
|
404 // Since excluded groups size and location are not updated, do it now |
|
405 fileSelectionGroup.setSize( deviceGroup.getSize() ); |
|
406 fileSelectionGroup.setLocation(deviceGroup.getLocation()); |
|
407 |
|
408 } |
|
409 // Hide/show needed controls |
|
410 fileSelectionGroup.setVisible(fileSelected); |
|
411 deviceGroup.setVisible(!fileSelected); |
|
412 |
|
413 } |
|
414 |
|
415 /** |
|
416 * Adds a log file. |
|
417 * @param location of log file |
|
418 */ |
|
419 private void addFileLog( String location ){ |
|
420 |
|
421 // create SWMTLogInfo object for log file. |
|
422 SWMTLogInfo info = new SWMTLogInfo(); |
|
423 info.setType( SWMTLogType.FILE ); |
|
424 info.setPath( location ); |
|
425 fileLogList.add(info); |
|
426 |
|
427 // get files name |
|
428 String fileName = location.substring( location.lastIndexOf("\\") + 1 ); |
|
429 |
|
430 // add name into table |
|
431 TableItem item = new TableItem( fileLogsTable, SWT.NONE, fileLogsTable.getItemCount() ); |
|
432 item.setText( new String[]{ fileName, LOG_TYPE_FILE }); |
|
433 |
|
434 } |
|
435 |
|
436 /** |
|
437 * Updates file log table so that it contains same data that file log list. |
|
438 */ |
|
439 private void refreshFileLogTable(){ |
|
440 //Remove all items |
|
441 fileLogsTable.removeAll(); |
|
442 |
|
443 for( int i = 0; i < fileLogList.size(); i++ ){ |
|
444 TableItem newItem = new TableItem(fileLogsTable, SWT.NONE,i); |
|
445 |
|
446 // get item |
|
447 SWMTLogInfo log = fileLogList.get(i); |
|
448 String fileName = log.getPath(); |
|
449 String fileType = LOG_TYPE_DIRECTORY; |
|
450 |
|
451 // Remove path if type is file |
|
452 if( log.getType() == SWMTLogType.FILE ){ |
|
453 fileName = fileName.substring( fileName.lastIndexOf("\\") + 1 ); |
|
454 fileType = LOG_TYPE_FILE; |
|
455 } |
|
456 |
|
457 newItem.setText( new String[]{ fileName, fileType } ); |
|
458 } |
|
459 |
|
460 } |
|
461 |
|
462 /** |
|
463 * Removed received logs. |
|
464 */ |
|
465 private void removeReceivedLogs(){ |
|
466 // Delete all items in deviceLogList and deviceLogsTable |
|
467 deviceLogList.clear(); |
|
468 deviceLogsTable.removeAll(); |
|
469 |
|
470 // Delete all temp files |
|
471 MemSpyFileOperations.deleteTempMemSpyFiles(); |
|
472 |
|
473 // set cycle number to zero |
|
474 cycleNumber = 0; |
|
475 |
|
476 // reset missed logs value |
|
477 missedLogs = false; |
|
478 |
|
479 // enable and disable buttons |
|
480 this.enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); |
|
481 } |
|
482 |
|
483 /** |
|
484 * Gets list of log files that are in currently selected table. |
|
485 * @return list of log files that are in currently selected table |
|
486 */ |
|
487 public ArrayList<SWMTLogInfo> getLogList(){ |
|
488 if( fileRadioButton.getSelection() ){ |
|
489 return fileLogList; |
|
490 } |
|
491 else{ |
|
492 return deviceLogList; |
|
493 } |
|
494 } |
|
495 |
|
496 /** |
|
497 * Updates connection text to match used settings. |
|
498 */ |
|
499 public void updateConnectionText(){ |
|
500 // Updating connection name. |
|
501 String displayName = MemSpyPlugin.getTraceProvider().getDisplayNameForCurrentConnection(); |
|
502 connectionNameInUseLabel.setText(displayName); |
|
503 loggingComposite.layout(); |
|
504 } |
|
505 |
|
506 /** |
|
507 * Loads previous values into UI components. |
|
508 */ |
|
509 private void loadUserEnteredData(){ |
|
510 |
|
511 // if last value is not found, set selection file. |
|
512 UserEnteredData data = new UserEnteredData(); |
|
513 int lastUsedSource = data.getPreviousRadioButtonSelection( ValueTypes.SWMT ); |
|
514 |
|
515 // Restoring previous state of radio buttons only if device import is also possible and was previously selected |
|
516 if(MemSpyPlugin.isTraceProviderAvailable() && lastUsedSource == DEVICE_RADIO_BUTTON_SELECTION_INDEX){ |
|
517 deviceRadioButton.setSelection( true ); |
|
518 fileRadioButton.setSelection( false ); |
|
519 } |
|
520 else{ |
|
521 deviceRadioButton.setSelection( false ); |
|
522 fileRadioButton.setSelection( true ); |
|
523 } |
|
524 |
|
525 // Restore previous values to file combobox |
|
526 String[] lastUsedFiles = data.getPreviousValues( ValueTypes.SWMT ); |
|
527 if (lastUsedFiles != null) { |
|
528 timerCombo.setItems(lastUsedFiles); |
|
529 timerCombo.select(0); |
|
530 } |
|
531 |
|
532 } |
|
533 |
|
534 /** |
|
535 * Saves user entered values and selections from UI components so that they can be restored later if needed. |
|
536 */ |
|
537 public void saveUserEnteredData(){ |
|
538 UserEnteredData data = new UserEnteredData(); |
|
539 |
|
540 // Save Action radio-buttons state |
|
541 if( deviceRadioButton.getSelection() ){ |
|
542 data.saveRadioButtonSelection(ValueTypes.SWMT, 2); |
|
543 } |
|
544 else { |
|
545 data.saveRadioButtonSelection(ValueTypes.SWMT, 1); |
|
546 } |
|
547 data.saveValue(ValueTypes.SWMT, timerCombo.getText()); |
|
548 } |
|
549 |
|
550 /* |
|
551 * (non-Javadoc) |
|
552 * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#deviceError(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherErrorType) |
|
553 */ |
|
554 public void deviceError( final LauncherErrorType error ){ |
|
555 |
|
556 Date date = new Date (System.currentTimeMillis()); |
|
557 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.deviceError: '" + error.name() +"' time:'" +date.toString() + "'."); //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$ |
|
558 |
|
559 // Set MemSpy's state correct |
|
560 memSpyOperationRunning = false; |
|
561 memSpyTimerRunning = false; |
|
562 |
|
563 // change Cancel text from wizard back to "Cancel" |
|
564 this.setCancelText( "Cancel" ); |
|
565 |
|
566 // Getting user visible error message |
|
567 errorMessage = UiUtils.getErrorMessageForLauncherError(error, traceEngine.getAdditionalErrorInformation(), traceEngine.getProgressStatus()); //$NON-NLS-1$ |
|
568 |
|
569 // Handling SWMT-specific logic related to the error |
|
570 switch (error){ |
|
571 case DUMPED_TRACES:{ |
|
572 this.receivedLog = null; |
|
573 break; |
|
574 } |
|
575 case CATEGORIES_NOT_SUPPORTED:{ |
|
576 disableSWMTCategoryFeature(); |
|
577 break; |
|
578 } |
|
579 } |
|
580 |
|
581 // Add reset info into error message. |
|
582 if(error != LauncherErrorType.CATEGORIES_NOT_SUPPORTED){ |
|
583 errorMessage = errorMessage + ERROR_SWMT_NEEDS_RESET; |
|
584 } |
|
585 |
|
586 // Set missedLogs value to true so that logs cannot be requested anymore because of missed logs. |
|
587 missedLogs = true; |
|
588 |
|
589 // Advising user to install launcher component to the device |
|
590 UiUtils.showErrorDialogToUser(error, errorMessage, traceEngine.getProgressStatus()); |
|
591 } |
|
592 |
|
593 /** |
|
594 * Disables SWMT category feature for the rest of the session in case is was not supported by the device. |
|
595 */ |
|
596 private void disableSWMTCategoryFeature() { |
|
597 Runnable disableRunnable = new Runnable(){ |
|
598 |
|
599 public void run() { |
|
600 try { |
|
601 MemSpyPlugin.getDefault().setSWMTCategorySettingFeatureEnabled(false); |
|
602 MemSpyPreferences.setProfileTrackedCategoriesSelected(true); |
|
603 categoryGroupComposite.disableCustomCategorySelection(); |
|
604 } catch (Exception e) { |
|
605 e.printStackTrace(); |
|
606 } |
|
607 } |
|
608 |
|
609 }; |
|
610 |
|
611 Display.getDefault().asyncExec(disableRunnable); |
|
612 } |
|
613 |
|
614 /* |
|
615 * (non-Javadoc) |
|
616 * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction) |
|
617 */ |
|
618 public void operationFinished(LauncherAction action) { |
|
619 |
|
620 // reset missed logs. |
|
621 missedLogs = false; |
|
622 |
|
623 if( action == LauncherAction.SWMT_UPDATE ){ |
|
624 cycleNumber++; |
|
625 this.updateReceivedSWMTLog( false ); |
|
626 } |
|
627 |
|
628 } |
|
629 |
|
630 /** |
|
631 * Does actions that are made when SWMT log is received. |
|
632 */ |
|
633 private void updateReceivedSWMTLog( final boolean timerRunning ){ |
|
634 |
|
635 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.updateReceivedSWMTLog/timerRunning=" + timerRunning ); //$NON-NLS-1$ |
|
636 |
|
637 Runnable updateUiRunnable = new Runnable(){ |
|
638 public void run(){ |
|
639 |
|
640 // get date formatter |
|
641 SimpleDateFormat formatter = new SimpleDateFormat ( MemSpyFileOperations.DATEFORMAT ); |
|
642 String date = formatter.format(receivedLog.getDate() ); |
|
643 // get files name |
|
644 String path = receivedLog.getPath().substring( receivedLog.getPath().lastIndexOf("\\") + 1 ); |
|
645 |
|
646 // add log into table |
|
647 TableItem item = new TableItem( deviceLogsTable, SWT.NONE, deviceLogsTable.getItemCount() ); |
|
648 item.setText( new String[]{ path, date }); |
|
649 |
|
650 // add receivedlog-object into deviceLogsList-Arraylist |
|
651 deviceLogList.add( receivedLog ); |
|
652 |
|
653 if( timerRunning ){ |
|
654 // show progress bar |
|
655 memSpyTimerRunning = true; |
|
656 memSpyOperationRunning = false; |
|
657 |
|
658 } |
|
659 else{ |
|
660 |
|
661 // change Cancel text from wizard back to "Cancel" |
|
662 setCancelText("Cancel"); |
|
663 |
|
664 // Set state correct |
|
665 memSpyOperationRunning = false; |
|
666 |
|
667 } |
|
668 } |
|
669 |
|
670 }; |
|
671 Display.getDefault().asyncExec(updateUiRunnable); |
|
672 } |
|
673 |
|
674 /** |
|
675 * Enables and disables device buttons and SWMT category group UI according to current situation |
|
676 */ |
|
677 private void enableAndDisableDeviceButtonsAndSWMTCategoryGroup(){ |
|
678 |
|
679 // Refreshes enable/disable status for SWMT category group UI |
|
680 categoryGroupComposite.refresh(); |
|
681 |
|
682 // if log table is not empty, enable remove all button. |
|
683 if( this.deviceLogsTable.getItemCount() > 0 ){ |
|
684 this.connectionSettingsButton.setEnabled(false); |
|
685 this.removeReceivedLogsButton.setEnabled(true); |
|
686 this.categoryGroupComposite.setButtonsEnabled(false); |
|
687 this.categoryGroupComposite.setEnabled(false); |
|
688 if( this.missedLogs ){ |
|
689 this.getLogNowButton.setEnabled(false); |
|
690 this.startTimerButton.setEnabled(false); |
|
691 } |
|
692 } |
|
693 else{ |
|
694 this.connectionSettingsButton.setEnabled(true); |
|
695 this.removeReceivedLogsButton.setEnabled(false); |
|
696 this.categoryGroupComposite.setButtonsEnabled(true); |
|
697 this.categoryGroupComposite.setEnabled(true); |
|
698 if( !this.missedLogs ){ |
|
699 this.getLogNowButton.setEnabled(true); |
|
700 this.startTimerButton.setEnabled(true); |
|
701 } |
|
702 } |
|
703 } |
|
704 |
|
705 /** |
|
706 * Enables and disables file buttons according to current situation. |
|
707 */ |
|
708 private void enableAndDisableFileButtons(){ |
|
709 |
|
710 // If one log is selected, enable Remove button, otherwise disable it |
|
711 if( this.fileLogsTable.getSelectionCount() == 1 ){ |
|
712 this.removeOneButton.setEnabled(true); |
|
713 } |
|
714 else{ |
|
715 this.removeOneButton.setEnabled(false); |
|
716 } |
|
717 |
|
718 // if log table is not empty, enable remove all button. |
|
719 if( this.fileLogsTable.getItemCount() > 0 ){ |
|
720 this.removeAllButton.setEnabled(true); |
|
721 } |
|
722 else{ |
|
723 this.removeAllButton.setEnabled(false); |
|
724 } |
|
725 |
|
726 } |
|
727 |
|
728 /* |
|
729 * (non-Javadoc) |
|
730 * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage() |
|
731 */ |
|
732 public boolean canFlipToNextPage() { |
|
733 return false; |
|
734 } |
|
735 |
|
736 /* |
|
737 * (non-Javadoc) |
|
738 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) |
|
739 */ |
|
740 public void createControl(Composite parent) { |
|
741 |
|
742 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": createControl()"); //$NON-NLS-1$ |
|
743 |
|
744 // Radio button group |
|
745 Composite composite = new Composite(parent, SWT.NULL); |
|
746 |
|
747 // create the desired layout for this wizard page |
|
748 GridLayout gl = new GridLayout(); |
|
749 gl.numColumns = 1; |
|
750 composite.setLayout(gl); |
|
751 |
|
752 //Create group where to select if import from File System / From Device |
|
753 createRadioButtonGroup(composite); |
|
754 |
|
755 //Create group where import logs from File |
|
756 createImportFromFileGroup(composite); |
|
757 |
|
758 //Create group where import logs from Device |
|
759 createImportFromDeviceGroup(composite); |
|
760 |
|
761 |
|
762 // load saved user entered data. |
|
763 this.loadUserEnteredData(); |
|
764 |
|
765 // update buttons and texts on screen. |
|
766 this.updateConnectionText(); |
|
767 |
|
768 // Enable/disable buttons |
|
769 this.enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); //will call also #enableOrDisableHeapFilterText(); |
|
770 this.enableAndDisableFileButtons(); |
|
771 |
|
772 this.hideAndRevealItems(); |
|
773 |
|
774 // Setting context-sensitive help ID |
|
775 PlatformUI.getWorkbench().getHelpSystem().setHelp( composite, HelpContextIDs.MEMSPY_IMPORT_SWMT); |
|
776 |
|
777 setInitialFocus(); |
|
778 setControl(composite); |
|
779 } |
|
780 |
|
781 private void createImportFromDeviceGroup(Composite parent) { |
|
782 // Device group |
|
783 |
|
784 deviceGroup = new Group(parent, SWT.NONE); |
|
785 GridLayout deviceGridLayout = new GridLayout(); |
|
786 deviceGridLayout.numColumns = 2; |
|
787 |
|
788 deviceGridData = new GridData(GridData.FILL_BOTH); |
|
789 deviceGroup.setLayoutData(deviceGridData); |
|
790 deviceGroup.setLayout(deviceGridLayout); |
|
791 deviceGroup.setText(GET_LOG_FROM_DEVICE_RADIO_BUTTON); |
|
792 |
|
793 |
|
794 |
|
795 // Logs from device table |
|
796 |
|
797 deviceLogsTable = new Table(deviceGroup, SWT.BORDER); |
|
798 GridData tableGridData = new GridData(GridData.FILL_BOTH); |
|
799 deviceLogsTable.setLayoutData(tableGridData); |
|
800 |
|
801 TableColumn logsColumn = new TableColumn(deviceLogsTable, SWT.LEFT); |
|
802 logsColumn.setText(LOGS); |
|
803 logsColumn.setWidth(300); |
|
804 |
|
805 TableColumn receivedColumn = new TableColumn(deviceLogsTable, SWT.LEFT); |
|
806 receivedColumn.setText(RECEIVED); |
|
807 receivedColumn.setWidth(110); |
|
808 |
|
809 GridData deviceLogsTableGridData = new GridData(GridData.FILL_BOTH); |
|
810 deviceLogsTable.setLayoutData(deviceLogsTableGridData); |
|
811 deviceLogsTable.setHeaderVisible(true); |
|
812 deviceLogsTable.addSelectionListener(this); |
|
813 |
|
814 |
|
815 // |
|
816 //Create logging composite, contains Get log now, Get log with timer and remove logs functions |
|
817 // |
|
818 createLoggingComposite(deviceGroup); |
|
819 |
|
820 // |
|
821 //Bottom composite where settings and categories are located |
|
822 // |
|
823 Composite bottomComposite = new Composite(deviceGroup,SWT.NONE); |
|
824 GridLayout pgl = new GridLayout(2, false); |
|
825 pgl.marginHeight = 0; |
|
826 pgl.marginWidth = 0; |
|
827 GridData pgd = new GridData(GridData.VERTICAL_ALIGN_END | GridData.FILL_HORIZONTAL); |
|
828 bottomComposite.setLayout(pgl); |
|
829 bottomComposite.setLayoutData(pgd); |
|
830 |
|
831 // |
|
832 //Create Connection settings group |
|
833 // |
|
834 createConnectionSettingsGroup(bottomComposite); |
|
835 |
|
836 // |
|
837 // Create and add SWMT category setting group |
|
838 // |
|
839 categoryGroupComposite = new SWMTCategoryGroupComposite(bottomComposite, false, this, MemSpyPlugin.getDefault().isSWMTCategorySettingFeatureEnabled()); |
|
840 |
|
841 } |
|
842 |
|
843 private void createLoggingComposite(Composite parent) { |
|
844 |
|
845 loggingComposite = new Composite(parent, SWT.NONE); |
|
846 GridLayout deviceButtonLayout = new GridLayout(); |
|
847 GridData deviceButtonGridData = new GridData(SWT.FILL, SWT.FILL, true, true);//GridData.FILL_BOTH | GridData.VERTICAL_ALIGN_CENTER |
|
848 deviceButtonLayout.numColumns = 1; |
|
849 loggingComposite.setLayoutData(deviceButtonGridData); |
|
850 loggingComposite.setLayout(deviceButtonLayout); |
|
851 |
|
852 // |
|
853 // Get Log now button |
|
854 // |
|
855 Composite getLogComposite = new Composite(loggingComposite, SWT.NONE); |
|
856 GridLayout getLogLayout = new GridLayout(); |
|
857 GridData getLogGD = new GridData(SWT.FILL, SWT.BEGINNING, true, false); |
|
858 getLogComposite.setLayoutData(getLogGD); |
|
859 getLogComposite.setLayout(getLogLayout); |
|
860 |
|
861 //Null label is added with no text to align get log now |
|
862 @SuppressWarnings("unused") |
|
863 Label nullLabel = new Label(getLogComposite,SWT.NULL); |
|
864 |
|
865 getLogNowButton = new Button(getLogComposite, SWT.PUSH); |
|
866 getLogNowButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL ));//| GridData.VERTICAL_ALIGN_BEGINNING |
|
867 getLogNowButton.setText(GET_LOG_NOW_BUTTON); |
|
868 getLogNowButton.addSelectionListener(this); |
|
869 |
|
870 // |
|
871 // Timer composite |
|
872 // |
|
873 Composite timerComposite = new Composite(loggingComposite, SWT.NONE); |
|
874 GridLayout timerLayout = new GridLayout(); |
|
875 timerLayout.marginWidth = 0; |
|
876 GridData timerGD = new GridData(SWT.FILL, SWT.CENTER, true, true); |
|
877 timerComposite.setLayoutData(timerGD); |
|
878 timerComposite.setLayout(timerLayout); |
|
879 |
|
880 createTimerComposite(timerComposite); |
|
881 |
|
882 // |
|
883 // Remove all files button |
|
884 // |
|
885 Composite removeComposite = new Composite(loggingComposite, SWT.NONE); |
|
886 GridLayout removeLayout = new GridLayout(); |
|
887 GridData removeGD = new GridData(SWT.FILL, SWT.BOTTOM, true, false); |
|
888 removeComposite.setLayoutData(removeGD); |
|
889 removeComposite.setLayout(removeLayout); |
|
890 |
|
891 removeReceivedLogsButton = new Button(removeComposite, SWT.PUSH); |
|
892 removeReceivedLogsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));//| GridData.VERTICAL_ALIGN_END |
|
893 removeReceivedLogsButton.setText(REMOVE_ALL); |
|
894 removeReceivedLogsButton.addSelectionListener(this); |
|
895 } |
|
896 |
|
897 private void createConnectionSettingsGroup(Composite parent) { |
|
898 Group connectionSettingsGroup = new Group(parent, SWT.NONE); |
|
899 connectionSettingsGroup.setText("Connection"); |
|
900 GridLayout connectionGroupLayout = new GridLayout(); |
|
901 connectionGroupLayout.numColumns = 1; |
|
902 connectionSettingsGroup.setLayout(connectionGroupLayout); |
|
903 GridData connectionGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
|
904 connectionSettingsGroup.setLayoutData(connectionGridData); |
|
905 |
|
906 |
|
907 connectionSettingsButton = new Button(connectionSettingsGroup, SWT.PUSH); |
|
908 connectionSettingsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
909 connectionSettingsButton.setText(CONNECTION_SETTINGS_BUTTON); |
|
910 connectionSettingsButton.addSelectionListener(this); |
|
911 |
|
912 // Connection settings labels |
|
913 Label connectionTextLabel = new Label(connectionSettingsGroup, SWT.LEFT); |
|
914 connectionTextLabel.setText(CURRENTLY_USING_TEXT); |
|
915 connectionTextLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); |
|
916 |
|
917 connectionNameInUseLabel = new Label(connectionSettingsGroup, SWT.LEFT); |
|
918 connectionNameInUseLabel.setLayoutData( new GridData(GridData.HORIZONTAL_ALIGN_CENTER) ); |
|
919 } |
|
920 |
|
921 private void createImportFromFileGroup(Composite parent) { |
|
922 // File selection group |
|
923 |
|
924 fileSelectionGroup = new Group(parent, SWT.NONE); |
|
925 GridLayout fileSelectionGridLayout = new GridLayout(); |
|
926 fileSelectionGridLayout.numColumns = 2; |
|
927 |
|
928 fileSelectionGridData = new GridData(GridData.FILL_BOTH); |
|
929 fileSelectionGroup.setLayoutData(fileSelectionGridData); |
|
930 fileSelectionGroup.setLayout(fileSelectionGridLayout); |
|
931 fileSelectionGroup.setText(GET_FROM_FROM_FILE_RADIO_BUTTON); |
|
932 |
|
933 // Logs from file table |
|
934 |
|
935 fileLogsTable = new Table(fileSelectionGroup, SWT.BORDER); |
|
936 TableColumn fileColumn = new TableColumn(fileLogsTable, SWT.LEFT); |
|
937 fileColumn.setText(LOG_FILES); |
|
938 fileColumn.setWidth(300); |
|
939 |
|
940 TableColumn nameColumn = new TableColumn(fileLogsTable, SWT.LEFT); |
|
941 nameColumn.setText(LOG_TYPE); |
|
942 nameColumn.setWidth(100); |
|
943 |
|
944 GridData fileLogsTableGridData = new GridData(GridData.FILL_BOTH); |
|
945 fileLogsTable.setLayoutData(fileLogsTableGridData); |
|
946 fileLogsTable.setHeaderVisible(true); |
|
947 fileLogsTable.addSelectionListener(this); |
|
948 |
|
949 // File Selection button composite. Contains file operation buttons |
|
950 |
|
951 fileSelectionButtonComposite = new Composite(fileSelectionGroup, SWT.NONE); |
|
952 GridLayout threadButtonLayout = new GridLayout(); |
|
953 GridData fileSelectionButtonGridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL); |
|
954 fileSelectionButtonComposite.setLayoutData(fileSelectionButtonGridData); |
|
955 fileSelectionButtonComposite.setLayout(threadButtonLayout); |
|
956 threadButtonLayout.numColumns = 1; |
|
957 |
|
958 // Add file button |
|
959 addFileButton = new Button(fileSelectionButtonComposite, SWT.PUSH); |
|
960 addFileButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
961 addFileButton.setText(ADD_FILE); |
|
962 addFileButton.addSelectionListener(this); |
|
963 |
|
964 // Add folder button |
|
965 addDirectoryButton = new Button(fileSelectionButtonComposite, SWT.PUSH); |
|
966 addDirectoryButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
967 addDirectoryButton.setText(ADD_DIRECTORY); |
|
968 addDirectoryButton.addSelectionListener(this); |
|
969 |
|
970 // Remove one file button |
|
971 removeOneButton = new Button(fileSelectionButtonComposite, SWT.PUSH); |
|
972 removeOneButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
973 removeOneButton.setText(REMOVE_ONE); |
|
974 removeOneButton.addSelectionListener(this); |
|
975 |
|
976 // Remove all files and folders button |
|
977 removeAllButton = new Button(fileSelectionButtonComposite, SWT.PUSH); |
|
978 removeAllButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
979 removeAllButton.setText(REMOVE_ALL); |
|
980 removeAllButton.addSelectionListener(this); |
|
981 } |
|
982 |
|
983 private void createRadioButtonGroup(Composite parent) { |
|
984 // Radio button group |
|
985 GridLayout radioButtonGroupGridLayout = new GridLayout(); |
|
986 radioButtonGroup = new Group(parent, SWT.NONE); |
|
987 radioButtonGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
|
988 radioButtonGroup.setText(GET_LOG_FROM_RADIO_BUTTON); |
|
989 radioButtonGroup.setLayout(radioButtonGroupGridLayout); |
|
990 GridData radioButtonGridData = new GridData(GridData.FILL_HORIZONTAL); |
|
991 radioButtonGridData.horizontalSpan = 2; |
|
992 |
|
993 // File radio button |
|
994 fileRadioButton = new Button(radioButtonGroup, SWT.RADIO); |
|
995 fileRadioButton.setText(GET_FROM_FROM_FILE_RADIO_BUTTON); |
|
996 fileRadioButton.setLayoutData(radioButtonGridData); |
|
997 fileRadioButton.addSelectionListener(this); |
|
998 fileRadioButton.setSelection(true); |
|
999 |
|
1000 // From Device via TraceViewer radio button |
|
1001 deviceRadioButton = new Button(radioButtonGroup, SWT.RADIO); |
|
1002 deviceRadioButton.setText(GET_LOG_FROM_DEVICE_RADIO_BUTTON); |
|
1003 deviceRadioButton.setLayoutData(radioButtonGridData); |
|
1004 deviceRadioButton.addSelectionListener(this); |
|
1005 deviceRadioButton.setSelection(false); |
|
1006 |
|
1007 // In case trace plugin is not available, disabling import from device selection |
|
1008 if(!MemSpyPlugin.isTraceProviderAvailable()){ |
|
1009 deviceRadioButton.setEnabled(false); |
|
1010 } |
|
1011 } |
|
1012 |
|
1013 private void createTimerComposite(Composite parent) { |
|
1014 // Timer UI-components |
|
1015 |
|
1016 Group timerComposite = new Group(parent, SWT.NONE); |
|
1017 timerComposite.setText(TEXT_GET_LOG_WITH_TIMER); |
|
1018 |
|
1019 GridLayout timerLayout = new GridLayout(); |
|
1020 timerLayout.numColumns = 2; |
|
1021 GridData timerGd = new GridData(SWT.FILL, SWT.CENTER, true, true);; |
|
1022 timerComposite.setLayoutData( timerGd ); |
|
1023 timerComposite.setLayout( timerLayout ); |
|
1024 |
|
1025 |
|
1026 // Interval- label |
|
1027 intervalLabel = new Label( timerComposite, SWT.LEFT ); |
|
1028 intervalLabel.setText( TEXT_INTERVAL ); |
|
1029 GridData intervalGd = new GridData(); |
|
1030 intervalGd.horizontalSpan = 2; |
|
1031 intervalLabel.setLayoutData( intervalGd ); |
|
1032 |
|
1033 // Timer combo box |
|
1034 timerCombo = new Combo( timerComposite, SWT.BORDER); |
|
1035 GridData timerComboGridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); |
|
1036 timerComboGridData.widthHint = 25; |
|
1037 timerCombo.setLayoutData( timerComboGridData ); |
|
1038 timerCombo.setTextLimit(3); |
|
1039 |
|
1040 // Interval- label |
|
1041 secondLabel = new Label( timerComposite, SWT.LEFT ); |
|
1042 secondLabel.setText( TEXT_SECOND ); |
|
1043 GridData secondLabelLayoutData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); |
|
1044 secondLabel.setLayoutData( secondLabelLayoutData ); |
|
1045 |
|
1046 // Start timer - button |
|
1047 startTimerButton = new Button(timerComposite, SWT.PUSH); |
|
1048 GridData startTimerGridData = new GridData( GridData.FILL_HORIZONTAL ); |
|
1049 startTimerGridData.horizontalSpan = 2; |
|
1050 startTimerButton.setLayoutData( startTimerGridData ); |
|
1051 startTimerButton.setText( START_TIMER ); |
|
1052 startTimerButton.addSelectionListener(this); |
|
1053 |
|
1054 |
|
1055 } |
|
1056 |
|
1057 |
|
1058 /** |
|
1059 * Checks if device radio buttons is selected. |
|
1060 * @return <code>true</code> if device radio button is selected, otherwise <code>false</code>. |
|
1061 */ |
|
1062 public boolean isDeviceRadioButtonSelected(){ |
|
1063 return deviceRadioButton.getSelection(); |
|
1064 } |
|
1065 |
|
1066 /** |
|
1067 * Updates connection settings. |
|
1068 */ |
|
1069 public void updateConnectionSettings() { |
|
1070 this.updateConnectionText(); |
|
1071 } |
|
1072 |
|
1073 |
|
1074 /** |
|
1075 * Gets timer interval from interval UI-component. |
|
1076 * If interval set to text box is not valid, method prints error message and returns value 0. |
|
1077 * @return current timer interval |
|
1078 */ |
|
1079 private int getTimerInteval() { |
|
1080 boolean showError = false; |
|
1081 |
|
1082 int integer = 0; |
|
1083 try{ |
|
1084 integer = Integer.parseInt( timerCombo.getText() ); |
|
1085 } |
|
1086 catch( NumberFormatException e ){ |
|
1087 // show error message of interval is not integer. |
|
1088 showError = true; |
|
1089 } |
|
1090 |
|
1091 if( integer <= 0 && showError == false ){ |
|
1092 // show error message if integer is negative or zero. |
|
1093 showError = true; |
|
1094 } |
|
1095 |
|
1096 if( showError ){ |
|
1097 // open error dialog and print error message |
|
1098 Status status = new Status(IStatus.ERROR, MemSpyPlugin.PLUGIN_ID, 0, ERROR_INTERVAL, null); |
|
1099 ErrorDialog.openError(Display.getCurrent().getActiveShell(),"MemSpy Error", null, status); |
|
1100 return 0; |
|
1101 } |
|
1102 |
|
1103 return integer; |
|
1104 |
|
1105 } |
|
1106 |
|
1107 /* |
|
1108 * (non-Javadoc) |
|
1109 * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#operationFinished(com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener.LauncherAction, com.nokia.s60tools.memspy.containers.SWMTLogInfo) |
|
1110 */ |
|
1111 public void operationFinished(LauncherAction action, SWMTLogInfo swmtLogInfo, boolean timerRunning) { |
|
1112 if( action == LauncherAction.TIMED_SWMT_UPDATE ){ |
|
1113 |
|
1114 // update received log to table |
|
1115 this.receivedLog = swmtLogInfo; |
|
1116 this.updateReceivedSWMTLog( timerRunning ); |
|
1117 |
|
1118 // increase cycle number |
|
1119 cycleNumber++; |
|
1120 } |
|
1121 } |
|
1122 |
|
1123 /* |
|
1124 * (non-Javadoc) |
|
1125 * @see com.nokia.s60tools.memspy.ui.wizards.MemSpyTraceListener#startedReceivingSWMTLog() |
|
1126 */ |
|
1127 public void startedReceivingSWMTLog() { |
|
1128 |
|
1129 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.startedReceivingSWMTLog"); //$NON-NLS-1$ |
|
1130 |
|
1131 // Set MemSpy's state correct |
|
1132 this.memSpyOperationRunning = true; |
|
1133 this.memSpyTimerRunning = false; |
|
1134 } |
|
1135 |
|
1136 /** |
|
1137 * Method that is called when "Get Log Now" - button is pressed. |
|
1138 */ |
|
1139 private void getLogNowPressed(){ |
|
1140 |
|
1141 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed"); //$NON-NLS-1$ |
|
1142 |
|
1143 // if cycle number is zero(this is first log file in list), MemSpy's SWMT-logging needs to be reseted. |
|
1144 boolean reset = false; |
|
1145 if( deviceLogsTable.getItemCount() == 0 ){ |
|
1146 reset = true; |
|
1147 cycleNumber = 1; |
|
1148 } |
|
1149 |
|
1150 //Check if S60 application is ment to reset between cycles |
|
1151 boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected(); |
|
1152 if(isToBeClosedBetweenCycles){ |
|
1153 reset = true; |
|
1154 } |
|
1155 |
|
1156 // Create new SWMTLogInfo object |
|
1157 receivedLog = new SWMTLogInfo(); |
|
1158 |
|
1159 // get temp file name for swmt-log |
|
1160 Date date = new Date(); |
|
1161 receivedLog.setPath( MemSpyFileOperations.getTempFileNameForSWMTLog( cycleNumber, date ) ); |
|
1162 receivedLog.setType( SWMTLogType.FILE ); |
|
1163 receivedLog.setDate(date); |
|
1164 receivedLog.setType(SWMTLogType.DEVICE); |
|
1165 |
|
1166 if( traceEngine.requestSWMTLog( this, receivedLog.getPath(), reset) ){ |
|
1167 |
|
1168 try { |
|
1169 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed/getContainer().run/receiveSWMTLogProcess"); //$NON-NLS-1$ |
|
1170 getContainer().run(true, false, receiveSWMTLogProcess); |
|
1171 } catch (InvocationTargetException e1) { |
|
1172 // do nothing |
|
1173 e1.printStackTrace(); |
|
1174 } catch (InterruptedException e1) { |
|
1175 // do nothing |
|
1176 e1.printStackTrace(); |
|
1177 } |
|
1178 enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); |
|
1179 } |
|
1180 else{ |
|
1181 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogNowPressed/openError"); //$NON-NLS-1$ |
|
1182 MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION); |
|
1183 receivedLog = null; |
|
1184 } |
|
1185 } |
|
1186 |
|
1187 |
|
1188 /** |
|
1189 * Method that is called when "Start Timer" - button is pressed. |
|
1190 */ |
|
1191 private void getLogWithTimerPressed(){ |
|
1192 |
|
1193 int interval = this.getTimerInteval(); |
|
1194 |
|
1195 // if interval is not zero continue |
|
1196 if( interval != 0 ){ |
|
1197 |
|
1198 // if cycle number is zero(this is first log file in list), MemSpy's SWMT-logging needs to be reseted. |
|
1199 boolean reset = false; |
|
1200 if( deviceLogsTable.getItemCount() == 0 ){ |
|
1201 reset = true; |
|
1202 cycleNumber = 1; |
|
1203 } |
|
1204 |
|
1205 boolean isToBeClosedBetweenCycles = MemSpyPreferences.isCloseSymbianAgentBetweenCyclesSelected() && !MemSpyPreferences.isProfileTrackedCategoriesSelected(); |
|
1206 |
|
1207 // if connect to trace source was established |
|
1208 if( traceEngine.startSWMTTimer(this, cycleNumber, reset, isToBeClosedBetweenCycles, interval) ){ |
|
1209 |
|
1210 // change Cancel text from wizard to "Stop Timer" |
|
1211 setCancelText("Stop Timer"); |
|
1212 |
|
1213 // launch receiveSWMTLog process. |
|
1214 try { |
|
1215 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.getLogWithTimerPressed/getContainer().run/receiveSWMTLogProcess"); //$NON-NLS-1$ |
|
1216 getContainer().run(true, true, receiveSWMTLogProcess); |
|
1217 } catch (InvocationTargetException e1) { |
|
1218 // do nothing |
|
1219 e1.printStackTrace(); |
|
1220 } catch (InterruptedException e1) { |
|
1221 // do nothing |
|
1222 e1.printStackTrace(); |
|
1223 } |
|
1224 |
|
1225 // Enable/Disable device buttons. |
|
1226 enableAndDisableDeviceButtonsAndSWMTCategoryGroup(); |
|
1227 |
|
1228 } |
|
1229 else{ |
|
1230 // increase cycle number |
|
1231 cycleNumber++; |
|
1232 |
|
1233 // show error message |
|
1234 MessageDialog.openError( this.getShell(), ERROR_MEMSPY, ERROR_CONNECTION); |
|
1235 |
|
1236 } |
|
1237 } |
|
1238 } |
|
1239 |
|
1240 /** |
|
1241 * Method that is called when stop timer-button is pressed. |
|
1242 */ |
|
1243 private void stopTimerPressed(){ |
|
1244 |
|
1245 this.memSpyTimerRunning = false; |
|
1246 if( traceEngine.stopSWMTTimer() ){ |
|
1247 // if timer is stopped immediately, hide progress bar |
|
1248 memSpyStopping = false; |
|
1249 |
|
1250 this.setCancelText("Cancel"); |
|
1251 } |
|
1252 } |
|
1253 |
|
1254 /** |
|
1255 * Created needed MemSpy processes. |
|
1256 */ |
|
1257 private void createMemSpyProcesses(){ |
|
1258 |
|
1259 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "SWMTLogPage.createMemSpyProcesses/receiveSWMTLogProcess"); //$NON-NLS-1$ |
|
1260 |
|
1261 // receive SWMT-Log process |
|
1262 receiveSWMTLogProcess = new IRunnableWithProgress() { |
|
1263 /** |
|
1264 * In receive SWMT-Log process process views progress bar and checks every 0,5 seconds |
|
1265 * if current MemSpy process has been finished. After MemSpy process has finished. Progress |
|
1266 * bar is hidden. |
|
1267 */ |
|
1268 public void run(IProgressMonitor monitor) { |
|
1269 memSpyOperationRunning = true; |
|
1270 |
|
1271 monitor.beginTask(RECEIVING_SWMT_LOG, IProgressMonitor.UNKNOWN); |
|
1272 while(true){ |
|
1273 // some delay, so that launcher has time to set it's state correct. |
|
1274 try { |
|
1275 Thread.sleep(500); |
|
1276 } catch (InterruptedException e) { |
|
1277 // do nothing |
|
1278 } |
|
1279 |
|
1280 // If no operations are on-going, break |
|
1281 if( !memSpyOperationRunning && !memSpyTimerRunning && !memSpyStopping ){ |
|
1282 break; |
|
1283 } |
|
1284 |
|
1285 // If Cancel-message received, send stop request. |
|
1286 if( monitor.isCanceled() ){ |
|
1287 monitor.beginTask(STOPPING_TIMER, IProgressMonitor.UNKNOWN); |
|
1288 stopTimerPressed(); |
|
1289 } |
|
1290 |
|
1291 // If timer and operation are running, show "Waiting for timer to expire"-text |
|
1292 else if ( memSpyTimerRunning ){ |
|
1293 monitor.beginTask(WAITING_FOR_TIMER, IProgressMonitor.UNKNOWN); |
|
1294 } |
|
1295 |
|
1296 // If MemSpy operation is running, show "Requesting Heap Dump" -text |
|
1297 else if( memSpyOperationRunning ){ |
|
1298 monitor.beginTask(RECEIVING_SWMT_LOG, IProgressMonitor.UNKNOWN); |
|
1299 } |
|
1300 } |
|
1301 monitor.done(); |
|
1302 } |
|
1303 }; |
|
1304 } |
|
1305 |
|
1306 /** |
|
1307 * Changes wizard's cancel button's text. |
|
1308 * @param newText new text for button |
|
1309 */ |
|
1310 private void setCancelText( final String newText ){ |
|
1311 Runnable updateUiRunnable = new Runnable(){ |
|
1312 public void run(){ |
|
1313 // change Cancel text from wizard back to "Cancel" |
|
1314 ( (MemSpyWizard)getWizard() ).setCancelText( newText ); |
|
1315 } |
|
1316 }; |
|
1317 // needs to be done on UI thread. |
|
1318 Display.getDefault().asyncExec(updateUiRunnable); |
|
1319 } |
|
1320 |
|
1321 /* (non-Javadoc) |
|
1322 * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategoryGroupComposite.SWMTCategorySelectionChangeListener#categorySelectionChanged(int) |
|
1323 */ |
|
1324 public void setCategorySelection(int newCategorySelection, boolean isProfileSettings) { |
|
1325 traceEngine.setCategoriesForSWMT(newCategorySelection, isProfileSettings); |
|
1326 } |
|
1327 |
|
1328 /* (non-Javadoc) |
|
1329 * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#getCategorySelection() |
|
1330 */ |
|
1331 public int getCategorySelection() { |
|
1332 return traceEngine.getCategoriesForSWMT(); |
|
1333 } |
|
1334 |
|
1335 /* (non-Javadoc) |
|
1336 * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#setAllTrackedCategoriesSelected(boolean) |
|
1337 */ |
|
1338 public void setProfileTrackedCategoriesSelected( |
|
1339 boolean isAllCategoriesSelected) { |
|
1340 traceEngine.setProfileTrackedCategoriesSelected(isAllCategoriesSelected); |
|
1341 } |
|
1342 |
|
1343 /* (non-Javadoc) |
|
1344 * @see com.nokia.s60tools.memspy.ui.wizards.SWMTCategorySelectionMediator#getAllTrackedCategoriesSelected() |
|
1345 */ |
|
1346 public boolean isProfileTrackedCategoriesSelected() { |
|
1347 return traceEngine.isProfileTrackedCategoriesSelected(); |
|
1348 } |
|
1349 |
|
1350 |
|
1351 /* (non-Javadoc) |
|
1352 * @see org.eclipse.jface.dialogs.DialogPage#dispose() |
|
1353 */ |
|
1354 public void dispose(){ |
|
1355 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + ": dispose()"); //$NON-NLS-1$ |
|
1356 categoryGroupComposite.dispose(); |
|
1357 super.dispose(); |
|
1358 } |
|
1359 |
|
1360 |
|
1361 } |
|
1362 |