+
+ private int width = 0;
+
+ private int firstCol = 0;
+
+ /**
+ * one or more ScGroup objects, which are referenced by each seqCigar's group
+ * membership
+ */
+ private Vector scGroups;
+
+ private boolean isNa = false;
+
+ /**
+ * false if the view concerns peptides
+ *
+ * @return
+ */
+ public boolean isNa()
+ {
+ return isNa;
+ }
+
+ /**
+ * Group defined over SeqCigars. Unlike AlignmentI associated groups, each
+ * SequenceGroup hold just the essential properties for the group, but no
+ * references to the sequences involved. SeqCigars hold references to the
+ * seuqenceGroup entities themselves.
+ */
+ private class ScGroup
+ {
+ public Vector seqs;
+
+ public SequenceGroup sg;
+
+ ScGroup()
+ {
+ seqs = new Vector();
+ }
+ }
+
+ /**
+ * vector of selected seqCigars. This vector is also referenced by each
+ * seqCigar contained in it.
+ */
+ private Vector selected;
+
+ /**
+ * Construct an alignmentView from a live jalview alignment view. Note -
+ * hidden rows will be excluded from alignmentView Note: JAL-1179
+ *
+ * @param alignment
+ * - alignment as referenced by an AlignViewport
+ * @param columnSelection
+ * -
+ * @param selection
+ * @param hasHiddenColumns
+ * - mark the hidden columns in columnSelection as hidden in the view
+ * @param selectedRegionOnly
+ * - when set, only include the selected region in the view,
+ * otherwise just mark the selected region on the constructed view.
+ * @param recordGroups
+ * - when set, any groups on the given alignment will be marked on
+ * the view
+ */
+ public AlignmentView(AlignmentI alignment,
+ ColumnSelection columnSelection, SequenceGroup selection,
+ boolean hasHiddenColumns, boolean selectedRegionOnly,
+ boolean recordGroups)
+ {
+ // refactored from AlignViewport.getAlignmentView(selectedOnly);
+ this(new jalview.datamodel.CigarArray(alignment,
+ (hasHiddenColumns ? columnSelection : null),
+ (selectedRegionOnly ? selection : null)),
+ (selectedRegionOnly && selection != null) ? selection
+ .getStartRes() : 0);
+ isNa = alignment.isNucleotide();
+ // walk down SeqCigar array and Alignment Array - optionally restricted by
+ // selected region.
+ // test group membership for each sequence in each group, store membership
+ // and record non-empty groups in group list.
+ // record / sub-select selected region on the alignment view
+ SequenceI[] selseqs;
+ if (selection != null && selection.getSize() > 0)
+ {
+ List<SequenceI> sel = selection.getSequences(null);
+ this.selected = new Vector();
+ selseqs = selection
+ .getSequencesInOrder(alignment, selectedRegionOnly);
+ }
+ else
+ {
+ selseqs = alignment.getSequencesArray();
+ }
+
+ // get the alignment's group list and make a copy
+ Vector grps = new Vector();
+ List<SequenceGroup> gg = alignment.getGroups();
+ grps.addAll(gg);
+ ScGroup[] sgrps = null;
+ boolean addedgps[] = null;
+ if (grps != null)
+ {
+ SequenceGroup sg;
+ if (selection != null && selectedRegionOnly)
+ {
+ // trim annotation to the region being stored.
+ // strip out any groups that do not actually intersect with the
+ // visible and selected region
+ int ssel = selection.getStartRes(), esel = selection.getEndRes();
+ Vector isg = new Vector();
+ Enumeration en = grps.elements();
+ while (en.hasMoreElements())
+ {
+ sg = (SequenceGroup) en.nextElement();
+
+ if (!(sg.getStartRes() > esel || sg.getEndRes() < ssel))
+ {
+ // adjust bounds of new group, if necessary.
+ if (sg.getStartRes() < ssel)
+ {
+ sg.setStartRes(ssel);
+ }
+ if (sg.getEndRes() > esel)
+ {
+ sg.setEndRes(esel);
+ }
+ sg.setStartRes(sg.getStartRes() - ssel + 1);
+ sg.setEndRes(sg.getEndRes() - ssel + 1);
+
+ isg.addElement(sg);
+ }
+ }
+ grps = isg;
+ }
+
+ sgrps = new ScGroup[grps.size()];
+ addedgps = new boolean[grps.size()];
+ for (int g = 0; g < sgrps.length; g++)
+ {
+ sg = (SequenceGroup) grps.elementAt(g);
+ sgrps[g] = new ScGroup();
+ sgrps[g].sg = new SequenceGroup(sg);
+ addedgps[g] = false;
+ grps.setElementAt(sg.getSequences(null), g);
+ }
+ // grps now contains vectors (should be sets) for each group, so we can
+ // track when we've done with the group
+ }
+ int csi = 0;
+ for (int i = 0; i < selseqs.length; i++)
+ {
+ if (selseqs[i] != null)
+ {
+ if (selection != null && selection.getSize() > 0
+ && !selectedRegionOnly)
+ {
+ sequences[csi].setGroupMembership(selected);
+ selected.addElement(sequences[csi]);
+ }
+ if (grps != null)
+ {
+ for (int sg = 0; sg < sgrps.length; sg++)
+ {
+ if (((Vector) grps.elementAt(sg)).contains(selseqs[i]))
+ {
+ sequences[csi].setGroupMembership(sgrps[sg]);
+ sgrps[sg].sg.deleteSequence(selseqs[i], false);
+ sgrps[sg].seqs.addElement(sequences[csi]);
+ if (!addedgps[sg])
+ {
+ if (scGroups == null)
+ {
+ scGroups = new Vector();
+ }
+ addedgps[sg] = true;
+ scGroups.addElement(sgrps[sg]);
+ }
+ }
+ }
+ }
+ csi++;
+ }
+ }
+ // finally, delete the remaining sequences (if any) not selected
+ for (int sg = 0; sg < sgrps.length; sg++)
+ {
+ SequenceI[] sqs = sgrps[sg].sg.getSequencesAsArray(null);
+ for (int si = 0; si < sqs.length; si++)
+ {
+ sgrps[sg].sg.deleteSequence(sqs[si], false);
+ }
+ sgrps[sg] = null;
+ }
+ }
+
+ /**
+ * construct an alignmentView from a SeqCigarArray. Errors are thrown if the
+ * seqcigararray.isSeqCigarArray() flag is not set.
+ */