crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/ui/wizards/FileOrPathSelectionPage.java
changeset 0 5ad7ad99af01
child 4 615035072f7e
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.jface.dialogs.MessageDialog;
       
    21 import org.eclipse.swt.SWT;
       
    22 import org.eclipse.swt.layout.GridData;
       
    23 import org.eclipse.swt.layout.GridLayout;
       
    24 import org.eclipse.swt.widgets.Button;
       
    25 import org.eclipse.swt.widgets.Combo;
       
    26 import org.eclipse.swt.widgets.Composite;
       
    27 import org.eclipse.swt.widgets.DirectoryDialog;
       
    28 import org.eclipse.swt.widgets.FileDialog;
       
    29 import org.eclipse.swt.widgets.Label;
       
    30 import org.eclipse.swt.dnd.DND;
       
    31 import org.eclipse.swt.dnd.DropTarget;
       
    32 import org.eclipse.swt.dnd.DropTargetEvent;
       
    33 import org.eclipse.swt.dnd.DropTargetListener;
       
    34 import org.eclipse.swt.dnd.FileTransfer;
       
    35 import org.eclipse.swt.dnd.Transfer;
       
    36 import org.eclipse.swt.events.*;
       
    37 import org.eclipse.ui.PlatformUI;
       
    38 import com.nokia.s60tools.ui.wizards.S60ToolsWizardPage;
       
    39 import com.nokia.s60tools.crashanalyser.export.ICrashFileProvider;
       
    40 import com.nokia.s60tools.crashanalyser.files.CrashAnalyserFile;
       
    41 import com.nokia.s60tools.crashanalyser.model.*;
       
    42 import com.nokia.s60tools.crashanalyser.resources.*;
       
    43 import com.nokia.s60tools.crashanalyser.data.*;
       
    44 import java.io.*;
       
    45 
       
    46 /**
       
    47  * This 1st Wizard page queries the user for a crash file or folder from which Crash 
       
    48  * files are found. 
       
    49  *
       
    50  */
       
    51 public class FileOrPathSelectionPage extends S60ToolsWizardPage implements SelectionListener,
       
    52 																			ModifyListener,
       
    53 																			DropTargetListener {
       
    54 
       
    55 	Combo comboFileOrPath;
       
    56 	Button buttonBrowseFolder;
       
    57 	Button buttonBrowseFile;
       
    58 	Button buttonReadFilesFromDevice;
       
    59 	Label labelComboTitle;
       
    60 	Label labelOr;
       
    61 	DecoderEngine engine;
       
    62 	ErrorLibrary errorLibrary;
       
    63 	String providedFileOrFolder;
       
    64 	CrashAnalyserWizard parentWizard;
       
    65 	ICrashFileProvider fileProvider = null;
       
    66 	
       
    67 	/**
       
    68 	 * Constructor
       
    69 	 * @param decEng decoder engine 
       
    70 	 * @param library error library
       
    71 	 */
       
    72 	public FileOrPathSelectionPage(DecoderEngine decEng, 
       
    73 									ErrorLibrary library,
       
    74 									String prefilledFileOrFolder,
       
    75 									CrashAnalyserWizard parent,
       
    76 									ICrashFileProvider crashFileProvider) {
       
    77 		super("");
       
    78 			
       
    79 		setTitle("Crash Files Selection");
       
    80 			
       
    81 		setDescription("MobileCrash File (*.bin), D_EXC File (*.txt), Decoded File (*.crashxml), ELF Core Dump File (*.elf)");
       
    82 		
       
    83 		engine = decEng;
       
    84 		errorLibrary = library;
       
    85 		providedFileOrFolder = prefilledFileOrFolder;
       
    86 		parentWizard = parent;
       
    87 		fileProvider = crashFileProvider;
       
    88 
       
    89 		// User cannot finish the page before some valid 
       
    90 		// selection is made.
       
    91 		setPageComplete(false);
       
    92 		
       
    93 	 }
       
    94 	
       
    95 	
       
    96 	@Override
       
    97 	public void recalculateButtonStates() {
       
    98 		// no implementation needed
       
    99 	}
       
   100 
       
   101 	@Override
       
   102 	public void setInitialFocus() {
       
   103 		comboFileOrPath.setFocus();
       
   104 	}
       
   105 	
       
   106 
       
   107 	/**
       
   108 	 * Creates all UI controls
       
   109 	 */
       
   110 	public void createControl(Composite parent) {
       
   111 		Composite composite =  new Composite(parent, SWT.NULL);
       
   112 		
       
   113 	    // create the desired layout for this wizard page
       
   114 		GridLayout gl = new GridLayout();
       
   115 		gl.numColumns = 3;
       
   116 		composite.setLayout(gl);
       
   117 		
       
   118 		GridData titleGD = new GridData(GridData.FILL_HORIZONTAL);
       
   119 		titleGD.horizontalSpan = 3;
       
   120 
       
   121 		// Combo title
       
   122 		labelComboTitle = new Label(composite, SWT.LEFT);
       
   123 		labelComboTitle.setText("A Crash File or a Folder Containing Crash Files:");
       
   124 		titleGD.horizontalSpan = 3;
       
   125 		labelComboTitle.setLayoutData(titleGD);
       
   126 		
       
   127 		// MobileCrash path combo
       
   128 		comboFileOrPath = new Combo(composite, SWT.BORDER);
       
   129 		GridData comboGD = new GridData(GridData.FILL_HORIZONTAL);
       
   130 		comboFileOrPath.setLayoutData(comboGD);
       
   131 		comboFileOrPath.addModifyListener(this);
       
   132 		
       
   133 
       
   134 		// Restore previous values to MobileCrash path combo
       
   135 		UserEnteredData data = new UserEnteredData();
       
   136 		String[] lastUsed = data.getPreviousValues(UserEnteredData.ValueTypes.CRASH_FILE_OR_PATH);
       
   137 		if (lastUsed != null) {
       
   138 			comboFileOrPath.setItems(lastUsed);
       
   139 			comboFileOrPath.select(0);
       
   140 		}
       
   141 		
       
   142 		// Browse folder button
       
   143 		buttonBrowseFolder = new Button(composite, SWT.PUSH);
       
   144 		buttonBrowseFolder.setText("Folder...");
       
   145 		buttonBrowseFolder.addSelectionListener(this);
       
   146 
       
   147 		// Browse file button
       
   148 		buttonBrowseFile = new Button(composite, SWT.PUSH);
       
   149 		buttonBrowseFile.setText("File...");
       
   150 		buttonBrowseFile.addSelectionListener(this);
       
   151 		
       
   152 		// OR label
       
   153 		labelOr = new Label(composite, SWT.LEFT);
       
   154 		labelOr.setText("OR");
       
   155 		labelOr.setLayoutData(titleGD);
       
   156 		if (fileProvider == null)
       
   157 			labelOr.setVisible(false);
       
   158 		
       
   159 		// Read Files from Device button
       
   160 		buttonReadFilesFromDevice = new Button(composite, SWT.PUSH);
       
   161 		if (fileProvider == null) {
       
   162 			buttonReadFilesFromDevice.setVisible(false);
       
   163 		} else {
       
   164 			buttonReadFilesFromDevice.setText(fileProvider.getFunctionalityName());
       
   165 			buttonReadFilesFromDevice.setToolTipText(fileProvider.getFunctionalityDescription());
       
   166 		}
       
   167 		buttonReadFilesFromDevice.addSelectionListener(this);
       
   168 		
       
   169 		setHelps();
       
   170 
       
   171 		setInitialFocus();
       
   172 		
       
   173 		setControl(composite);
       
   174 		
       
   175 		if (!"".equals(providedFileOrFolder)) {
       
   176 			comboFileOrPath.setText(providedFileOrFolder);
       
   177 		}
       
   178 		
       
   179 		Transfer[] types = new Transfer[] { FileTransfer.getInstance() };
       
   180 	    DropTarget dropTarget = new DropTarget(composite, DND.DROP_COPY);
       
   181 	    dropTarget.setTransfer(types);
       
   182 	    dropTarget.addDropListener(this);		
       
   183 	}
       
   184 	
       
   185 	
       
   186 	public void widgetDefaultSelected(SelectionEvent e)	{
       
   187 		// no implementation needed
       
   188 	}
       
   189 	
       
   190 	public void widgetSelected(SelectionEvent e) {
       
   191 		
       
   192 		// browse directory button
       
   193 		if (e.widget == buttonBrowseFolder) {
       
   194 			// open directory dialog for selecting directory which contains crash files
       
   195 			DirectoryDialog dialog = new DirectoryDialog(this.getShell());
       
   196 			dialog.setText("Select crash files path");
       
   197 			String result = dialog.open();
       
   198 			comboFileOrPath.setText(result);
       
   199 			
       
   200 		// browse file button
       
   201 		} else if (e.widget == buttonBrowseFile){
       
   202 			// open file dialog for selecting a crash file
       
   203 			FileDialog dialog = new FileDialog(this.getShell());
       
   204 			dialog.setText("Select a crash file");
       
   205 			String[] filterExt = { "*."+CrashAnalyserFile.MOBILECRASH_FILE_EXTENSION, 
       
   206 									"*."+CrashAnalyserFile.OUTPUT_FILE_EXTENSION,
       
   207 									"*."+CrashAnalyserFile.D_EXC_FILE_EXTENSION,
       
   208 									"*."+CrashAnalyserFile.ELF_CORE_DUMP_FILE_EXTENSION};
       
   209 	        dialog.setFilterExtensions(filterExt);			
       
   210 			String result = dialog.open();
       
   211 			comboFileOrPath.setText(result);
       
   212 			
       
   213 		// Read Files from Device button
       
   214 		} else if (e.widget == buttonReadFilesFromDevice) {
       
   215 			parentWizard.moveToSecondPageRequest(true);
       
   216 		}
       
   217 	}
       
   218 	
       
   219 	public void modifyText(ModifyEvent event) {
       
   220 		if(event.widget.equals(comboFileOrPath)){
       
   221 			try {
       
   222 				getWizard().getContainer().updateButtons();
       
   223 			} catch (Exception e) {
       
   224 			}
       
   225 		}
       
   226 	}
       
   227 	
       
   228 	/**
       
   229 	 * Checks if user has selected a valid directory or file
       
   230 	 */
       
   231 	public boolean canFlipToNextPage() {
       
   232 		try {
       
   233 			// nothing is selected
       
   234 			if (comboFileOrPath.getText().length() <= 0) {
       
   235 				this.setErrorMessage(null);
       
   236 				return false;
       
   237 			}
       
   238 			
       
   239 			File file = new File(comboFileOrPath.getText());
       
   240 			
       
   241 			// user has selected a directory
       
   242 			if (file.isDirectory() && file.exists()) {
       
   243 				// if selected path has crash files, we can proceed to next page
       
   244 				if (engine.isPathValid(comboFileOrPath.getText(), DecoderEngine.PathTypes.CRASH)) {
       
   245 					this.setErrorMessage(null);
       
   246 					return true;
       
   247 				}
       
   248 				// selected path does not contain crash files, show error
       
   249 				else {
       
   250 					this.setErrorMessage("Selected path does not contain any crash files");
       
   251 					return false;
       
   252 				}
       
   253 			// user has selected a single file
       
   254 			} else if (file.isFile() && file.exists()) {
       
   255 				// file seems to be a known crash file type
       
   256 				if (DecoderEngine.isFileValidCrashFile(file)) {
       
   257 					this.setErrorMessage(null);
       
   258 					return true;
       
   259 				// file type is not a crash file
       
   260 				} else {
       
   261 					this.setErrorMessage("Invalid file");
       
   262 					return false;
       
   263 				}
       
   264 			// user has not selected a folder nor a file
       
   265 			} else {
       
   266 				this.setErrorMessage("Invalid file or folder.");
       
   267 				return false;
       
   268 			}
       
   269 		} catch (Exception e) {
       
   270 			e.printStackTrace();
       
   271 			return false;
       
   272 		}
       
   273 	}	
       
   274 	
       
   275 	/**
       
   276 	 * Returns the user provided crash file directory if it is a directory
       
   277 	 * @return the user provided crash file directory if it is a directory, otherwise ""
       
   278 	 */
       
   279 	public String getSelectedFolder() {
       
   280 		if (comboFileOrPath.getText().length() <= 0) {
       
   281 			return "";
       
   282 		}
       
   283 		
       
   284 		File file = new File(comboFileOrPath.getText());
       
   285 		
       
   286 		// user has selected a directory
       
   287 		if (file.isDirectory() && file.exists()) {
       
   288 			return comboFileOrPath.getText();
       
   289 		}
       
   290 		
       
   291 		return "";
       
   292 	}
       
   293 	
       
   294 	/**
       
   295 	 * Returns the user provided crash file or crash file directory
       
   296 	 * @return the user provided crash file or crash file directory
       
   297 	 */
       
   298 	public String getSelectedFileOrFolder() {
       
   299 		return comboFileOrPath.getText();
       
   300 	}
       
   301 	
       
   302 	/**
       
   303 	 * When next press has been processed, this should be called to inform
       
   304 	 * if any errors were found during next press processing
       
   305 	 * @param error
       
   306 	 */
       
   307 	public void errorInProcessingNextPress(boolean error) {
       
   308 		if (error)
       
   309 			this.setErrorMessage("Could not read files");
       
   310 		else
       
   311 			this.setErrorMessage(null);
       
   312 	}
       
   313 	
       
   314 	/**
       
   315 	 * Saves current combo value so that it will be the default value
       
   316 	 * next time this wizard is shown.
       
   317 	 */
       
   318 	public void saveUserEnteredData() {
       
   319 		UserEnteredData userData = new UserEnteredData();
       
   320 		userData.saveValue(UserEnteredData.ValueTypes.CRASH_FILE_OR_PATH, comboFileOrPath.getText());			
       
   321 	}
       
   322 	
       
   323 	/**
       
   324 	 * Sets this page's context sensitive helps
       
   325 	 *
       
   326 	 */
       
   327 	protected void setHelps() {
       
   328 		PlatformUI.getWorkbench().getHelpSystem().setHelp(comboFileOrPath,
       
   329 				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);
       
   330 		PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonBrowseFolder,
       
   331 				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);		
       
   332 		PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonBrowseFile,
       
   333 				HelpContextIDs.CRASH_ANALYSER_HELP_IMPORT_CRASH_FILES);		
       
   334 	}
       
   335 	
       
   336 	/**
       
   337 	 * Executes drop functionality when files are drag&dropped to wizard page.
       
   338 	 * Checks whether dropped files are supported and starts "presses next automatically"
       
   339 	 * @param files drag&dropped files (paths)
       
   340 	 */
       
   341 	void executeDrop(String[] files) {
       
   342 		// just one (supported) file dropped
       
   343 		if (files.length == 1 && DecoderEngine.isFileValidCrashFile(files[0])) {
       
   344 			comboFileOrPath.setText(files[0]);
       
   345 			parentWizard.moveToSecondPageRequest(files);
       
   346 		// multiple files dropped
       
   347 		} else if (files.length > 1) {
       
   348 			String path = "";
       
   349 			// go through all dropped files, and check that they are from same folder
       
   350 			// (wizard doesn't know how to handle multiple files from multiple locations)
       
   351 			for (int i = 0; i < files.length; i++) {
       
   352 				if (DecoderEngine.isFileValidCrashFile(files[i])) {
       
   353 					if ("".equals(path)) {
       
   354 						path = FileOperations.getFolder(files[i]);
       
   355 					} else if (!FileOperations.getFolder(files[i]).equalsIgnoreCase(path)){
       
   356 						showMessage("Multiple files from different folders are not supported");
       
   357 						break;
       
   358 					}
       
   359 				} else {
       
   360 					showMessage("Unsupported file type");
       
   361 					break;
       
   362 				}
       
   363 			}
       
   364 			comboFileOrPath.setText(path);
       
   365 			parentWizard.moveToSecondPageRequest(files);
       
   366 		} else {
       
   367 			showMessage("Unsupported file type");
       
   368 		}
       
   369 	}
       
   370 	
       
   371 	/**
       
   372 	 * Shows a message box with given message
       
   373 	 * @param message
       
   374 	 */
       
   375 	private void showMessage(String message) {
       
   376 		MessageDialog.openInformation(
       
   377 			comboFileOrPath.getShell(),
       
   378 			"Crash Analyser",
       
   379 			message);
       
   380 	}
       
   381 	
       
   382 	public void dragEnter(DropTargetEvent event) {
       
   383 		event.detail = DND.DROP_COPY;
       
   384 	}
       
   385 
       
   386 	public void dragLeave(DropTargetEvent event) {
       
   387 		// nothing to be done
       
   388 	}
       
   389 
       
   390 	public void dragOperationChanged(DropTargetEvent event) {
       
   391 		// nothing to be done
       
   392 	}
       
   393 
       
   394 	public void dragOver(DropTargetEvent event) {
       
   395 		event.feedback = DND.FEEDBACK_NONE;
       
   396 	}
       
   397 
       
   398 	public void drop(DropTargetEvent event) {
       
   399 		// we accept only file drops
       
   400 		if (FileTransfer.getInstance().isSupportedType(event.currentDataType)) {
       
   401 			if (event.data != null) {
       
   402 				String[] files = (String[])event.data;
       
   403 				executeDrop(files);
       
   404 			}
       
   405 		}
       
   406 	}
       
   407 
       
   408 	public void dropAccept(DropTargetEvent event) {
       
   409 		// nothing to be done
       
   410 	}
       
   411 	
       
   412 }