Merge branch 'develop' into features/JAL-2446NCList
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 30 May 2017 15:32:36 +0000 (16:32 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 30 May 2017 15:32:36 +0000 (16:32 +0100)
Conflicts:
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/Finder.java
src/jalview/appletgui/SeqPanel.java
src/jalview/gui/SeqPanel.java

1  2 
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/Finder.java
src/jalview/appletgui/SeqPanel.java
src/jalview/gui/SeqPanel.java

@@@ -829,18 -830,11 +830,11 @@@ public class APopupMenu extends java.aw
          int end = sg.findEndRes(sg.getSequenceAt(i));
          if (start <= end)
          {
-           seqs[rsize] = sg.getSequenceAt(i);
-           features[rsize] = new SequenceFeature(null, null, start,
-                   end, "Jalview");
-           rsize++;
+           seqs.add(sg.getSequenceAt(i));
 -          features.add(new SequenceFeature(null, null, null, start, end,
++          features.add(new SequenceFeature(null, null, start, end,
+                   "Jalview"));
          }
        }
-       rseqs = new SequenceI[rsize];
-       tfeatures = new SequenceFeature[rsize];
-       System.arraycopy(seqs, 0, rseqs, 0, rsize);
-       System.arraycopy(features, 0, tfeatures, 0, rsize);
-       features = tfeatures;
-       seqs = rseqs;
  
        if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
                features, true, ap))
@@@ -406,36 -404,29 +407,36 @@@ public class FeatureRenderer extend
  
      if (!create)
      {
-       SequenceFeature sf = features[featureIndex];
+       SequenceFeature sf = features.get(featureIndex);
        if (dialog.accept)
        {
 -        sf.type = enteredType;
 -        sf.featureGroup = group.getText().trim();
 -        if (sf.featureGroup != null && sf.featureGroup.length() < 1)
 -        {
 -          sf.featureGroup = null;
 -        }
 -        sf.description = description.getText().replace('\n', ' ');
          if (!colourPanel.isGcol)
          {
            // update colour - otherwise its already done.
            setColour(sf.type, new FeatureColour(colourPanel.getBackground()));
          }
 +        int newBegin = sf.begin;
 +        int newEnd = sf.end;
          try
          {
 -          sf.begin = Integer.parseInt(start.getText());
 -          sf.end = Integer.parseInt(end.getText());
 +          newBegin = Integer.parseInt(start.getText());
 +          newEnd = Integer.parseInt(end.getText());
          } catch (NumberFormatException ex)
          {
 -          //
 +          // 
          }
 +
 +        /*
 +         * replace the feature by deleting it and adding a new one
 +         * (to ensure integrity of SequenceFeatures data store)
 +         */
-         sequences[0].deleteFeature(sf);
++        sequences.get(0).deleteFeature(sf);
 +        SequenceFeature newSf = new SequenceFeature(sf, newBegin, newEnd,
 +                enteredGroup, sf.getScore());
 +        newSf.setDescription(enteredDesc);
 +        ffile.parseDescriptionHTML(newSf, false);
 +        // amend features dialog only updates one sequence at a time
-         sequences[0].addSequenceFeature(newSf);
++        sequences.get(0).addSequenceFeature(newSf);
          boolean typeOrGroupChanged = (!featureType.equals(sf.type) || !featureGroup
                  .equals(sf.featureGroup));
  
         */
        if (dialog.accept && name.getText().length() > 0)
        {
-         for (int i = 0; i < sequences.length; i++)
+         for (int i = 0; i < sequences.size(); i++)
          {
-           SequenceFeature sf = features[i];
 -          features.get(i).type = enteredType;
 -          features.get(i).featureGroup = group.getText().trim();
 -          features.get(i).description = description.getText()
 -                  .replace('\n', ' ');
 -          sequences.get(i).addSequenceFeature(features.get(i));
 -          ffile.parseDescriptionHTML(features.get(i), false);
++          SequenceFeature sf = features.get(i);
 +          SequenceFeature sf2 = new SequenceFeature(enteredType,
 +                  enteredDesc, sf.getBegin(), sf.getEnd(), enteredGroup);
 +          ffile.parseDescriptionHTML(sf2, false);
-           sequences[i].addSequenceFeature(sf2);
++          sequences.get(i).addSequenceFeature(sf2);
          }
  
          Color newColour = colourPanel.getBackground();
@@@ -113,19 -115,16 +115,15 @@@ public class Finder extends Panel imple
  
    public void createNewGroup_actionPerformed()
    {
-     SequenceI[] seqs = new SequenceI[searchResults.getSize()];
-     SequenceFeature[] features = new SequenceFeature[searchResults
-             .getSize()];
+     List<SequenceI> seqs = new ArrayList<SequenceI>();
+     List<SequenceFeature> features = new ArrayList<SequenceFeature>();
      String searchString = textfield.getText().trim();
  
-     int i = 0;
      for (SearchResultMatchI match : searchResults.getResults())
      {
-       seqs[i] = match.getSequence().getDatasetSequence();
-       features[i] = new SequenceFeature(searchString, "Search Results",
-               match.getStart(), match.getEnd(), "Search Results");
-       i++;
+       seqs.add(match.getSequence().getDatasetSequence());
 -      features.add(new SequenceFeature(searchString,
 -              "Search Results", null, match.getStart(), match.getEnd(),
 - "Search Results"));
++      features.add(new SequenceFeature(searchString, "Search Results",
++              match.getStart(), match.getEnd(), "Search Results"));
      }
  
      if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
@@@ -54,7 -54,10 +54,9 @@@ import java.awt.event.InputEvent
  import java.awt.event.MouseEvent;
  import java.awt.event.MouseListener;
  import java.awt.event.MouseMotionListener;
 -import java.util.ArrayList;
+ import java.util.Collections;
  import java.util.List;
+ import java.util.ListIterator;
  import java.util.Vector;
  
  public class SeqPanel extends Panel implements MouseMotionListener,
          highlight.addResult(sequence, features.get(0).getBegin(), features
                  .get(0).getEnd());
          seqCanvas.highlightSearchResults(highlight);
-         SequenceFeature[] featuresArray = features
-                 .toArray(new SequenceFeature[features.size()]);
          seqCanvas.getFeatureRenderer().amendFeatures(
-                 new SequenceI[] { sequence }, featuresArray, false, ap);
+                 Collections.singletonList(sequence), features, false, ap);
 -
          seqCanvas.highlightSearchResults(null);
        }
      }
      }
  
      /*
-      * add feature details to tooltip if over one or more features
+      * add feature details to tooltip, including any that straddle
+      * a gapped position
       */
-     if (respos != -1)
+     if (av.isShowSequenceFeatures())
      {
        List<SequenceFeature> allFeatures = findFeaturesAtRes(sequence,
 -              sequence.findPosition(column));
 +              respos);
+       if (isGapped)
+       {
+         removeAdjacentFeatures(allFeatures, column + 1, sequence);
+       }
        for (SequenceFeature sf : allFeatures)
        {
          tooltipText.append(sf.getType() + " " + sf.begin + ":" + sf.end);
      }
    }
  
 +  List<SequenceFeature> findFeaturesAtRes(SequenceI sequence, int res)
 +  {
 +    return seqCanvas.getFeatureRenderer().findFeaturesAtRes(sequence, res);
 +  }
 +
+   /**
+    * Removes from the list of features any that start after, or end before, the
+    * given column position. This allows us to retain only those features
+    * adjacent to a gapped position that straddle the position.
+    * 
+    * @param features
+    * @param column
+    *          alignment column (1..)
+    * @param sequence
+    */
+   protected void removeAdjacentFeatures(List<SequenceFeature> features,
+           int column, SequenceI sequence)
+   {
+     // TODO should this be an AlignViewController method (shared by gui)?
+     ListIterator<SequenceFeature> it = features.listIterator();
+     while (it.hasNext())
+     {
+       SequenceFeature sf = it.next();
+       if (sequence.findIndex(sf.getBegin()) > column
+               || sequence.findIndex(sf.getEnd()) < column)
+       {
+         it.remove();
+       }
+     }
+   }
 -  List<SequenceFeature> findFeaturesAtRes(SequenceI sequence, int res)
 -  {
 -    List<SequenceFeature> result = new ArrayList<SequenceFeature>();
 -    SequenceFeature[] features = sequence.getSequenceFeatures();
 -    if (features != null)
 -    {
 -      for (int i = 0; i < features.length; i++)
 -      {
 -        if (av.getFeaturesDisplayed() == null
 -                || !av.getFeaturesDisplayed().isVisible(
 -                        features[i].getType()))
 -        {
 -          continue;
 -        }
 -
 -        if (features[i].featureGroup != null
 -                && !seqCanvas.fr.checkGroupVisibility(
 -                        features[i].featureGroup, false))
 -        {
 -          continue;
 -        }
 -
 -        if ((features[i].getBegin() <= res)
 -                && (features[i].getEnd() >= res))
 -        {
 -          result.add(features[i]);
 -        }
 -      }
 -    }
 -
 -    return result;
 -  }
 -
    Tooltip tooltip;
  
    /**
@@@ -798,17 -787,46 +809,43 @@@ public class SeqPanel extends JPanel im
      }
      else
      {
 -      if (lastTooltip == null
 -              || !lastTooltip.equals(tooltipText.toString()))
 +      String textString = tooltipText.toString();
 +      if (lastTooltip == null || !lastTooltip.equals(textString))
        {
--        String formatedTooltipText = JvSwingUtils.wrapTooltip(true,
 -                tooltipText.toString());
 -        // String formatedTooltipText = tooltipText.toString();
 -        setToolTipText(formatedTooltipText);
 -        lastTooltip = tooltipText.toString();
++        String formattedTooltipText = JvSwingUtils.wrapTooltip(true,
 +                textString);
-         setToolTipText(formatedTooltipText);
++        setToolTipText(formattedTooltipText);
 +        lastTooltip = textString;
        }
 -
      }
 -
    }
  
+   /**
+    * Removes from the list of features any that start after, or end before, the
+    * given column position. This allows us to retain only those features
+    * adjacent to a gapped position that straddle the position.
+    * 
+    * @param features
+    * @param column
+    *          alignment column (1..)
+    * @param sequence
+    */
+   protected void removeAdjacentFeatures(List<SequenceFeature> features,
+           final int column, SequenceI sequence)
+   {
+     // TODO should this be an AlignViewController method (and reused by applet)?
+     ListIterator<SequenceFeature> it = features.listIterator();
+     while (it.hasNext())
+     {
+       SequenceFeature sf = it.next();
+       if (sequence.findIndex(sf.getBegin()) > column
+               || sequence.findIndex(sf.getEnd()) < column)
+       {
+         it.remove();
+       }
+     }
+   }
    private Point lastp = null;
  
    /*