Merge branch 'bug/JAL-2541cutWithFeatures' into features/JAL-2446NCList
[jalview.git] / src / jalview / commands / EditCommand.java
index 2d3a8d8..388c533 100644 (file)
@@ -307,8 +307,7 @@ public class EditCommand implements CommandI
    * @param performEdit
    */
   final public void appendEdit(Action command, SequenceI[] seqs,
-          int position,
-          int number, AlignmentI al, boolean performEdit)
+          int position, int number, AlignmentI al, boolean performEdit)
   {
     appendEdit(command, seqs, position, number, al, performEdit, null);
   }
@@ -326,8 +325,8 @@ public class EditCommand implements CommandI
    * @param views
    */
   final public void appendEdit(Action command, SequenceI[] seqs,
-          int position,
-          int number, AlignmentI al, boolean performEdit, AlignmentI[] views)
+          int position, int number, AlignmentI al, boolean performEdit,
+          AlignmentI[] views)
   {
     Edit edit = new Edit(command, seqs, position, number,
             al.getGapCharacter());
@@ -432,7 +431,7 @@ public class EditCommand implements CommandI
    */
   @Override
   final public void undoCommand(AlignmentI[] views)
-  { 
+  {
     ListIterator<Edit> iterator = edits.listIterator(edits.size());
     while (iterator.hasPrevious())
     {
@@ -474,8 +473,8 @@ public class EditCommand implements CommandI
 
     for (int s = 0; s < command.seqs.length; s++)
     {
-      command.seqs[s].insertCharAt(command.position,
-              command.number, command.gapChar);
+      command.seqs[s].insertCharAt(command.position, command.number,
+              command.gapChar);
       // System.out.println("pos: "+command.position+" number: "+command.number);
     }
 
@@ -556,12 +555,13 @@ public class EditCommand implements CommandI
               command.oldds = new SequenceI[command.seqs.length];
             }
             command.oldds[i] = oldds;
+            // FIXME JAL-2541 JAL-2526 get correct positions if on a gap
             adjustFeatures(
                     command,
                     i,
                     sequence.findPosition(command.position),
-                    sequence.findPosition(command.position
-                            + command.number), false);
+                    sequence.findPosition(command.position + command.number),
+                    false);
           }
         }
       }
@@ -1045,7 +1045,7 @@ public class EditCommand implements CommandI
           int copylen = Math.min(command.position,
                   annotations[a].annotations.length);
           if (copylen > 0)
-           {
+          {
             System.arraycopy(annotations[a].annotations, 0, temp, 0,
                     copylen); // command.position);
           }
@@ -1102,8 +1102,8 @@ public class EditCommand implements CommandI
     }
   }
 
-  final static void adjustFeatures(Edit command, int index, int i, int j,
-          boolean insert)
+  final static void adjustFeatures(Edit command, int index, final int i,
+          final int j, boolean insert)
   {
     SequenceI seq = command.seqs[index];
     SequenceI sequence = seq.getDatasetSequence();
@@ -1117,58 +1117,75 @@ public class EditCommand implements CommandI
       if (command.editedFeatures != null
               && command.editedFeatures.containsKey(seq))
       {
-        sequence.setSequenceFeatures(command.editedFeatures
-                .get(seq));
+        sequence.setSequenceFeatures(command.editedFeatures.get(seq));
       }
 
       return;
     }
 
-    SequenceFeature[] sf = sequence.getSequenceFeatures();
+    List<SequenceFeature> sf = sequence.getFeatures()
+            .getPositionalFeatures();
 
-    if (sf == null)
+    if (sf.isEmpty())
     {
       return;
     }
 
-    SequenceFeature[] oldsf = new SequenceFeature[sf.length];
+    SequenceFeature[] oldsf = new SequenceFeature[sf.size()];
 
     int cSize = j - i;
 
-    for (int s = 0; s < sf.length; s++)
+    int s = 0;
+    for (SequenceFeature feature : sf)
     {
-      SequenceFeature copy = new SequenceFeature(sf[s]);
+      SequenceFeature copy = new SequenceFeature(feature);
 
-      oldsf[s] = copy;
+      oldsf[s++] = copy;
 
-      if (sf[s].getEnd() < i)
+      if (feature.getEnd() < i)
       {
         continue;
       }
 
-      if (sf[s].getBegin() > j)
+      if (feature.getBegin() > j)
       {
-        sf[s].setBegin(copy.getBegin() - cSize);
-        sf[s].setEnd(copy.getEnd() - cSize);
+        int newBegin = copy.getBegin() - cSize;
+        int newEnd = copy.getEnd() - cSize;
+        SequenceFeature newSf = new SequenceFeature(feature, newBegin,
+                newEnd, feature.getFeatureGroup());
+        sequence.deleteFeature(feature);
+        sequence.addSequenceFeature(newSf);
+        // feature.setBegin(newBegin);
+        // feature.setEnd(newEnd);
         continue;
       }
 
-      if (sf[s].getBegin() >= i)
+      int newBegin = feature.getBegin();
+      int newEnd = feature.getEnd();
+      if (newBegin >= i)
       {
-        sf[s].setBegin(i);
+        newBegin = i;
+        // feature.setBegin(i);
       }
 
-      if (sf[s].getEnd() < j)
+      if (newEnd < j)
       {
-        sf[s].setEnd(j - 1);
+        newEnd = j - 1;
+        // feature.setEnd(j - 1);
       }
+      newEnd = newEnd - cSize;
+      // feature.setEnd(feature.getEnd() - (cSize));
 
-      sf[s].setEnd(sf[s].getEnd() - (cSize));
-
-      if (sf[s].getBegin() > sf[s].getEnd())
+      sequence.deleteFeature(feature);
+      if (newEnd >= newBegin)
       {
-        sequence.deleteFeature(sf[s]);
+        sequence.addSequenceFeature(new SequenceFeature(feature, newBegin,
+                newEnd, feature.getFeatureGroup()));
       }
+      // if (feature.getBegin() > feature.getEnd())
+      // {
+      // sequence.deleteFeature(feature);
+      // }
     }
 
     if (command.editedFeatures == null)
@@ -1222,10 +1239,15 @@ public class EditCommand implements CommandI
         for (SequenceI seq : e.getSequences())
         {
           SequenceI ds = seq.getDatasetSequence();
-          SequenceI preEdit = result.get(ds);
-          if (preEdit == null)
+          // SequenceI preEdit = result.get(ds);
+          if (!result.containsKey(ds))
           {
-            preEdit = new Sequence("", seq.getSequenceAsString());
+            /*
+             * copy sequence including start/end (but don't use copy constructor
+             * as we don't need annotations)
+             */
+            SequenceI preEdit = new Sequence("", seq.getSequenceAsString(),
+                    seq.getStart(), seq.getEnd());
             preEdit.setDatasetSequence(ds);
             result.put(ds, preEdit);
           }
@@ -1238,10 +1260,10 @@ public class EditCommand implements CommandI
      * Work backwards through the edit list, deriving the sequences before each
      * was applied. The final result is the sequence set before any edits.
      */
-    Iterator<Edit> edits = new ReverseListIterator<Edit>(getEdits());
-    while (edits.hasNext())
+    Iterator<Edit> editList = new ReverseListIterator<Edit>(getEdits());
+    while (editList.hasNext())
     {
-      Edit oldEdit = edits.next();
+      Edit oldEdit = editList.next();
       Action action = oldEdit.getAction();
       int position = oldEdit.getPosition();
       int number = oldEdit.getNumber();
@@ -1252,7 +1274,8 @@ public class EditCommand implements CommandI
         SequenceI preEdit = result.get(ds);
         if (preEdit == null)
         {
-          preEdit = new Sequence("", seq.getSequenceAsString());
+          preEdit = new Sequence("", seq.getSequenceAsString(),
+                  seq.getStart(), seq.getEnd());
           preEdit.setDatasetSequence(ds);
           result.put(ds, preEdit);
         }
@@ -1265,8 +1288,7 @@ public class EditCommand implements CommandI
           if (action == Action.DELETE_GAP)
           {
             preEdit.setSequence(new String(StringUtils.insertCharAt(
-                    preEdit.getSequence(), position,
-                    number, gap)));
+                    preEdit.getSequence(), position, number, gap)));
           }
           else if (action == Action.INSERT_GAP)
           {