Merge branch 'develop' into spike/JAL-4047/JAL-4048_columns_in_sequenceID spike/JAL-4047/JAL-4048_columns_in_sequenceID
authorJames Procter <j.procter@dundee.ac.uk>
Thu, 14 Sep 2023 09:16:21 +0000 (10:16 +0100)
committerJames Procter <j.procter@dundee.ac.uk>
Thu, 14 Sep 2023 09:16:21 +0000 (10:16 +0100)
1  2 
src/jalview/api/AlignViewportI.java
src/jalview/gui/IdCanvas.java
src/jalview/gui/PopupMenu.java
src/jalview/viewmodel/AlignmentViewport.java

   */
  package jalview.api;
  
 +import java.awt.Color;
 +import java.awt.Font;
 +import java.util.Hashtable;
 +import java.util.Iterator;
 +import java.util.List;
 +import java.util.Map;
 +
  import jalview.analysis.Conservation;
  import jalview.analysis.TreeModel;
  import jalview.datamodel.AlignmentAnnotation;
@@@ -44,7 -37,13 +44,7 @@@ import jalview.datamodel.SequenceI
  import jalview.renderer.ResidueShaderI;
  import jalview.schemes.ColourSchemeI;
  import jalview.viewmodel.ViewportRanges;
 -
 -import java.awt.Color;
 -import java.awt.Font;
 -import java.util.Hashtable;
 -import java.util.Iterator;
 -import java.util.List;
 -import java.util.Map;
 +import jalview.viewmodel.seqfeatures.IdColumns;
  
  /**
   * @author jimp
@@@ -478,6 -477,15 +478,15 @@@ public interface AlignViewportI extend
     */
    SearchResultsI getSearchResults();
  
+   /**
+    * Retrieve a ContactListI corresponding to column in an annotation row in an
+    * alignment.
+    * 
+    * @param _aa
+    *          - annotation with associated matrix data
+    * @param column
+    *          - column in alignment where _aa is associated
+    */
    ContactListI getContactList(AlignmentAnnotation _aa, int column);
  
    /**
     */
    Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly);
  
 +  IdColumns getIdColumns();
 +
    ContactMatrixI getContactMatrix(AlignmentAnnotation alignmentAnnotation);
  }
@@@ -22,6 -22,7 +22,7 @@@ package jalview.gui
  
  import java.awt.BorderLayout;
  import java.awt.Color;
+ import java.awt.Dimension;
  import java.awt.Font;
  import java.awt.FontMetrics;
  import java.awt.Graphics;
@@@ -36,9 -37,6 +37,9 @@@ import javax.swing.JPanel
  import jalview.datamodel.SequenceI;
  import jalview.viewmodel.ViewportListenerI;
  import jalview.viewmodel.ViewportRanges;
 +import jalview.viewmodel.seqfeatures.IdColumn;
 +import jalview.viewmodel.seqfeatures.IdColumns;
 +import jalview.viewmodel.seqfeatures.IdColumns.ColumnCell;
  
  /**
   * DOCUMENT ME!
@@@ -201,7 -199,7 +202,7 @@@ public class IdCanvas extends JPanel im
  
      gg.translate(0, transY);
  
-     drawIds(gg, av, ss, es, searchResults);
+     drawIds(gg, av, ss, es, searchResults,true);
  
      gg.translate(0, -transY);
  
      gg.fillRect(0, 0, getWidth(), imgHeight);
  
      drawIds(gg, av, av.getRanges().getStartSeq(),
-             av.getRanges().getEndSeq(), searchResults);
+             av.getRanges().getEndSeq(), searchResults,true);
  
      gg.dispose();
  
     * @param selection
     */
    void drawIds(Graphics2D g, AlignViewport alignViewport,
-           final int startSeq, final int endSeq, List<SequenceI> selection)
+           final int startSeq, final int endSeq, List<SequenceI> selection, boolean forGUI)
    {
      Font font = alignViewport.getFont();
      if (alignViewport.isSeqNameItalics())
      }
  
      // Now draw the id strings
 -    int panelWidth = getWidth();
 -    int xPos = 0;
 +    int fullPanelWidth = getWidth();
 +
 +    IdColumns id_cols = alignViewport.getIdColumns();
 +    List<IdColumn> visible = id_cols.getVisible();
 +    /**
 +     * width of an idColumn
 +     */
 +    int colWid = 20;
 +    int panelWidth = Math.max(fullPanelWidth / 2,
 +            fullPanelWidth - (colWid * visible.size()));
  
      // Now draw the id strings
      for (int i = startSeq; i <= endSeq; i++)
      {
 +      int xPos = 0;
        SequenceI sequence = alignViewport.getAlignment().getSequenceAt(i);
  
        if (sequence == null)
        {
          continue;
        }
 -
        if (hasHiddenRows || alignViewport.isDisplayReferenceSeq())
        {
          g.setFont(getHiddenFont(sequence, alignViewport));
                (((i - startSeq) * charHeight) + charHeight)
                        - (charHeight / 5));
  
 +      if (visible != null && visible.size() > 0)
 +      {
 +        try
 +        {
 +          xPos = panelWidth + 2;
 +          for (IdColumn col : visible)
 +          {
 +            ColumnCell col_cell = id_cols.getCellFor(sequence, col);
 +            if (col_cell == null)
 +            {
 +              g.setColor(Color.gray);
 +              g.fillRect(xPos + 1, (i - startSeq) * charHeight,
 +                      xPos + colWid - 3, charHeight);
 +            }
 +            else
 +            {
 +              g.setColor(col_cell.bg);
 +              g.fillRect(xPos + 1, (i - startSeq) * charHeight,
 +                      xPos + colWid - 3, charHeight);
 +              g.setColor(col_cell.fg);
 +              g.drawString(col_cell.label, xPos,
 +                      (((i - startSeq) * charHeight) + charHeight)
 +                              - (charHeight / 5));
 +            }
 +            xPos += colWid;
 +            g.setColor(currentTextColor);
 +          }
 +        } catch (Exception q)
 +        {
 +        }
 +      }
        if (hasHiddenRows && av.getShowHiddenMarkers())
        {
          drawMarker(g, alignViewport, i, startSeq, 0);
    void drawIdsWrapped(Graphics2D g, AlignViewport alignViewport,
            int startSeq, int pageHeight)
    {
+     drawIdsWrapped(g, alignViewport, startSeq, pageHeight, -1, true);
+   }
+   /**
+    * render sequence IDs and annotation labels when wrapped - without GUI junk
+    * @param g
+    * @param av2
+    * @param i
+    * @param totalHeight
+    */
+   public void drawIdsWrappedNoGUI(Graphics2D g, AlignViewport av2, int i,
+           int totalHeight)
+   {
+     drawIdsWrapped(g, av2, totalHeight, totalHeight, i,false);
+   }
+   void drawIdsWrapped(Graphics2D g, AlignViewport alignViewport,
+           int startSeq, int pageHeight, int idWidth, boolean forGUI)
+   {
      int alignmentWidth = alignViewport.getAlignment().getWidth();
      final int alheight = alignViewport.getAlignment().getHeight();
  
  
        if (labels != null && alignViewport.isShowAnnotation())
        {
+         int getWidth = getWidth();
+         int thisIdWidth = getWidth;
          g.translate(0, ypos + (alheight * charHeight));
-         labels.drawComponent(g, getWidth());
+         if (!manuallyAdjusted())
+         {
+           int getAnnotationsIdWidth = labels.drawLabels(g, false, -1, false,forGUI,
+                   null);
+           thisIdWidth = idWidth < 0 ? getAnnotationsIdWidth : idWidth;
+           if (thisIdWidth > getWidth)
+           {
+             this.setPreferredSize(
+                     new Dimension(thisIdWidth, this.getHeight()));
+             this.repaint();
+             alignViewport.setIdWidth(thisIdWidth);
+           }
+         }
+         labels.drawComponent(g, false, thisIdWidth, forGUI);
          g.translate(0, -ypos - (alheight * charHeight));
        }
  
        repaint();
      }
    }
+   private boolean manuallyAdjusted = false;
+   public boolean manuallyAdjusted()
+   {
+     return manuallyAdjusted;
+   }
+   public void setManuallyAdjusted(boolean b)
+   {
+     manuallyAdjusted = b;
+   }
  }
@@@ -87,8 -87,6 +87,8 @@@ import jalview.util.Platform
  import jalview.util.StringUtils;
  import jalview.util.UrlLink;
  import jalview.viewmodel.seqfeatures.FeatureRendererModel;
 +import jalview.viewmodel.seqfeatures.IdColumn;
 +import jalview.viewmodel.seqfeatures.IdColumns;
  
  /**
   * The popup menu that is displayed on right-click on a sequence id, or in the
@@@ -728,38 -726,9 +728,38 @@@ public class PopupMenu extends JPopupMe
        rnaStructureMenu.setVisible(false);
      }
  
 +    if (forIdPanel)
 +    {
 +      addDisplayColumnsMenu();
 +    }
 +
      addLinksAndFeatures(seq, column);
    }
  
 +  void addDisplayColumnsMenu()
 +  {
 +    JMenu dis_cols = new JMenu(
 +            MessageManager.getString("action.displayed_columns"));
 +    final IdColumns id_cols = ap.av.getIdColumns();
 +    id_cols.updateTypeList();
 +    for (final IdColumn col : id_cols.getIdColumns())
 +    {
 +      JMenuItem col_entry = new JCheckBoxMenuItem(col.getLabel(),
 +              col.isVisible());
 +      col_entry.addActionListener(new ActionListener()
 +      {
 +
 +        @Override
 +        public void actionPerformed(ActionEvent e)
 +        {
 +          id_cols.toggleVisible(col.getLabel());
 +        }
 +      });
 +      dis_cols.add(col_entry);
 +    }
 +    add(dis_cols);
 +  }
 +
    /**
     * Adds
     * <ul>
      if (Platform.isJS())
      {
        details = new JInternalFrame();
+       details.setFrameIcon(null);
        JPanel panel = new JPanel(new BorderLayout());
        panel.setOpaque(true);
        panel.setBackground(Color.white);
    protected void addReferenceAnnotations_actionPerformed(
            Map<SequenceI, List<AlignmentAnnotation>> candidates)
    {
-     final SequenceGroup selectionGroup = this.ap.av.getSelectionGroup();
      final AlignmentI alignment = this.ap.getAlignment();
      AlignmentUtils.addReferenceAnnotations(candidates, alignment,
-             selectionGroup);
+             null);
      refresh();
    }
  
        pane.setBackground(Color.WHITE);
        pane.add(textLabel, BorderLayout.NORTH);
        frame = new JInternalFrame();
+       frame.setFrameIcon(null);
        frame.getContentPane().add(new JScrollPane(pane));
      }
      else
                sg.setName(dialog.getName());
                sg.setDescription(dialog.getDescription());
                refresh();
-               return null;
              });
    }
  
                {
                  if (dialog.getName().indexOf(" ") > -1)
                  {
-                   JvOptionPane.showMessageDialog(ap,
-                           MessageManager.getString(
-                                   "label.spaces_converted_to_underscores"),
-                           MessageManager.getString(
-                                   "label.no_spaces_allowed_sequence_name"),
-                           JvOptionPane.WARNING_MESSAGE);
+                   String ok = MessageManager.getString("action.ok");
+                   String cancel = MessageManager.getString("action.cancel");
+                   String message = MessageManager.getString(
+                           "label.spaces_converted_to_underscores");
+                   String title = MessageManager.getString(
+                           "label.no_spaces_allowed_sequence_name");
+                   Object[] options = new Object[] { ok, cancel };
+                   JvOptionPane.frameDialog(message, title,
+                           JvOptionPane.WARNING_MESSAGE, null, null, null,
+                           false);
                  }
                  sequence.setName(dialog.getName().replace(' ', '_'));
                  ap.paintAlignment(false, false);
                sequence.setDescription(dialog.getDescription());
                ap.av.firePropertyChange("alignment", null,
                        ap.av.getAlignment().getSequences());
-               return null;
              });
    }
  
  
      String[] omitHidden = null;
  
-     System.out.println("PROMPT USER HERE"); // TODO: decide if a prompt happens
+     jalview.bin.Console.outPrintln("PROMPT USER HERE"); // TODO: decide if a prompt happens
      // or we simply trust the user wants
      // wysiwig behaviour
  
                  ap.alignFrame.addHistoryItem(editCommand);
                  ap.av.firePropertyChange("alignment", null,
                          ap.av.getAlignment().getSequences());
-                 return null;
                });
      }
    }
@@@ -72,7 -72,6 +72,7 @@@ import jalview.util.Comparison
  import jalview.util.MapList;
  import jalview.util.MappingUtils;
  import jalview.util.MessageManager;
 +import jalview.viewmodel.seqfeatures.IdColumns;
  import jalview.viewmodel.styles.ViewStyle;
  import jalview.workers.AlignCalcManager;
  import jalview.workers.ComplementConsensusThread;
@@@ -935,7 -934,7 +935,7 @@@ public abstract class AlignmentViewpor
      }
      if (calculator.workingInvolvedWith(alignmentAnnotation))
      {
-       // System.err.println("grey out ("+alignmentAnnotation.label+")");
+       // jalview.bin.Console.errPrintln("grey out ("+alignmentAnnotation.label+")");
        return true;
      }
      return false;
    {
      if (sequenceSetID != null)
      {
-       System.err.println(
+       jalview.bin.Console.errPrintln(
                "Warning - overwriting a sequenceSetId for a viewport!");
      }
      sequenceSetID = new String(newid);
        {
          if (aa == null)
          {
-           System.err.println("Null annotation row: ignoring.");
+           jalview.bin.Console.errPrintln("Null annotation row: ignoring.");
            continue;
          }
          if (!aa.visible)
  
          if (aa.graph > 0)
          {
-           aa.height += aa.graphHeight;
+           aa.height += aa.graphHeight+20;
          }
  
          if (aa.height == 0)
    {
      if (this == av)
      {
-       System.err.println("Ignoring recursive setCodingComplement request");
+       jalview.bin.Console.errPrintln("Ignoring recursive setCodingComplement request");
      }
      else
      {
      return alignment.getContactMatrixFor(alignmentAnnotation);
    }
  
    /**
     * get the consensus sequence as displayed under the PID consensus annotation
     * row.
              false));
    }
  
 +  /**
 +   * ordered list of annotation values displayed per sequence in ID panel
 +   */
 +  private IdColumns id_columns = null;
 +
 +  /**
 +   * available and currently visible columns for this view
 +   */
 +  @Override
 +  public IdColumns getIdColumns()
 +  {
 +    if (alignment == null)
 +    {
 +      return null;
 +    }
 +    if (id_columns == null)
 +    {
 +      id_columns = new IdColumns(alignment);
 +    }
 +    return id_columns;
 +  }
 +
    public void setSavedUpToDate(boolean s)
    {
      setSavedUpToDate(s, QuitHandler.Message.UNSAVED_CHANGES);