crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/ui/wizards/FilesSelectionPage.java
changeset 0 5ad7ad99af01
child 16 72f198be1c1d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/ui/wizards/FilesSelectionPage.java	Thu Feb 11 15:06:45 2010 +0200
@@ -0,0 +1,563 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.crashanalyser.ui.wizards;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.browser.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.ui.PlatformUI;
+import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
+import com.nokia.s60tools.crashanalyser.model.*;
+import com.nokia.s60tools.crashanalyser.resources.HelpContextIDs;
+import com.nokia.s60tools.crashanalyser.files.*;
+import java.util.*;
+import java.text.Collator;
+import java.util.Locale;
+import java.text.DateFormat;
+import java.util.Date;
+
+/**
+ * This is the 2nd page in the wizard. This page contains a table from which
+ * user selects the crash files he/she wants to import.
+ */
+public class FilesSelectionPage extends S60ToolsWizardPage implements SelectionListener{
+
+	Button buttonSelectDeselect;
+	Table tableFiles;
+	TableColumn tableColumnCreated;
+	TableColumn tableColumnType;
+	TableColumn tableColumnRomId;
+	TableColumn tableColumnFile;
+	Label labelFileInfoTitle;
+	Browser browserFileInfo;
+	DecoderEngine engine;
+	Composite composite;
+	List<CrashFileBundle> files = null;
+	String[] filesToBeShown = null;
+	public boolean romIdsMatch = true;
+	static final int TABLE_COLUMN_CREATED = 0;
+	static final int TABLE_COLUMN_TYPE = 1;
+	static final int TABLE_COLUMN_ROMID = 2;
+	static final int TABLE_COLUMN_FILE = 3;
+	static final int TABLE_COLUMN_COUNT = 4;
+	
+	/**
+	 * Constructor
+	 * @param decEng decoder engine
+	 */
+	public FilesSelectionPage(DecoderEngine decEng, String[] showOnlyTheseFiles) {
+		super("");
+			
+		setTitle("Select Files");
+			
+		setDescription("Select crash files to be imported.");
+
+		// User cannot finish the page before some valid 
+		// selection is made.
+		setPageComplete(false);
+		engine = decEng;
+		filesToBeShown = showOnlyTheseFiles;
+	}
+
+	public void showOnlyTheseFiles(String[] files) {
+		filesToBeShown = files;
+	}
+	
+	@Override
+	public void recalculateButtonStates() {
+		// no implementation needed
+	}
+
+	@Override
+	public void setInitialFocus() {
+		tableFiles.setFocus();
+	}
+
+	/**
+	 * Creates all UI controls
+	 */
+	public void createControl(Composite parent) {
+		composite =  new Composite(parent, SWT.NULL);
+		
+	    // create the desired layout for this wizard page
+		GridLayout gl = new GridLayout();
+		gl.numColumns = 1;
+		composite.setLayout(gl);
+
+		// Table
+		tableFiles = new Table(composite, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION | SWT.CHECK | SWT.V_SCROLL | SWT.H_SCROLL);
+		tableFiles.setLinesVisible (true);
+		tableFiles.setHeaderVisible (true);
+		
+		// Created column
+		tableColumnCreated = new TableColumn (tableFiles, SWT.NONE);
+		tableColumnCreated.setText("Created");
+		tableColumnCreated.addSelectionListener(this);
+		
+		// Type column
+		tableColumnType = new TableColumn (tableFiles, SWT.NONE);
+		tableColumnType.setText("Type");
+		tableColumnType.addSelectionListener(this);
+
+		// ROM ID column
+		tableColumnRomId = new TableColumn (tableFiles, SWT.NONE);
+		tableColumnRomId.setText("ROM ID");
+		tableColumnRomId.addSelectionListener(this);
+
+		// File column
+		tableColumnFile = new TableColumn (tableFiles, SWT.NONE);
+		tableColumnFile.setText("File");
+		tableColumnFile.addSelectionListener(this);
+		
+		autoSizeTableColumns();
+		
+		GridData treeGD = new GridData(GridData.FILL_BOTH);
+		tableFiles.setLayoutData(treeGD);		
+		tableFiles.addSelectionListener(this);
+		
+		// Select/Deselect button
+		buttonSelectDeselect = new Button(composite, SWT.PUSH);
+		buttonSelectDeselect.setText("Select/Unselect");
+		buttonSelectDeselect.addSelectionListener(this);
+
+		// File info title
+		labelFileInfoTitle = new Label(composite, SWT.LEFT);
+		labelFileInfoTitle.setText("File Info");
+		
+		// File info
+		browserFileInfo = new Browser(composite, SWT.BORDER);
+		GridData textGD = new GridData(GridData.FILL_HORIZONTAL);
+		textGD.heightHint = 150;
+		browserFileInfo.setLayoutData(textGD);
+		browserFileInfo.setText("");
+		
+		setHelps();
+		
+		setInitialFocus();
+		
+		setControl(composite);		
+		
+		updateButtons();
+	}
+	
+	/**
+	 * Autos sizes all table columns
+	 */
+	void autoSizeTableColumns() {
+		for (int i = 0; i < TABLE_COLUMN_COUNT; i++) {
+			tableFiles.getColumn(i).pack();
+		}		
+	}
+	
+	/**
+	 * Loads the table with files given by decoder engine
+	 */
+	public void loadTable() {
+		tableFiles.removeAll();
+		files = engine.getCrashFiles();
+		if (files == null || files.size() < 1) {
+			setErrorMessage("No crash files found.");
+		} else {
+			for (int i = 0; i < files.size(); i++) {
+				CrashFileBundle file = files.get(i);
+				String fileType = "";
+				String fileName = "";
+				// summary xml file
+				if (file.isPartiallyDecoded()) {
+					SummaryFile summaryFile = file.getSummaryFile();
+					fileType = summaryFile.getSourceFileType();
+					fileName = summaryFile.getSourceFileName();
+				// .crashxml file
+				} else {
+					CrashFile crashfile = file.getCrashFile();
+					fileType = crashfile.getSourceFileType();
+					fileName = crashfile.getFileName();
+				}
+				// if user has drag&dropped multiple files, we have scanned the whole
+				// folder, but we should show only the dragged ones
+				if (!shouldCrashFileBeShown(fileName))
+					continue;
+				TableItem item = new TableItem (tableFiles, SWT.NONE);
+				item.setText(0, file.getTime());
+				item.setText(1, fileType);
+				item.setText(2, file.getRomId());
+				item.setText(3, fileName);
+				item.setData(file);
+				item.setChecked(true);
+			}
+			autoSizeTableColumns();
+		}
+		browserFileInfo.setText("");
+		
+		if (tableFiles.getItemCount() > 0) {
+			tableFiles.select(0);
+			showFileInfo();
+		}
+	}
+	
+	/**
+	 * Checks whether given crash file should be shown in table. if user has drag&dropped 
+	 * multiple files, we have scanned the whole folder, but we should show only the dragged ones. 
+	 * @param fileName file to be checked
+	 * @return true if file should be shown, false if not
+	 */
+	boolean shouldCrashFileBeShown(String fileName) {
+		if (filesToBeShown != null && filesToBeShown.length > 0) {
+			for (int i = 0; i < filesToBeShown.length; i++) {
+				if (fileName.equalsIgnoreCase(FileOperations.getFileNameWithExtension(filesToBeShown[i])))
+					return true;
+			}
+			return false;
+
+		} else {
+			return true;
+		}
+	}
+
+	public void widgetDefaultSelected(SelectionEvent e) {
+		// no implementation needed
+	}
+
+	public void widgetSelected(SelectionEvent e) {
+		// Select/Unselect button pressed
+		if (e.widget == buttonSelectDeselect) {
+			TableItem[] items = tableFiles.getItems();
+			if (items != null) {
+				boolean checkAll = true;
+				// check whether items needs to be checked or unchecked
+				for (int i = 0; i < items.length; i++) {
+					if (items[i].getChecked()) {
+						checkAll = false;
+						break;
+					}
+				}
+				
+				// check/uncheck all items
+				for (int i = 0; i < items.length; i++)
+					items[i].setChecked(checkAll);
+			}
+			showFileInfo();
+			updateButtons();
+			
+		// table item selected/checked/unchecked
+		} else if (e.widget == tableFiles) {
+			// item was checked/unchecked
+			if (e.detail == SWT.CHECK) {
+				tableFiles.setSelection((TableItem)e.item);
+				updateButtons();
+			}
+			showFileInfo();
+			
+		// table column presses -> sort
+		} else if (e.widget == tableColumnCreated ) {
+			sortTableByColumn(TABLE_COLUMN_CREATED, tableColumnCreated);
+		} else if (e.widget == tableColumnType) {
+			sortTableByColumn(TABLE_COLUMN_TYPE, tableColumnType);
+		} else if (e.widget == tableColumnRomId) {
+			sortTableByColumn(TABLE_COLUMN_ROMID, tableColumnRomId);
+		} else if (e.widget == tableColumnFile) {
+			sortTableByColumn(TABLE_COLUMN_FILE, tableColumnFile);
+		}
+	}
+	
+	/**
+	 * Sorts table by given column number
+	 * @param column column number
+	 * @param col column item
+	 */
+	void sortTableByColumn(int column, TableColumn col) {
+		TableItem[] items = tableFiles.getItems();
+		Collator collator = Collator.getInstance(Locale.getDefault());
+
+		TableColumn sortColumn = tableFiles.getSortColumn();
+		
+		// column is sorted for the "first time" or column is sorted UP. Sort column DOWN.
+		if (sortColumn == null || !col.equals(sortColumn) || tableFiles.getSortDirection() == SWT.UP) {
+			for (int i = 1; i < items.length; i++) {
+				String value1 = items[i].getText(column);
+				for (int j = 0; j < i; j++) {
+					String value2 = items[j].getText(column);
+					// time compare
+					if (column == TABLE_COLUMN_CREATED) {
+						try {
+							DateFormat date = DateFormat.getInstance();
+							Date d1 = date.parse(value1);
+							Date d2 = date.parse(value2);
+							if (d1 != null && d2 != null && d1.compareTo(d2) < 0) {
+								boolean checked = items[i].getChecked();
+								String[] values = { items[i].getText(0), items[i].getText(1), items[i].getText(2), items[i].getText(3)};
+								items[i].dispose();
+								TableItem item = new TableItem(tableFiles, SWT.NONE, j);
+								item.setText(values);
+								item.setChecked(checked);
+								items = tableFiles.getItems();
+								break;
+							}
+						} catch (Exception e) {
+							e.printStackTrace();
+						}
+					// string compare
+					} else {
+						if (collator.compare(value1, value2) < 0) {
+							boolean checked = items[i].getChecked();
+							String[] values = { items[i].getText(0), items[i].getText(1), items[i].getText(2), items[i].getText(3)};
+							items[i].dispose();
+							TableItem item = new TableItem(tableFiles, SWT.NONE, j);
+							item.setText(values);
+							item.setChecked(checked);
+							items = tableFiles.getItems();
+							break;
+						}
+					}
+				}
+			}
+			tableFiles.setSortColumn(col);
+			tableFiles.setSortDirection(SWT.DOWN);
+		
+		// Reverse rows
+		} else {
+			int index = items.length-1;
+			for (int i = 0; i < items.length-1; i++) {
+				boolean checked = items[index].getChecked();
+				String[] values = { items[index].getText(0), items[index].getText(1), items[index].getText(2), items[index].getText(3)};
+				items[index].dispose();
+				TableItem item = new TableItem(tableFiles, SWT.NONE, i);
+				item.setText(values);
+				item.setChecked(checked);
+				items = tableFiles.getItems();
+			}
+			
+			tableFiles.setSortColumn(col);
+			tableFiles.setSortDirection(SWT.UP);
+		}
+	}
+	
+	/**
+	 * Updates next, finish button states
+	 */
+	void updateButtons() {
+		try {
+			getWizard().getContainer().updateButtons();
+		} catch (Exception E) {
+		}
+	}
+	
+	/**
+	 * Show information about the currently selected file
+	 */
+	void showFileInfo() {
+		int selected = tableFiles.getSelectionIndex();
+		if (selected >= 0) {
+			CrashFileBundle cfb = (CrashFileBundle)tableFiles.getItem(selected).getData();
+			browserFileInfo.setText(HtmlFormatter.formatHtmlStyle(labelFileInfoTitle.getFont(), 
+																	cfb.getDescription(false)));
+		} else {
+			browserFileInfo.setText("");
+		}
+	}
+
+	/**
+	 * Checks whether we can press Next button
+	 */
+	public boolean canFlipToNextPage() {
+		try {
+			// decoder engine contains no files (shouldn't happen)
+			if (files == null || files.size() < 1)
+				return false;
+			
+			TableItem[] items = tableFiles.getItems();
+			// no items in table (shouldn't happen)
+			if (items == null) {
+				return false;
+			// table contains items
+			} else {
+				String romId = "";
+				boolean selectedFiles = false;
+				boolean hasMultipleRomIds = false;
+				// check whether user is trying to import files which 
+				// have different ROM IDs
+				for (int i = 0; i < items.length; i++) {
+					CrashFileBundle file = (CrashFileBundle)items[i].getData();
+					if (!items[i].getChecked() || file == null)
+						continue;
+
+					selectedFiles = true;
+					
+					// ignore ROM ID of .crashxml file
+					if (file.isFullyDecoded())
+						continue;
+					
+					//ignore if file has no rom id
+					if ("".equals(file.getRomId()))
+						continue;
+					
+					if (!"".equals(romId) && !file.getRomId().equalsIgnoreCase(romId)) {
+						hasMultipleRomIds = true;
+					}
+					romId = file.getRomId();
+				}
+				
+				// don't allow to proceed when multiple different ROM ID file are selected
+				if (hasMultipleRomIds) {
+					this.setErrorMessage("ROM IDs of selected files do not match. Please select only files which have same ROM IDs.");
+					return false;
+				} else {
+					this.setErrorMessage(null);
+				}
+				
+				// no checked files
+				if (!selectedFiles)
+					return false;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+		return true;
+	}		
+	
+	/**
+	 * Checks whether Finish button can be enabled. Finish button can be
+	 * enabled if user is importing only already decoded files (.crashxml files).
+	 * 
+	 * @return true if Finish button can be enable, false if not
+	 */
+	public boolean canFinish() {
+		try {
+			// if no files in this page (shouldn't happen)
+			if (files == null || files.size() < 1)
+				return false;
+			
+			TableItem[] items = tableFiles.getItems();
+			// if no files in table (shouldn't happen)
+			if (items == null) {
+				return false;
+			} else {
+				boolean hasAnalyzedFiles = false;
+				boolean hasUndecodedFiles = false;
+				// go through all checked files in the table
+				for (int i = 0; i < items.length; i++) {
+					if (!items[i].getChecked())
+						continue;
+					
+					CrashFileBundle file = (CrashFileBundle)items[i].getData();
+					if (file != null) {
+						if (file.isPartiallyDecoded()) {
+							hasUndecodedFiles = true;
+						} else {
+							hasAnalyzedFiles = true;
+						}
+					}
+				}
+				
+				// only .crashxml files are selected, we can show Finish button
+				if (hasAnalyzedFiles && !hasUndecodedFiles)
+					return true;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return false;
+	}
+	
+	/**
+	 * Checks whether only .crashxml files are selected in the table 
+	 * @return true if only .crashxml files are selected, false if not
+	 */
+	public boolean onlyCrashxmlFilesSelected() {
+		try {
+			// if no files in this page (shouldn't happen)
+			if (files == null || files.size() < 1)
+				return false;
+			
+			TableItem[] items = tableFiles.getItems();
+			// if no files in table (shouldn't happen)
+			if (items == null) {
+				return false;
+			} else {
+				boolean onlyCrashxmlFiles = true;
+				// go through all checked files in the table
+				for (int i = 0; i < items.length; i++) {
+					if (!items[i].getChecked())
+						continue;
+					CrashFileBundle file = (CrashFileBundle)items[i].getData();
+					if (file.isPartiallyDecoded()) {
+						onlyCrashxmlFiles = false;
+						break;
+					}
+				}
+				
+				if (onlyCrashxmlFiles)
+					return true;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+		return false;
+	}
+	
+	/**
+	 * Returns indexes of those Crash files which are selected (checked) in the table
+	 * @return indexes of those Crash files which are selected (checked) in the table
+	 */
+	public List<Integer> getFileIndexes() {
+		List<Integer> indexes = new ArrayList<Integer>();
+		
+		TableItem[] items = tableFiles.getItems();
+		// if no files in table (shouldn't happen)
+		if (items == null) {
+			return null;
+		} else {
+			// go through all checked files in the table
+			for (int i = 0; i < items.length; i++) {
+				if (items[i].getChecked())
+					indexes.add(i);
+			}
+		}
+		
+		if (indexes.isEmpty()) {
+			return null;
+		} else {
+			return indexes;
+		}
+	}
+	
+	/**
+	 * Sets this page's context sensitive helps
+	 *
+	 */
+	protected void setHelps() {
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(tableFiles,
+				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);
+		
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(browserFileInfo,
+				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);		
+
+		PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonSelectDeselect,
+				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);		
+	}
+}