/*******************************************************************************
* Copyright (c) 2017 Rogue Wave Software Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Rogue Wave Software Inc. - initial implementation
*******************************************************************************/
package org.eclipse.php.profile.ui.views;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.php.internal.debug.core.zend.debugger.RemoteDebugger;
import org.eclipse.php.internal.debug.ui.editor.OpenRemoteFileContentRequestor;
import org.eclipse.php.internal.ui.util.EditorUtility;
import org.eclipse.php.profile.core.data.ProfilerClassData;
import org.eclipse.php.profile.core.data.ProfilerFileData;
import org.eclipse.php.profile.core.data.ProfilerFunctionData;
import org.eclipse.php.profile.core.data.ProfilerGlobalData;
import org.eclipse.php.profile.core.engine.IProfileSessionListener;
import org.eclipse.php.profile.core.engine.ProfileSessionsManager;
import org.eclipse.php.profile.core.engine.ProfilerDB;
import org.eclipse.php.profile.ui.PHPProfileUIMessages;
import org.eclipse.php.profile.ui.ProfilerUIConstants;
import org.eclipse.php.profile.ui.ProfilerUIImages;
import org.eclipse.php.profile.ui.ProfilerUiPlugin;
import org.eclipse.php.profile.ui.actions.ExecutionStatisticsActionGroup;
import org.eclipse.php.profile.ui.filters.ExecutionStatisticsFilter;
import org.eclipse.php.profile.ui.filters.ExecutionStatisticsFiltersRegistry;
import org.eclipse.php.profile.ui.preferences.PreferenceKeys;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
/**
* Execution statistics view.
*/
public class ExecutionStatisticsView extends AbstractProfilerFunctionsView
implements IDoubleClickListener, ITreeViewerListener, IMenuListener, IProfileSessionListener {
private Tree fTree;
private TreeViewer fTreeViewer;
private String[] fColumnHeaders = { PHPProfileUIMessages.getString("ExecutionStatisticsView_1"), //$NON-NLS-1$
PHPProfileUIMessages.getString("ExecutionStatisticsView_2"), //$NON-NLS-1$
PHPProfileUIMessages.getString("ExecutionStatisticsView_3"), //$NON-NLS-1$
PHPProfileUIMessages.getString("ExecutionStatisticsView_4"), //$NON-NLS-1$
PHPProfileUIMessages.getString("ExecutionStatisticsView_5"), //$NON-NLS-1$
PHPProfileUIMessages.getString("ExecutionStatisticsView_6"), //$NON-NLS-1$
};
private int[] fColumnWidths = new int[] { 200, 130, 150, 130, 130, 130 };
private int[] fNumericColumns = new int[] { 1, 2, 3, 4, 5 };
private ExecutionStatisticsActionGroup fActionSet;
private ExecutionStatisticsSorter fSorter;
private Menu fContextMenu;
private ProfilerDB fProfilerDB;
private IPreferenceStore fPreferenceStore;
public ExecutionStatisticsView() {
fPreferenceStore = ProfilerUiPlugin.getDefault().getPreferenceStore();
}
private void createTable(Composite parent) {
fTree = new Tree(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
fTree.setLinesVisible(true);
fTree.setHeaderVisible(true);
fSorter = new ExecutionStatisticsSorter();
for (int i = 0; i < fColumnHeaders.length; ++i) {
TreeColumn tableColumn = new TreeColumn(fTree, SWT.LEFT, i);
tableColumn.setText(fColumnHeaders[i]);
tableColumn.setWidth(fColumnWidths[i]);
for (int c = 0; c < fNumericColumns.length; ++c) {
if (fNumericColumns[c] == i) {
tableColumn.setAlignment(SWT.RIGHT);
break;
}
}
final int field = i;
tableColumn.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.SelectionAdapter#widgetSelected(org
* .eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
fSorter.setColumn(field);
TreeColumn[] tableColumns = fTree.getColumns();
for (int i = 0; i < fColumnHeaders.length; ++i) {
tableColumns[i].setImage(null);
}
if (fSorter.getOrder() == ProfilerUIConstants.SORT_ASCENDING) {
tableColumns[field]
.setImage(ProfilerUIImages.get(ProfilerUIImages.IMG_OBJ_SORT_ASCENDING));
} else if (fSorter.getOrder() == ProfilerUIConstants.SORT_DESCENDING) {
tableColumns[field]
.setImage(ProfilerUIImages.get(ProfilerUIImages.IMG_OBJ_SORT_DESCENDING));
}
BusyIndicator.showWhile(fTree.getDisplay(), new Runnable() {
public void run() {
fTreeViewer.getControl().setRedraw(false);
fTreeViewer.refresh();
fTreeViewer.getControl().setRedraw(true);
restoreExpandedElements();
}
});
}
});
}
fTreeViewer = new TreeViewer(fTree);
fTreeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
fTreeViewer.setContentProvider(new ExecutionStatisticsContentProvider());
fTreeViewer.setLabelProvider(new ExecutionStatisticsLabelProvider());
fTreeViewer.setSorter(fSorter);
String selectedFilter = fPreferenceStore.getString(PreferenceKeys.EXECUTION_STATISTICS_SELECTED_FILTER);
if (selectedFilter.length() > 0) {
ExecutionStatisticsFilter filter = ExecutionStatisticsFiltersRegistry.getFilterByName(selectedFilter);
if (filter != null) {
fTreeViewer.addFilter(filter);
}
}
fTreeViewer.addDoubleClickListener(this);
fTreeViewer.addTreeListener(this);
fActionSet = new ExecutionStatisticsActionGroup(this);
fActionSet.fillActionBars(getViewSite().getActionBars());
hookContextMenu();
// TODO - context menu
// fTree.setData(WorkbenchHelpSystem.HELP_KEY,
// IStudioHelpContextIds.EXECUTION_STATISTICS_VIEW);
// fTree.addHelpListener(new HelpListener() {
// public void helpRequested(HelpEvent arg0) {
// org.eclipse.swt.program.Program
// .launch(IStudioHelpContextIds.EXECUTION_STATISTICS_VIEW);
// }
// });
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.
* widgets.Composite)
*/
public void createPartControl(Composite parent) {
createTable(parent);
ProfileSessionsManager.addProfileSessionListener(this);
setInput(ProfileSessionsManager.getCurrent());
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
public void dispose() {
if (fTreeViewer != null) {
fTreeViewer.removeDoubleClickListener(this);
}
ProfileSessionsManager.removeProfileSessionListener(this);
super.dispose();
}
public void setFocus() {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see org.eclipse.php.profile.ui.views.AbstractProfilerView#getInput()
*/
public ProfilerDB getInput() {
return fProfilerDB;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.php.profile.ui.views.AbstractProfilerView#setInput(org.eclipse.
* php.profile.core.profiler.ProfilerDB)
*/
public void setInput(ProfilerDB profilerDB) {
if (fTreeViewer == null || fTreeViewer.getContentProvider() == null) {
return;
}
if (fProfilerDB != profilerDB) {
if (profilerDB != null) {
ProfilerFileData[] files = profilerDB.getFiles();
SimpleHTMLPresentableTreeElement root = new SimpleHTMLPresentableTreeElement();
for (int i = 0; i < files.length; ++i) {
SimpleHTMLPresentableTreeElement fileItem = new SimpleHTMLPresentableTreeElement(root, files[i]);
root.addChild(fileItem);
ProfilerClassData[] classes = files[i].getClasses();
for (int j = 0; j < classes.length; ++j) {
SimpleHTMLPresentableTreeElement classItem = new SimpleHTMLPresentableTreeElement(fileItem,
classes[j]);
fileItem.addChild(classItem);
ProfilerFunctionData[] methods = classes[j].getMethods();
for (int k = 0; k < methods.length; ++k) {
SimpleHTMLPresentableTreeElement element = new SimpleHTMLPresentableTreeElement(classItem,
methods[k]);
classItem.addChild(element);
}
}
ProfilerFunctionData[] functions = files[i].getFunctions();
for (int j = 0; j < functions.length; ++j) {
if (functions[j].getClassName() == null) {
SimpleHTMLPresentableTreeElement element = new SimpleHTMLPresentableTreeElement(fileItem,
functions[j]);
fileItem.addChild(element);
}
}
}
fTreeViewer.setInput(root);
} else {
fTreeViewer.setInput(null);
}
BusyIndicator.showWhile(fTreeViewer.getControl().getDisplay(), new Runnable() {
public void run() {
fTreeViewer.getControl().setRedraw(false);
fTreeViewer.refresh();
fTreeViewer.getControl().setRedraw(true);
storeExpandedElements();
}
});
fProfilerDB = profilerDB;
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse
* .jface.viewers.DoubleClickEvent)
*/
public void doubleClick(DoubleClickEvent event) {
ISelection selection = event.getSelection();
if (selection != null && selection instanceof IStructuredSelection) {
IStructuredSelection sSelection = (IStructuredSelection) selection;
SimpleHTMLPresentableTreeElement ExecutionStatisticsTreeElement = (SimpleHTMLPresentableTreeElement) sSelection
.getFirstElement();
Object element = ExecutionStatisticsTreeElement.getData();
if (element instanceof ProfilerFunctionData) {
ProfilerFunctionData data = (ProfilerFunctionData) element;
try {
if (EditorUtility.openLocalFile(data.getLocalFileName(), data.getLineNumber()) == null) {
String url = fProfilerDB.getGlobalData().getOriginalURL();
if (!ProfilerGlobalData.URL_NOT_AVAILABLE_MSG.equals(url)) {
// try to retrieve the file from server
RemoteDebugger.requestRemoteFile(new OpenRemoteFileContentRequestor(),
data.getAbsoluteFileName(), data.getLineNumber(), url);
}
}
} catch (CoreException e) {
MessageDialog.openError(fTreeViewer.getControl().getShell(),
PHPProfileUIMessages.getString("ExecutionStatisticsView.0"), //$NON-NLS-1$
NLS.bind(PHPProfileUIMessages.getString("ExecutionStatisticsView.1"), //$NON-NLS-1$
data.getLocalFileName()));
}
} else {
boolean expanded = !fTreeViewer.getExpandedState(ExecutionStatisticsTreeElement);
fTreeViewer.setExpandedState(ExecutionStatisticsTreeElement, expanded);
fTreeViewer.getControl().setRedraw(true);
}
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.php.profile.ui.views.AbstractProfilerFunctionsView#getViewer()
*/
public TreeViewer getViewer() {
return fTreeViewer;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.viewers.ITreeViewerListener#treeCollapsed(org.eclipse
* .jface.viewers.TreeExpansionEvent)
*/
public void treeCollapsed(TreeExpansionEvent event) {
SimpleHTMLPresentableTreeElement element = (SimpleHTMLPresentableTreeElement) event.getElement();
element.setExpanded(false);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.viewers.ITreeViewerListener#treeExpanded(org.eclipse
* .jface.viewers.TreeExpansionEvent)
*/
public void treeExpanded(TreeExpansionEvent event) {
SimpleHTMLPresentableTreeElement element = (SimpleHTMLPresentableTreeElement) event.getElement();
element.setExpanded(true);
}
public void hookContextMenu() {
MenuManager menuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$
menuManager.setRemoveAllWhenShown(true);
menuManager.addMenuListener(this);
fContextMenu = menuManager.createContextMenu(fTree);
fTree.setMenu(fContextMenu);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface
* .action.IMenuManager)
*/
public void menuAboutToShow(IMenuManager manager) {
fActionSet.fillContextMenu(manager);
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.php.profile.core.profiler.IProfileSessionListener#
* currentSessionChanged(org.eclipse.php.profile.core.profiler.ProfilerDB)
*/
public void currentSessionChanged(final ProfilerDB current) {
getSite().getShell().getDisplay().asyncExec(new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
setInput(current);
}
});
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.php.profile.core.profiler.IProfileSessionListener#
* profileSessionAdded(org.eclipse.php.profile.core.profiler.ProfilerDB)
*/
public void profileSessionAdded(ProfilerDB db) {
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.php.profile.core.profiler.IProfileSessionListener#
* profileSessionRemoved(org.eclipse.php.profile.core.profiler.ProfilerDB)
*/
public void profileSessionRemoved(ProfilerDB db) {
}
}