net.bioclipse.qsar.ui.editors.MoleculesPage.java Source code

Java tutorial

Introduction

Here is the source code for net.bioclipse.qsar.ui.editors.MoleculesPage.java

Source

/*******************************************************************************
 * Copyright (c) 2008 The Bioclipse Project 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:
 *     Ola Spjuth
 *     
 ******************************************************************************/
package net.bioclipse.qsar.ui.editors;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.List;

import net.bioclipse.cdk.business.Activator;
import net.bioclipse.cdk.business.ICDKManager;
import net.bioclipse.cdk.domain.ICDKMolecule;
import net.bioclipse.core.business.BioclipseException;
import net.bioclipse.qsar.QsarFactory;
import net.bioclipse.qsar.QsarPackage;
import net.bioclipse.qsar.QsarType;
import net.bioclipse.qsar.ResourceType;
import net.bioclipse.qsar.StructurelistType;
import net.bioclipse.qsar.business.IQsarManager;
import net.bioclipse.ui.dialogs.WSFileDialog;

import org.apache.log4j.Logger;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
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.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.databinding.edit.EMFEditObservables;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;

/**
 * Page for adding molecular content to model
 * @author ola
 *
 */
public class MoleculesPage extends FormPage
        implements IEditingDomainProvider, IViewerProvider, IPageChangedListener {

    private TableViewer molViewer;
    private Table molTable;

    private TableViewer preTableViewer;
    private Table preTable;

    private static final Logger logger = Logger.getLogger(MoleculesPage.class);

    ICDKManager cdk;
    IQsarManager qsar;
    DecimalFormat formatter;

    private EditingDomain editingDomain;

    private IProject activeProject;

    public MoleculesPage(FormEditor editor, EditingDomain editingDomain) {

        super(editor, "qsar.molecules", "Molecules");
        this.editingDomain = editingDomain;

        //Get managers
        cdk = Activator.getDefault().getJavaCDKManager();
        qsar = net.bioclipse.qsar.init.Activator.getDefault().getQsarManager();

        //Set up formatter
        //We need to ensure that '.' is always decimal separator in all locales
        DecimalFormatSymbols sym = new DecimalFormatSymbols();
        sym.setDecimalSeparator('.');
        formatter = new DecimalFormat("0.00", sym);

        QsarType qsarModel = ((QsarEditor) getEditor()).getQsarModel();

        //Get mollist from qsar model, init if empty (should not be)
        StructurelistType structList = qsarModel.getStructurelist();
        if (structList == null) {
            structList = QsarFactory.eINSTANCE.createStructurelistType();
            qsarModel.setStructurelist(structList);
        }

        editor.addPageChangedListener(this);
        if (editor.getEditorInput() instanceof IFileEditorInput) {
            IFileEditorInput fin = (IFileEditorInput) editor.getEditorInput();
            activeProject = fin.getFile().getProject();
        }

    }

    /**
     * Add content to form
     */
    @Override
    protected void createFormContent(IManagedForm managedForm) {

        ScrolledForm form = managedForm.getForm();
        FormToolkit toolkit = managedForm.getToolkit();
        form.setText("Molecules for QSAR analysis");
        toolkit.decorateFormHeading(form.getForm());

        IProject project = ((QsarEditor) getEditor()).getActiveProject();
        ToolbarHelper.setupToolbar(form, project);

        //        form.setBackgroundImage(FormArticlePlugin.getDefault().getImage(FormArticlePlugin.IMG_FORM_BG));
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        form.getBody().setLayout(layout);

        createMoleculesSection(form, toolkit);
        populateMolsViewerFromModel();

        createPreprocessingSection(form, toolkit);
        //        populatePreViewerFromModel();  //TODO!

        preTableViewer.getTable().setEnabled(false); //TODO: change!

        addDragAndDrop();

    }

    private void addDragAndDrop() {
        int ops = DND.DROP_COPY | DND.DROP_MOVE;
        Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer(), FileTransfer.getInstance() };
        molViewer.addDropSupport(ops, transfers, new ViewerDropAdapter(molViewer) {

            @Override
            public boolean performDrop(Object data) {

                if (!((data instanceof String[]) || (data instanceof IStructuredSelection))) {
                    return false;
                }

                final Object indata = data;

                WorkspaceJob job = new WorkspaceJob("Adding resources to QSAR project") {

                    @Override
                    public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {

                        List<IResource> resources = new ArrayList<IResource>();

                        //Handle selections within Bioclipse
                        if (indata instanceof String[]) {

                            List<IResource> newRes = handleDropOfFiles((String[]) indata, monitor);
                            if (newRes != null && newRes.size() > 0)
                                resources.addAll(newRes);
                        }

                        //Handle selections within Bioclipse
                        else if (indata instanceof IStructuredSelection) {

                            IStructuredSelection ssel = (IStructuredSelection) indata;
                            for (Object obj : ssel.toList()) {
                                if (obj instanceof IResource) {
                                    IResource res = (IResource) obj;
                                    resources.add(res);
                                }
                            }
                        }

                        //If none, return error
                        if (resources.size() <= 0)
                            return Status.CANCEL_STATUS;

                        //Add resources to model and molecules folder is necessary
                        try {
                            addResources(resources.toArray(new IResource[0]), monitor);
                        } catch (final UnsupportedOperationException e) {
                            Display.getDefault().syncExec(new Runnable() {
                                public void run() {
                                    showError("Error adding files: " + e.getMessage());
                                }
                            });
                        }

                        Display.getDefault().syncExec(new Runnable() {

                            public void run() {
                                molViewer.getTable().setFocus();
                            }

                        });
                        return Status.OK_STATUS;

                    }

                };

                job.setUser(true);
                job.schedule();

                return true;

            }

            @Override
            public boolean validateDrop(Object target, int operation, TransferData transferType) {
                return true;
            }
        });
    }

    /**
     * Handle the dropping of files on molviewer.
     * Test if contains molecules and copy to molecules folder in that case.
     * @param data
     * @param monitor
     * @return
     */
    protected List<IResource> handleDropOfFiles(final String[] data, IProgressMonitor monitor) {

        final List<IResource> retlist = new ArrayList<IResource>();

        for (String path : (String[]) data) {

            //For now, removed parsing of mols on addition

            //            try {
            //                List<ICDKMolecule> lst = cdk.loadMolecules(path);
            //                if (lst!=null && lst.size()>0){

            //Copy to molecules folder
            IResource res = copyFileToMoleculesFolder(path, monitor);
            if (res != null)
                retlist.add(res);
            //                }
            //            } catch (FileNotFoundException e) {
            //                e.printStackTrace();
            //            } catch (IOException e) {
            //                e.printStackTrace();
            //            } catch (BioclipseException e) {
            //                e.printStackTrace();
            //            } catch (CoreException e) {
            //                e.printStackTrace();
            //            }
        }

        return retlist;
    }

    /**
     * Copy the file into the molecules folder
     * @param path absolut path to the file
     * @param monitor
     * @return IFile in molecules folder
     */
    protected IResource copyFileToMoleculesFolder(String path, IProgressMonitor monitor) {

        java.io.File file = new java.io.File(path);
        final String filename = file.getName();

        FileInputStream instream;
        IFile newfile = null;
        try {
            instream = new FileInputStream(file);

            IFolder molfolder = activeProject.getFolder("molecules");
            IPath newpath = molfolder.getProjectRelativePath().append(filename);

            newfile = activeProject.getFile(newpath);

            if (newfile.exists()) {

                final boolean[] valueIsSet = { false };
                final boolean[] answer = { false };

                Display.getDefault().asyncExec(new Runnable() {
                    public void run() {
                        synchronized (valueIsSet) {
                            answer[0] = MessageDialog.openQuestion(getSite().getShell(), "Overwrite file?",
                                    "File " + filename + "exists in " + "project folder 'molecules'. "
                                            + "Would you like to replace " + "it?");
                            valueIsSet[0] = true;
                            valueIsSet.notifyAll();
                        }
                    }
                });

                synchronized (valueIsSet) {
                    while (!valueIsSet[0]) {
                        try {
                            valueIsSet.wait();
                        } catch (InterruptedException e) {
                            continue;
                        }
                    }
                }

                if (!answer[0])
                    return null;

                newfile.setContents(instream, true, false, monitor);

            } else {
                newfile.create(instream, true, monitor);

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (CoreException e) {
            e.printStackTrace();
            return null;
        }

        return newfile;

    }

    /**
     * Add resources to QSAR model. First check if contains molecules. 
     * Next copy the resource into the project/molecules folder if not already
     * there.
     * @param resources
     * @param monitor
     * @return
     */
    protected void addResources(final IResource[] resources, final IProgressMonitor monitor) {

        List<IResource> resourcesToAdd = new ArrayList<IResource>();

        QsarType qsarModel = ((QsarEditor) getEditor()).getQsarModel();
        StructurelistType structList = qsarModel.getStructurelist();

        //Copy files to project if needed
        for (IResource resource : resources) {

            if (resource instanceof IFile) {
                IFile file = (IFile) resource;
                boolean skipFile = false;

                //Check if this file is already in model
                for (ResourceType existingRes : structList.getResources()) {
                    if (existingRes.getName().equals(file.getName())) {
                        throw new UnsupportedOperationException(
                                "File: " + file.getName() + " already exists in QSAR analysis.");
                    }
                }

                try {
                    //Verify this is a file with at least one molecule
                    int x = cdk.getNoMolecules(file.getFullPath().toOSString());
                    if (x > 0) {

                        //If resource is in another project,
                        //copy it to molecules folder as use that copy
                        if (file.getProject() != activeProject) {
                            IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
                            IPath projectPath = activeProject.getFullPath(),
                                    molFolderPath = projectPath.append("molecules"),
                                    destinationPath = molFolderPath.append(file.getName());

                            final IFile newfile = root.getFile(destinationPath);
                            if (newfile.exists()) {
                                final String filename = file.getName();

                                ConfirmRunnable cr = new ConfirmRunnable(getSite().getShell(), "Overwrite file?",
                                        "File " + filename + "exists in QSAR project, " + "folder 'molecules'. "
                                                + "Would you like to replace it?");

                                Display.getDefault().syncExec(cr);

                                if (!cr.getAnswer())
                                    skipFile = true;

                                else {
                                    try {
                                        newfile.setContents(file.getContents(), true, true, monitor);
                                    } catch (CoreException e) {
                                        e.printStackTrace();
                                    }
                                }

                            } else {
                                //Copy it
                                file.copy(destinationPath, true, monitor);
                            }

                            file = root.getFile(destinationPath);
                        }

                        if (!skipFile) {
                            resourcesToAdd.add(file);
                        }
                    }
                } catch (final Exception e) {
                    Display.getDefault().syncExec(new Runnable() {
                        public void run() {
                            showError("Could not add molecule file. \n\nReason: " + e.getMessage());
                        }
                    });
                }
            }
        }

        //Ok, add these resources to QsarModel using manager

        try {
            qsar.addResourcesToQsarModel(qsarModel, editingDomain, resourcesToAdd, monitor);
        } catch (IOException e) {
            logger.error(e.getStackTrace());
            showError(e.getMessage());
        } catch (BioclipseException e) {
            logger.error(e.getStackTrace());
            showError(e.getMessage());
        } catch (CoreException e) {
            logger.error(e.getStackTrace());
            showError(e.getMessage());
        }

    }

    private void populateMolsViewerFromModel() {

        // The content provider is responsible to handle add and
        // remove notification for the Person#address EList
        ObservableListContentProvider provider = new ObservableListContentProvider();
        molViewer.setContentProvider(provider);

        // The label provider in turn handles the addresses
        // The EStructuralFeature[] defines which fields get shown
        // in the TableViewer columns
        IObservableSet knownElements = provider.getKnownElements();
        IObservableMap[] observeMaps = EMFEditObservables.observeMaps(editingDomain, knownElements,
                new EStructuralFeature[] { QsarPackage.Literals.RESOURCE_TYPE__NAME,
                        QsarPackage.Literals.RESOURCE_TYPE__NO_MOLS, QsarPackage.Literals.RESOURCE_TYPE__NO2D,
                        QsarPackage.Literals.RESOURCE_TYPE__NO3D });
        ObservableMapLabelProvider labelProvider = new ObservableQSARLabelProvider(observeMaps);
        molViewer.setLabelProvider(labelProvider);

        QsarType qsarModel = ((QsarEditor) getEditor()).getQsarModel();
        StructurelistType structList = qsarModel.getStructurelist();

        // Person#addresses is the Viewer's input
        molViewer.setInput(EMFEditObservables.observeList(Realm.getDefault(), editingDomain, structList,
                QsarPackage.Literals.STRUCTURELIST_TYPE__RESOURCES));

    }

    private void createMoleculesSection(final ScrolledForm form, FormToolkit toolkit) {

        Section molSection = toolkit.createSection(form.getBody(), Section.TWISTIE | Section.DESCRIPTION);
        molSection.setActiveToggleColor(toolkit.getHyperlinkGroup().getActiveForeground());
        molSection.setToggleColor(toolkit.getColors().getColor(IFormColors.SEPARATOR));
        toolkit.createCompositeSeparator(molSection);
        Composite client = toolkit.createComposite(molSection, SWT.WRAP);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        client.setLayout(layout);

        molViewer = new TableViewer(client, SWT.BORDER | SWT.MULTI);
        molTable = molViewer.getTable();
        toolkit.adapt(molTable, true, true);
        GridData gd = new GridData(GridData.FILL_VERTICAL);
        gd.widthHint = 350;
        gd.verticalSpan = 2;
        molTable.setLayoutData(gd);

        molTable.setHeaderVisible(true);
        //          molTable.setLinesVisible(true);
        toolkit.adapt(molTable, true, true);

        //Add name columns
        TableLayout tableLayout = new TableLayout();
        molTable.setLayout(tableLayout);
        TableViewerColumn ixcol = new TableViewerColumn(molViewer, SWT.BORDER);
        ixcol.getColumn().setText("Name");
        tableLayout.addColumnData(new ColumnPixelData(175));

        //Add # column
        TableViewerColumn col = new TableViewerColumn(molViewer, SWT.BORDER);
        col.getColumn().setText("# Molecules");
        tableLayout.addColumnData(new ColumnPixelData(75));

        //Add 2D column
        TableViewerColumn col2d = new TableViewerColumn(molViewer, SWT.BORDER);
        col2d.getColumn().setText("2D");
        tableLayout.addColumnData(new ColumnPixelData(30));

        //Add 2D column
        TableViewerColumn col3d = new TableViewerColumn(molViewer, SWT.BORDER);
        col3d.getColumn().setText("3D");
        tableLayout.addColumnData(new ColumnPixelData(30));

        molTable.addKeyListener(new KeyListener() {
            public void keyPressed(KeyEvent e) {
                //Delete key
                if (e.keyCode == SWT.DEL) {
                    deleteSelectedMolecules();
                }

                //Space key, toggle selection
                if (e.keyCode == 32) {

                    //                    IStructuredSelection msel=(IStructuredSelection) molViewer.getSelection();
                    //TODO: implement

                }
            }

            public void keyReleased(KeyEvent e) {
            }
        });

        //If focus gained, make this viewer provide selections
        molViewer.getTable().addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
                molViewer.setSelection(null);
            }

            public void focusLost(FocusEvent e) {
            }
        });

        Button btnAdd = toolkit.createButton(client, "Add...", SWT.PUSH);
        btnAdd.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                addMoleculeFile();
            }
        });
        GridData gd2 = new GridData();
        gd2.verticalAlignment = SWT.BEGINNING;
        gd2.widthHint = 60;
        btnAdd.setLayoutData(gd2);

        Button btnDel = toolkit.createButton(client, "Remove", SWT.PUSH);
        btnDel.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                deleteSelectedMolecules();
            }
        });
        gd2 = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
        gd2.widthHint = 60;
        btnDel.setLayoutData(gd2);

        //Wrap up section
        toolkit.paintBordersFor(client);
        molSection.setText("Molecules");
        molSection.setDescription("Molecules for descriptor calculations");
        molSection.setClient(client);
        molSection.setExpanded(true);
        molSection.addExpansionListener(new ExpansionAdapter() {
            public void expansionStateChanged(ExpansionEvent e) {
                form.reflow(false);
            }
        });

        gd = new GridData(GridData.FILL_BOTH);
        molSection.setLayoutData(gd);

    }

    private void createPreprocessingSection(final ScrolledForm form, FormToolkit toolkit) {

        Section preSection = toolkit.createSection(form.getBody(), Section.TWISTIE | Section.DESCRIPTION);
        preSection.setActiveToggleColor(toolkit.getHyperlinkGroup().getActiveForeground());
        preSection.setToggleColor(toolkit.getColors().getColor(IFormColors.SEPARATOR));
        toolkit.createCompositeSeparator(preSection);
        Composite client = toolkit.createComposite(preSection, SWT.WRAP);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        client.setLayout(layout);

        //Query TreeViewer
        preTableViewer = new TableViewer(client, SWT.BORDER | SWT.SINGLE);
        preTableViewer.setContentProvider(new PreprocessingContentProvider());
        preTableViewer.setLabelProvider(new PreprocessingLabelProvider());
        preTable = preTableViewer.getTable();
        toolkit.adapt(preTable, true, true);
        GridData gd6 = new GridData(GridData.FILL_VERTICAL);
        gd6.widthHint = 200;
        gd6.verticalSpan = 4;
        preTable.setLayoutData(gd6);

        preTable.addKeyListener(new KeyListener() {
            public void keyPressed(KeyEvent e) {

                //Delete key
                if (e.keyCode == SWT.DEL) {
                    deletePreprocessingStep();
                }

            }

            public void keyReleased(KeyEvent e) {
            }
        });

        Button btnAdd = toolkit.createButton(client, "Add...", SWT.PUSH);
        btnAdd.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                addPreprocessingStep();
            }
        });
        GridData gd2 = new GridData();
        gd2.verticalAlignment = SWT.BEGINNING;
        gd2.widthHint = 60;
        btnAdd.setLayoutData(gd2);

        Button btnDel = toolkit.createButton(client, "Remove", SWT.PUSH);
        btnDel.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                deletePreprocessingStep();
            }
        });
        gd2 = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
        gd2.widthHint = 60;
        btnDel.setLayoutData(gd2);

        Button btnUp = toolkit.createButton(client, "Up", SWT.PUSH);
        btnUp.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                moveSelectedUp();
            }
        });
        gd2 = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
        gd2.widthHint = 60;
        btnUp.setLayoutData(gd2);

        Button btnDown = toolkit.createButton(client, "Down", SWT.PUSH);
        btnDown.addListener(SWT.Selection, new Listener() {
            public void handleEvent(Event e) {
                moveSelectedDown();
            }
        });
        gd2 = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
        gd2.widthHint = 60;
        btnDown.setLayoutData(gd2);

        //Wrap up section
        toolkit.paintBordersFor(client);
        preSection.setText("Molecule preprocessing");
        preSection.setDescription("Add/remove and order preprocessing steps");
        preSection.setClient(client);
        preSection.setExpanded(true);
        preSection.addExpansionListener(new ExpansionAdapter() {
            public void expansionStateChanged(ExpansionEvent e) {
                form.reflow(false);
            }
        });
        GridData gd = new GridData(GridData.FILL_BOTH);
        preSection.setLayoutData(gd);

        //Post selections to Eclipse
        //          getSite().setSelectionProvider(queryViewer);

    }

    protected void moveSelectedDown() {

        showMessage("Not implemented");
        //TODO: implement

    }

    protected void moveSelectedUp() {

        showMessage("Not implemented");
        //TODO: implement

    }

    /**
     * After click of "ADD" button, add preprocess step
     */
    protected void addPreprocessingStep() {

        showMessage("Not implemented");
        //TODO: implement

    }

    protected void deletePreprocessingStep() {

        showMessage("Not implemented");
        //TODO: implement

        /*
        IStructuredSelection sel=(IStructuredSelection)preTableViewer.getSelection();
        for (Object obj : sel.toList()){
            
        }
        }
            
        preViewe 
        preTableViewer.getTable().setFocus();
         */
    }

    protected void changeMolViewerState(Object obj, boolean newState) {

        showMessage("Not implemented");
        //TODO: implement

        /*
        molViewer.setChecked( obj, newState );
            
        if ( obj instanceof MoleculeResource ) {
        molViewer.expandToLevel(obj, 1);
        MoleculeFile cont = (MoleculeFile) obj;
        for (PcoreMolecule mol : cont.getChildren()){
            molViewer.setChecked( mol, newState );
            for (PcoreConformer conf : mol.getConformers()){
                molViewer.setChecked( conf, newState );
            }
        }
        }
        if ( obj instanceof PcoreMolecule ) {
        //            molViewer.expandToLevel(obj, AbstractTreeViewer.ALL_LEVELS);
        PcoreMolecule pmol=(PcoreMolecule)obj;
        for (PcoreConformer conf : pmol.getConformers()){
            molViewer.setChecked( conf, newState );
        }
        }
         */
    }

    /**
     * Handle the case when users press the ADD button next to moleculeviewer
     */
    protected void addMoleculeFile() {

        IProject proj = ((QsarEditor) getEditor()).getActiveProject();

        WSFileDialog dlg = new WSFileDialog(getEditorSite().getShell(), SWT.MULTI, "Select molecules", proj, true,
                null, null);

        //Collect a list of resources currently in viewer 
        //to hide them in dialog
        //TODO

        //      if (molecules!=null && molecules.size()>0){
        //         List<IResource> res=new ArrayList<IResource>();
        //         for (MoleculeResource r : molecules){
        //            res.add(r.getResource());
        //         }
        //         dlg.setBlacklistFilter( res );
        //      }

        int r = dlg.open();
        if (r == Window.CANCEL) {
            return;
        }

        if (dlg.getMultiResult() == null || dlg.getMultiResult().length <= 0) {
            showMessage("Please select at least one molecule to add");
            return;
        }

        addResources(dlg.getMultiResult(), new NullProgressMonitor());

        //      for (IResource resource : dlg.getMultiResult()){
        //
        //         //Also add to QSAR model
        //         MoleculeResourceType mol1=QsarFactory.eINSTANCE.createMoleculeResourceType();
        //         mol1.setId(resource.getName());
        //         mol1.setName(resource.getName());
        //         mol1.setFile(resource.getFullPath().toString());
        //         Command cmd=AddCommand.create(editingDomain, moleculeList, 
        //               QsarPackage.Literals.MOLECULELIST_TYPE__MOLECULE_RESOURCE, mol1);
        //
        //         //Execute the CompoundCommand
        //         editingDomain.getCommandStack().execute(cmd);       
        //      }

        molViewer.refresh();

    }

    /**
     * Handle the case when users press the Remove button next to moleculeviewer
     * or presses the delete button on something
     */
    @SuppressWarnings("unchecked")
    protected void deleteSelectedMolecules() {

        IStructuredSelection ssel = (IStructuredSelection) molViewer.getSelection();
        if (ssel == null) {
            showMessage("Please select a molecule to remove");
            return;
        }

        QsarType qsarModel = ((QsarEditor) getEditor()).getQsarModel();
        qsar.removeResourcesFromModel(qsarModel, editingDomain, ssel.toList());

        molViewer.refresh();
    }

    private void showMessage(String message) {
        MessageDialog.openInformation(getSite().getShell(), "Information", message);
    }

    private void showError(String message) {
        MessageDialog.openError(getSite().getShell(), "Information", message);
    }

    public void activatePage() {

    }

    public class Stopwatch {
        private long start;
        private long stop;

        public void start() {
            start = System.currentTimeMillis(); // start timing
        }

        public void stop() {
            stop = System.currentTimeMillis(); // stop timing
        }

        public long elapsedTimeMillis() {
            return stop - start;
        }

        //return number of seconds
        public String toString() {
            return "" + Long.toString(elapsedTimeMillis() / 1000); // print execution time
        }
    }

    public EditingDomain getEditingDomain() {
        return editingDomain;
    }

    public Viewer getViewer() {
        return molViewer;
    }

    public void pageChanged(PageChangedEvent event) {

        if (event.getSelectedPage() != this)
            return;

        if (molViewer != null) {
            populateMolsViewerFromModel();
        }

        activatePage();

    }

}