crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/ui/editors/RegistersPage.java
changeset 4 615035072f7e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/ui/editors/RegistersPage.java	Tue Apr 20 14:41:43 2010 +0300
@@ -0,0 +1,454 @@
+/*
+* Copyright (c) 2010 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.editors;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.crashanalyser.containers.Process;
+import com.nokia.s60tools.crashanalyser.containers.Register;
+import com.nokia.s60tools.crashanalyser.containers.RegisterBit;
+import com.nokia.s60tools.crashanalyser.containers.RegisterDetails;
+import com.nokia.s60tools.crashanalyser.containers.RegisterSet;
+import com.nokia.s60tools.crashanalyser.containers.Thread;
+import com.nokia.s60tools.crashanalyser.files.CrashFile;
+import com.nokia.s60tools.crashanalyser.files.SummaryFile;
+import com.nokia.s60tools.crashanalyser.resources.HelpContextIDs;
+
+public class RegistersPage implements SelectionListener {
+	// registers group UI items
+	Combo comboRegisters;
+	Table tableRegisters;
+
+	// CPSR details group UI items
+	Group groupCpsrEmpty;
+	Combo comboCpsrDetails;
+	Table tableCpsrDetails;
+
+	FontRegistry fontRegistry;
+	SummaryFile crashFile;
+	Process selectedProcess = null;
+	Thread selectedThread = null;
+
+	
+	/**
+	 * Creates the page
+	 * @param parent composite
+	 * @param file summary file
+	 * @return composite
+	 */
+	public Composite createPage(Composite parent, SummaryFile file) {
+		crashFile = file;
+		return doCreatePage(parent);
+	}
+	
+	/**
+	 * Creates the page
+	 * @param parent composite
+	 * @return composite
+	 */
+	public Composite createPage(Composite parent) {
+		return doCreatePage(parent);
+	}
+	
+	/**
+	 * Loads data from given file into UI elements.
+	 * @param file crash file
+	 */
+	public void setFile(CrashFile file) {
+		if (file != null) {
+			crashFile = file;
+			initialUserRegistersTableLoad();
+			initialCpsrDetailsTableLoad();
+		}
+	}
+	
+	/**
+	 * Creates all UI elements to the page
+	 * @param parent
+	 * @return composite
+	 */
+	Composite doCreatePage(Composite parent) {
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 1;
+		parent.setLayout(layout);
+		parent.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		fontRegistry = new FontRegistry(Display.getCurrent());
+		fontRegistry.put("monospace", new FontData[]{new FontData("Courier", 8, SWT.NORMAL)});
+
+		SashForm sashFormMain = new SashForm(parent, SWT.VERTICAL);
+		sashFormMain.setLayoutData(new GridData(GridData.FILL_BOTH));
+//		SashForm sashFormTop = new SashForm(sashFormMain, SWT.HORIZONTAL);
+		createRegistersGroup(sashFormMain);
+//		createCodeSegmentsGroup(sashFormTop);
+//		SashForm sashFormBottom = new SashForm(sashFormMain, SWT.HORIZONTAL);
+//		createEventLogGroup(sashFormBottom);
+		createCpsrDetailsGroup(sashFormMain);
+		
+//		sashFormTop.setWeights(new int[]{3,2});
+//		sashFormBottom.setWeights(new int[]{3,7});
+			
+		setHelps();
+		
+		return parent;
+	}
+
+	/**
+	 * Creates registers group
+	 * @param parent
+	 */
+	void createRegistersGroup(Composite parent) {
+		Group groupRegisters = new Group(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		groupRegisters.setLayout(layout);
+		groupRegisters.setText("Registers");
+		GridData groupGD = new GridData(GridData.FILL_HORIZONTAL);
+		groupRegisters.setLayoutData(groupGD);
+		
+		comboRegisters = new Combo(groupRegisters, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
+		GridData comboGD = new GridData();
+		comboGD.horizontalSpan = 2;
+		comboRegisters.setLayoutData(comboGD);
+		comboRegisters.addSelectionListener(this);
+		
+		tableRegisters = new Table(groupRegisters, SWT.BORDER);
+		tableRegisters.setHeaderVisible(true);
+		tableRegisters.setLinesVisible(true);
+		TableColumn col = new TableColumn(tableRegisters, SWT.LEFT);
+		col.setWidth(100);
+		col.setText("Register");
+		col = new TableColumn(tableRegisters, SWT.LEFT);
+		col.setWidth(100);
+		col.setText("Value");
+		col = new TableColumn(tableRegisters, SWT.LEFT);
+		col.setWidth(100);
+		col.setText("Symbol");
+		col = new TableColumn(tableRegisters, SWT.LEFT);
+		col.setWidth(100);
+		col.setText("Comment");
+		tableRegisters.setFont(fontRegistry.get("monospace"));
+
+		GridData tableGd = new GridData(GridData.FILL_BOTH);
+		tableGd.horizontalSpan = 2;
+		tableRegisters.setLayoutData(tableGd);
+
+		initialUserRegistersTableLoad();
+	}
+		/**
+		 * Creates cpsr details group
+		 * @param parent
+		 */
+		void createCpsrDetailsGroup(Composite parent) {
+			Group groupCpsrDetails = new Group(parent, SWT.NONE);
+			GridLayout layout = new GridLayout();
+			layout.numColumns = 1;
+			groupCpsrDetails.setLayout(layout);
+			groupCpsrDetails.setText("CPSR Details");
+			GridData groupGD = new GridData(GridData.FILL_VERTICAL);
+			groupCpsrDetails.setLayoutData(groupGD);
+			
+			comboCpsrDetails = new Combo(groupCpsrDetails, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
+			comboCpsrDetails.addSelectionListener(this);
+
+			// Empty group
+			groupCpsrEmpty = new Group(groupCpsrDetails, SWT.NONE);
+			FormLayout fl = new FormLayout();
+			fl.marginRight = 5;
+			fl.marginLeft = 5;
+			fl.marginBottom = 5;
+			groupCpsrEmpty.setLayout(fl);
+			GridData groupCpsrEmptyGd = new GridData(GridData.FILL_HORIZONTAL);
+			groupCpsrEmptyGd.horizontalAlignment = SWT.FILL;
+			groupCpsrEmptyGd.grabExcessHorizontalSpace = true;
+			groupCpsrEmpty.setLayoutData(groupCpsrEmptyGd);
+
+			// create 32 empty text boxes
+			for (int i = 0; i < 32; i++) {
+				Text text = new Text(groupCpsrEmpty, SWT.READ_ONLY | SWT.BORDER | SWT.NO_FOCUS | SWT.CENTER);
+				text.setFont(fontRegistry.get("monospace"));
+				FormData textFd = new FormData();
+				textFd.left = new FormAttachment(0,i*20);
+				textFd.top = new FormAttachment(8, 15);
+				textFd.width = 8;
+				text.setLayoutData(textFd); 			
+			}
+
+			tableCpsrDetails = new Table(groupCpsrDetails, SWT.BORDER);
+			tableCpsrDetails.setLinesVisible(true);
+			tableCpsrDetails.setHeaderVisible(true);
+			TableColumn col = new TableColumn(tableCpsrDetails, SWT.LEFT);
+			col.setWidth(380);
+			col.setText("Name");
+			col = new TableColumn(tableCpsrDetails, SWT.LEFT);
+			col.setWidth(220);
+			col.setText("Value");
+			GridData tableGd = new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL);
+			tableGd.horizontalAlignment = SWT.FILL;
+			tableGd.grabExcessHorizontalSpace = true;
+			tableCpsrDetails.setLayoutData(tableGd);
+			tableCpsrDetails.setFont(fontRegistry.get("monospace"));
+			initialCpsrDetailsTableLoad();
+		}
+		
+		
+		/**
+		 * Loads register sets to combo, selects the correct set as
+		 * default set and then loads set's registers to table.
+		 */
+		void initialUserRegistersTableLoad() {
+			if (crashFile == null)
+				return;
+
+			int defaultSelectionIndex = 0;
+
+			// show the data of crashed process
+			if (crashFile.getThread() != null) {
+				selectedProcess = crashFile.getProcessByThread(crashFile.getThread().getId());
+			} else {
+				selectedProcess = crashFile.getCrashedProcess();
+			}
+				
+			if (selectedProcess != null) {
+				// current UI support only one thread, so show the first thread of first process
+				if(crashFile.getThread() != null) {
+					selectedThread = crashFile.getThread();
+				} else {
+					selectedThread = crashFile.getCrashedThread();
+				}
+				
+				if (selectedThread != null) {
+					List<RegisterSet> registerSets = selectedThread.getRegisters();
+					if (registerSets != null && !registerSets.isEmpty()) {
+						// load all register sets to combo
+						for (int i = 0; i < registerSets.size(); i++) {
+							RegisterSet registerSet = registerSets.get(i);
+							// default register to show is the one that contains CPSR register
+							if (registerSet.containsCPSR()) 
+								defaultSelectionIndex = i;
+							comboRegisters.add(registerSet.getName());
+							comboRegisters.setData(registerSet.getName(), registerSet);
+						}
+					}
+				}
+			}
+			
+			List<RegisterSet> standAloneRegisters = crashFile.getStandAloneRegisterSets();
+			if (standAloneRegisters != null && !standAloneRegisters.isEmpty()) {
+				for (int i = 0; i < standAloneRegisters.size(); i++) {
+					RegisterSet regSet = standAloneRegisters.get(i);
+					if (regSet.containsCPSR())
+						defaultSelectionIndex = comboRegisters.getItemCount() + i;
+					comboRegisters.add(regSet.getName());
+					comboRegisters.setData(regSet.getName(), regSet);
+				}
+			}
+			
+			if (comboRegisters.getItemCount() > 0) {
+				comboRegisters.select(defaultSelectionIndex);
+				loadRegistersTable();
+			}
+			
+		}
+		
+		/**
+		 * Loads user registers table according to which registers set is
+		 * selected in combo. 
+		 */
+		void loadRegistersTable() {
+			tableRegisters.removeAll();
+			
+			if (comboRegisters.getItemCount() < 1)
+				return;
+			
+			try {
+				RegisterSet registerSet = (RegisterSet)comboRegisters.getData(comboRegisters.getText());
+				List<Register> registers = registerSet.getRegisters();
+				if (registers != null && !registers.isEmpty()) {
+					// show all register values in selected register set
+					for (int i = 0; i < registers.size(); i++) {
+						Register register = registers.get(i);
+						newRegistersTableItem(register);
+					}
+					AutoSizeTableCells(tableRegisters);
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+
+		/**
+		 * Loads cprs types to combo, selects first type and then loads it's
+		 * data to table.
+		 */
+		void initialCpsrDetailsTableLoad() {
+			if (crashFile == null)
+				return;
+
+			List<RegisterDetails> registerDetails = crashFile.getRegisterDetails();
+			if (registerDetails != null && !registerDetails.isEmpty()) {
+				for (int i = 0; i < registerDetails.size(); i++) {
+					RegisterDetails regDetails = registerDetails.get(i);
+					if (regDetails.getDescription().contains("CPSR")) {
+						comboCpsrDetails.add(regDetails.getDescription());
+						comboCpsrDetails.setData(regDetails.getDescription(), regDetails);
+					}
+				}
+				comboCpsrDetails.select(0);
+				loadCpsrDetailsTable();
+			}		
+		}
+		
+		/**
+		 * Loads currently selected cprs's details into table.
+		 */
+		void loadCpsrDetailsTable() {
+			try {
+				tableCpsrDetails.removeAll();
+
+				RegisterDetails registerDetails = null;
+				if (comboRegisters.getSelectionIndex() >= 0)
+					registerDetails = (RegisterDetails)comboCpsrDetails.getData(comboCpsrDetails.getText());
+
+				if (registerDetails != null) {
+					boolean bitStartFromRight = registerDetails.bitsStartFromRight();
+					Map<String, String> categories = new HashMap<String, String>();
+					// go through all 32 text boxes, and see if there is a bit for each box
+					for (int i = 0, j = 31; i < 32; i++, j--) {
+						Text box = (Text)groupCpsrEmpty.getChildren().clone()[j];
+						// bits can start from the right or left (endianess)
+						if (!bitStartFromRight)
+							box = (Text)groupCpsrEmpty.getChildren().clone()[i];
+						RegisterBit bit = registerDetails.getBit(i);
+						// there's no bit for this box
+						if (bit == null) {
+							box.setText("");
+							box.setToolTipText("");
+							// there is a bit for this box
+						} else {
+							String regChar = bit.getRegisterChar();
+							String category = bit.getCategory();
+							String interpretation = bit.getInterpretation();
+							// if this bit contains a longer description, it should be shown in the table also
+							if (!"".equals(interpretation) && !categories.containsKey(category)) {
+								categories.put(category, interpretation);
+							}
+							box.setText(regChar);
+							box.setToolTipText(category);
+						}
+					}
+				
+					// load table
+					for (int i = 0; i < categories.size(); i++) {
+						newCpsrDetailsTableItem(categories.keySet().toArray()[i].toString(),
+											categories.values().toArray()[i].toString());
+					}
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		
+		/**
+		 * Adds a new table row for registers table
+		 * @param register row data
+		 */
+		void newRegistersTableItem(Register register) {
+			TableItem item = new TableItem(tableRegisters, SWT.NONE);
+			item.setText(new String[] {register.getName(),
+										register.getValue(),
+										register.getSymbol(),
+										register.getComments()});
+		}	
+
+		/**
+		 * Adds a new table row for cpsr details table
+		 * @param header header text
+		 * @param value value text
+		 */
+		void newCpsrDetailsTableItem(String header, String value) {
+			TableItem item = new TableItem(tableCpsrDetails, SWT.NONE);
+			item.setText(new String[] {header, value});
+		}
+
+		/**
+		 * Packs all columns for given table
+		 * @param table table which columns are to be packed
+		 */
+		void AutoSizeTableCells(Table table) {
+			for (int i = 0; i < table.getColumnCount(); i++) {
+				table.getColumn(i).pack();
+			}
+		}
+		
+		public void widgetDefaultSelected(SelectionEvent arg0) {
+			// No implementation needed
+		}
+
+		public void widgetSelected(SelectionEvent event) {
+			// cpsr was changed in combo
+			if (event.widget == comboCpsrDetails) {
+				loadCpsrDetailsTable();
+			// register set was changed in combo
+			} else if (event.widget == comboRegisters) {
+				loadRegistersTable();
+			}
+		}
+		
+		/**
+		 * Sets context sensitive help ids to UI elements
+		 */
+		void setHelps() {
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(tableCpsrDetails,
+					HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);	
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(tableRegisters,
+					HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);	
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(tableRegisters,
+					HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);	
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(comboCpsrDetails,
+					HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);	
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(comboRegisters,
+					HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);	
+		}
+		
+	}
+
+