+ public String getViewId()
+ {
+ return viewId;
+ }
+
+ /**
+ * Returns true if any of the viewer's models (not necessarily the one
+ * currently displayed) is for the given sequence
+ *
+ * @param seq
+ * @return
+ */
+ public boolean isListeningFor(SequenceI seq)
+ {
+ for (RnaModel model : models.values())
+ {
+ if (model.seq == seq)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a value representing the horizontal split divider location
+ *
+ * @return
+ */
+ public int getDividerLocation()
+ {
+ return split == null ? 0 : split.getDividerLocation();
+ }
+
+ /**
+ * Tidy up as necessary when the viewer panel is closed
+ */
+ protected void close()
+ {
+ /*
+ * Deregister as a listener, to release references to this object
+ */
+ if (ssm != null)
+ {
+ ssm.removeStructureViewerListener(AppVarna.this, null);
+ ssm.removeSelectionListener(AppVarna.this);
+ }
+ }
+
+ /**
+ * Returns the secondary structure annotation that this viewer displays for
+ * the given sequence
+ *
+ * @return
+ */
+ public AlignmentAnnotation getAnnotation(SequenceI seq)
+ {
+ for (RnaModel model : models.values())
+ {
+ if (model.seq == seq)
+ {
+ return model.ann;
+ }
+ }
+ return null;
+ }
+
+ public int getSelectedIndex()
+ {
+ return this.vab.getSelectedIndex();
+ }
+
+ /**
+ * Returns the set of models shown by the viewer
+ *
+ * @return
+ */
+ public Collection<RnaModel> getModels()
+ {
+ return models.values();
+ }
+
+ /**
+ * Add a model (e.g. loaded from project file)
+ *
+ * @param rna
+ * @param modelName
+ */
+ public RNA addModel(RnaModel model, String modelName)
+ {
+ if (!model.ann.isValidStruc())
+ {
+ throw new IllegalArgumentException("Invalid RNA structure annotation");
+ }
+
+ /*
+ * opened on request in Jalview session
+ */
+ RNA rna = new RNA(modelName);
+ String struc = model.ann.getRNAStruc();
+ struc = replaceOddGaps(struc);
+
+ String strucseq = model.seq.getSequenceAsString();
+ try
+ {
+ rna.setRNA(strucseq, struc);
+ } catch (ExceptionUnmatchedClosingParentheses e2)
+ {
+ e2.printStackTrace();
+ } catch (ExceptionFileFormatOrSyntax e3)
+ {
+ e3.printStackTrace();
+ }
+
+ if (!model.gapped)
+ {
+ rna = trimRNA(rna, modelName);
+ }
+ models.put(rna, new RnaModel(modelName, model.ann, model.seq, rna,
+ model.gapped));
+ vab.addStructure(rna);
+ return rna;
+ }
+
+ /**
+ * Constructs a shift list that describes the gaps in the sequence
+ *
+ * @param seq
+ * @return
+ */
+ protected ShiftList buildOffset(SequenceI seq)
+ {
+ // TODO refactor to avoid duplication with trimRNA()
+ // TODO JAL-1789 bugs in use of ShiftList here
+ ShiftList offset = new ShiftList();
+ int ofstart = -1;
+ int sleng = seq.getLength();
+ char[] seqChars = seq.getSequence();
+
+ for (int i = 0; i < sleng; i++)
+ {
+ if (Comparison.isGap(seqChars[i]))
+ {
+ if (ofstart == -1)
+ {
+ ofstart = i;
+ }
+ }
+ else
+ {
+ if (ofstart > -1)
+ {
+ offset.addShift(offset.shift(ofstart), ofstart - i);
+ ofstart = -1;
+ }
+ }
+ }
+ // final gap
+ if (ofstart > -1)
+ {
+ offset.addShift(offset.shift(ofstart), ofstart - sleng);
+ ofstart = -1;
+ }
+ return offset;
+ }
+
+ /**
+ * Set the selected index in the model selection list
+ *
+ * @param selectedIndex
+ */
+ public void setInitialSelection(final int selectedIndex)