/*********************************************************************************************
* Copyright (c) 2014-2015 Software Behaviour Analysis Lab, Concordia University, Montreal, Canada
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of Eclipse Public License v1.0 License which
* accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Syed Shariyar Murtaza -- Initial design and implementation
**********************************************************************************************/
package org.eclipse.tracecompass.totalads.ui.results;
import java.util.HashMap;
import org.eclipse.tracecompass.totalads.algorithms.Results;
import org.eclipse.tracecompass.totalads.ui.results.Messages;
import org.eclipse.swt.SWT;
//import org.eclipse.swt.custom.CLabel;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
/**
* This class creates GUI widgets for the results and feedback part of the GUI.
*
* @author <p>
* Syed Shariyar Murtaza justsshary@hotmail.com
* </p>
*
*/
public class ResultsAndFeedback {
private Tree fTreeTraceResults;
private Text fTxtAnomalyType;
private Text fTxtAnomalySummary;
private Text fTxtAnalysisDetails;
private Label fLblAnalysisCurrentAnomaly;
private Group fGrpAnalysisResults;
private Label fLblAnomalySummary;
private Label fLblDetails;
private Group fGrpResults;
private Composite fCompTraceList;
private Composite fCompSummary;
private Label fLblTreeTraceResult;
private Composite fCompResAndFeedback;
private Label fLblTraceSummary;
private Label fLblSelectModel;
private Combo fCmbModels;
private Text fTxtTraceSummary;
private Integer fMaxAllowableTraces;
private HashMap<String, Double> fModelAndAnomalyCount;
private Display fDisplay;
private Shell fDialogShel;
private String fTraceToDelete;
/**
* Constructor
*
* @param parent
* Composite object
* @param isDiagnosis
* false if model combo box is to be made visible
*/
public ResultsAndFeedback(Composite parent, Boolean isDiagnosis) {
detailsAndFeedBack(parent, isDiagnosis);
fMaxAllowableTraces = 5000;
}
/**
* Constructor to create results object as a separate dialog form
*/
public ResultsAndFeedback() {
fDisplay = Display.getDefault();
fDialogShel = new Shell(fDisplay, SWT.BORDER | SWT.CLOSE | SWT.V_SCROLL);
fDialogShel.setLayout(new GridLayout(4, false));
detailsAndFeedBack(fDialogShel, false);
fMaxAllowableTraces = 5000;
// adding event to avoid disposing it off
fDialogShel.addListener(SWT.Close, new Listener() {
@Override
public void handleEvent(Event event) {
event.doit = false;
fDialogShel.setVisible(false);
}
});
}
/**
* Shows the modal form
*/
public void showForm() {
// open the form as a modal only if it has been created like this
if (fDialogShel != null) {
fDialogShel.open();
while (!fDialogShel.isDisposed()) {
if (!fDisplay.readAndDispatch()) {
fDisplay.sleep();
}
}
}
}// end function ShowForm
/**
* Close the shell dialog
*/
public void destroy() {
if (fDialogShel != null) {
fDialogShel.dispose();
}
}
/**
* Creates widgets for details and results
*
* @param compParent
* Composite object
* @param isDiagnosis
* It is false if it is from live monitor and true if it s from
* diagnosis
*/
private void detailsAndFeedBack(Composite compParent, Boolean isDiagnosis) {
// Group "Feedback: Is it anomaly?"
fGrpResults = new Group(compParent, SWT.NONE);
fGrpResults.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 4));
// grpAnalysisIdentify.setText("Results and Feedback");
fGrpResults.setText(Messages.ResultsAndFeedback_Results);
fGrpResults.setLayout(new GridLayout(2, false));
// ///////////////////////////////////
// Widgets for summary
// ////////////////////////////////////
fCompSummary = new Composite(fGrpResults, SWT.None);
fCompSummary.setLayout(new GridLayout(4, false));
fCompSummary.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
fLblTraceSummary = new Label(fCompSummary, SWT.NONE);
fLblTraceSummary.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, false, false, 2, 1));
fLblTraceSummary.setText(Messages.ResultsAndFeedback_TotTraces);
fTxtTraceSummary = new Text(fCompSummary, SWT.BORDER);
fTxtTraceSummary.setEditable(false);
fTxtTraceSummary.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false, 2, 1));
fLblSelectModel = new Label(fCompSummary, SWT.NONE);
fLblSelectModel.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, false, false, 1, 1));
fLblSelectModel.setText(Messages.ResultsAndFeedback_SelModels);
fCmbModels = new Combo(fCompSummary, SWT.BORDER | SWT.READ_ONLY);
fCmbModels.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false, 1, 1));
if (isDiagnosis == true) {
fCmbModels.setVisible(false);
fLblSelectModel.setVisible(false);
}
fLblAnomalySummary = new Label(fCompSummary, SWT.NONE);
fLblAnomalySummary.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, false, false, 1, 1));
fLblAnomalySummary.setText(Messages.ResultsAndFeedback_TotAnomalies);
fTxtAnomalySummary = new Text(fCompSummary, SWT.BORDER);
fTxtAnomalySummary.setEditable(false);
fTxtAnomalySummary.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false, 1, 1));
// /////////////////////////////////
// / Widgets for Trace list
// ///////////////////////////////
fCompTraceList = new Composite(fGrpResults, SWT.None);
fCompTraceList.setLayout(new GridLayout(1, false));
fCompTraceList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
fLblTreeTraceResult = new Label(fCompTraceList, SWT.NONE);
fLblTreeTraceResult.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false, 1, 1));
fLblTreeTraceResult.setText(Messages.ResultsAndFeedback_TraceList);
fTreeTraceResults = new Tree(fCompTraceList, SWT.BORDER | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL);
fTreeTraceResults.setLinesVisible(true);
fTreeTraceResults.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 1, 5));
fCompResAndFeedback = new Composite(fGrpResults, SWT.NONE);
fCompResAndFeedback.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
fCompResAndFeedback.setLayout(new GridLayout(1, false));
results(fCompResAndFeedback);
addHandlers();
// *** End Trace list
// *** Group Feedback: To be included in the next version.
}
/**
* Creates widgets or GUI elements for the results
*
* @param compParent
* Composite object
*/
private void results(Composite compParent) {
/**
*
* Result
*
*/
fGrpAnalysisResults = new Group(compParent, SWT.NONE);
GridData gridDataResult = new GridData(SWT.FILL, SWT.FILL, true, true);
gridDataResult.horizontalSpan = 1;
fGrpAnalysisResults.setLayoutData(gridDataResult);
fGrpAnalysisResults.setLayout(new GridLayout(2, false));
fLblAnalysisCurrentAnomaly = new Label(fGrpAnalysisResults, SWT.NONE);
fLblAnalysisCurrentAnomaly.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));// gridDataResultLabels);
fLblAnalysisCurrentAnomaly.setText(Messages.ResultsAndFeedback_Anomaly);
fTxtAnomalyType = new Text(fGrpAnalysisResults, SWT.BORDER);
fTxtAnomalyType.setEditable(false);
fTxtAnomalyType.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));// gridDataResultText);
fLblDetails = new Label(fGrpAnalysisResults, SWT.NONE);
fLblDetails.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 2, 1));
fLblDetails.setText(Messages.ResultsAndFeedback_Details);
fTxtAnalysisDetails = new Text(fGrpAnalysisResults, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL);
fTxtAnalysisDetails.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 2));
/**
* End result group
*
*/
}
/**
* This function adds the handlers for the different events called on
* widgets
*/
private void addHandlers() {
//
// Event handler for the tree
//
fTreeTraceResults.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String modelName = fCmbModels.getItem(fCmbModels.getSelectionIndex());
if (modelName == null || modelName.isEmpty()) {
return;
}
TreeItem item = (TreeItem) e.item;
@SuppressWarnings("unchecked")
HashMap<String, Results> modelResults = (HashMap<String, Results>) item.getData();
Results results = modelResults.get(modelName);
if (results != null) {
// currentTraceResults=results;
if (results.getAnomaly() != null && results.getAnomaly() && (results.getAnomalyType() != null && !results.getAnomalyType().isEmpty())) {
fTxtAnomalyType.setText(results.getAnomalyType());
} else {
fTxtAnomalyType.setText(booleanAnomalyToString(results.getAnomaly()));
}
fTxtAnalysisDetails.setText(results.getDetails().toString());
} else {
fTxtAnomalyType.setText(Messages.ResultsAndFeedback_Evaluating);
fTxtAnalysisDetails.setText(Messages.ResultsAndFeedback_Evaluating);
}
}
});
/**
* Add Combo handlers
*/
fCmbModels.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String item = fCmbModels.getItem(fCmbModels.getSelectionIndex());
if (item != null && !item.isEmpty()) {
if (fModelAndAnomalyCount != null) {
Double anomalies = fModelAndAnomalyCount.get(item);
if (anomalies != null) {
fTxtAnomalySummary.setText(anomalies.toString());
fTxtAnalysisDetails.setText(""); //$NON-NLS-1$
fTxtAnomalyType.setText(""); //$NON-NLS-1$
}
}
}
}
});
}
/**
* Add all model names
*
* @param modelNames
* Array of all the models whose results will appear in the
* results section
*/
public void registerAllModelNames(final String[] modelNames) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
for (int j = 0; j < modelNames.length; j++) {
fCmbModels.add(modelNames[j]);
}
fCmbModels.select(0);
}
});
}
/**
* This function sets the maximum traces that are allowed to be displayed in
* the results sections
*
* @param maxTraces
* Maximum traces
*/
public void setMaxAllowableTrace(Integer maxTraces) {
fMaxAllowableTraces = maxTraces;
}
/**
* Assigns a trace and its results to appropriate widgets for viewing in
* Results Section. If the number of traces increase beyond maximum
* allowable traces then the first trace is removed and its name is
* returned. First call registerAllModels function before calling this
* function.
*
* @param traceName
* Name of the trace
* @param modelResults
* Results of all the models as a HashMap
* @return Name of the trace removed or empty if none is removed
*/
public String addTraceResult(final String traceName, final HashMap<String, Results> modelResults) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
fTraceToDelete = ""; //$NON-NLS-1$
if (!traceName.isEmpty() && modelResults != null) {
// Check if the same name already exists
TreeItem[] allItems = fTreeTraceResults.getItems();
for (int j = 0; j < allItems.length; j++)
{
if (allItems[j].getText().equalsIgnoreCase(traceName))
{
return; // if it exists do not add it again
}
}
// Add if no such name is there
TreeItem item = new TreeItem(fTreeTraceResults, SWT.NONE);
item.setText(traceName);
item.setData(modelResults);
if (fTreeTraceResults.getItemCount() > fMaxAllowableTraces) {
fTraceToDelete = fTreeTraceResults.getItem(0).getText();
fTreeTraceResults.getItem(0).dispose();
}
}
}
});
return fTraceToDelete;
}
/**
* Converts a boolean to displayable string
*
* @param anomaly
* @return A String value to be displayed
*/
private static String booleanAnomalyToString(Boolean anomaly) {
if (anomaly == null) {
return Messages.ResultsAndFeedback_AnomYes;
} else if (anomaly) {
return Messages.ResultsAndFeedback_AnomYes;
} else {
return Messages.ResultsAndFeedback_AnomNo;
}
}
/**
*
* Clears the tree
*/
public void clearData() {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
fTreeTraceResults.removeAll();
fTxtAnomalyType.setText(""); //$NON-NLS-1$
fTxtAnalysisDetails.setText(""); //$NON-NLS-1$
fTxtAnomalySummary.setText(""); //$NON-NLS-1$
fTxtTraceSummary.setText(""); //$NON-NLS-1$
fCmbModels.removeAll();
}
});
}
/**
* Sets the summary of results
*
* @param modelAnomCount
* Model and anomaly count
*/
public void setTotalAnomalyCount(final HashMap<String, Double> modelAnomCount) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
fModelAndAnomalyCount = modelAnomCount;
if (fCmbModels.getItemCount() > 0) {
int index = fCmbModels.getSelectionIndex();
if (index == -1) {
index = 0;
}
Double anomCount = fModelAndAnomalyCount.get(fCmbModels.getItem(index));
if (anomCount != null) {
fTxtAnomalySummary.setText(anomCount.toString());
}
}
}
});
}
/**
* Sets the total trace count
*
* @param traceCount
* Total trace count
*/
public void setTotalTraceCount(final String traceCount) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
fTxtTraceSummary.setText(traceCount);
}
});
}
}