+ /**
+ * modify current selection according to a received message.
+ */
+ @Override
+ public void selection(SequenceGroup seqsel, ColumnSelection colsel,
+ SelectionSource source)
+ {
+ // TODO: fix this hack - source of messages is align viewport, but SeqPanel
+ // handles selection messages...
+ // TODO: extend config options to allow user to control if selections may be
+ // shared between viewports.
+ if (av != null
+ && (av == source || !av.followSelection || (source instanceof AlignViewport && ((AlignmentViewport) source)
+ .getSequenceSetId().equals(av.getSequenceSetId()))))
+ {
+ return;
+ }
+
+ /*
+ * Check for selection in a view of which this one is a dna/protein
+ * complement.
+ */
+ if (selectionFromTranslation(seqsel, colsel, source))
+ {
+ return;
+ }
+
+ // do we want to thread this ? (contention with seqsel and colsel locks, I
+ // suspect)
+ /*
+ * only copy colsel if there is a real intersection between
+ * sequence selection and this panel's alignment
+ */
+ boolean repaint = false;
+ boolean copycolsel = false;
+ if (av.getSelectionGroup() == null || !av.isSelectionGroupChanged(true))
+ {
+ SequenceGroup sgroup = null;
+ if (seqsel != null && seqsel.getSize() > 0)
+ {
+ if (av.getAlignment() == null)
+ {
+ System.out
+ .println("Selection message: alignviewport av SeqSetId="
+ + av.getSequenceSetId() + " ViewId="
+ + av.getViewId()
+ + " 's alignment is NULL! returning immediatly.");
+ return;
+ }
+ sgroup = seqsel.intersect(av.getAlignment(),
+ (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
+ if ((sgroup != null && sgroup.getSize() > 0))
+ {
+ copycolsel = true;
+ }
+ }
+ if (sgroup != null && sgroup.getSize() > 0)
+ {
+ av.setSelectionGroup(sgroup);
+ }
+ else
+ {
+ av.setSelectionGroup(null);
+ }
+ repaint = av.isSelectionGroupChanged(true);
+ }
+ if (copycolsel
+ && (av.getColumnSelection() == null || !av
+ .isColSelChanged(true)))
+ {
+ // the current selection is unset or from a previous message
+ // so import the new colsel.
+ if (colsel == null || colsel.isEmpty())
+ {
+ if (av.getColumnSelection() != null)
+ {
+ av.getColumnSelection().clear();
+ }
+ }
+ else
+ {
+ // TODO: shift colSel according to the intersecting sequences
+ if (av.getColumnSelection() == null)
+ {
+ av.setColumnSelection(new ColumnSelection(colsel));
+ }
+ else
+ {
+ av.getColumnSelection().setElementsFrom(colsel);
+ }
+ }
+ repaint |= av.isColSelChanged(true);
+ }
+ if (copycolsel
+ && av.hasHiddenColumns()
+ && (av.getColumnSelection() == null || av.getColumnSelection()
+ .getHiddenColumns() == null))
+ {
+ System.err.println("Bad things");
+ }
+ if (repaint)
+ {
+ ap.scalePanelHolder.repaint();
+ ap.repaint();
+ }
+ }
+
+ /**
+ * scroll to the given row/column - or nearest visible location
+ *
+ * @param row
+ * @param column
+ */
+ public void scrollTo(int row, int column)
+ {
+
+ row = row < 0 ? ap.av.startSeq : row;
+ column = column < 0 ? ap.av.startRes : column;
+ ap.scrollTo(column, column, row, true, true);
+ }
+
+ /**
+ * scroll to the given row - or nearest visible location
+ *
+ * @param row
+ */
+ public void scrollToRow(int row)
+ {
+
+ row = row < 0 ? ap.av.startSeq : row;
+ ap.scrollTo(ap.av.startRes, ap.av.startRes, row, true, true);
+ }
+
+ /**
+ * scroll to the given column - or nearest visible location
+ *
+ * @param column
+ */
+ public void scrollToColumn(int column)
+ {
+
+ column = column < 0 ? ap.av.startRes : column;
+ ap.scrollTo(column, column, ap.av.startSeq, true, true);
+ }
+
+ /**
+ * If this panel is a cdna/protein translation view of the selection source,
+ * tries to map the source selection to a local one, and returns true. Else
+ * returns false.
+ *
+ * @param seqsel
+ * @param colsel
+ * @param source
+ */
+ protected boolean selectionFromTranslation(SequenceGroup seqsel,
+ ColumnSelection colsel, SelectionSource source)
+ {
+ if (!(source instanceof AlignViewportI))
+ {
+ return false;
+ }
+ final AlignViewportI sourceAv = (AlignViewportI) source;
+ if (sourceAv.getCodingComplement() != av
+ && av.getCodingComplement() != sourceAv)
+ {
+ return false;
+ }
+
+ /*
+ * Map sequence selection
+ */
+ SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av);
+ av.setSelectionGroup(sg);
+ av.isSelectionGroupChanged(true);
+
+ /*
+ * Map column selection
+ */
+ ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
+ av);
+ av.setColumnSelection(cs);
+
+ ap.scalePanelHolder.repaint();
+ ap.repaint();
+
+ return true;
+ }
+