package net.certware.argument.sfp.review.wizard;
import java.text.MessageFormat;
import net.certware.argument.sfp.review.Activator;
import net.certware.argument.sfp.semiFormalProof.Proof;
import net.certware.argument.sfp.semiFormalProof.Statement;
import net.certware.argument.sfp.semiFormalProof.ValidationKind;
import net.certware.argument.sfp.semiFormalProof.impl.ProofImpl;
import net.certware.argument.sfp.semiFormalProof.impl.StatementImpl;
import net.certware.argument.sfp.util.ProofUtil;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.forms.DetailsPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.MasterDetailsBlock;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
/**
* A master-details block to show proof statements.
* @author mrb
* @since 1.0.3
*/
public class ScrolledPropertiesBlock extends MasterDetailsBlock {
/** proof statements for the trees */
private Proof proof;
/** containing wizard page, for access to buttons */
private ReviewValidatePage validatePage;
/** wizard setup page */
private ReviewSetupPage setupPage;
/** image registry */
private ImageRegistry imageRegistry;
/** tree viewer */
private TreeViewer viewer;
/** model container */
private ModelContainer model;
private ProofDetailPage proofDetailPage;
private StatementDetailPage statementDetailPage;
/**
* Creates the scrolled properties block.
* Creates the supporting images.
* @param proof proof to display and validate
* @param wp wizard page for parent reference
*/
public ScrolledPropertiesBlock(Proof proof, ReviewValidatePage wp, ReviewSetupPage sp) {
validatePage = wp;
setupPage = sp;
this.imageRegistry = Activator.getDefault().getImageRegistry();
this.proof = proof;
// create a dummy container to serve as tree root
model = new ModelContainer();
model.proof = proof;
}
/**
* Disposes of resources used by this block.
*/
public void dispose() {
if ( proofDetailPage != null )
proofDetailPage.dispose();
if ( statementDetailPage != null )
statementDetailPage.dispose();
}
/**
* Tree content provider.
* Proof is root, statements are leaves
*/
class MasterContentProvider implements ITreeContentProvider
{
/**
* Gets the array of elements based on input.
*/
public Object[] getElements(Object inputElement) {
// model container provides proof
if ( inputElement instanceof ModelContainer ) {
ModelContainer mc = (ModelContainer)inputElement;
return new Object[] { mc.proof };
}
// individual proof statements
if (inputElement instanceof Proof) {
Proof p = (Proof)inputElement;
if ( p.getProofSteps() == null ) {
return new Object[0];
}
return p.getProofSteps().getStatements().toArray();
}
return new Object[0];
}
/**
* Nothing to dispose.
*/
public void dispose() {
}
/**
* Input changed for provider. Unused.
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
/**
* Returns the children of the given parent object.
* @param parentElement parent object, a proof
* @return array of children for the parent, or null
*/
public Object[] getChildren(Object parentElement)
{
if ( parentElement instanceof Proof ) {
Proof p = (Proof)parentElement;
if ( p.getProofSteps() == null ) {
return null;
}
return p.getProofSteps().getStatements().toArray();
}
return null;
}
/**
* Returns the parent of the given element.
* @param element child to find parent, supports category only
* @return container parent of the element (a category object), or null
*/
public Object getParent(Object element)
{
if ( element instanceof Statement ) {
return proof;
}
return null;
}
/**
* Whether the element has children.
* @param element to identify
* @return true if element has non-empty children list, otherwise false
*/
public boolean hasChildren(Object element)
{
if ( element instanceof Proof ) {
Proof p = (Proof)element;
if ( p.getProofSteps() != null && p.getProofSteps().getStatements().isEmpty() == false )
return true;
}
return false;
}
}
/**
* Label provider class.
*/
class MasterLabelProvider implements ILabelProvider
{
/**
* Get the proof or statement as the label text.
* @param obj object to label
* @return proof or statement label text
*/
public String getText(Object obj) {
if ( obj instanceof Proof ) {
Proof p = (Proof)obj;
return MessageFormat.format("{0}: {1}", "Theorem:", p.getTitle());
}
if ( obj instanceof Statement ) {
Statement s = (Statement)obj;
if ( ProofUtil.statementIsHypothesis(s) ) {
return MessageFormat.format("{0}. {1} ({2})",
s.getId(), s.getStatement(), "hypothesis");
}
if ( ProofUtil.statementIsEpsilon(s) ) {
return MessageFormat.format("{0}. {1} ({2})",
s.getId(), s.getStatement(), "epsilon");
}
return MessageFormat.format("{0}. {1}", s.getId(), s.getStatement());
}
return obj.toString();
}
/**
* Get the image associated with the statement type.
* @param obj object to identify
* @return image for proof, hypothesis, statement, or null
*/
public Image getImage(Object obj) {
// proof image based on validation of statements
if ( obj instanceof Proof ) {
Proof p = (Proof)obj;
ValidationKind vk = ProofUtil.getProofValidationKind(p);
if ( vk == ValidationKind.INVALID )
return imageRegistry.get( Activator.REVIEW_INVALID_IMAGE );
if ( vk == ValidationKind.VALID )
return imageRegistry.get( Activator.REVIEW_VALID_IMAGE );
return imageRegistry.get( Activator.REVIEW_UNKNOWN_IMAGE );
}
// statement image based on its validation
if ( obj instanceof Statement ) {
Statement s = (Statement)obj;
if ( s.getValidation() != null ) {
if ( s.getValidation().getState().getValue() == ValidationKind.INVALID_VALUE ) {
return imageRegistry.get( Activator.REVIEW_INVALID_IMAGE );
}
if ( s.getValidation().getState().getValue() == ValidationKind.VALID_VALUE ) {
return imageRegistry.get( Activator.REVIEW_VALID_IMAGE );
}
}
return imageRegistry.get( Activator.REVIEW_UNKNOWN_IMAGE );
}
return null;
}
/**
* Not used.
*/
public void addListener(ILabelProviderListener listener)
{
}
/**
* Not used.
*/
public void dispose()
{
}
/**
* @return always returns false
*/
public boolean isLabelProperty(Object element, String property)
{
return false;
}
/**
* Not used.
*/
public void removeListener(ILabelProviderListener listener)
{
}
}
/**
* Creates the master part of the master-details block.
* @param managedForm managed for for toolkit reference
* @param parent composite parent for the part; we put a new composite on it
*/
protected void createMasterPart(final IManagedForm managedForm, Composite parent)
{
FormToolkit toolkit = managedForm.getToolkit();
Section section = toolkit.createSection(parent, Section.DESCRIPTION | Section.TITLE_BAR );
section.setText("Proof Statements");
section.setDescription("Select a statement to review");
section.marginWidth = 10;
section.marginHeight = 5;
toolkit.createCompositeSeparator(section);
Composite client = toolkit.createComposite(section, SWT.WRAP);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
client.setLayout(layout);
Tree t = toolkit.createTree(client, SWT.NULL);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.heightHint = 300;
gd.widthHint = 200;
t.setLayoutData(gd);
toolkit.paintBordersFor(client);
section.setClient(client);
final SectionPart spart = new SectionPart(section);
managedForm.addPart(spart);
viewer = new TreeViewer(t);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
managedForm.fireSelectionChanged(spart, event.getSelection());
validatePage.setSelectedNode(event.getSelection());
}
});
viewer.setContentProvider(new MasterContentProvider());
viewer.setLabelProvider(new MasterLabelProvider());
viewer.setInput( model );
viewer.expandAll();
}
/**
* Create toolbar actions to change the layout from vertical to horizontal orientation.
* @param managedForm form reference for toolbar manager
*/
protected void createToolBarActions(IManagedForm managedForm) {
final ScrolledForm form = managedForm.getForm();
Action haction = new Action("hor", Action.AS_RADIO_BUTTON) {
public void run() {
sashForm.setOrientation(SWT.HORIZONTAL);
form.reflow(true);
}
};
haction.setChecked(true);
haction.setToolTipText("Horizontal orientation");
haction.setImageDescriptor( Activator.getDefault().getImageRegistry().getDescriptor( Activator.REVIEW_HORIZONTAL_IMAGE));
Action vaction = new Action("ver", Action.AS_RADIO_BUTTON) {
public void run() {
sashForm.setOrientation(SWT.VERTICAL);
form.reflow(true);
}
};
vaction.setChecked(false);
vaction.setToolTipText("Vertical orientation");
vaction.setImageDescriptor( Activator.getDefault().getImageRegistry().getDescriptor( Activator.REVIEW_VERTICAL_IMAGE ));
form.getToolBarManager().add(haction);
form.getToolBarManager().add(vaction);
}
/**
* Adds the details pages for each master example type.
* There are pages for statements and proofs.
*/
protected void registerPages(DetailsPart detailsPart) {
proofDetailPage = new ProofDetailPage(proof,viewer,validatePage,setupPage);
statementDetailPage = new StatementDetailPage(proof,viewer,validatePage,setupPage);
detailsPart.registerPage(ProofImpl.class, proofDetailPage);
detailsPart.registerPage(StatementImpl.class, statementDetailPage );
}
class ModelContainer {
Proof proof;
}
}