JAL-1165 allow progress indicators on the web service window
[jalview.git] / src / jalview / commands / EditCommand.java
index d556442..d41f9f8 100644 (file)
@@ -1,18 +1,18 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
- * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
- * 
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
+ * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
+ *
  * This file is part of Jalview.
- * 
+ *
  * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
+ * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- * 
- * Jalview 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 
+ *
+ * Jalview 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 General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  */
 package jalview.commands;
@@ -22,24 +22,24 @@ import java.util.*;
 import jalview.datamodel.*;
 
 /**
- * 
+ *
  * <p>
  * Title: EditCommmand
  * </p>
- * 
+ *
  * <p>
  * Description: Essential information for performing undo and redo for cut/paste
  * insert/delete gap which can be stored in the HistoryList
  * </p>
- * 
+ *
  * <p>
  * Copyright: Copyright (c) 2006
  * </p>
- * 
+ *
  * <p>
  * Company: Dundee University
  * </p>
- * 
+ *
  * @author not attributable
  * @version 1.0
  */
@@ -55,6 +55,8 @@ public class EditCommand implements CommandI
 
   public static final int REPLACE = 4;
 
+  public static final int INSERT_NUC=5;
+
   Edit[] edits;
 
   String description;
@@ -94,11 +96,13 @@ public class EditCommand implements CommandI
     performEdit(0, null);
   }
 
+  @Override
   final public String getDescription()
   {
     return description;
   }
 
+  @Override
   public int getSize()
   {
     return edits == null ? 0 : edits.length;
@@ -114,7 +118,7 @@ public class EditCommand implements CommandI
    * operation affects more alignment objects than the one referenced in al (for
    * example, cut or pasting whole sequences). Use the form with an additional
    * AlignmentI[] views parameter.
-   * 
+   *
    * @param command
    * @param seqs
    * @param position
@@ -131,7 +135,7 @@ public class EditCommand implements CommandI
   /**
    * append a new edit command with a set of alignment views that may be
    * operated on
-   * 
+   *
    * @param command
    * @param seqs
    * @param position
@@ -143,8 +147,8 @@ public class EditCommand implements CommandI
   final public void appendEdit(int command, SequenceI[] seqs, int position,
           int number, AlignmentI al, boolean performEdit, AlignmentI[] views)
   {
-    Edit edit = new Edit(command, seqs, position, number, al
-            .getGapCharacter());
+    Edit edit = new Edit(command, seqs, position, number,
+            al.getGapCharacter());
     if (al.getHeight() == seqs.length)
     {
       edit.al = al;
@@ -192,15 +196,21 @@ public class EditCommand implements CommandI
       case REPLACE:
         replace(edits[e]);
         break;
+        //TODO:add deleteNuc for UNDO
+//      case INSERT_NUC:
+//     insertNuc(edits[e]);
+//     break;
       }
     }
   }
 
+  @Override
   final public void doCommand(AlignmentI[] views)
   {
     performEdit(0, views);
   }
 
+  @Override
   final public void undoCommand(AlignmentI[] views)
   {
     int e = 0, eSize = edits.length;
@@ -223,7 +233,7 @@ public class EditCommand implements CommandI
       case REPLACE:
         replace(edits[e]);
         break;
-      }
+       }
     }
   }
 
@@ -234,10 +244,23 @@ public class EditCommand implements CommandI
     {
       command.seqs[s].insertCharAt(command.position, command.number,
               command.gapChar);
+//      System.out.println("pos: "+command.position+" number: "+command.number);
     }
 
     adjustAnnotations(command, true, false, null);
   }
+//
+//  final void insertNuc(Edit command)
+//  {
+//
+//    for (int s = 0; s < command.seqs.length; s++)
+//    {
+//        System.out.println("pos: "+command.position+" number: "+command.number);
+//     command.seqs[s].insertCharAt(command.position, command.number,'A');
+//    }
+//
+//    adjustAnnotations(command, true, false, null);
+//  }
 
   final void deleteGap(Edit command)
   {
@@ -286,9 +309,12 @@ public class EditCommand implements CommandI
               command.oldds = new SequenceI[command.seqs.length];
             }
             command.oldds[i] = oldds;
-            adjustFeatures(command, i, command.seqs[i]
-                    .findPosition(command.position), command.seqs[i]
-                    .findPosition(command.position + command.number), false);
+            adjustFeatures(
+                    command,
+                    i,
+                    command.seqs[i].findPosition(command.position),
+                    command.seqs[i].findPosition(command.position
+                            + command.number), false);
           }
         }
       }
@@ -322,8 +348,10 @@ public class EditCommand implements CommandI
         // read it to the alignment
         if (command.alIndex[i] < command.al.getHeight())
         {
-          command.al.getSequences().insertElementAt(command.seqs[i],
-                  command.alIndex[i]);
+          List<SequenceI> sequences;
+          synchronized (sequences=command.al.getSequences()) {
+            sequences.add(command.alIndex[i], command.seqs[i]);
+          }
         }
         else
         {
@@ -424,23 +452,63 @@ public class EditCommand implements CommandI
     command.number = start + command.string[0].length;
     for (int i = 0; i < command.seqs.length; i++)
     {
+      boolean newDSWasNeeded = command.oldds != null && command.oldds[i] != null;
+
       /**
        * cut addHistoryItem(new EditCommand("Cut Sequences", EditCommand.CUT,
        * cut, sg.getStartRes(), sg.getEndRes()-sg.getStartRes()+1,
        * viewport.alignment));
-       * 
+       *
        */
       /**
        * then addHistoryItem(new EditCommand( "Add sequences",
        * EditCommand.PASTE, sequences, 0, alignment.getWidth(), alignment) );
-       * 
+       *
        */
       oldstring = command.seqs[i].getSequenceAsString();
       tmp = new StringBuffer(oldstring.substring(0, start));
       tmp.append(command.string[i]);
+      String nogaprep = jalview.analysis.AlignSeq.extractGaps(
+              jalview.util.Comparison.GapChars, new String(
+                      command.string[i]));
+      int ipos = command.seqs[i].findPosition(start)
+              - command.seqs[i].getStart();
       tmp.append(oldstring.substring(end));
       command.seqs[i].setSequence(tmp.toString());
       command.string[i] = oldstring.substring(start, end).toCharArray();
+      String nogapold = jalview.analysis.AlignSeq.extractGaps(
+              jalview.util.Comparison.GapChars, new String(
+                      command.string[i]));
+      if (!nogaprep.toLowerCase().equals(nogapold.toLowerCase()))
+      {
+        if (newDSWasNeeded)
+        {
+          SequenceI oldds = command.seqs[i].getDatasetSequence();
+          command.seqs[i].setDatasetSequence(command.oldds[i]);
+          command.oldds[i] = oldds;
+        }
+        else
+        {
+          if (command.oldds == null)
+          {
+            command.oldds = new SequenceI[command.seqs.length];
+          }
+          command.oldds[i] = command.seqs[i].getDatasetSequence();
+          SequenceI newds = new Sequence(
+                  command.seqs[i].getDatasetSequence());
+          String fullseq, osp = newds.getSequenceAsString();
+          fullseq = osp.substring(0, ipos) + nogaprep
+                  + osp.substring(ipos + nogaprep.length());
+          newds.setSequence(fullseq.toUpperCase());
+          // TODO: JAL-1131 ensure newly created dataset sequence is added to the set of
+          // dataset sequences associated with the alignment.
+          // TODO: JAL-1131 fix up any annotation associated with new dataset
+          // sequence to ensure that original sequence/annotation relationships
+          // are preserved.
+          command.seqs[i].setDatasetSequence(newds);
+
+        }
+      }
       tmp = null;
       oldstring = null;
     }
@@ -781,9 +849,8 @@ public class EditCommand implements CommandI
       if (command.editedFeatures != null
               && command.editedFeatures.containsKey(seq))
       {
-        sequence
-                .setSequenceFeatures((SequenceFeature[]) command.editedFeatures
-                        .get(seq));
+        sequence.setSequenceFeatures((SequenceFeature[]) command.editedFeatures
+                .get(seq));
       }
 
       return;