Logo Search packages:      
Sourcecode: cdk version File versions

CopyPasteAction.java

/* $RCSfile$
 * $Author: egonw $
 * $Date: 2007-05-01 18:33:49 +0200 (Tue, 01 May 2007) $
 * $Revision: 8289 $
 * 
 * Copyright (C) 2005-2007  The JChemPaint project
 * 
 * Contact: jchempaint-devel@lists.sourceforge.net
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 * All we ask is that proper credit is given for our work, which includes
 * - but is not limited to - adding the above copyright notice to the beginning
 * of your source code files, and to any copyright notice that you may distribute
 * with programs based on this work.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.openscience.cdk.applications.jchempaint.action;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.util.Iterator;

import javax.swing.undo.UndoableEdit;

import org.openscience.cdk.ChemFile;
import org.openscience.cdk.ChemModel;
import org.openscience.cdk.DefaultChemObjectBuilder;
import org.openscience.cdk.Molecule;
import org.openscience.cdk.MoleculeSet;
import org.openscience.cdk.applications.jchempaint.JChemPaintModel;
import org.openscience.cdk.applications.undoredo.AddAtomsAndBondsEdit;
import org.openscience.cdk.geometry.GeometryTools;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IChemFile;
import org.openscience.cdk.io.IChemObjectReader;
import org.openscience.cdk.io.IChemObjectWriter;
import org.openscience.cdk.io.MDLV2000Reader;
import org.openscience.cdk.io.MDLWriter;
import org.openscience.cdk.io.ReaderFactory;
import org.openscience.cdk.io.SVGWriter;
import org.openscience.cdk.layout.StructureDiagramGenerator;
import org.openscience.cdk.layout.TemplateHandler;
import org.openscience.cdk.renderer.Renderer2DModel;
import org.openscience.cdk.smiles.SmilesGenerator;
import org.openscience.cdk.smiles.SmilesParser;
import org.openscience.cdk.tools.manipulator.ChemFileManipulator;

/**
 * Action to copy/paste structures.
 *
 * @cdk.module jchempaint
 * @author     Egon Willighagen <e.willighagen@science.ru.nl>
 * @cdk.bug    1288449
 */
00075 public class CopyPasteAction extends JCPAction{

      private static final long serialVersionUID = -3343207264261279526L;
      
      private DataFlavor molFlavor = new DataFlavor(
            "chemical/x-mdl-molfile", "mdl mol file format");
      private DataFlavor svgFlavor = new DataFlavor(
            "image/svg+xml",          "scalable vector graphics");
      private DataFlavor cmlFlavor = new DataFlavor(
              "image/cml",          "chemical markup language");
    
00086       public void actionPerformed(ActionEvent e) {
      try {
            handleSystemClipboard();
              logger.info("  type  ", type);
              logger.debug("  source ", e.getSource());
              JChemPaintModel jcpModel = jcpPanel.getJChemPaintModel();
              Renderer2DModel renderModel = jcpModel.getRendererModel();
              if ("copy".equals(type)) {
                  IAtomContainer tocopy = renderModel.getSelectedPart();
                  if (tocopy == null) {
                        return;
                  }
                  Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
                  IAtomContainer tocopyclone=(IAtomContainer)tocopy.clone();
                  for(int i=0;i<tocopy.getAtomCount();i++){
                        tocopyclone.getAtom(i).setPoint2d(renderModel.getRenderingCoordinate(tocopy.getAtom(i)));
                  }
                  JcpSelection jcpselection=new JcpSelection(tocopyclone);
                  sysClip.setContents(jcpselection,null);
              } else if ("paste".equals(type)) {
                  Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
                  Transferable transfer = sysClip.getContents( null );
                  IChemObjectReader reader = null;
                  // if a MIME type is given ...
                  if (transfer!=null && (transfer.isDataFlavorSupported (molFlavor))) {
                        String mol = (String) transfer.getTransferData (molFlavor);
                        logger.debug("Dataflavor molFlavor found");
                        reader = new MDLV2000Reader(new StringReader(mol));
                  } else if(transfer!=null && (transfer.isDataFlavorSupported (DataFlavor.stringFlavor))) {
                        // otherwise, try to use the ReaderFactory...
                        logger.debug("Dataflavor stringFlavor found");
                        String content = (String) transfer.getTransferData (DataFlavor.stringFlavor);
                        try {
                              reader = new ReaderFactory().createReader(new StringReader(content));
                        } catch (Exception exception) {
                              logger.warn("Pastes string is not recognized.");
                        }
                  }
                  IAtomContainer topaste = null;
                  if (reader != null) {
                        if (reader.accepts(Molecule.class)) { 
                              topaste = (IAtomContainer) reader.read(new Molecule());
                        } else if (reader.accepts(ChemFile.class)) {
                              topaste = new Molecule();
                              IChemFile file = (IChemFile)reader.read(new ChemFile());
                        Iterator containers = ChemFileManipulator.getAllAtomContainers(file).iterator();
                        while (containers.hasNext()) {
                              topaste.add((IAtomContainer)containers.next());
                        }
                        }
                  }
                  if(topaste==null && transfer!=null && (transfer.isDataFlavorSupported (DataFlavor.stringFlavor))) {
                        try{
                              SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
                              topaste = sp.parseSmiles((String) transfer.getTransferData (DataFlavor.stringFlavor));
                              StructureDiagramGenerator sdg = new StructureDiagramGenerator((Molecule)topaste);
                        sdg.setTemplateHandler(
                            new TemplateHandler(topaste.getBuilder())
                        );
                        sdg.generateCoordinates();
                              jcpPanel.scaleAndCenterMolecule(topaste,jcpPanel.getSize());
                              for(int i=0;i<topaste.getAtomCount();i++){
                                    renderModel.getRenderingCoordinates().put(topaste.getAtom(i), topaste.getAtom(i).getPoint2d());
                              }
                        }catch(Exception ex){
                              //we just try smiles
                        }
                  }
                  if (topaste != null) {
                      topaste = (IAtomContainer)topaste.clone();
                      
                      org.openscience.cdk.interfaces.IChemModel chemModel = jcpModel.getChemModel();
                      //translate the new structure a bit
                      GeometryTools.translate2D(topaste, 25, 25,jcpModel.getRendererModel().getRenderingCoordinates()); //in pixels
                      //paste the new structure into the active model
                      org.openscience.cdk.interfaces.IMoleculeSet moleculeSet = chemModel.getMoleculeSet();
                      if (moleculeSet == null) {
                          moleculeSet = new MoleculeSet();
                            chemModel.setMoleculeSet(moleculeSet);
                      }
                      moleculeSet.addMolecule(new Molecule(topaste));
                      // to ensure, that the molecule is  shown in the actual visibile part of jcp
                      jcpPanel.scaleAndCenterMolecule((ChemModel)jcpPanel.getChemModel());
                      //make the pasted structure selected
                      renderModel.setSelectedPart(topaste);
                      //handle undo/redo
                      UndoableEdit  edit = new AddAtomsAndBondsEdit(chemModel, topaste, "Pasted something",jcpModel.getControllerModel());
                      jcpPanel.getUndoSupport().postEdit(edit);
                  }
            }
      } catch(Exception ex){
            ex.printStackTrace();
      }
    }
    
    void handleSystemClipboard()
    {
            Clipboard clipboard = jcpPanel.getToolkit().getSystemClipboard();
            Transferable clipboardContent = clipboard.getContents(this);
            DataFlavor flavors[]=clipboardContent.getTransferDataFlavors();
            String text = "System.clipoard content";
            for(int i=0;i<flavors.length;++i)
            {
                  text+="\n\n Name: "+ flavors[i].getHumanPresentableName();
                  text+="\n MIME Type: "+flavors[i].getMimeType();
                  text+="\n Class: ";
                  Class cl = flavors[i].getRepresentationClass();
                  if(cl==null) text+="null";
                  else text+=cl.getName();
            }
            logger.debug(text);
    }

    class JcpSelection implements Transferable, ClipboardOwner {
        private DataFlavor [] supportedFlavors = {
            molFlavor, DataFlavor.stringFlavor, svgFlavor, cmlFlavor
        };
      String mol;
      String smiles;
      String svg;
      String cml;

      public JcpSelection (IAtomContainer tocopy1) throws Exception{
        Molecule tocopy=new Molecule(tocopy1);
        // MDL mol output
          StringWriter sw = new StringWriter();
          new MDLWriter(sw).writeMolecule(tocopy);
        this.mol=sw.toString();
        SmilesGenerator sg=new SmilesGenerator();
        smiles = sg.createSMILES(tocopy);
        // SVG output
        sw=new StringWriter();
        IChemObjectWriter cow = new SVGWriter(sw);
        cow.write(tocopy);
        cow.close();
        svg=sw.toString();
        // CML output
        sw = new StringWriter();
        Class cmlWriterClass = null;
        try {
              cmlWriterClass = this.getClass().getClassLoader().loadClass("org.openscience.cdk.io.CMLWriter");
        } catch (Exception exception) {
              logger.error("Could not load CMLWriter: ", exception.getMessage());
              logger.debug(exception);
        }
        if (cmlWriterClass != null) {
              cow = (IChemObjectWriter)cmlWriterClass.newInstance();
              Constructor constructor = cow.getClass().getConstructor(new Class[]{Writer.class});
              cow = (IChemObjectWriter)constructor.newInstance(new Object[]{sw});
              cow.write(tocopy);
              cow.close();
        }
        cml=sw.toString();
      }
      
      public synchronized DataFlavor [] getTransferDataFlavors () {
      return (supportedFlavors);
        }
      
      public boolean isDataFlavorSupported (DataFlavor parFlavor) {
        for(int i=0;i<supportedFlavors.length;i++){
              if(supportedFlavors[i].equals(parFlavor))
                    return true;
        }
        return false;
      }
      
      public synchronized Object getTransferData (DataFlavor parFlavor) throws UnsupportedFlavorException {
      if (parFlavor.equals (molFlavor)) {
            return mol;
      } else if(parFlavor.equals(DataFlavor.stringFlavor)) {
            return smiles;
      } else if(parFlavor.equals(cmlFlavor)) {
            return cml;
      } else if(parFlavor.equals(svgFlavor)) {
            return svg;
      } else {
            throw new UnsupportedFlavorException (parFlavor);
      }
      }
      
      public void lostOwnership (Clipboard parClipboard, Transferable parTransferable) {
      System.out.println ("Lost ownership");
      }
   }
}


Generated by  Doxygen 1.6.0   Back to index