blob: 1715709434435e63ea17ce07ed5f605058e65342 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2020 SAP AG and IBM Corporation.
* 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:
* SAP AG - initial API and implementation
* Andrew Johnson (IBM Corporation) - set operations
*******************************************************************************/
package org.eclipse.mat.ui.snapshot.panes;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.mat.internal.snapshot.inspections.CompareTablesQuery.ComparedColumn;
import org.eclipse.mat.internal.snapshot.inspections.CompareTablesQuery.Mode;
import org.eclipse.mat.internal.snapshot.inspections.CompareTablesQuery.Operation;
import org.eclipse.mat.internal.snapshot.inspections.CompareTablesQuery.TableComparisonResult;
import org.eclipse.mat.query.IResult;
import org.eclipse.mat.query.registry.QueryResult;
import org.eclipse.mat.ui.MemoryAnalyserPlugin;
import org.eclipse.mat.ui.Messages;
import org.eclipse.mat.ui.internal.panes.QueryResultPane;
import org.eclipse.mat.ui.internal.viewer.RefinedResultViewer;
import org.eclipse.mat.ui.util.EasyToolBarDropDown;
import org.eclipse.mat.ui.util.PopupMenu;
public class CompareTablesPane extends QueryResultPane
{
public enum DiffOption
{
ABSOLUTE(Messages.CompareTablesPane_AbsoluteValues), DIFF_TO_BASE(
Messages.CompareTablesPane_DifferenceToBaseTable), DIFF_RATIO_TO_BASE(
Messages.CompareTablesPane_PercentageDifferenceToBaseTable), DIFF_TO_PREV(
Messages.CompareTablesPane_DifferenceToPrecedingTable), DIFF_RATIO_TO_PREV(
Messages.CompareTablesPane_PercentageDifferenceToPrecedingTable);
String label;
private DiffOption(String label)
{
this.label = label;
}
public String toString()
{
return label;
}
}
private DiffOption diffOption;
public enum SetopOption
{
NONE(Messages.CompareTablesPane_Setop_None),
ALL(Messages.CompareTablesPane_Setop_All),
INTERSECTION(Messages.CompareTablesPane_Setop_Intersection),
UNION(Messages.CompareTablesPane_Setop_Union),
SYMMETRIC_DIFFERENCE(Messages.CompareTablesPane_Setop_SymmetricDifference),
DIFFERENCE(Messages.CompareTablesPane_Setop_Difference),
REVERSE_DIFFERENCE(Messages.CompareTablesPane_Setop_ReverseDifference);
String label;
private SetopOption(String label)
{
this.label = label;
}
public String toString()
{
return label;
}
}
private SetopOption setopOption;
@Override
public void initWithArgument(Object argument)
{
super.initWithArgument(argument);
IResult subject = ((QueryResult) argument).getSubject();
if (subject instanceof TableComparisonResult)
{
Mode mode = ((TableComparisonResult) subject).getMode();
switch (mode)
{
case ABSOLUTE:
diffOption = DiffOption.ABSOLUTE;
break;
case DIFF_TO_FIRST:
diffOption = DiffOption.DIFF_TO_BASE;
break;
case DIFF_TO_PREVIOUS:
diffOption = DiffOption.DIFF_TO_PREV;
break;
case DIFF_RATIO_TO_FIRST:
diffOption = DiffOption.DIFF_RATIO_TO_BASE;
break;
case DIFF_RATIO_TO_PREVIOUS:
diffOption = DiffOption.DIFF_RATIO_TO_PREV;
break;
default:
break;
}
Operation op = ((TableComparisonResult) subject).getOperation();
switch (op)
{
case NONE:
setopOption = SetopOption.NONE;
break;
case ALL:
setopOption = SetopOption.ALL;
break;
case INTERSECTION:
setopOption = SetopOption.INTERSECTION;
break;
case UNION:
setopOption = SetopOption.UNION;
break;
case SYMMETRIC_DIFFERENCE:
setopOption = SetopOption.SYMMETRIC_DIFFERENCE;
break;
case DIFFERENCE:
setopOption = SetopOption.DIFFERENCE;
break;
case REVERSE_DIFFERENCE:
setopOption = SetopOption.REVERSE_DIFFERENCE;
break;
default:
break;
}
}
}
@Override
public void contributeToToolBar(IToolBarManager manager)
{
addDiffOptions(manager);
addSetopOptions(manager);
addSelectColumns(manager);
manager.add(new Separator());
super.contributeToToolBar(manager);
}
private void addSelectColumns(IToolBarManager manager)
{
final IResult result = viewer.getQueryResult().getSubject();
if (result instanceof TableComparisonResult)
{
Action selectColumnsAction = new EasyToolBarDropDown(Messages.CompareTablesPane_SelectDisplayedColumnsTooltip, //
MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SELECT_COLUMN), this) {
@Override
public void contribute(PopupMenu menu)
{
List<ComparedColumn> columns = ((TableComparisonResult) result).getComparedColumns();
for (ComparedColumn comparedColumn : columns)
{
menu.add(new SelectColumnAction(comparedColumn));
}
}
};
manager.add(selectColumnsAction);
}
}
private void addDiffOptions(IToolBarManager manager)
{
Action diffOptionAction = new EasyToolBarDropDown(Messages.CompareTablesPane_ChooseDiffOptionTooltip, //
MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.GROUPING), this) {
@Override
public void contribute(PopupMenu menu)
{
for (DiffOption opt : DiffOption.values())
{
Action action = new DiffOptionAction(opt);
action.setEnabled(opt != diffOption);
action.setChecked(opt == diffOption);
menu.add(action);
}
}
};
manager.add(diffOptionAction);
}
private void addSetopOptions(IToolBarManager manager)
{
final IResult result = viewer.getQueryResult().getSubject();
// Test whether set operations make sense
if (result instanceof TableComparisonResult)
{
TableComparisonResult tcr = (TableComparisonResult)result;
Operation op1 = tcr.getOperation();
if (op1 == Operation.NONE)
{
// Try setting the operation
Operation op2 = Operation.ALL;
tcr.setOperation(op2);
Operation op3 = tcr.getOperation();
// Restore
tcr.setOperation(op1);
// If we can't change the mode, don't give the option to change
if (op3 != op2)
return;
}
}
Action setopOptionAction = new EasyToolBarDropDown(Messages.CompareTablesPane_ChooseOperation, //
MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SET_SYMMETRIC_DIFFERENCE), this)
{
@Override
public void contribute(PopupMenu menu)
{
for (SetopOption opt : SetopOption.values())
{
Action action = new SetopOptionAction(opt);
action.setEnabled(opt != setopOption);
action.setChecked(opt == setopOption);
switch (opt)
{
case UNION:
action.setImageDescriptor(MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SET_UNION));
break;
case INTERSECTION:
action.setImageDescriptor(MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SET_INTERSECTION));
break;
case SYMMETRIC_DIFFERENCE:
action.setImageDescriptor(MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SET_SYMMETRIC_DIFFERENCE));
break;
case DIFFERENCE:
action.setImageDescriptor(MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SET_DIFFERENCE_A));
break;
case REVERSE_DIFFERENCE:
action.setImageDescriptor(MemoryAnalyserPlugin.getImageDescriptor(MemoryAnalyserPlugin.ISharedImages.SET_DIFFERENCE_B));
break;
case NONE:
case ALL:
break;
}
menu.add(action);
}
}
};
manager.add(setopOptionAction);
}
private class DiffOptionAction extends Action
{
private DiffOption diffOption;
private DiffOptionAction(DiffOption diffOption)
{
super(diffOption.toString(), AS_CHECK_BOX);
this.diffOption = diffOption;
}
@Override
public void run()
{
// do not run the same action twice - selection was not changed
if (!isChecked()) return;
Mode mode = Mode.ABSOLUTE;
switch (diffOption)
{
case DIFF_TO_PREV:
mode = Mode.DIFF_TO_PREVIOUS;
break;
case DIFF_TO_BASE:
mode = Mode.DIFF_TO_FIRST;
break;
case DIFF_RATIO_TO_PREV:
mode = Mode.DIFF_RATIO_TO_PREVIOUS;
break;
case DIFF_RATIO_TO_BASE:
mode = Mode.DIFF_RATIO_TO_FIRST;
break;
default:
break;
}
IResult result = viewer.getQueryResult().getSubject();
if (result instanceof TableComparisonResult)
{
((TableComparisonResult) result).setMode(mode);
}
final QueryResult queryResult = new QueryResult(null, "compare", result); //$NON-NLS-1$
new Job(getText()) {
protected IStatus run(IProgressMonitor monitor)
{
top.getDisplay().asyncExec(new Runnable() {
public void run()
{
CompareTablesPane.this.diffOption = diffOption;
deactivateViewer();
RefinedResultViewer v = createViewer(queryResult);
activateViewer(v);
}
});
return Status.OK_STATUS;
}
}.schedule();
}
}
private class SelectColumnAction extends Action
{
ComparedColumn column;
public SelectColumnAction(ComparedColumn column)
{
super(column.getDescription().getLabel(), AS_CHECK_BOX);
this.column = column;
setChecked(column.isDisplayed());
}
@Override
public void run()
{
column.setDisplayed(!column.isDisplayed());
IResult result = viewer.getQueryResult().getSubject();
if (result instanceof TableComparisonResult)
{
((TableComparisonResult) result).updateColumns();
}
final QueryResult queryResult = new QueryResult(null, "compare", result); //$NON-NLS-1$
new Job(getText()) {
protected IStatus run(IProgressMonitor monitor)
{
top.getDisplay().asyncExec(new Runnable() {
public void run()
{
deactivateViewer();
RefinedResultViewer v = createViewer(queryResult);
activateViewer(v);
}
});
return Status.OK_STATUS;
}
}.schedule();
}
}
private class SetopOptionAction extends Action
{
private SetopOption setopOption;
private SetopOptionAction(SetopOption setopOption)
{
super(setopOption.toString(), AS_CHECK_BOX);
this.setopOption = setopOption;
}
@Override
public void run()
{
// do not run the same action twice - selection was not changed
if (!isChecked())
return;
Operation op = Operation.NONE;
switch (setopOption)
{
case ALL:
op = Operation.ALL;
break;
case INTERSECTION:
op = Operation.INTERSECTION;
break;
case UNION:
op = Operation.UNION;
break;
case SYMMETRIC_DIFFERENCE:
op = Operation.SYMMETRIC_DIFFERENCE;
break;
case DIFFERENCE:
op = Operation.DIFFERENCE;
break;
case REVERSE_DIFFERENCE:
op = Operation.REVERSE_DIFFERENCE;
break;
default:
break;
}
IResult result = viewer.getQueryResult().getSubject();
if (result instanceof TableComparisonResult)
{
((TableComparisonResult) result).setOperation(op);
}
final QueryResult queryResult = new QueryResult(null, viewer.getQueryResult().getCommand(), result);
new Job(getText())
{
protected IStatus run(IProgressMonitor monitor)
{
top.getDisplay().asyncExec(new Runnable()
{
public void run()
{
CompareTablesPane.this.setopOption = setopOption;
deactivateViewer();
RefinedResultViewer v = createViewer(queryResult);
activateViewer(v);
}
});
return Status.OK_STATUS;
}
}.schedule();
}
}
}