paste adds or creates full copies of objects in clipboard, and properly copies sequen...
authorjprocter <Jim Procter>
Tue, 17 Apr 2007 11:31:15 +0000 (11:31 +0000)
committerjprocter <Jim Procter>
Tue, 17 Apr 2007 11:31:15 +0000 (11:31 +0000)
src/jalview/gui/AlignFrame.java

index 1396c93..ee2f7fd 100755 (executable)
@@ -180,7 +180,6 @@ public class AlignFrame
               && Character.isDigit(evt.getKeyChar()))
             alignPanel.seqPanel.numberPressed(evt.getKeyChar());
 
-
           switch (evt.getKeyCode())
           {
 
@@ -1409,6 +1408,7 @@ public class AlignFrame
    */
   void paste(boolean newAlignment)
   {
+    boolean externalPaste=true;
     try
     {
       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
@@ -1451,102 +1451,143 @@ public class AlignFrame
       }
 
       SequenceI[] sequences;
-
+      boolean annotationAdded = false;
+      AlignmentI alignment = null;
 
      if(Desktop.jalviewClipboard!=null)
      {
        // The clipboard was filled from within Jalview, we must use the sequences
        // And dataset from the copied alignment
-       sequences = (SequenceI[])Desktop.jalviewClipboard[0];
+       SequenceI[] newseq = (SequenceI[])Desktop.jalviewClipboard[0];
+       // be doubly sure that we create *new* sequence objects.
+       sequences = new SequenceI[newseq.length];
+       for (int i=0;i<newseq.length;i++) {
+         sequences[i] = new Sequence(newseq[i]);
+       }
+       alignment = new Alignment(sequences);
+       externalPaste = false;
      }
      else
      {
-        sequences = new FormatAdapter().readFile(str, "Paste", format).
-            getSequencesArray();
+       // parse the clipboard as an alignment.
+       alignment = new FormatAdapter().readFile(str, "Paste", format);
+       sequences = alignment.getSequencesArray();
      }
 
-     AlignmentI alignment = null;
-
-      if (newAlignment)
-      {
-          alignment = new Alignment(sequences);
 
-          if (Desktop.jalviewClipboard != null)
+     if (newAlignment)
+     {
+       
+       if (Desktop.jalviewClipboard != null)
+       {
+         // dataset is inherited
+         alignment.setDataset( (Alignment) Desktop.jalviewClipboard[1]);
+       }
+       else
+       {
+         // new dataset is constructed
+         alignment.setDataset(null);
+       }
+     }
+     else
+     {
+       AlignmentI pastedal = alignment; // preserve pasted alignment object
+       // Add pasted sequences and dataset into existing alignment.
+       alignment = viewport.getAlignment();
+        // decide if we need to import sequences from an existing dataset
+        boolean importDs = Desktop.jalviewClipboard != null
+                && Desktop.jalviewClipboard[1] != alignment.getDataset();
+        // importDs==true instructs us to copy over new dataset sequences from
+        // an existing alignment
+        Vector newDs = (importDs) ? new Vector() : null; // used to create
+                                                          // minimum dataset set
+        
+        for (int i = 0; i < sequences.length; i++)
         {
-            alignment.setDataset( (Alignment) Desktop.jalviewClipboard[1]);
-        }
+          if (importDs) 
+          {
+            newDs.addElement(null);
+          }
+          SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
+                                                            // paste
+          if (importDs && ds != null)
+          {
+            if (!newDs.contains(ds))
+            {
+              newDs.setElementAt(ds, i); 
+              ds = new Sequence(ds);
+              // update with new dataset sequence
+              sequences[i].setDatasetSequence(ds);
+            }
+            else
+            {
+              ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
+            }
+          }
           else
+          {
+            // copy and derive new dataset sequence
+            sequences[i] = sequences[i].deriveSequence();
+            alignment.getDataset().addSequence(sequences[i].getDatasetSequence());
+            // TODO: avoid creation of duplicate dataset sequences with a
+            // 'contains' method using SequenceI.equals()/SequenceI.contains()
+          }
+          alignment.addSequence(sequences[i]); // merges dataset
+        }
+        if (newDs != null)
         {
-            alignment.setDataset(null);
-      }
-      }
-      else
-      {
-        alignment = viewport.getAlignment();
-
-        //!newAlignment
-        SequenceI [] newseqs = new SequenceI[sequences.length];
-        for (int i = 0; i < sequences.length; i++)
-        {
-          newseqs[i] = new Sequence(sequences[i].getName(),
-                                    sequences[i].getSequence(),
-                                    sequences[i].getStart(),
-              sequences[i].getEnd());
-
-          alignment.addSequence(newseqs[i]);
+          newDs.clear(); // tidy up
         }
-
-        /*
-         //ADD HISTORY ITEM
-         */
-        addHistoryItem(new EditCommand(
-            "Add sequences",
-            EditCommand.PASTE,
-            newseqs,
-            0,
-            alignment.getWidth(),
-            alignment)
-            );
-
-
-        viewport.setEndSeq(alignment.getHeight());
-        alignment.getWidth();
-        viewport.firePropertyChange("alignment", null, alignment.getSequences());
-      }
-
-
-
-      // Add any annotations attached to sequences
-      for (int i = 0; i < sequences.length; i++)
+        if (pastedal.getAlignmentAnnotation()!=null) {
+          // Add any annotation attached to alignment.
+          AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
+          for (int i=0; i<alann.length; i++)
+          {
+            annotationAdded=true;
+            if (alann[i].sequenceRef==null && !alann[i].autoCalculated) {
+              alignment.addAnnotation(new AlignmentAnnotation(alann[i]));
+            }
+          }
+        }
+     }
+     if (!newAlignment) {
+       ///////
+       // ADD HISTORY ITEM
+       //
+       addHistoryItem(new EditCommand(
+               "Add sequences",
+               EditCommand.PASTE,
+               sequences,
+               0,
+               alignment.getWidth(),
+               alignment)
+              );
+     }
+     // Add any annotations attached to sequences
+     for (int i = 0; i < sequences.length; i++)
      {
        if (sequences[i].getAnnotation() != null)
        {
          for (int a = 0; a < sequences[i].getAnnotation().length; a++)
          {
-           AlignmentAnnotation newAnnot =
-               new AlignmentAnnotation(
-                   sequences[i].getAnnotation()[a].label,
-                   sequences[i].getAnnotation()[a].description,
-                   sequences[i].getAnnotation()[a].annotations,
-                   sequences[i].getAnnotation()[a].graphMin,
-                   sequences[i].getAnnotation()[a].graphMax,
-                   sequences[i].getAnnotation()[a].graph);
-
-           sequences[i].getAnnotation()[a] = newAnnot;
-           newAnnot.sequenceMapping = sequences[i].getAnnotation()[a].
-               sequenceMapping;
-           newAnnot.sequenceRef = sequences[i];
-           newAnnot.adjustForAlignment();
-           alignment.addAnnotation(newAnnot);
-           alignment.setAnnotationIndex(newAnnot, a);
+           annotationAdded=true;
+           sequences[i].getAnnotation()[a].adjustForAlignment();
+           alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation was duplicated earlier
+           alignment.setAnnotationIndex(sequences[i].getAnnotation()[a], a);
          }
 
-         alignPanel.annotationPanel.adjustPanelHeight();
+         
        }
      }
-
-     if(newAlignment)
-     {
+     if (!newAlignment) {
+       // propagate alignment changed.
+       viewport.setEndSeq(alignment.getHeight());
+       if (annotationAdded)
+       {
+         alignPanel.annotationPanel.adjustPanelHeight();
+       }
+       viewport.firePropertyChange("alignment", null, alignment.getSequences());
+     } else {
        AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        String newtitle = new String("Copied sequences");
 
@@ -1564,15 +1605,19 @@ public class AlignFrame
        //>>>This is a fix for the moment, until a better solution is found!!<<<
        af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().transferSettings(
            alignPanel.seqPanel.seqCanvas.getFeatureRenderer());
-
-
-       if (title.startsWith("Copied sequences"))
-       {
-         newtitle = title;
-       }
-       else
-       {
-         newtitle = newtitle.concat("- from " + title);
+       
+       // TODO: maintain provenance of an alignment, rather than just make the title a concatenation of operations.
+       if (!externalPaste) {
+         if (title.startsWith("Copied sequences"))
+         {
+           newtitle = title;
+         }
+         else
+         {
+           newtitle = newtitle.concat("- from " + title);
+         }
+       } else {
+         newtitle = new String("Pasted sequences");
        }
 
        Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,