sysperfana/memspyext/com.nokia.s60tools.memspy/src/com/nokia/s60tools/memspy/ui/wizards/SWMTLogPage.java
changeset 7 8e12a575a9b5
equal deleted inserted replaced
6:f65f740e69f9 7:8e12a575a9b5
       
     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