~ubuntu-branches/ubuntu/trusty/cdk/trusty-proposed

« back to all changes in this revision

Viewing changes to src/org/openscience/cdk/applications/jchempaint/action/CopyPasteAction.java

  • Committer: Bazaar Package Importer
  • Author(s): Paul Cager
  • Date: 2008-04-09 21:17:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080409211753-46lmjw5z8mx5pd8d
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $RCSfile$
 
2
 * $Author: egonw $
 
3
 * $Date: 2007-05-01 18:33:49 +0200 (Tue, 01 May 2007) $
 
4
 * $Revision: 8289 $
 
5
 * 
 
6
 * Copyright (C) 2005-2007  The JChemPaint project
 
7
 * 
 
8
 * Contact: jchempaint-devel@lists.sourceforge.net
 
9
 * 
 
10
 * This program is free software; you can redistribute it and/or
 
11
 * modify it under the terms of the GNU Lesser General Public License
 
12
 * as published by the Free Software Foundation; either version 2.1
 
13
 * of the License, or (at your option) any later version.
 
14
 * All we ask is that proper credit is given for our work, which includes
 
15
 * - but is not limited to - adding the above copyright notice to the beginning
 
16
 * of your source code files, and to any copyright notice that you may distribute
 
17
 * with programs based on this work.
 
18
 * 
 
19
 * This program is distributed in the hope that it will be useful,
 
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
 * GNU Lesser General Public License for more details.
 
23
 * 
 
24
 * You should have received a copy of the GNU Lesser General Public License
 
25
 * along with this program; if not, write to the Free Software
 
26
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
27
 */
 
28
package org.openscience.cdk.applications.jchempaint.action;
 
29
 
 
30
import java.awt.Toolkit;
 
31
import java.awt.datatransfer.Clipboard;
 
32
import java.awt.datatransfer.ClipboardOwner;
 
33
import java.awt.datatransfer.DataFlavor;
 
34
import java.awt.datatransfer.Transferable;
 
35
import java.awt.datatransfer.UnsupportedFlavorException;
 
36
import java.awt.event.ActionEvent;
 
37
import java.io.StringReader;
 
38
import java.io.StringWriter;
 
39
import java.io.Writer;
 
40
import java.lang.reflect.Constructor;
 
41
import java.util.Iterator;
 
42
 
 
43
import javax.swing.undo.UndoableEdit;
 
44
 
 
45
import org.openscience.cdk.ChemFile;
 
46
import org.openscience.cdk.ChemModel;
 
47
import org.openscience.cdk.DefaultChemObjectBuilder;
 
48
import org.openscience.cdk.Molecule;
 
49
import org.openscience.cdk.MoleculeSet;
 
50
import org.openscience.cdk.applications.jchempaint.JChemPaintModel;
 
51
import org.openscience.cdk.applications.undoredo.AddAtomsAndBondsEdit;
 
52
import org.openscience.cdk.geometry.GeometryTools;
 
53
import org.openscience.cdk.interfaces.IAtomContainer;
 
54
import org.openscience.cdk.interfaces.IChemFile;
 
55
import org.openscience.cdk.io.IChemObjectReader;
 
56
import org.openscience.cdk.io.IChemObjectWriter;
 
57
import org.openscience.cdk.io.MDLV2000Reader;
 
58
import org.openscience.cdk.io.MDLWriter;
 
59
import org.openscience.cdk.io.ReaderFactory;
 
60
import org.openscience.cdk.io.SVGWriter;
 
61
import org.openscience.cdk.layout.StructureDiagramGenerator;
 
62
import org.openscience.cdk.layout.TemplateHandler;
 
63
import org.openscience.cdk.renderer.Renderer2DModel;
 
64
import org.openscience.cdk.smiles.SmilesGenerator;
 
65
import org.openscience.cdk.smiles.SmilesParser;
 
66
import org.openscience.cdk.tools.manipulator.ChemFileManipulator;
 
67
 
 
68
/**
 
69
 * Action to copy/paste structures.
 
70
 *
 
71
 * @cdk.module jchempaint
 
72
 * @author     Egon Willighagen <e.willighagen@science.ru.nl>
 
73
 * @cdk.bug    1288449
 
74
 */
 
75
public class CopyPasteAction extends JCPAction{
 
76
 
 
77
        private static final long serialVersionUID = -3343207264261279526L;
 
78
        
 
79
        private DataFlavor molFlavor = new DataFlavor(
 
80
                "chemical/x-mdl-molfile", "mdl mol file format");
 
81
        private DataFlavor svgFlavor = new DataFlavor(
 
82
                "image/svg+xml",          "scalable vector graphics");
 
83
        private DataFlavor cmlFlavor = new DataFlavor(
 
84
                  "image/cml",          "chemical markup language");
 
85
    
 
86
        public void actionPerformed(ActionEvent e) {
 
87
        try {
 
88
                handleSystemClipboard();
 
89
                logger.info("  type  ", type);
 
90
                logger.debug("  source ", e.getSource());
 
91
                JChemPaintModel jcpModel = jcpPanel.getJChemPaintModel();
 
92
                Renderer2DModel renderModel = jcpModel.getRendererModel();
 
93
                if ("copy".equals(type)) {
 
94
                    IAtomContainer tocopy = renderModel.getSelectedPart();
 
95
                    if (tocopy == null) {
 
96
                        return;
 
97
                    }
 
98
                    Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
 
99
                    IAtomContainer tocopyclone=(IAtomContainer)tocopy.clone();
 
100
                    for(int i=0;i<tocopy.getAtomCount();i++){
 
101
                        tocopyclone.getAtom(i).setPoint2d(renderModel.getRenderingCoordinate(tocopy.getAtom(i)));
 
102
                    }
 
103
                    JcpSelection jcpselection=new JcpSelection(tocopyclone);
 
104
                    sysClip.setContents(jcpselection,null);
 
105
                } else if ("paste".equals(type)) {
 
106
                        Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
 
107
                        Transferable transfer = sysClip.getContents( null );
 
108
                        IChemObjectReader reader = null;
 
109
                        // if a MIME type is given ...
 
110
                        if (transfer!=null && (transfer.isDataFlavorSupported (molFlavor))) {
 
111
                                String mol = (String) transfer.getTransferData (molFlavor);
 
112
                                logger.debug("Dataflavor molFlavor found");
 
113
                                reader = new MDLV2000Reader(new StringReader(mol));
 
114
                        } else if(transfer!=null && (transfer.isDataFlavorSupported (DataFlavor.stringFlavor))) {
 
115
                                // otherwise, try to use the ReaderFactory...
 
116
                                logger.debug("Dataflavor stringFlavor found");
 
117
                                String content = (String) transfer.getTransferData (DataFlavor.stringFlavor);
 
118
                                try {
 
119
                                        reader = new ReaderFactory().createReader(new StringReader(content));
 
120
                                } catch (Exception exception) {
 
121
                                        logger.warn("Pastes string is not recognized.");
 
122
                                }
 
123
                        }
 
124
                        IAtomContainer topaste = null;
 
125
                        if (reader != null) {
 
126
                                if (reader.accepts(Molecule.class)) { 
 
127
                                        topaste = (IAtomContainer) reader.read(new Molecule());
 
128
                                } else if (reader.accepts(ChemFile.class)) {
 
129
                                        topaste = new Molecule();
 
130
                                        IChemFile file = (IChemFile)reader.read(new ChemFile());
 
131
                        Iterator containers = ChemFileManipulator.getAllAtomContainers(file).iterator();
 
132
                        while (containers.hasNext()) {
 
133
                                topaste.add((IAtomContainer)containers.next());
 
134
                        }
 
135
                                }
 
136
                        }
 
137
                        if(topaste==null && transfer!=null && (transfer.isDataFlavorSupported (DataFlavor.stringFlavor))) {
 
138
                                try{
 
139
                                        SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance());
 
140
                                        topaste = sp.parseSmiles((String) transfer.getTransferData (DataFlavor.stringFlavor));
 
141
                                        StructureDiagramGenerator sdg = new StructureDiagramGenerator((Molecule)topaste);
 
142
                        sdg.setTemplateHandler(
 
143
                            new TemplateHandler(topaste.getBuilder())
 
144
                        );
 
145
                        sdg.generateCoordinates();
 
146
                                        jcpPanel.scaleAndCenterMolecule(topaste,jcpPanel.getSize());
 
147
                                        for(int i=0;i<topaste.getAtomCount();i++){
 
148
                                                renderModel.getRenderingCoordinates().put(topaste.getAtom(i), topaste.getAtom(i).getPoint2d());
 
149
                                        }
 
150
                                }catch(Exception ex){
 
151
                                        //we just try smiles
 
152
                                }
 
153
                        }
 
154
                    if (topaste != null) {
 
155
                        topaste = (IAtomContainer)topaste.clone();
 
156
                        
 
157
                        org.openscience.cdk.interfaces.IChemModel chemModel = jcpModel.getChemModel();
 
158
                        //translate the new structure a bit
 
159
                        GeometryTools.translate2D(topaste, 25, 25,jcpModel.getRendererModel().getRenderingCoordinates()); //in pixels
 
160
                        //paste the new structure into the active model
 
161
                        org.openscience.cdk.interfaces.IMoleculeSet moleculeSet = chemModel.getMoleculeSet();
 
162
                        if (moleculeSet == null) {
 
163
                            moleculeSet = new MoleculeSet();
 
164
                                chemModel.setMoleculeSet(moleculeSet);
 
165
                        }
 
166
                        moleculeSet.addMolecule(new Molecule(topaste));
 
167
                        // to ensure, that the molecule is  shown in the actual visibile part of jcp
 
168
                        jcpPanel.scaleAndCenterMolecule((ChemModel)jcpPanel.getChemModel());
 
169
                        //make the pasted structure selected
 
170
                        renderModel.setSelectedPart(topaste);
 
171
                        //handle undo/redo
 
172
                        UndoableEdit  edit = new AddAtomsAndBondsEdit(chemModel, topaste, "Pasted something",jcpModel.getControllerModel());
 
173
                        jcpPanel.getUndoSupport().postEdit(edit);
 
174
                    }
 
175
                }
 
176
        } catch(Exception ex){
 
177
                ex.printStackTrace();
 
178
        }
 
179
    }
 
180
    
 
181
    void handleSystemClipboard()
 
182
    {
 
183
                Clipboard clipboard = jcpPanel.getToolkit().getSystemClipboard();
 
184
                Transferable clipboardContent = clipboard.getContents(this);
 
185
                DataFlavor flavors[]=clipboardContent.getTransferDataFlavors();
 
186
                String text = "System.clipoard content";
 
187
                for(int i=0;i<flavors.length;++i)
 
188
                {
 
189
                        text+="\n\n Name: "+ flavors[i].getHumanPresentableName();
 
190
                        text+="\n MIME Type: "+flavors[i].getMimeType();
 
191
                        text+="\n Class: ";
 
192
                        Class cl = flavors[i].getRepresentationClass();
 
193
                        if(cl==null) text+="null";
 
194
                        else text+=cl.getName();
 
195
                }
 
196
                logger.debug(text);
 
197
    }
 
198
 
 
199
    class JcpSelection implements Transferable, ClipboardOwner {
 
200
          private DataFlavor [] supportedFlavors = {
 
201
              molFlavor, DataFlavor.stringFlavor, svgFlavor, cmlFlavor
 
202
          };
 
203
      String mol;
 
204
      String smiles;
 
205
      String svg;
 
206
      String cml;
 
207
 
 
208
      public JcpSelection (IAtomContainer tocopy1) throws Exception{
 
209
          Molecule tocopy=new Molecule(tocopy1);
 
210
          // MDL mol output
 
211
          StringWriter sw = new StringWriter();
 
212
          new MDLWriter(sw).writeMolecule(tocopy);
 
213
          this.mol=sw.toString();
 
214
          SmilesGenerator sg=new SmilesGenerator();
 
215
          smiles = sg.createSMILES(tocopy);
 
216
          // SVG output
 
217
          sw=new StringWriter();
 
218
          IChemObjectWriter cow = new SVGWriter(sw);
 
219
          cow.write(tocopy);
 
220
          cow.close();
 
221
          svg=sw.toString();
 
222
          // CML output
 
223
          sw = new StringWriter();
 
224
          Class cmlWriterClass = null;
 
225
          try {
 
226
                  cmlWriterClass = this.getClass().getClassLoader().loadClass("org.openscience.cdk.io.CMLWriter");
 
227
          } catch (Exception exception) {
 
228
                  logger.error("Could not load CMLWriter: ", exception.getMessage());
 
229
                  logger.debug(exception);
 
230
          }
 
231
          if (cmlWriterClass != null) {
 
232
                  cow = (IChemObjectWriter)cmlWriterClass.newInstance();
 
233
                  Constructor constructor = cow.getClass().getConstructor(new Class[]{Writer.class});
 
234
                  cow = (IChemObjectWriter)constructor.newInstance(new Object[]{sw});
 
235
                  cow.write(tocopy);
 
236
                  cow.close();
 
237
          }
 
238
          cml=sw.toString();
 
239
      }
 
240
        
 
241
      public synchronized DataFlavor [] getTransferDataFlavors () {
 
242
        return (supportedFlavors);
 
243
          }
 
244
      
 
245
      public boolean isDataFlavorSupported (DataFlavor parFlavor) {
 
246
          for(int i=0;i<supportedFlavors.length;i++){
 
247
                  if(supportedFlavors[i].equals(parFlavor))
 
248
                          return true;
 
249
          }
 
250
          return false;
 
251
      }
 
252
        
 
253
      public synchronized Object getTransferData (DataFlavor parFlavor) throws UnsupportedFlavorException {
 
254
        if (parFlavor.equals (molFlavor)) {
 
255
                return mol;
 
256
        } else if(parFlavor.equals(DataFlavor.stringFlavor)) {
 
257
                return smiles;
 
258
        } else if(parFlavor.equals(cmlFlavor)) {
 
259
                return cml;
 
260
        } else if(parFlavor.equals(svgFlavor)) {
 
261
                return svg;
 
262
        } else {
 
263
                throw new UnsupportedFlavorException (parFlavor);
 
264
        }
 
265
      }
 
266
      
 
267
      public void lostOwnership (Clipboard parClipboard, Transferable parTransferable) {
 
268
        System.out.println ("Lost ownership");
 
269
      }
 
270
   }
 
271
}
 
272