crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/ui/wizards/FilesSelectionPage.java
changeset 0 5ad7ad99af01
child 16 72f198be1c1d
equal deleted inserted replaced
-1:000000000000 0:5ad7ad99af01
       
     1 /*
       
     2 * Copyright (c) 2008 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 package com.nokia.s60tools.crashanalyser.ui.wizards;
       
    19 
       
    20 import org.eclipse.swt.SWT;
       
    21 import org.eclipse.swt.layout.GridData;
       
    22 import org.eclipse.swt.layout.GridLayout;
       
    23 import org.eclipse.swt.widgets.Composite;
       
    24 import org.eclipse.swt.widgets.Label;
       
    25 import org.eclipse.swt.widgets.Table;
       
    26 import org.eclipse.swt.widgets.TableColumn;
       
    27 import org.eclipse.swt.widgets.Button;
       
    28 import org.eclipse.swt.widgets.TableItem;
       
    29 import org.eclipse.swt.browser.*;
       
    30 import org.eclipse.swt.events.*;
       
    31 import org.eclipse.ui.PlatformUI;
       
    32 import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
       
    33 import com.nokia.s60tools.crashanalyser.model.*;
       
    34 import com.nokia.s60tools.crashanalyser.resources.HelpContextIDs;
       
    35 import com.nokia.s60tools.crashanalyser.files.*;
       
    36 import java.util.*;
       
    37 import java.text.Collator;
       
    38 import java.util.Locale;
       
    39 import java.text.DateFormat;
       
    40 import java.util.Date;
       
    41 
       
    42 /**
       
    43  * This is the 2nd page in the wizard. This page contains a table from which
       
    44  * user selects the crash files he/she wants to import.
       
    45  */
       
    46 public class FilesSelectionPage extends S60ToolsWizardPage implements SelectionListener{
       
    47 
       
    48 	Button buttonSelectDeselect;
       
    49 	Table tableFiles;
       
    50 	TableColumn tableColumnCreated;
       
    51 	TableColumn tableColumnType;
       
    52 	TableColumn tableColumnRomId;
       
    53 	TableColumn tableColumnFile;
       
    54 	Label labelFileInfoTitle;
       
    55 	Browser browserFileInfo;
       
    56 	DecoderEngine engine;
       
    57 	Composite composite;
       
    58 	List<CrashFileBundle> files = null;
       
    59 	String[] filesToBeShown = null;
       
    60 	public boolean romIdsMatch = true;
       
    61 	static final int TABLE_COLUMN_CREATED = 0;
       
    62 	static final int TABLE_COLUMN_TYPE = 1;
       
    63 	static final int TABLE_COLUMN_ROMID = 2;
       
    64 	static final int TABLE_COLUMN_FILE = 3;
       
    65 	static final int TABLE_COLUMN_COUNT = 4;
       
    66 	
       
    67 	/**
       
    68 	 * Constructor
       
    69 	 * @param decEng decoder engine
       
    70 	 */
       
    71 	public FilesSelectionPage(DecoderEngine decEng, String[] showOnlyTheseFiles) {
       
    72 		super("");
       
    73 			
       
    74 		setTitle("Select Files");
       
    75 			
       
    76 		setDescription("Select crash files to be imported.");
       
    77 
       
    78 		// User cannot finish the page before some valid 
       
    79 		// selection is made.
       
    80 		setPageComplete(false);
       
    81 		engine = decEng;
       
    82 		filesToBeShown = showOnlyTheseFiles;
       
    83 	}
       
    84 
       
    85 	public void showOnlyTheseFiles(String[] files) {
       
    86 		filesToBeShown = files;
       
    87 	}
       
    88 	
       
    89 	@Override
       
    90 	public void recalculateButtonStates() {
       
    91 		// no implementation needed
       
    92 	}
       
    93 
       
    94 	@Override
       
    95 	public void setInitialFocus() {
       
    96 		tableFiles.setFocus();
       
    97 	}
       
    98 
       
    99 	/**
       
   100 	 * Creates all UI controls
       
   101 	 */
       
   102 	public void createControl(Composite parent) {
       
   103 		composite =  new Composite(parent, SWT.NULL);
       
   104 		
       
   105 	    // create the desired layout for this wizard page
       
   106 		GridLayout gl = new GridLayout();
       
   107 		gl.numColumns = 1;
       
   108 		composite.setLayout(gl);
       
   109 
       
   110 		// Table
       
   111 		tableFiles = new Table(composite, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK | SWT.V_SCROLL | SWT.H_SCROLL);
       
   112 		tableFiles.setLinesVisible (true);
       
   113 		tableFiles.setHeaderVisible (true);
       
   114 		
       
   115 		// Created column
       
   116 		tableColumnCreated = new TableColumn (tableFiles, SWT.NONE);
       
   117 		tableColumnCreated.setText("Created");
       
   118 		tableColumnCreated.addSelectionListener(this);
       
   119 		
       
   120 		// Type column
       
   121 		tableColumnType = new TableColumn (tableFiles, SWT.NONE);
       
   122 		tableColumnType.setText("Type");
       
   123 		tableColumnType.addSelectionListener(this);
       
   124 
       
   125 		// ROM ID column
       
   126 		tableColumnRomId = new TableColumn (tableFiles, SWT.NONE);
       
   127 		tableColumnRomId.setText("ROM ID");
       
   128 		tableColumnRomId.addSelectionListener(this);
       
   129 
       
   130 		// File column
       
   131 		tableColumnFile = new TableColumn (tableFiles, SWT.NONE);
       
   132 		tableColumnFile.setText("File");
       
   133 		tableColumnFile.addSelectionListener(this);
       
   134 		
       
   135 		autoSizeTableColumns();
       
   136 		
       
   137 		GridData treeGD = new GridData(GridData.FILL_BOTH);
       
   138 		tableFiles.setLayoutData(treeGD);		
       
   139 		tableFiles.addSelectionListener(this);
       
   140 		
       
   141 		// Select/Deselect button
       
   142 		buttonSelectDeselect = new Button(composite, SWT.PUSH);
       
   143 		buttonSelectDeselect.setText("Select/Unselect");
       
   144 		buttonSelectDeselect.addSelectionListener(this);
       
   145 
       
   146 		// File info title
       
   147 		labelFileInfoTitle = new Label(composite, SWT.LEFT);
       
   148 		labelFileInfoTitle.setText("File Info");
       
   149 		
       
   150 		// File info
       
   151 		browserFileInfo = new Browser(composite, SWT.BORDER);
       
   152 		GridData textGD = new GridData(GridData.FILL_HORIZONTAL);
       
   153 		textGD.heightHint = 150;
       
   154 		browserFileInfo.setLayoutData(textGD);
       
   155 		browserFileInfo.setText("");
       
   156 		
       
   157 		setHelps();
       
   158 		
       
   159 		setInitialFocus();
       
   160 		
       
   161 		setControl(composite);		
       
   162 		
       
   163 		updateButtons();
       
   164 	}
       
   165 	
       
   166 	/**
       
   167 	 * Autos sizes all table columns
       
   168 	 */
       
   169 	void autoSizeTableColumns() {
       
   170 		for (int i = 0; i < TABLE_COLUMN_COUNT; i++) {
       
   171 			tableFiles.getColumn(i).pack();
       
   172 		}		
       
   173 	}
       
   174 	
       
   175 	/**
       
   176 	 * Loads the table with files given by decoder engine
       
   177 	 */
       
   178 	public void loadTable() {
       
   179 		tableFiles.removeAll();
       
   180 		files = engine.getCrashFiles();
       
   181 		if (files == null || files.size() < 1) {
       
   182 			setErrorMessage("No crash files found.");
       
   183 		} else {
       
   184 			for (int i = 0; i < files.size(); i++) {
       
   185 				CrashFileBundle file = files.get(i);
       
   186 				String fileType = "";
       
   187 				String fileName = "";
       
   188 				// summary xml file
       
   189 				if (file.isPartiallyDecoded()) {
       
   190 					SummaryFile summaryFile = file.getSummaryFile();
       
   191 					fileType = summaryFile.getSourceFileType();
       
   192 					fileName = summaryFile.getSourceFileName();
       
   193 				// .crashxml file
       
   194 				} else {
       
   195 					CrashFile crashfile = file.getCrashFile();
       
   196 					fileType = crashfile.getSourceFileType();
       
   197 					fileName = crashfile.getFileName();
       
   198 				}
       
   199 				// if user has drag&dropped multiple files, we have scanned the whole
       
   200 				// folder, but we should show only the dragged ones
       
   201 				if (!shouldCrashFileBeShown(fileName))
       
   202 					continue;
       
   203 				TableItem item = new TableItem (tableFiles, SWT.NONE);
       
   204 				item.setText(0, file.getTime());
       
   205 				item.setText(1, fileType);
       
   206 				item.setText(2, file.getRomId());
       
   207 				item.setText(3, fileName);
       
   208 				item.setData(file);
       
   209 				item.setChecked(true);
       
   210 			}
       
   211 			autoSizeTableColumns();
       
   212 		}
       
   213 		browserFileInfo.setText("");
       
   214 		
       
   215 		if (tableFiles.getItemCount() > 0) {
       
   216 			tableFiles.select(0);
       
   217 			showFileInfo();
       
   218 		}
       
   219 	}
       
   220 	
       
   221 	/**
       
   222 	 * Checks whether given crash file should be shown in table. if user has drag&dropped 
       
   223 	 * multiple files, we have scanned the whole folder, but we should show only the dragged ones. 
       
   224 	 * @param fileName file to be checked
       
   225 	 * @return true if file should be shown, false if not
       
   226 	 */
       
   227 	boolean shouldCrashFileBeShown(String fileName) {
       
   228 		if (filesToBeShown != null && filesToBeShown.length > 0) {
       
   229 			for (int i = 0; i < filesToBeShown.length; i++) {
       
   230 				if (fileName.equalsIgnoreCase(FileOperations.getFileNameWithExtension(filesToBeShown[i])))
       
   231 					return true;
       
   232 			}
       
   233 			return false;
       
   234 
       
   235 		} else {
       
   236 			return true;
       
   237 		}
       
   238 	}
       
   239 
       
   240 	public void widgetDefaultSelected(SelectionEvent e) {
       
   241 		// no implementation needed
       
   242 	}
       
   243 
       
   244 	public void widgetSelected(SelectionEvent e) {
       
   245 		// Select/Unselect button pressed
       
   246 		if (e.widget == buttonSelectDeselect) {
       
   247 			TableItem[] items = tableFiles.getItems();
       
   248 			if (items != null) {
       
   249 				boolean checkAll = true;
       
   250 				// check whether items needs to be checked or unchecked
       
   251 				for (int i = 0; i < items.length; i++) {
       
   252 					if (items[i].getChecked()) {
       
   253 						checkAll = false;
       
   254 						break;
       
   255 					}
       
   256 				}
       
   257 				
       
   258 				// check/uncheck all items
       
   259 				for (int i = 0; i < items.length; i++)
       
   260 					items[i].setChecked(checkAll);
       
   261 			}
       
   262 			showFileInfo();
       
   263 			updateButtons();
       
   264 			
       
   265 		// table item selected/checked/unchecked
       
   266 		} else if (e.widget == tableFiles) {
       
   267 			// item was checked/unchecked
       
   268 			if (e.detail == SWT.CHECK) {
       
   269 				tableFiles.setSelection((TableItem)e.item);
       
   270 				updateButtons();
       
   271 			}
       
   272 			showFileInfo();
       
   273 			
       
   274 		// table column presses -> sort
       
   275 		} else if (e.widget == tableColumnCreated ) {
       
   276 			sortTableByColumn(TABLE_COLUMN_CREATED, tableColumnCreated);
       
   277 		} else if (e.widget == tableColumnType) {
       
   278 			sortTableByColumn(TABLE_COLUMN_TYPE, tableColumnType);
       
   279 		} else if (e.widget == tableColumnRomId) {
       
   280 			sortTableByColumn(TABLE_COLUMN_ROMID, tableColumnRomId);
       
   281 		} else if (e.widget == tableColumnFile) {
       
   282 			sortTableByColumn(TABLE_COLUMN_FILE, tableColumnFile);
       
   283 		}
       
   284 	}
       
   285 	
       
   286 	/**
       
   287 	 * Sorts table by given column number
       
   288 	 * @param column column number
       
   289 	 * @param col column item
       
   290 	 */
       
   291 	void sortTableByColumn(int column, TableColumn col) {
       
   292 		TableItem[] items = tableFiles.getItems();
       
   293 		Collator collator = Collator.getInstance(Locale.getDefault());
       
   294 
       
   295 		TableColumn sortColumn = tableFiles.getSortColumn();
       
   296 		
       
   297 		// column is sorted for the "first time" or column is sorted UP. Sort column DOWN.
       
   298 		if (sortColumn == null || !col.equals(sortColumn) || tableFiles.getSortDirection() == SWT.UP) {
       
   299 			for (int i = 1; i < items.length; i++) {
       
   300 				String value1 = items[i].getText(column);
       
   301 				for (int j = 0; j < i; j++) {
       
   302 					String value2 = items[j].getText(column);
       
   303 					// time compare
       
   304 					if (column == TABLE_COLUMN_CREATED) {
       
   305 						try {
       
   306 							DateFormat date = DateFormat.getInstance();
       
   307 							Date d1 = date.parse(value1);
       
   308 							Date d2 = date.parse(value2);
       
   309 							if (d1 != null && d2 != null && d1.compareTo(d2) < 0) {
       
   310 								boolean checked = items[i].getChecked();
       
   311 								String[] values = { items[i].getText(0), items[i].getText(1), items[i].getText(2), items[i].getText(3)};
       
   312 								items[i].dispose();
       
   313 								TableItem item = new TableItem(tableFiles, SWT.NONE, j);
       
   314 								item.setText(values);
       
   315 								item.setChecked(checked);
       
   316 								items = tableFiles.getItems();
       
   317 								break;
       
   318 							}
       
   319 						} catch (Exception e) {
       
   320 							e.printStackTrace();
       
   321 						}
       
   322 					// string compare
       
   323 					} else {
       
   324 						if (collator.compare(value1, value2) < 0) {
       
   325 							boolean checked = items[i].getChecked();
       
   326 							String[] values = { items[i].getText(0), items[i].getText(1), items[i].getText(2), items[i].getText(3)};
       
   327 							items[i].dispose();
       
   328 							TableItem item = new TableItem(tableFiles, SWT.NONE, j);
       
   329 							item.setText(values);
       
   330 							item.setChecked(checked);
       
   331 							items = tableFiles.getItems();
       
   332 							break;
       
   333 						}
       
   334 					}
       
   335 				}
       
   336 			}
       
   337 			tableFiles.setSortColumn(col);
       
   338 			tableFiles.setSortDirection(SWT.DOWN);
       
   339 		
       
   340 		// Reverse rows
       
   341 		} else {
       
   342 			int index = items.length-1;
       
   343 			for (int i = 0; i < items.length-1; i++) {
       
   344 				boolean checked = items[index].getChecked();
       
   345 				String[] values = { items[index].getText(0), items[index].getText(1), items[index].getText(2), items[index].getText(3)};
       
   346 				items[index].dispose();
       
   347 				TableItem item = new TableItem(tableFiles, SWT.NONE, i);
       
   348 				item.setText(values);
       
   349 				item.setChecked(checked);
       
   350 				items = tableFiles.getItems();
       
   351 			}
       
   352 			
       
   353 			tableFiles.setSortColumn(col);
       
   354 			tableFiles.setSortDirection(SWT.UP);
       
   355 		}
       
   356 	}
       
   357 	
       
   358 	/**
       
   359 	 * Updates next, finish button states
       
   360 	 */
       
   361 	void updateButtons() {
       
   362 		try {
       
   363 			getWizard().getContainer().updateButtons();
       
   364 		} catch (Exception E) {
       
   365 		}
       
   366 	}
       
   367 	
       
   368 	/**
       
   369 	 * Show information about the currently selected file
       
   370 	 */
       
   371 	void showFileInfo() {
       
   372 		int selected = tableFiles.getSelectionIndex();
       
   373 		if (selected >= 0) {
       
   374 			CrashFileBundle cfb = (CrashFileBundle)tableFiles.getItem(selected).getData();
       
   375 			browserFileInfo.setText(HtmlFormatter.formatHtmlStyle(labelFileInfoTitle.getFont(), 
       
   376 																	cfb.getDescription(false)));
       
   377 		} else {
       
   378 			browserFileInfo.setText("");
       
   379 		}
       
   380 	}
       
   381 
       
   382 	/**
       
   383 	 * Checks whether we can press Next button
       
   384 	 */
       
   385 	public boolean canFlipToNextPage() {
       
   386 		try {
       
   387 			// decoder engine contains no files (shouldn't happen)
       
   388 			if (files == null || files.size() < 1)
       
   389 				return false;
       
   390 			
       
   391 			TableItem[] items = tableFiles.getItems();
       
   392 			// no items in table (shouldn't happen)
       
   393 			if (items == null) {
       
   394 				return false;
       
   395 			// table contains items
       
   396 			} else {
       
   397 				String romId = "";
       
   398 				boolean selectedFiles = false;
       
   399 				boolean hasMultipleRomIds = false;
       
   400 				// check whether user is trying to import files which 
       
   401 				// have different ROM IDs
       
   402 				for (int i = 0; i < items.length; i++) {
       
   403 					CrashFileBundle file = (CrashFileBundle)items[i].getData();
       
   404 					if (!items[i].getChecked() || file == null)
       
   405 						continue;
       
   406 
       
   407 					selectedFiles = true;
       
   408 					
       
   409 					// ignore ROM ID of .crashxml file
       
   410 					if (file.isFullyDecoded())
       
   411 						continue;
       
   412 					
       
   413 					//ignore if file has no rom id
       
   414 					if ("".equals(file.getRomId()))
       
   415 						continue;
       
   416 					
       
   417 					if (!"".equals(romId) && !file.getRomId().equalsIgnoreCase(romId)) {
       
   418 						hasMultipleRomIds = true;
       
   419 					}
       
   420 					romId = file.getRomId();
       
   421 				}
       
   422 				
       
   423 				// don't allow to proceed when multiple different ROM ID file are selected
       
   424 				if (hasMultipleRomIds) {
       
   425 					this.setErrorMessage("ROM IDs of selected files do not match. Please select only files which have same ROM IDs.");
       
   426 					return false;
       
   427 				} else {
       
   428 					this.setErrorMessage(null);
       
   429 				}
       
   430 				
       
   431 				// no checked files
       
   432 				if (!selectedFiles)
       
   433 					return false;
       
   434 			}
       
   435 		} catch (Exception e) {
       
   436 			e.printStackTrace();
       
   437 			return false;
       
   438 		}
       
   439 		return true;
       
   440 	}		
       
   441 	
       
   442 	/**
       
   443 	 * Checks whether Finish button can be enabled. Finish button can be
       
   444 	 * enabled if user is importing only already decoded files (.crashxml files).
       
   445 	 * 
       
   446 	 * @return true if Finish button can be enable, false if not
       
   447 	 */
       
   448 	public boolean canFinish() {
       
   449 		try {
       
   450 			// if no files in this page (shouldn't happen)
       
   451 			if (files == null || files.size() < 1)
       
   452 				return false;
       
   453 			
       
   454 			TableItem[] items = tableFiles.getItems();
       
   455 			// if no files in table (shouldn't happen)
       
   456 			if (items == null) {
       
   457 				return false;
       
   458 			} else {
       
   459 				boolean hasAnalyzedFiles = false;
       
   460 				boolean hasUndecodedFiles = false;
       
   461 				// go through all checked files in the table
       
   462 				for (int i = 0; i < items.length; i++) {
       
   463 					if (!items[i].getChecked())
       
   464 						continue;
       
   465 					
       
   466 					CrashFileBundle file = (CrashFileBundle)items[i].getData();
       
   467 					if (file != null) {
       
   468 						if (file.isPartiallyDecoded()) {
       
   469 							hasUndecodedFiles = true;
       
   470 						} else {
       
   471 							hasAnalyzedFiles = true;
       
   472 						}
       
   473 					}
       
   474 				}
       
   475 				
       
   476 				// only .crashxml files are selected, we can show Finish button
       
   477 				if (hasAnalyzedFiles && !hasUndecodedFiles)
       
   478 					return true;
       
   479 			}
       
   480 		} catch (Exception e) {
       
   481 			e.printStackTrace();
       
   482 		}
       
   483 		return false;
       
   484 	}
       
   485 	
       
   486 	/**
       
   487 	 * Checks whether only .crashxml files are selected in the table 
       
   488 	 * @return true if only .crashxml files are selected, false if not
       
   489 	 */
       
   490 	public boolean onlyCrashxmlFilesSelected() {
       
   491 		try {
       
   492 			// if no files in this page (shouldn't happen)
       
   493 			if (files == null || files.size() < 1)
       
   494 				return false;
       
   495 			
       
   496 			TableItem[] items = tableFiles.getItems();
       
   497 			// if no files in table (shouldn't happen)
       
   498 			if (items == null) {
       
   499 				return false;
       
   500 			} else {
       
   501 				boolean onlyCrashxmlFiles = true;
       
   502 				// go through all checked files in the table
       
   503 				for (int i = 0; i < items.length; i++) {
       
   504 					if (!items[i].getChecked())
       
   505 						continue;
       
   506 					CrashFileBundle file = (CrashFileBundle)items[i].getData();
       
   507 					if (file.isPartiallyDecoded()) {
       
   508 						onlyCrashxmlFiles = false;
       
   509 						break;
       
   510 					}
       
   511 				}
       
   512 				
       
   513 				if (onlyCrashxmlFiles)
       
   514 					return true;
       
   515 			}
       
   516 		} catch (Exception e) {
       
   517 			e.printStackTrace();
       
   518 			return false;
       
   519 		}
       
   520 		return false;
       
   521 	}
       
   522 	
       
   523 	/**
       
   524 	 * Returns indexes of those Crash files which are selected (checked) in the table
       
   525 	 * @return indexes of those Crash files which are selected (checked) in the table
       
   526 	 */
       
   527 	public List<Integer> getFileIndexes() {
       
   528 		List<Integer> indexes = new ArrayList<Integer>();
       
   529 		
       
   530 		TableItem[] items = tableFiles.getItems();
       
   531 		// if no files in table (shouldn't happen)
       
   532 		if (items == null) {
       
   533 			return null;
       
   534 		} else {
       
   535 			// go through all checked files in the table
       
   536 			for (int i = 0; i < items.length; i++) {
       
   537 				if (items[i].getChecked())
       
   538 					indexes.add(i);
       
   539 			}
       
   540 		}
       
   541 		
       
   542 		if (indexes.isEmpty()) {
       
   543 			return null;
       
   544 		} else {
       
   545 			return indexes;
       
   546 		}
       
   547 	}
       
   548 	
       
   549 	/**
       
   550 	 * Sets this page's context sensitive helps
       
   551 	 *
       
   552 	 */
       
   553 	protected void setHelps() {
       
   554 		PlatformUI.getWorkbench().getHelpSystem().setHelp(tableFiles,
       
   555 				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);
       
   556 		
       
   557 		PlatformUI.getWorkbench().getHelpSystem().setHelp(browserFileInfo,
       
   558 				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);		
       
   559 
       
   560 		PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonSelectDeselect,
       
   561 				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);		
       
   562 	}
       
   563 }