JAL-4020 Added search for PyMOLWinWithConsole.bat (and PyMOLWin.exe) in likely places...
[jalview.git] / src / jalview / commands / EditCommand.java
index f80bd4a..62ef660 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.commands;
 
+import java.util.Locale;
+
 import jalview.analysis.AlignSeq;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
@@ -116,6 +118,7 @@ public class EditCommand implements CommandI
         return null;
       }
     };
+
     public abstract Action getUndoAction();
   };
 
@@ -530,16 +533,16 @@ public class EditCommand implements CommandI
         ContiguousI cutPositions = sequence.findPositions(
                 command.position + 1, command.position + command.number);
         boolean cutIsInternal = cutPositions != null
-                && sequence.getStart() != cutPositions
-                .getBegin() && sequence.getEnd() != cutPositions.getEnd();
+                && sequence.getStart() != cutPositions.getBegin()
+                && sequence.getEnd() != cutPositions.getEnd();
 
         /*
          * perform the cut; if this results in a new dataset sequence, add
          * that to the alignment dataset
          */
         SequenceI ds = sequence.getDatasetSequence();
-        sequence.deleteChars(command.position, command.position
-                + command.number);
+        sequence.deleteChars(command.position,
+                command.position + command.number);
 
         if (command.oldds != null && command.oldds[i] != null)
         {
@@ -564,15 +567,14 @@ public class EditCommand implements CommandI
           command.oldds[i] = oldds;// todo not if !cutIsInternal?
 
           // do we need to edit sequence features for new sequence ?
-          if (oldds != sequence.getDatasetSequence()
-                  || (cutIsInternal
-                          && sequence.getFeatures().hasFeatures()))
+          if (oldds != sequence.getDatasetSequence() || (cutIsInternal
+                  && sequence.getFeatures().hasFeatures()))
           // todo or just test cutIsInternal && cutPositions != null ?
           {
             if (cutPositions != null)
             {
               cutFeatures(command, sequence, cutPositions.getBegin(),
-                              cutPositions.getEnd(), cutIsInternal);
+                      cutPositions.getEnd(), cutIsInternal);
             }
           }
         }
@@ -619,8 +621,8 @@ public class EditCommand implements CommandI
          */
         if (command.alIndex[i] < command.al.getHeight())
         {
-          List<SequenceI> sequences;
-          synchronized (sequences = command.al.getSequences())
+          List<SequenceI> sequences = command.al.getSequences();
+          synchronized (sequences)
           {
             if (!(command.alIndex[i] < 0))
             {
@@ -751,7 +753,8 @@ public class EditCommand implements CommandI
     {
       boolean newDSWasNeeded = command.oldds != null
               && command.oldds[i] != null;
-      boolean newStartEndWasNeeded = command.oldStartEnd!=null && command.oldStartEnd[i]!=null;
+      boolean newStartEndWasNeeded = command.oldStartEnd != null
+              && command.oldStartEnd[i] != null;
 
       /**
        * cut addHistoryItem(new EditCommand("Cut Sequences", EditCommand.CUT,
@@ -768,7 +771,7 @@ public class EditCommand implements CommandI
               start);
       ContiguousI afterEditedPositions = command.seqs[i]
               .findPositions(end + 1, command.seqs[i].getLength());
-      
+
       oldstring = command.seqs[i].getSequenceAsString();
       tmp = new StringBuilder(oldstring.substring(0, start));
       tmp.append(command.string[i]);
@@ -789,17 +792,18 @@ public class EditCommand implements CommandI
       String nogapold = AlignSeq.extractGaps(Comparison.GapChars,
               new String(command.string[i]));
 
-      if (!nogaprep.toLowerCase().equals(nogapold.toLowerCase()))
+      if (!nogaprep.toLowerCase(Locale.ROOT)
+              .equals(nogapold.toLowerCase(Locale.ROOT)))
       {
         // we may already have dataset and limits stashed...
         if (newDSWasNeeded || newStartEndWasNeeded)
         {
           if (newDSWasNeeded)
           {
-          // then just switch the dataset sequence
-          SequenceI oldds = command.seqs[i].getDatasetSequence();
-          command.seqs[i].setDatasetSequence(command.oldds[i]);
-          command.oldds[i] = oldds;
+            // then just switch the dataset sequence
+            SequenceI oldds = command.seqs[i].getDatasetSequence();
+            command.seqs[i].setDatasetSequence(command.oldds[i]);
+            command.oldds[i] = oldds;
           }
           if (newStartEndWasNeeded)
           {
@@ -809,7 +813,7 @@ public class EditCommand implements CommandI
             command.seqs[i].setEnd(newStart.getEnd());
           }
         }
-        else         
+        else
         {
           // decide if we need a new dataset sequence or modify start/end
           // first edit the original dataset sequence string
@@ -821,15 +825,11 @@ public class EditCommand implements CommandI
                                   ? afterEditedPositions.getBegin() - 1
                                   : oldstartend.getBegin()
                                           + nogapold.length())
-                          : beforeEditedPositions.getEnd()
-                  );
+                          : beforeEditedPositions.getEnd());
           int afterEndOfEdit = -oldds.getStart() + 1
-                  + ((afterEditedPositions == null)
-                  ? oldstartend.getEnd()
+                  + ((afterEditedPositions == null) ? oldstartend.getEnd()
                           : afterEditedPositions.getBegin() - 1);
-          String fullseq = osp.substring(0,
-                  beforeStartOfEdit)
-                  + nogaprep
+          String fullseq = osp.substring(0, beforeStartOfEdit) + nogaprep
                   + osp.substring(afterEndOfEdit);
 
           // and check if new sequence data is different..
@@ -838,7 +838,7 @@ public class EditCommand implements CommandI
             // old ds and edited ds are different, so
             // create the new dataset sequence
             SequenceI newds = new Sequence(oldds);
-            newds.setSequence(fullseq);
+            newds.setSequence(fullseq.toUpperCase(Locale.ROOT));
 
             if (command.oldds == null)
             {
@@ -874,9 +874,8 @@ public class EditCommand implements CommandI
                     && afterEditedPositions == null)
             {
               // modification at end
-              command.seqs[i].setEnd(
-                      beforeEditedPositions.getEnd() + nogaprep.length()
-                              - nogapold.length());
+              command.seqs[i].setEnd(beforeEditedPositions.getEnd()
+                      + nogaprep.length() - nogapold.length());
             }
             else if (afterEditedPositions != null
                     && beforeEditedPositions == null)
@@ -891,7 +890,8 @@ public class EditCommand implements CommandI
               // new
               // start/end
               String nogapalseq = AlignSeq.extractGaps(Comparison.GapChars,
-                      command.seqs[i].getSequenceAsString().toUpperCase());
+                      command.seqs[i].getSequenceAsString()
+                              .toUpperCase(Locale.ROOT));
               int newStart = command.seqs[i].getDatasetSequence()
                       .getSequenceAsString().indexOf(nogapalseq);
               if (newStart == -1)
@@ -1023,7 +1023,8 @@ public class EditCommand implements CommandI
                 }
                 // and then duplicate added annotation on every other alignment
                 // view
-                for (int vnum = 0; views != null && vnum < views.length; vnum++)
+                for (int vnum = 0; views != null
+                        && vnum < views.length; vnum++)
                 {
                   if (views[vnum] != command.al)
                   {
@@ -1297,9 +1298,9 @@ public class EditCommand implements CommandI
              * feature was shifted left to cut position (not truncated),
              * so shift it back right
              */
-            SequenceFeature shifted = new SequenceFeature(sf, sf.getBegin()
-                    + length, sf.getEnd() + length, sf.getFeatureGroup(),
-                    sf.getScore());
+            SequenceFeature shifted = new SequenceFeature(sf,
+                    sf.getBegin() + length, sf.getEnd() + length,
+                    sf.getFeatureGroup(), sf.getScore());
             seq.addSequenceFeature(shifted);
             seq.deleteFeature(sf);
           }
@@ -1444,48 +1445,53 @@ public class EditCommand implements CommandI
 
   public class Edit
   {
-    private SequenceI[] oldds;
+    SequenceI[] oldds;
 
     /**
      * start and end of sequence prior to edit
      */
-    private Range[] oldStartEnd;
+    Range[] oldStartEnd;
 
-    private boolean fullAlignmentHeight = false;
+    boolean fullAlignmentHeight = false;
 
-    private Map<SequenceI, AlignmentAnnotation[]> deletedAnnotationRows;
+    Map<SequenceI, AlignmentAnnotation[]> deletedAnnotationRows;
 
-    private Map<String, Annotation[]> deletedAnnotations;
+    Map<String, Annotation[]> deletedAnnotations;
 
     /*
      * features deleted by the cut (re-add on Undo)
      * (including the original of any shortened features)
      */
-    private Map<SequenceI, List<SequenceFeature>> deletedFeatures;
+    Map<SequenceI, List<SequenceFeature>> deletedFeatures;
 
     /*
      * shortened features added by the cut (delete on Undo)
      */
-    private Map<SequenceI, List<SequenceFeature>> truncatedFeatures;
+    Map<SequenceI, List<SequenceFeature>> truncatedFeatures;
 
-    private AlignmentI al;
+    AlignmentI al;
 
-    final private Action command;
+    final Action command;
 
     char[][] string;
 
     SequenceI[] seqs;
 
-    private int[] alIndex;
+    int[] alIndex;
+
+    int position;
 
-    private int position;
+    int number;
 
-    private int number;
+    char gapChar;
 
-    private char gapChar;
+    /*
+     * flag that identifies edits inserted to balance 
+     * user edits in a 'locked editing' region
+     */
+    private boolean systemGenerated;
 
-    public Edit(Action cmd, SequenceI[] sqs, int pos, int count,
-            char gap)
+    public Edit(Action cmd, SequenceI[] sqs, int pos, int count, char gap)
     {
       this.command = cmd;
       this.seqs = sqs;
@@ -1494,8 +1500,7 @@ public class EditCommand implements CommandI
       this.gapChar = gap;
     }
 
-    Edit(Action cmd, SequenceI[] sqs, int pos, int count,
-            AlignmentI align)
+    Edit(Action cmd, SequenceI[] sqs, int pos, int count, AlignmentI align)
     {
       this(cmd, sqs, pos, count, align.getGapCharacter());
 
@@ -1520,8 +1525,8 @@ public class EditCommand implements CommandI
      * @param align
      * @param replace
      */
-    Edit(Action cmd, SequenceI[] sqs, int pos, int count,
-            AlignmentI align, String replace)
+    Edit(Action cmd, SequenceI[] sqs, int pos, int count, AlignmentI align,
+            String replace)
     {
       this(cmd, sqs, pos, count, align);
 
@@ -1556,6 +1561,16 @@ public class EditCommand implements CommandI
     {
       return gapChar;
     }
+
+    public void setSystemGenerated(boolean b)
+    {
+      systemGenerated = b;
+    }
+
+    public boolean isSystemGenerated()
+    {
+      return systemGenerated;
+    }
   }
 
   /**
@@ -1608,25 +1623,25 @@ public class EditCommand implements CommandI
     }
     List<SequenceFeature> added = new ArrayList<>();
     List<SequenceFeature> removed = new ArrayList<>();
-  
+
     SequenceFeaturesI featureStore = seq.getFeatures();
     if (toPosition < fromPosition || featureStore == null)
     {
       return;
     }
-  
+
     int cutStartPos = fromPosition;
     int cutEndPos = toPosition;
     int cutWidth = cutEndPos - cutStartPos + 1;
-  
+
     synchronized (featureStore)
     {
       /*
        * get features that overlap the cut region
        */
-      List<SequenceFeature> toAmend = featureStore.findFeatures(
-              cutStartPos, cutEndPos);
-  
+      List<SequenceFeature> toAmend = featureStore.findFeatures(cutStartPos,
+              cutEndPos);
+
       /*
        * add any contact features that span the cut region
        * (not returned by findFeatures)
@@ -1653,7 +1668,7 @@ public class EditCommand implements CommandI
         int newEnd = sfEnd;
         boolean toDelete = false;
         boolean follows = false;
-        
+
         if (sfBegin >= cutStartPos && sfEnd <= cutEndPos)
         {
           /*
@@ -1692,7 +1707,7 @@ public class EditCommand implements CommandI
             toDelete = true;
           }
         }
-  
+
         seq.deleteFeature(sf);
         if (!follows)
         {
@@ -1709,7 +1724,7 @@ public class EditCommand implements CommandI
           }
         }
       }
-  
+
       /*
        * and left shift any features lying to the right of the cut region
        */