| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.android.ide.eclipse.traceview.editors; |
| |
| import com.android.ide.eclipse.ddms.JavaSourceRevealer; |
| import com.android.ide.eclipse.traceview.TraceviewPlugin; |
| import com.android.traceview.ColorController; |
| import com.android.traceview.DmTraceReader; |
| import com.android.traceview.MethodData; |
| import com.android.traceview.ProfileView; |
| import com.android.traceview.ProfileView.MethodHandler; |
| import com.android.traceview.SelectionController; |
| import com.android.traceview.TimeLineView; |
| import com.android.traceview.TraceReader; |
| import com.android.traceview.TraceUnits; |
| |
| import org.eclipse.core.filesystem.EFS; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.filesystem.URIUtil; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| 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.Status; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IMessageProvider; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.SashForm; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.dialogs.SaveAsDialog; |
| import org.eclipse.ui.ide.FileStoreEditorInput; |
| import org.eclipse.ui.part.EditorPart; |
| import org.eclipse.ui.part.FileEditorInput; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.URI; |
| |
| public class TraceviewEditor extends EditorPart implements MethodHandler { |
| |
| private Composite mParent; |
| private String mFilename; |
| private Composite mContents; |
| |
| @Override |
| public void doSave(IProgressMonitor monitor) { |
| // We do not modify the file |
| } |
| |
| /* |
| * Copied from org.eclipse.ui.texteditor.AbstractDecoratedTextEditor. |
| */ |
| /** |
| * Checks whether there given file store points to a file in the workspace. |
| * Only returns a workspace file if there's a single match. |
| * |
| * @param fileStore the file store |
| * @return the <code>IFile</code> that matches the given file store |
| */ |
| private IFile getWorkspaceFile(IFileStore fileStore) { |
| IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); |
| IFile[] files = workspaceRoot.findFilesForLocationURI(fileStore.toURI()); |
| if (files != null && files.length == 1) |
| return files[0]; |
| return null; |
| } |
| |
| /* |
| * Based on the performSaveAs() method defined in class |
| * org.eclipse.ui.texteditor.AbstractDecoratedTextEditor of the |
| * org.eclipse.ui.editors plugin. |
| */ |
| @Override |
| public void doSaveAs() { |
| Shell shell = getSite().getShell(); |
| final IEditorInput input = getEditorInput(); |
| |
| final IEditorInput newInput; |
| |
| if (input instanceof FileEditorInput) { |
| // the file is part of the current workspace |
| FileEditorInput fileEditorInput = (FileEditorInput) input; |
| SaveAsDialog dialog = new SaveAsDialog(shell); |
| |
| IFile original = fileEditorInput.getFile(); |
| if (original != null) { |
| dialog.setOriginalFile(original); |
| } |
| |
| dialog.create(); |
| |
| if (original != null && !original.isAccessible()) { |
| String message = String.format( |
| "The original file ''%s'' has been deleted or is not accessible.", |
| original.getName()); |
| dialog.setErrorMessage(null); |
| dialog.setMessage(message, IMessageProvider.WARNING); |
| } |
| |
| if (dialog.open() == Window.CANCEL) { |
| return; |
| } |
| |
| IPath filePath = dialog.getResult(); |
| if (filePath == null) { |
| return; |
| } |
| |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| IFile file = workspace.getRoot().getFile(filePath); |
| |
| if (copy(shell, fileEditorInput.getURI(), file.getLocationURI()) == null) { |
| return; |
| } |
| |
| try { |
| file.refreshLocal(IFile.DEPTH_ZERO, null); |
| } catch (CoreException e) { |
| // TODO Auto-generated catch block |
| e.printStackTrace(); |
| } |
| newInput = new FileEditorInput(file); |
| setInput(newInput); |
| setPartName(newInput.getName()); |
| } else if (input instanceof FileStoreEditorInput) { |
| // the file is not part of the current workspace |
| FileStoreEditorInput fileStoreEditorInput = (FileStoreEditorInput) input; |
| FileDialog dialog = new FileDialog(shell, SWT.SAVE); |
| IPath oldPath = URIUtil.toPath(fileStoreEditorInput.getURI()); |
| if (oldPath != null) { |
| dialog.setFileName(oldPath.lastSegment()); |
| dialog.setFilterPath(oldPath.toOSString()); |
| } |
| |
| String path = dialog.open(); |
| if (path == null) { |
| return; |
| } |
| |
| // Check whether file exists and if so, confirm overwrite |
| final File localFile = new File(path); |
| if (localFile.exists()) { |
| MessageDialog overwriteDialog = new MessageDialog( |
| shell, |
| "Save As", |
| null, |
| String.format( |
| "%s already exists.\nDo you want to replace it?" |
| , path), |
| MessageDialog.WARNING, |
| new String[] { |
| IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL |
| }, 1); // 'No' is the default |
| if (overwriteDialog.open() != Window.OK) { |
| return; |
| } |
| } |
| |
| IFileStore destFileStore = copy(shell, fileStoreEditorInput.getURI(), localFile.toURI()); |
| if (destFileStore != null) { |
| IFile file = getWorkspaceFile(destFileStore); |
| if (file != null) { |
| newInput = new FileEditorInput(file); |
| } else { |
| newInput = new FileStoreEditorInput(destFileStore); |
| } |
| setInput(newInput); |
| setPartName(newInput.getName()); |
| } |
| } |
| } |
| |
| private IFileStore copy(Shell shell, URI source, URI dest) { |
| IFileStore destFileStore = null; |
| IFileStore sourceFileStore = null; |
| try { |
| destFileStore = EFS.getStore(dest); |
| sourceFileStore = EFS.getStore(source); |
| sourceFileStore.copy(destFileStore, EFS.OVERWRITE, null); |
| } catch (CoreException ex) { |
| String title = "Problems During Save As..."; |
| String msg = String.format("Save could not be completed. %s", |
| ex.getMessage()); |
| MessageDialog.openError(shell, title, msg); |
| return null; |
| } |
| return destFileStore; |
| } |
| |
| @Override |
| public void init(IEditorSite site, IEditorInput input) throws PartInitException { |
| // The contract of init() mentions we need to fail if we can't |
| // understand the input. |
| if (input instanceof FileEditorInput) { |
| // We try to open a file that is part of the current workspace |
| FileEditorInput fileEditorInput = (FileEditorInput) input; |
| mFilename = fileEditorInput.getPath().toOSString(); |
| setSite(site); |
| setInput(input); |
| setPartName(input.getName()); |
| } else if (input instanceof FileStoreEditorInput) { |
| // We try to open a file that is not part of the current workspace |
| FileStoreEditorInput fileStoreEditorInput = (FileStoreEditorInput) input; |
| mFilename = fileStoreEditorInput.getURI().getPath(); |
| setSite(site); |
| setInput(input); |
| setPartName(input.getName()); |
| } else { |
| throw new PartInitException("Input is not of type FileEditorInput " + //$NON-NLS-1$ |
| "nor FileStoreEditorInput: " + //$NON-NLS-1$ |
| input == null ? "null" : input.toString()); //$NON-NLS-1$ |
| } |
| } |
| |
| @Override |
| public boolean isDirty() { |
| return false; |
| } |
| |
| @Override |
| public boolean isSaveAsAllowed() { |
| return true; |
| } |
| |
| @Override |
| public void createPartControl(Composite parent) { |
| mParent = parent; |
| try { |
| TraceReader reader = new DmTraceReader(mFilename, false); |
| reader.getTraceUnits().setTimeScale(TraceUnits.TimeScale.MilliSeconds); |
| |
| mContents = new Composite(mParent, SWT.NONE); |
| |
| Display display = mContents.getDisplay(); |
| ColorController.assignMethodColors(display, reader.getMethods()); |
| SelectionController selectionController = new SelectionController(); |
| |
| GridLayout gridLayout = new GridLayout(1, false); |
| gridLayout.marginWidth = 0; |
| gridLayout.marginHeight = 0; |
| gridLayout.horizontalSpacing = 0; |
| gridLayout.verticalSpacing = 0; |
| mContents.setLayout(gridLayout); |
| |
| Color darkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY); |
| |
| // Create a sash form to separate the timeline view (on top) |
| // and the profile view (on bottom) |
| SashForm sashForm1 = new SashForm(mContents, SWT.VERTICAL); |
| sashForm1.setBackground(darkGray); |
| sashForm1.SASH_WIDTH = 3; |
| GridData data = new GridData(GridData.FILL_BOTH); |
| sashForm1.setLayoutData(data); |
| |
| // Create the timeline view |
| new TimeLineView(sashForm1, reader, selectionController); |
| |
| // Create the profile view |
| new ProfileView(sashForm1, reader, selectionController).setMethodHandler(this); |
| } catch (IOException e) { |
| Label l = new Label(parent, 0); |
| l.setText("Failed to read the stack trace."); |
| |
| Status status = new Status(IStatus.ERROR, TraceviewPlugin.PLUGIN_ID, |
| "Failed to read the stack trace.", e); |
| TraceviewPlugin.getDefault().getLog().log(status); |
| } |
| |
| mParent.layout(); |
| } |
| |
| @Override |
| public void setFocus() { |
| mParent.setFocus(); |
| } |
| |
| // ---- MethodHandler methods |
| |
| @Override |
| public void handleMethod(MethodData method) { |
| String methodName = method.getMethodName(); |
| String className = method.getClassName().replaceAll("/", "."); //$NON-NLS-1$ //$NON-NLS-2$ |
| String fqmn = className + "." + methodName; //$NON-NLS-1$ |
| |
| JavaSourceRevealer.revealMethod(fqmn, null, -1, null); |
| } |
| } |