Merge branch 'JAL-3878_web_services_overhaul' into try-to-update-slivka-jar
[jalview.git] / src / jalview / viewmodel / AlignmentViewport.java
index 8f1fc83..066be9b 100644 (file)
@@ -23,7 +23,8 @@ package jalview.viewmodel;
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.analysis.Conservation;
 import jalview.analysis.TreeModel;
-import jalview.api.AlignCalcManagerI;
+import jalview.api.AlignCalcManagerI2;
+import jalview.api.AlignCalcWorkerI;
 import jalview.api.AlignExportSettingsI;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
@@ -56,11 +57,12 @@ import jalview.util.MapList;
 import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
 import jalview.viewmodel.styles.ViewStyle;
-import jalview.workers.AlignCalcManager;
+import jalview.workers.AlignCalcManager2;
 import jalview.workers.ComplementConsensusThread;
 import jalview.workers.ConsensusThread;
 import jalview.workers.InformationThread;
 import jalview.workers.StrucConsensusThread;
+import jalview.ws2.PollingTaskExecutor;
 
 import java.awt.Color;
 import java.beans.PropertyChangeSupport;
@@ -84,6 +86,8 @@ import java.util.Map;
 public abstract class AlignmentViewport
         implements AlignViewportI, CommandListener, VamsasSource
 {
+  public static final String PROPERTY_ALIGNMENT = "alignment";
+  public static final String PROPERTY_SEQUENCE = "sequence";
   protected ViewportRanges ranges;
 
   protected ViewStyleI viewStyle = new ViewStyle();
@@ -612,6 +616,7 @@ public abstract class AlignmentViewport
    * alignment
    */
   protected boolean isDataset = false;
+
   
   public void setDataset(boolean b)
   {
@@ -627,13 +632,33 @@ public abstract class AlignmentViewport
 
   protected ColumnSelection colSel = new ColumnSelection();
 
-  public boolean autoCalculateConsensus = true;
+  protected boolean autoCalculateConsensusAndConservation = true;
+
+  public boolean getAutoCalculateConsensusAndConservation()
+  { // BH 2019.07.24
+    return autoCalculateConsensusAndConservation;
+  }
+
+  public void setAutoCalculateConsensusAndConservation(boolean b)
+  {
+    autoCalculateConsensusAndConservation = b;
+  }
 
   protected boolean autoCalculateStrucConsensus = true;
 
+  public boolean getAutoCalculateStrucConsensus()
+  { // BH 2019.07.24
+    return autoCalculateStrucConsensus;
+  }
+
+  public void setAutoCalculateStrucConsensus(boolean b)
+  {
+    autoCalculateStrucConsensus = b;
+  }
   protected boolean ignoreGapsInConsensusCalculation = false;
 
   protected ResidueShaderI residueShading = new ResidueShader();
+
   
   @Override
   public void setGlobalColourScheme(ColourSchemeI cs)
@@ -708,6 +733,7 @@ public abstract class AlignmentViewport
   {
     return residueShading;
   }
+
   
   protected AlignmentAnnotation consensus;
 
@@ -742,6 +768,7 @@ public abstract class AlignmentViewport
   protected Hashtable<String, Object>[] hStrucConsensus = null;
 
   protected Conservation hconservation = null;
+
   
   @Override
   public void setConservation(Conservation cons)
@@ -848,7 +875,7 @@ public abstract class AlignmentViewport
     return strucConsensus;
   }
 
-  protected AlignCalcManagerI calculator = new AlignCalcManager();
+  protected AlignCalcManagerI2 calculator = new AlignCalcManager2();
 
   /**
    * trigger update of conservation annotation
@@ -858,12 +885,12 @@ public abstract class AlignmentViewport
     // see note in mantis : issue number 8585
     if (alignment.isNucleotide()
             || (conservation == null && quality == null)
-            || !autoCalculateConsensus)
+            || !autoCalculateConsensusAndConservation)
     {
       return;
     }
-    if (calculator.getRegisteredWorkersOfClass(
-            jalview.workers.ConservationThread.class) == null)
+    if (calculator.getWorkersOfClass(
+            jalview.workers.ConservationThread.class).isEmpty())
     {
       calculator.registerWorker(
               new jalview.workers.ConservationThread(this, ap));
@@ -876,12 +903,11 @@ public abstract class AlignmentViewport
   public void updateConsensus(final AlignmentViewPanel ap)
   {
     // see note in mantis : issue number 8585
-    if (consensus == null || !autoCalculateConsensus)
+    if (consensus == null || !autoCalculateConsensusAndConservation)
     {
       return;
     }
-    if (calculator
-            .getRegisteredWorkersOfClass(ConsensusThread.class) == null)
+    if (calculator.getWorkersOfClass(ConsensusThread.class).isEmpty())
     {
       calculator.registerWorker(new ConsensusThread(this, ap));
     }
@@ -912,11 +938,9 @@ public abstract class AlignmentViewport
       }
       if (doConsensus)
       {
-        if (calculator.getRegisteredWorkersOfClass(
-                ComplementConsensusThread.class) == null)
+        if (calculator.getWorkersOfClass(ComplementConsensusThread.class).isEmpty())
         {
-          calculator
-                  .registerWorker(new ComplementConsensusThread(this, ap));
+          calculator.registerWorker(new ComplementConsensusThread(this, ap));
         }
       }
     }
@@ -925,13 +949,11 @@ public abstract class AlignmentViewport
   @Override
   public void initInformationWorker(final AlignmentViewPanel ap)
   {
-    if (calculator
-            .getRegisteredWorkersOfClass(InformationThread.class) == null)
+    if (calculator.getWorkersOfClass(InformationThread.class).isEmpty())
     {
       calculator.registerWorker(new InformationThread(this, ap));
     }
   }
-
   // --------START Structure Conservation
   public void updateStrucConsensus(final AlignmentViewPanel ap)
   {
@@ -947,8 +969,7 @@ public abstract class AlignmentViewport
     {
       return;
     }
-    if (calculator.getRegisteredWorkersOfClass(
-            StrucConsensusThread.class) == null)
+    if (calculator.getWorkersOfClass(StrucConsensusThread.class).isEmpty())
     {
       calculator.registerWorker(new StrucConsensusThread(this, ap));
     }
@@ -967,7 +988,7 @@ public abstract class AlignmentViewport
     {
       return false;
     }
-    if (calculator.workingInvolvedWith(alignmentAnnotation))
+    if (calculator.isWorkingWithAnnotation(alignmentAnnotation))
     {
       // System.err.println("grey out ("+alignmentAnnotation.label+")");
       return true;
@@ -975,6 +996,13 @@ public abstract class AlignmentViewport
     return false;
   }
 
+  private PollingTaskExecutor wsExecutor = new PollingTaskExecutor();
+
+  public PollingTaskExecutor getWSExecutor()
+  {
+    return wsExecutor;
+  }
+
   public void setAlignment(AlignmentI align)
   {
     this.alignment = align;
@@ -1002,12 +1030,16 @@ public abstract class AlignmentViewport
     hconservation = null;
     hcomplementConsensus = null;
     gapcounts = null;
+    calculator.shutdown();
     calculator = null;
+    wsExecutor.shutdown();
+    wsExecutor = null;
     residueShading = null; // may hold a reference to Consensus
     changeSupport = null;
     ranges = null;
     currentTree = null;
     selectionGroup = null;
+    colSel = null;
     setAlignment(null);
   }
 
@@ -1020,7 +1052,7 @@ public abstract class AlignmentViewport
   }
 
   @Override
-  public AlignCalcManagerI getCalcManager()
+  public AlignCalcManagerI2 getCalcManager()
   {
     return calculator;
   }
@@ -1094,9 +1126,15 @@ public abstract class AlignmentViewport
       // TODO: decouple settings setting from calculation when refactoring
       // annotation update method from alignframe to viewport
       this.showSequenceLogo = showSequenceLogo;
-      calculator.updateAnnotationFor(ConsensusThread.class);
-      calculator.updateAnnotationFor(ComplementConsensusThread.class);
-      calculator.updateAnnotationFor(StrucConsensusThread.class);
+      for (AlignCalcWorkerI worker : calculator.getWorkers())
+      {
+        if (worker.getClass().equals(ConsensusThread.class) ||
+                worker.getClass().equals(ComplementConsensusThread.class) ||
+                worker.getClass().equals(StrucConsensusThread.class))
+        {
+          worker.updateAnnotation();
+        }
+      }
     }
     this.showSequenceLogo = showSequenceLogo;
   }
@@ -1112,7 +1150,6 @@ public abstract class AlignmentViewport
     }
     this.hmmShowSequenceLogo = showHMMSequenceLogo;
   }
-
   /**
    * @param showConsensusHistogram
    *          the showConsensusHistogram to set
@@ -1384,21 +1421,22 @@ public abstract class AlignmentViewport
    * checks current colsel against record of last hash value, and optionally
    * updates record.
    * 
-   * @param b
+   * @param updateHash
    *          update the record of last hash value
    * @return true if colsel changed since last call (when b is true)
    */
-  public boolean isColSelChanged(boolean b)
+  public boolean isColSelChanged(boolean updateHash)
   {
     int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
     if (hc != -1 && hc != colselhash)
     {
-      if (b)
+      if (updateHash)
       {
         colselhash = hc;
       }
       return true;
     }
+    notifySequence();
     return false;
   }
 
@@ -1419,7 +1457,6 @@ public abstract class AlignmentViewport
   {
     return infoLetterHeight;
   }
-
   // property change stuff
   // JBPNote Prolly only need this in the applet version.
   private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
@@ -1471,21 +1508,6 @@ public abstract class AlignmentViewport
     }
   }
 
-  /**
-   * Property change listener for changes in alignment
-   * 
-   * @param prop
-   *          DOCUMENT ME!
-   * @param oldvalue
-   *          DOCUMENT ME!
-   * @param newvalue
-   *          DOCUMENT ME!
-   */
-  public void firePropertyChange(String prop, Object oldvalue,
-          Object newvalue)
-  {
-    changeSupport.firePropertyChange(prop, oldvalue, newvalue);
-  }
 
   // common hide/show column stuff
 
@@ -1551,9 +1573,9 @@ public abstract class AlignmentViewport
 
       ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
 
-      firePropertyChange("alignment", null, alignment.getSequences());
       // used to set hasHiddenRows/hiddenRepSequences here, after the property
       // changed event
+      notifySequence();
       sendSelection();
     }
   }
@@ -1581,7 +1603,7 @@ public abstract class AlignmentViewport
 
       ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
 
-      firePropertyChange("alignment", null, alignment.getSequences());
+      notifyAlignment();
       sendSelection();
     }
   }
@@ -1615,7 +1637,7 @@ public abstract class AlignmentViewport
         setSequenceAnnotationsVisible(seq[i], false);
       }
       ranges.setStartSeq(startSeq);
-      firePropertyChange("alignment", null, alignment.getSequences());
+      notifyAlignment();
     }
   }
 
@@ -1980,11 +2002,11 @@ public abstract class AlignmentViewport
     {
       alignment.padGaps();
     }
-    if (autoCalculateConsensus)
+    if (autoCalculateConsensusAndConservation)
     {
       updateConsensus(ap);
     }
-    if (hconsensus != null && autoCalculateConsensus)
+    if (hconsensus != null && autoCalculateConsensusAndConservation)
     {
       updateConservation(ap);
     }
@@ -2066,7 +2088,6 @@ public abstract class AlignmentViewport
               MessageManager.getString("label.consensus_descr"),
               new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
       initConsensus(consensus);
-
       initGapCounts();
 
       initComplementConsensus();
@@ -3112,7 +3133,6 @@ public abstract class AlignmentViewport
     }
     return false;
   }
-
   @Override
   public void setCurrentTree(TreeModel tree)
   {
@@ -3240,6 +3260,23 @@ public abstract class AlignmentViewport
     }
   }
 
+  @Override
+  public Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly)
+  {
+    int start = 0;
+    int end = 0;
+    if (selectedRegionOnly && selectionGroup != null)
+    {
+      start = selectionGroup.getStartRes();
+      end = selectionGroup.getEndRes() + 1;
+    }
+    else
+    {
+      end = alignment.getWidth();
+    }
+    return (alignment.getHiddenColumns().getVisContigsIterator(start, end,
+            false));
+  }
   /**
    * Filters out sequences with an eValue higher than the specified value. The
    * filtered sequences are hidden or deleted. Sequences with no eValues are also
@@ -3280,5 +3317,21 @@ public abstract class AlignmentViewport
         hideSequence(new SequenceI[] { seq });
       }
     }
+  }  
+
+  /**
+   * Notify TreePanel and AlignmentPanel of some sort of alignment change.
+   */
+  public void notifyAlignment()
+  {
+    changeSupport.firePropertyChange(PROPERTY_ALIGNMENT, null, alignment.getSequences());
+  }
+  
+  /**
+   * Notify AlignmentPanel of a sequence column selection or visibility changes.
+   */
+  public void notifySequence()
+  {
+    changeSupport.firePropertyChange(PROPERTY_SEQUENCE, null, null);
   }
 }