diff -r 5b9d4d8641ce -r ae255c9aa552 sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/ProfilerActivatorGroup.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.wizards/src/com/nokia/carbide/cpp/internal/pi/wizards/ui/ProfilerActivatorGroup.java Wed Jun 23 15:05:09 2010 +0300 @@ -0,0 +1,706 @@ +/* + * 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 the License "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.carbide.cpp.internal.pi.wizards.ui; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.eclipse.core.resources.WorkspaceJob; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.wizard.IWizardContainer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; + +import com.nokia.carbide.cpp.internal.pi.plugin.model.ITrace; +import com.nokia.carbide.cpp.pi.PiPlugin; +import com.nokia.carbide.cpp.pi.export.ITraceProvider; +import com.nokia.carbide.cpp.pi.wizards.WizardsPlugin; +import com.nokia.s60tools.ui.preferences.PreferenceUtils; + +/** + * Provides functionality of the profiler activator + */ +public class ProfilerActivatorGroup extends AbstractBaseGroup { + + private TableViewer profileDataTable; + private Composite rightButtonsComposite; + private Label connectionNameInUseLabel; + private IWizardContainer wizardContainer; + private NewPIWizardPage wizardPage; + private TraceHandler traceHandler; + private PluginSelectionGroup pluginSelectionGroup; + private Group settingsButtonGroup; + private Button refreshListButton; + private Button connectionSettingsButton; + private Button tracingButton; + + /** + * Constructor + * + * @param parent + * instance of the parent composite + * @param wizardSettings + * instance of the INewPIWizardSettings + * @param wizardPage + * instance of the NewPIWizardPage + * @param wizardContainer + * instance of the IWizardContainer + */ + public ProfilerActivatorGroup(Composite parent, + INewPIWizardSettings wizardSettings, NewPIWizardPage wizardPage, + IWizardContainer wizardContainer) { + super(parent, wizardSettings, true); + this.wizardContainer = wizardContainer; + this.wizardPage = wizardPage; + traceHandler = new TraceHandler(this); + } + + /* + * (non-Javadoc) + * + * @see + * com.nokia.carbide.cpp.internal.pi.wizards.ui.AbstractBaseGroup#createContent + * () + */ + protected void createContent() { + GridLayout gridLayout = new GridLayout(); + gridLayout.numColumns = 2; + this.setLayout(gridLayout); + this.setLayoutData(new GridData(GridData.FILL_BOTH)); + this.setText(Messages.getString("NewPIWizardPageInputTask.fromDevice")); //$NON-NLS-1$ + + final Composite leftTables = new Composite(this, SWT.NONE); + leftTables.setLayout(new GridLayout()); + leftTables.setLayoutData(new GridData(GridData.FILL_BOTH)); + pluginSelectionGroup = new PluginSelectionGroup(leftTables, + wizardSettings, true); + + new Label(leftTables, SWT.NONE).setText(Messages + .getString("ProfilerActivatorGroup.profilerDataTableTitle")); //$NON-NLS-1$ + profileDataTable = new TableViewer(leftTables, SWT.BORDER | SWT.SINGLE + | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + + TableColumn column = new TableColumn(profileDataTable.getTable(), + SWT.NONE); + column.setText(Messages.getString("ProfilerActivatorGroup.columnName")); //$NON-NLS-1$ + column.setWidth(200); + column.setResizable(true); + column.setMoveable(true); + column.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (!(e.widget instanceof TableColumn)) + return; + ((AbstractBaseSorter) profileDataTable.getSorter()).doSort(0); + profileDataTable.refresh(); + + } + }); + + column = new TableColumn(profileDataTable.getTable(), SWT.NONE); + column.setText(Messages.getString("ProfilerActivatorGroup.columnTime")); //$NON-NLS-1$ + column.setWidth(120); + column.setResizable(true); + column.setMoveable(true); + column.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (!(e.widget instanceof TableColumn)) + return; + ((AbstractBaseSorter) profileDataTable.getSorter()).doSort(1); + profileDataTable.refresh(); + + } + }); + + column = new TableColumn(profileDataTable.getTable(), SWT.NONE); + column.setText(Messages.getString("ProfilerActivatorGroup.columnSize")); //$NON-NLS-1$ + column.setWidth(120); + column.setResizable(true); + column.setMoveable(true); + column.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (!(e.widget instanceof TableColumn)) + return; + ((AbstractBaseSorter) profileDataTable.getSorter()).doSort(2); + profileDataTable.refresh(); + + } + }); + + GridData fileLogsTableGridData = new GridData(GridData.FILL_BOTH); + fileLogsTableGridData.minimumHeight = 120; + profileDataTable.getTable().setLayoutData(fileLogsTableGridData); + profileDataTable.getTable().setHeaderVisible(true); + profileDataTable.getTable().setLinesVisible(true); + profileDataTable.setContentProvider(new IStructuredContentProvider() { + public Object[] getElements(Object inputElement) { + if (inputElement instanceof List) { + return ((List) inputElement).toArray(); + } + return new Object[0]; + } + + public void dispose() { + } + + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + + }); + + profileDataTable.setSorter(new AbstractBaseSorter(profileDataTable + .getTable(), 0) { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + ProfilerDataPlugins pdp1 = (ProfilerDataPlugins) e1; + ProfilerDataPlugins pdp2 = (ProfilerDataPlugins) e2; + int returnCode = 0; + switch (column) { + case 0: + returnCode = pdp1 + .getProfilerDataPath() + .lastSegment() + .compareTo(pdp2.getProfilerDataPath().lastSegment()); + break; + case 1: + returnCode = compareNumber(pdp1.getTime(), pdp2.getTime()); + break; + case 2: + returnCode = compareNumber(pdp1.getSize(), pdp2.getSize()); + break; + + default: + + break; + } + if (!sortAscending) + returnCode = -returnCode; + return returnCode; + } + }); + + profileDataTable.setLabelProvider(new AbstractLabelProvider() { + public String getColumnText(Object element, int columnIndex) { + ProfilerDataPlugins plugins = (ProfilerDataPlugins) element; + + switch (columnIndex) { + case 0: + return plugins.getProfilerDataPath().lastSegment(); + case 1: + SimpleDateFormat formatter = new SimpleDateFormat("mm:ss"); //$NON-NLS-1$ + return formatter.format(new Date(plugins.getTime())); + case 2: + return String.valueOf((plugins.getSize() + 512) / 1024); + default: + break; + } + return ""; //$NON-NLS-1$ + } + }); + + rightButtonsComposite = new Composite(this, SWT.NONE); + + GridData rightButtonsCompositeGridData = new GridData( + GridData.HORIZONTAL_ALIGN_FILL); + rightButtonsComposite.setLayoutData(rightButtonsCompositeGridData); + rightButtonsComposite.setLayout(new GridLayout()); + + // Connection settings button + settingsButtonGroup = new Group(rightButtonsComposite, SWT.NONE); + settingsButtonGroup.setLayout(new GridLayout()); + settingsButtonGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + + refreshListButton = new Button(settingsButtonGroup, SWT.PUSH); + refreshListButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + refreshListButton.setText(Messages + .getString("ProfilerActivatorGroup.refreshButtonName")); //$NON-NLS-1$ + refreshListButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updatePlugins(traceHandler.fetchAvailablePlugins()); + } + }); + + connectionSettingsButton = new Button(settingsButtonGroup, SWT.PUSH); + connectionSettingsButton.setLayoutData(new GridData( + GridData.FILL_HORIZONTAL)); + connectionSettingsButton + .setText(Messages + .getString("ProfilerActivatorGroup.connectionSettingsButtonName")); //$NON-NLS-1$ + connectionSettingsButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + Shell shell = PiPlugin.getCurrentlyActiveWbWindowShell(); + PreferenceUtils.openPreferencePage(PiPlugin.getTraceProvider() + .getTraceSourcePreferencePageId(), shell); + updateConnectionText(); + } + }); + // Connection settings labels + Label connectionTextLabel = new Label(settingsButtonGroup, SWT.LEFT); + connectionTextLabel.setText(Messages + .getString("ProfilerActivatorGroup.currentlyUsingTitle")); //$NON-NLS-1$ + connectionTextLabel.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_CENTER)); + + connectionNameInUseLabel = new Label(settingsButtonGroup, SWT.NONE); + connectionNameInUseLabel.setLayoutData(new GridData( + GridData.HORIZONTAL_ALIGN_CENTER)); + Group traceButtonGroup = new Group(rightButtonsComposite, SWT.NONE); + traceButtonGroup.setLayout(new GridLayout()); + traceButtonGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); + new Label(traceButtonGroup, SWT.LEFT).setText(Messages + .getString("ProfilerActivatorGroup.filePrefixTitle")); //$NON-NLS-1$ + final Text filePrefixText = new Text(traceButtonGroup, SWT.BORDER); + filePrefixText.setText("PIProfiler_#"); //$NON-NLS-1$ + filePrefixText.setLayoutData(new GridData(GridData.FILL_BOTH)); + + // Start/Stop tracing button + tracingButton = new Button(traceButtonGroup, SWT.PUSH); + tracingButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + tracingButton.setText(Messages + .getString("ProfilerActivatorGroup.startTracingButtonName")); //$NON-NLS-1$ + tracingButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + if (PiPlugin.getTraceProvider().isListening()) { + addTraceFile(traceHandler.stopTrace()); + } else { + traceHandler.startTrace(filePrefixText.getText(), + pluginSelectionGroup.getSelectedPluginIds()); + } + updateButtons(); + } + }); + + } + + /** + * Compare two long number + * + * @param one + * @param two + * @return result of the comparison + */ + private int compareNumber(long one, long two) { + if (one > two) { + return 1; + } else if (one < two) { + return -1; + } else { + return 0; + } + } + + /** + * updateConnectionText updates connection text to match used settings + */ + private void updateConnectionText(boolean forceUpdate) { + traceHandler.updateCurrenConnection(); + if (pluginSelectionGroup.getSelectedPluginIds().length <= 0 + || forceUpdate) { + updatePlugins(traceHandler.fetchAvailablePlugins()); + } + } + + /** + * updateConnectionText updates connection text to match used settings + */ + private void updateConnectionText() { + traceHandler.updateCurrenConnection(); + } + + /** + * Set current connection name + * + * @param connection + * the current connection name + */ + public void setCurrentConnection(final String connection) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + connectionNameInUseLabel.setText(connection); + getParent().layout(true, true); + } + }); + + } + + /* + * (non-Javadoc) + * + * @see + * com.nokia.carbide.cpp.internal.pi.wizards.ui.AbstractBaseGroup#getTable() + */ + @Override + public Table getTable() { + return profileDataTable.getTable(); + } + + @Override + public IStatus validateContent(NewPIWizard wizardPage) { + List dataFiles = getProfilerDataFiles(); + if (dataFiles != null && dataFiles.size() > 0) { + wizardPage.setProfilerDataFiles(getProfilerDataFiles()); + return Status.OK_STATUS; + } else { + return new Status( + Status.INFO, + WizardsPlugin.PLUGIN_ID, + Messages + .getString("ProfilerActivatorGroup.profilerGroupDescription")); //$NON-NLS-1$ + } + + } + + @Override + public void setVisible(boolean visible) { + if (visible) { + updateConnectionText(false); + } + super.setVisible(visible); + + } + + private void updatePlugins(final List plugins) { + pluginSelectionGroup.updateTraceIds(new ProfilerDataPlugins( + new Path(""), plugins)); //$NON-NLS-1$ + updateButtons(); + } + + /** + * Add given trace data file to profiler data file table + * + * @param path + */ + private void addTraceFile(final IPath path) { + if (path == null) { + return; + } + ProfilerDataPlugins dataPlugins = removeWithPath(path + .removeFileExtension().addFileExtension( + ITraceProvider.BASE_FILE)); + if (dataPlugins != null) { + try { + addProfilerDataFile(path, dataPlugins.getTime(), path.toFile() + .length()); + refreshTable(profileDataTable, true); + } catch (Exception e) { + wizardPage + .setErrorMessage(e.getMessage() + + " " + Messages.getString("ProfilerActivatorGroup.tryDeselectPluginsFromList")); //$NON-NLS-1$ //$NON-NLS-2$ + wizardPage.setPageComplete(false); + refreshTable(profileDataTable, false); + path.toFile().delete(); + } + } + } + + public NewPIWizardPage getWizardPage() { + return wizardPage; + } + + public IWizardContainer getWizardContainer() { + return wizardContainer; + } + + /** + * Update trace data files + * + * @param path + * @param time + * @param size + */ + public void updateTraceDataFile(final IPath path, final long time, + final long size) { + Display.getDefault().syncExec(new Runnable() { + public void run() { + // remove if both time and size are -1 + if (time == -1 && size == -1) { + removeWithPath(path); + } else { + updateProfilerDataFile(path, time, size); + } + refreshTable(profileDataTable, false); + } + }); + } + + /** + * Update buttons + */ + public void updateButtons() { + if (PiPlugin.getTraceProvider().isListening()) { + wizardPage.setErrorMessage(null); + refreshListButton.setEnabled(false); + connectionSettingsButton.setEnabled(false); + ((NewPIWizardPageInputTask) wizardPage) + .setButtonGroupEnabled(false); + tracingButton.setText(Messages + .getString("ProfilerActivatorGroup.stopTracingButtonName")); //$NON-NLS-1$ + } else { + refreshListButton.setEnabled(true); + connectionSettingsButton.setEnabled(true); + ((NewPIWizardPageInputTask) wizardPage).setButtonGroupEnabled(true); + tracingButton + .setText(Messages + .getString("ProfilerActivatorGroup.startTracingButtonName")); //$NON-NLS-1$ + } + + if (pluginSelectionGroup.getSelectedPluginIds().length <= 0) { + tracingButton.setEnabled(false); + } else { + tracingButton.setEnabled(true); + } + } + + /** + * Generate next dat file name + * + * @param path + * @return + */ + private IPath generateDatFile(IPath path) { + while (path.toFile().exists()) { + String file = path.lastSegment(); + String fileExtension = path.getFileExtension(); + file = file.substring(0, file.lastIndexOf("." + fileExtension)); //$NON-NLS-1$ + int index = file.lastIndexOf("_"); //$NON-NLS-1$ + if (index != -1) { + try { + int count = Integer.valueOf(file.substring(index + 1)); + count++; + file = file.substring(0, index + 1) + count; + path = path.removeLastSegments(1).append( + file + "." + fileExtension); //$NON-NLS-1$ + } catch (Exception e) { + path = path.removeLastSegments(1).append( + file + "_0." + fileExtension); //$NON-NLS-1$ + } + + } else { + path = path.removeLastSegments(1).append( + file + "_0." + fileExtension); //$NON-NLS-1$ + } + } + return path; + + } + + /** + * Handle temporary profiler data files in case user is tried to close + * wizard and user has traced some data from device + * + * @param forceRemove + */ + public void handleTemporaryProfilerDataFiles(boolean forceRemove) { + final List plugins = new ArrayList(); + plugins.addAll(getProfilerDataFiles()); + getProfilerDataFiles().clear(); + if (forceRemove) { + deleteProfilerDataFiles(plugins); + } else if (plugins.size() > 0) { + boolean answer = MessageDialog + .openQuestion( + Display.getDefault().getActiveShell(), + Messages + .getString("ProfilerActivatorGroup.questionDialogTitle"), Messages.getString("ProfilerActivatorGroup.questionDialogMessage")); //$NON-NLS-1$ //$NON-NLS-2$ + if (answer) { + // open file dialog for selecting a crash file + DirectoryDialog dialog = new DirectoryDialog(Display + .getDefault().getActiveShell()); + dialog + .setText(Messages + .getString("ProfilerActivatorGroup.directorySelectionDialogTitle")); //$NON-NLS-1$ + final String result = dialog.open(); + if (result != null) { + WorkspaceJob job = new WorkspaceJob( + Messages + .getString("ProfilerActivatorGroup.movingProfilerDataFilesJob") + result) { //$NON-NLS-1$ + @Override + public IStatus runInWorkspace(IProgressMonitor monitor) + throws CoreException { + monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + for (ProfilerDataPlugins plugin : plugins) { + IPath dataFile = plugin.getProfilerDataPath(); + IPath targetFile = generateDatFile(new Path( + result).append(dataFile.lastSegment())); + try { + moveFile(dataFile, targetFile, + new SubProgressMonitor(monitor, + IProgressMonitor.UNKNOWN)); + } catch (Exception e) { + List list = new ArrayList(); + list.add(plugin); + deleteProfilerDataFiles(list); + e.printStackTrace(); + MessageDialog + .openError( + getShell(), + Messages + .getString("ProfilerActivatorGroup.errorDialogTitle"), MessageFormat.format(Messages.getString("ProfilerActivatorGroup.failedToMoveFileTo"), dataFile.lastSegment(), result)); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + monitor.done(); + return Status.OK_STATUS; + } + }; + job.schedule(); + } else { + deleteProfilerDataFiles(plugins); + } + } else { + deleteProfilerDataFiles(plugins); + } + } + } + + /** + * Delete profiler data files + * + * @param plugins + */ + private void deleteProfilerDataFiles(final List plugins) { + WorkspaceJob job = new WorkspaceJob(Messages + .getString("ProfilerActivatorGroup.removeProfilerDataFilesJob")) { //$NON-NLS-1$ + + @Override + public IStatus runInWorkspace(IProgressMonitor monitor) + throws CoreException { + monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + for (ProfilerDataPlugins plugin : plugins) { + IPath dataFile = plugin.getProfilerDataPath(); + monitor + .setTaskName(MessageFormat + .format( + Messages + .getString("ProfilerActivatorGroup.deletingProfilerDataFiles"), dataFile.lastSegment())); //$NON-NLS-1$ + if (dataFile.toFile().exists()) { + while (!dataFile.toFile().delete()) { + if (monitor.isCanceled()) { + break; + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + } + ; + monitor.done(); + return Status.OK_STATUS; + } + + }; + job.schedule(); + + } + + /** + * Move profiler data file from temporary location to user selected target + * + * @param source + * @param target + * @param monitor + * @throws IOException + */ + private void moveFile(final IPath source, IPath target, + IProgressMonitor monitor) throws IOException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + InputStream in = null; + OutputStream out = null; + try { + monitor + .beginTask( + MessageFormat + .format( + Messages + .getString("ProfilerActivatorGroup.copyingProfilerDataFiles"), source.lastSegment(), target.removeLastSegments(1)), IProgressMonitor.UNKNOWN); //$NON-NLS-1$ + in = new FileInputStream(source.toFile()); + out = new FileOutputStream(target.toFile()); + int bufferSize = 1024; + byte[] buf = new byte[bufferSize]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + out.flush(); + } + + } finally { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + monitor + .setTaskName(MessageFormat + .format( + Messages + .getString("ProfilerActivatorGroup.deletingProfilerDataFiles"), source.lastSegment())); //$NON-NLS-1$ + while (!source.toFile().delete()) { + if (monitor.isCanceled()) { + break; + } + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + monitor.done(); + } + } +}