/**
   * Left Mouse dragging drags end of feature if drag type right or left boundary. dragType is
   * figured in mousePressed
   */
  public void mouseDragged(MouseEvent e) {
    if (!MouseButtonEvent.isLeftMouseClick(e)) return;
    // dragFeature set in mousePressed
    // not needed
    if (dragging == false && dragFeature != null) {
      // changer = baseEditorPanel.getAnnotationEditor().beginRangeChange(dragFeature);// ??
      preDragStartBasePair = dragFeature.getStart();
      preDragEndBasePair = dragFeature.getEnd();
    }
    dragging = true;
    // dragType determined in MousePressed
    if (dragType == baseEditorPanel.START_BOUNDARY)
      baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
    else if (dragType == baseEditorPanel.END_BOUNDARY)
      baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
    else if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) {
      baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
    }
    setPos(e.getX(), e.getY());
    startPos = pos;
    // going right
    // substract the one because during dragging
    // the person operating the mouse drags it
    // one position beyond where they want the
    // drop to occur.
    // pos--;

    if (dragType == baseEditorPanel.START_BOUNDARY) {
      // Is this position okay to use as the new
      // low end or will it make the feature too short?
      if (baseEditorPanel.notTooSmall(
          pos, baseEditorPanel.basePairToPos((int) dragFeature.getEnd())))
        // this actually changes the model - do we really need to do that
        // with every mouse drag - cant we just change it at the end of the
        // drag? No - the EDE relies on the feature being changed - bummer
        baseEditorPanel.changeStart(dragFeature, pos - dragStartPos, limit_5prime, limit_3prime);
    } else if (dragType == baseEditorPanel.END_BOUNDARY) {
      // Is this position okay to use as the new
      // high end or will it make the feature too short?
      if (baseEditorPanel.notTooSmall(
          baseEditorPanel.basePairToPos((int) dragFeature.getStart()), pos))
        // This changes the actual exon model! EDE relies on this
        baseEditorPanel.changeEnd(dragFeature, pos - dragStartPos, limit_5prime, limit_3prime);
    } else if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) {
      int redrawLowPos = baseEditorPanel.selectLowPos();
      int redrawHighPos = baseEditorPanel.selectHighPos();
      if (pos < redrawLowPos) redrawLowPos = pos;
      if (pos > redrawHighPos) redrawHighPos = pos;
      // selectCurrentPos = pos;
      baseEditorPanel.setSelectCurrentPos(pos);
      baseEditorPanel.repaint(redrawLowPos, redrawHighPos);
      return;
    }
    // repaint with exon seq feature ends changed
    baseEditorPanel.repaint(pos, dragStartPos);
    dragStartPos = pos;
  }
  /** Scrolls the window to the start/end of the next annotation to the right. */
  public void nextAnnotation() {
    int basepair = getVisibleBase();
    if (getType().equals("AA")) {
      basepair += 3 * getAnnotationPanel().getStrand().toInt();
    }
    int position =
        getAnnotationPanel()
            .tierPositionToPixelPosition(getAnnotationPanel().basePairToTierPosition(basepair));
    SeqFeatureI feature = getAnnotationPanel().getNextFeature(position);

    if (feature != null) {

      if (getAnnotationPanel().getOrientation() == Orientation.FIVE_TO_THREE) {
        scrollToBase(feature.getStart());
      } else {
        scrollToBase(feature.getEnd());
      }

      AnnotatedFeatureI selection = null;
      if (feature instanceof AnnotatedFeatureI) {
        selection = getTransOrOneLevelAnn((AnnotatedFeatureI) feature);
      }

      if (selection != null
          && selection.isTranscript()
          && ((Transcript) selection).haveWholeSequence()) {
        setSelection((AnnotatedFeatureI) feature);
        getCurationState().getSelectionManager().select(feature, this);
      } else if (selection != null && selection != getSelection()) {
        nextAnnotation();
      }
    }
  }
Exemplo n.º 3
0
 /**
  * This just returns sf.getBioType() (capitalized) unless its a transcript. For transcript it only
  * returns "Transcript" if its part of a Gene. Otherwise it returns its parent's bio type +
  * transcript. (should it not tack on the transcript?) Thus a tRNA's transcript would display
  * "tRNA transcript", where a gene's transcript would display just "Transcript". Should it
  * actually display "Gene transcript"? rename getTypeForDisplay?
  */
 public String getBioTypeForDisplay(SeqFeatureI sf) {
   String typeDisplay;
   if (sf instanceof AnnotatedFeatureI) {
     typeDisplay = sf.getTopLevelType();
     typeDisplay = capitalize(typeDisplay);
     if (!sf.getTopLevelType().equalsIgnoreCase(sf.getFeatureType()))
       typeDisplay += " " + capitalize(sf.getFeatureType());
   } else {
     String db = sf.getDatabase();
     // Don't bother showing db name if it is "dummy"
     if (db != null && !db.equals("") && !db.equals("dummy"))
       typeDisplay = sf.getProgramName() + ":" + sf.getDatabase();
     // yet again, the users have requested a change
     // Now instead of an enumeration it is the range of the feature
     else {
       typeDisplay = (sf.getProgramName() + ":" + sf.getStart() + "-" + sf.getEnd());
     }
   }
   return typeDisplay;
 }
  /**
   * @param position
   * @param tier
   * @return
   */
  public static int getOffset(int position, TierI tier) {

    SeqFeatureI sf = null;

    int offset = 0;
    if (tier.featureExsitsAt(position, Level.BOTTOM)) {
      sf = tier.featureAt(position, Level.BOTTOM);
      ReadingFrame exonFrame = ReadingFrame.valueOf(sf.getFrame());
      ReadingFrame tierFrame = tier.getReadingFrame();

      if (exonFrame == ReadingFrame.NONE
          && sf.getParent() != null
          && sf.getParent().isTranscript()) {
        FeatureSetI parent = sf.getParent();
        Transcript parentClone = (Transcript) sf.getParent().clone();

        int start = parentClone.getEnd();

        // the transcript start might be different than the lowest exon start
        // when in the middle of an edit
        if (parentClone.canHaveChildren()) {
          for (int i = 0; i < parentClone.size(); i++) {
            SeqFeatureI f = parentClone.getFeatureAt(i);
            if ((Strand.valueOf(f.getStrand()) == Strand.FORWARD && f.getStart() < start)
                || (Strand.valueOf(f.getStrand()) == Strand.REVERSE && f.getStart() > start))
              start = f.getStart();
          }
        }

        int translationStart = parentClone.getTranslationStart();
        int translationPos = parentClone.getFeaturePosition(translationStart);
        int oldstart = start;
        start += ((translationPos - 1) % 3) * parentClone.getStrand();

        parentClone.setTranslationStart(start);
        parentClone.setTranslationEnd(parentClone.getEnd());
        parentClone.setPeptideSequence(null);
        String translation = parentClone.translate();
        SequenceI sequence = parentClone.getPeptideSequence();

        int index = parent.getFeatureIndex(sf);
        exonFrame = ReadingFrame.valueOf(parentClone.getFeatureAt(index).getFrame());
      }

      if (tierFrame != exonFrame && sf.getParent() != null && sf.getParent().isTranscript()) {
        if (tierFrame == ReadingFrame.THREE) {
          offset = exonFrame == ReadingFrame.ONE ? -2 : -1;
        } else if (tierFrame == ReadingFrame.TWO) {
          offset = exonFrame == ReadingFrame.ONE ? -1 : 1;
        } else if (tierFrame == ReadingFrame.ONE) {
          offset = exonFrame == ReadingFrame.TWO ? 1 : 2;
        }
      }

      if (exonFrame == ReadingFrame.NONE) {
        offset = 0;
      }
    }

    return offset;
  }
  /**
   * Get component to be rendered, if pos outside of current range getFeatureAtPosition and reset
   * currentRange, if feature is non null and not an instance of FeatureSetI then its an exon, and
   * set isExon flag
   */
  public Component getBaseComponent(int position, TierI tier, Orientation o) {

    transcript = null;

    int bp = tier.getBasePair(position);
    int oldPos = position;

    // We need to change the position if dealing with aa view
    if (tier.getType() == SequenceType.AA) {
      int offset = getOffset(position, tier);
      bp += offset * tier.getStrand().toInt();
      position = tier.getPosition(bp);
    }

    char base = tier.charAt(position);

    if (tier.featureExsitsAt(position, TierI.Level.BOTTOM)) {
      this.state = State.EXON;
      SeqFeatureI feature = tier.featureAt(position, TierI.Level.BOTTOM);
      Transcript parentClone = null;
      Transcript otherParentClone = null;

      if (tier.getType() == SequenceType.AA
          && feature.getParent() != null
          && feature.getParent().isTranscript()) {

        FeatureSetI parent = feature.getParent();
        int index = parent.getFeatureIndex(feature);

        int start = parent.getEnd();
        // the transcript start might be different than the lowest exon start
        // when in the middle of an edit
        if (parent.canHaveChildren()) {
          for (int i = 0; i < parent.size(); i++) {
            SeqFeatureI sf = parent.getFeatureAt(i);
            if ((Strand.valueOf(sf.getStrand()) == Strand.FORWARD && sf.getStart() < start)
                || (Strand.valueOf(sf.getStrand()) == Strand.REVERSE && sf.getStart() > start))
              start = sf.getStart();
          }
        }

        int translationStart = parent.getTranslationStart();
        int translationEnd = parent.getTranslationEnd();
        int translationPos = parent.getFeaturePosition(translationStart);
        int oldstart = start;
        start += ((translationPos - 1) % 3) * parent.getStrand();

        // Tring to avoid all the recalculation...
        if (feature.getParent() == currentParent
            && start == currentStart
            && featureStart == feature.getStart()
            && featureEnd == feature.getEnd()) {
          parentClone = currentParentClone;
          otherParentClone = currentParentClone2;
        } else {
          // need to get a full translation so that we can get the amino acids
          // in the UTR region
          parentClone = (Transcript) feature.getParent().clone();
          otherParentClone = (Transcript) feature.getParent().clone();

          if (!parentClone.setTranslationStart(start)) {
            start = oldstart;
            TranslationI cds = otherParentClone.getTranslation();
            cds.calcTranslationStartForLongestPeptide();
            translationStart = otherParentClone.getTranslationStart();
            translationPos = otherParentClone.getFeaturePosition(translationStart);
            start += ((translationPos - 1) % 3) * otherParentClone.getStrand();
            parentClone.setTranslationStart(start);
          }

          parentClone.setTranslationEnd(parentClone.getEnd());
          parentClone.setPeptideSequence(null);

          String translation = parentClone.translate();
          SequenceI sequence = parentClone.getPeptideSequence();

          currentParent = (Transcript) feature.getParent();
          currentParentClone = parentClone;
          currentParentClone2 = otherParentClone;
          currentStart = start;
          featureStart = feature.getStart();
          featureEnd = feature.getEnd();

          if (otherParentClone.getFeatureContaining(translationEnd) == null) {
            TranslationI cds = otherParentClone.getTranslation();
            cds.setTranslationEndFromStart();
          }
        }

        SeqFeatureI sf = parentClone.getFeatureAt(index);

        if (bp >= sf.getLow() && bp <= sf.getHigh()) {
          base = getPeptide(bp, sf);
        } else {
          base = '\0';
        }

        if (otherParentClone != null) {
          feature = otherParentClone.getFeatureAt(index);
        }

      } else if (tier.getType() == SequenceType.AA
          && feature.getParent() != null
          && !feature.getParent().isTranscript()) {
        base = '\0';
      }

      if (isUTR(bp, feature, tier)) {
        this.state = State.UTR;
      }

      if (isTranslationStart(bp, feature)) {
        this.state = State.TRANSLATION_START;
      }

      if (isTranslationEnd(bp, feature)) {
        this.state = State.TRANSLATION_END;
      }

      // Can have an error or a shift on a position but not both
      if (isSequencingErrorPosition(bp, feature, tier.getType())) {
        this.state = State.ERROR;
        // set base to the base of the new sequence?
      }

      if (isShiftPosition(bp, feature, tier.getType())) {
        this.state = State.SHIFT;
      }

    } else if (tier.featureExsitsAt(position, TierI.Level.TOP)) {
      SeqFeatureI feature = tier.featureAt(position, Level.TOP);
      this.state = State.INTRON;
      if (tier.getType() == SequenceType.AA) {
        base = '\0';
      }

      int start = feature.getEnd();
      int end = feature.getStart();

      if (feature.canHaveChildren()) {
        for (int i = 0; i < feature.size(); i++) {
          SeqFeatureI sf = feature.getFeatureAt(i);
          if ((Strand.valueOf(sf.getStrand()) == Strand.FORWARD && sf.getStart() < start)
              || (Strand.valueOf(sf.getStrand()) == Strand.REVERSE && sf.getStart() > start))
            start = sf.getStart();

          if ((Strand.valueOf(sf.getStrand()) == Strand.FORWARD && sf.getEnd() > end)
              || (Strand.valueOf(sf.getStrand()) == Strand.REVERSE && sf.getEnd() < end))
            end = sf.getEnd();
        }
      }

      if (bp <= Math.min(start, end) || bp >= Math.max(start, end)) {
        this.state = State.OUT;
        base = '\0';
      }
    } else {
      this.state = State.OUT;
      base = '\0';
    }

    if (!(state == State.SHIFT || state == State.ERROR)
        && getRegionLow() <= position
        && position <= getRegionHigh()) {
      this.state = State.SELECTED;
      base = tier.charAt(oldPos);
    }

    init(base);
    return this;
  }
  /**
   * Right mouse: highlight base. Left mouse: figure dragType, dragFeature, dragStartPos,
   * startDragTier
   */
  public void mousePressed(MouseEvent e) {
    setPos(e.getX(), e.getY());

    // show base at right mouse click highlighted (on release - popup menu)
    if (MouseButtonEvent.isRightMouseClickNoShift(e)) {
      BaseRenderer rend = baseEditorPanel.getRendererAt(tier);
      if (rend instanceof SelectableDNARenderer) {
        ((SelectableDNARenderer) rend).setTargetPos(pos, tier);
        baseEditorPanel.repaint();
        return;
      }
    }

    if (!MouseButtonEvent.isLeftMouseClick(e)) return;

    if (dragStartPos == -1) {

      if (e.isControlDown()) dragType = baseEditorPanel.SEQ_SELECT_DRAG;
      else dragType = baseEditorPanel.getBoundaryType(pos, tier);

      dragFeature = baseEditorPanel.getFeatureAtPosition(pos, tier);

      dragStartPos = pos;
      startPos = pos;
      startDragTier = tier;
      if (dragFeature == null
          && ((dragType != baseEditorPanel.SEQ_SELECT_DRAG)
              || startDragTier > baseEditorPanel.getTierCount()
              || startDragTier < 3)) {
        resetDragState();
        return;
      }

      if (dragType == baseEditorPanel.START_BOUNDARY) {
        /* the 5 prime edge of the feature (exon) can
        be moved within limits. These are no farther
        in the 3prime direction than the end of the
        feature and no farther in the 5prime direction
        than the beginning (5prime) of the preceding
        intron */
        limit_3prime = (int) dragFeature.getEnd();
        int lowBound = baseEditorPanel.basePairToPos(dragFeature.getStart());
        // subtract one to move into the preceding intron
        double[] lowRange = baseEditorPanel.getRangeAtPosition(tier, lowBound - 1);
        if (lowRange[0] < 0) limit_5prime = baseEditorPanel.posToBasePair(0);
        else limit_5prime = baseEditorPanel.posToBasePair((int) lowRange[0]);
        baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
      } else if (dragType == baseEditorPanel.END_BOUNDARY) {
        limit_5prime = (int) dragFeature.getStart();
        int highBound = baseEditorPanel.basePairToPos((int) dragFeature.getEnd());
        double[] highRange = baseEditorPanel.getRangeAtPosition(tier, highBound + 1);
        SequenceI seq = baseEditorPanel.getSequenceForTier(tier);
        if (highRange[1] > seq.getLength())
          limit_3prime = baseEditorPanel.posToBasePair(seq.getLength());
        else limit_3prime = baseEditorPanel.posToBasePair((int) highRange[1]);
        baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
      } else if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) {
        baseEditorPanel.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
        baseEditorPanel.setSelectBeginPos(pos);
        baseEditorPanel.setSelectCurrentPos(pos);
      }
    }
  }
  /**
   * If right mouse deselect base If end of feature drag notify AnnotationEditor (endRangeChange)
   * and recalc translation end from start
   */
  public void mouseReleased(MouseEvent e) {

    // RIGHT MOUSE CLICK
    if (MouseButtonEvent.isRightMouseClick(e)) {
      BaseRenderer rend = baseEditorPanel.getRendererAt(tier);
      if (rend instanceof SelectableDNARenderer) {
        ((SelectableDNARenderer) rend).setTargetPos(-1, -1);
        baseEditorPanel.repaint();
      }
    }

    // SEQ SELECT DRAG
    if (dragType == baseEditorPanel.SEQ_SELECT_DRAG) {
      SequenceI seq = baseEditorPanel.getSequenceForTier(startDragTier);
      int lowBP = baseEditorPanel.posToResidue(baseEditorPanel.selectLowPos());
      int highBP = baseEditorPanel.posToResidue(baseEditorPanel.selectHighPos());
      String sequence = seq.getResidues(lowBP, highBP);

      String header = " Arbitrary selection (" + seq.getName() + ": " + lowBP + "," + highBP + ")";

      // controllingWindow.copySeqToClipboard(new Sequence (header, sequence));
      ClipboardUtil.copySeqToClipboard(new Sequence(header, sequence));

      resetDragState();
      baseEditorPanel.repaint();
      return;
    }

    // NOT SEQ SELECT DRAG
    else {

      // NOT DRAGGING - RETURN
      if (!MouseButtonEvent.isLeftMouseClick(e) || !dragging || dragFeature == null) {
        resetDragState();
        return;
      }

      // DRAGGING ANNOT ENDS
      if (dragging && dragFeature != null && dragFeature.isAnnot()) {

        // NOTIFY ANNOTATION EDITOR (generates transaction)
        int oldStart = (preDragStartBasePair == -1) ? dragFeature.getStart() : preDragStartBasePair;
        int oldEnd = (preDragEndBasePair == -1) ? dragFeature.getEnd() : preDragEndBasePair;
        AnnotationEditor ae = baseEditorPanel.getAnnotationEditor();
        ae.setAnnotTerminus(
            dragFeature.getAnnotatedFeature(),
            oldStart,
            oldEnd,
            dragFeature.getStart(),
            dragFeature.getEnd());

        // RECALC CDS (if exon/transcript - not for 1 level annots)
        if (dragFeature.isExon()
            && dragFeature.getRefFeature() != null
            && (dragFeature.getRefFeature().isTranscript())) {
          // ExonI exon = (ExonI)dragFeature;
          // Transcript t = (Transcript)exon.getRefFeature();
          SeqFeatureI transcript = dragFeature.getRefFeature();
          TranslationI cds = transcript.getTranslation();
          int transStart = transcript.getStart();
          int cdsStart = cds.getTranslationStart();
          boolean isForward = transcript.isForwardStrand();
          if (cds.isMissing5prime()
              && ((isForward && transStart < cdsStart) || (!isForward && transStart > cdsStart))) {
            cds.calcTranslationStartForLongestPeptide(); // missing start
          } else {
            cds.setTranslationEndFromStart(); // got start - set end
          }
        }

        baseEditorPanel.repaint();
      }
    }

    resetDragState();
    baseEditorPanel.getCurationState().getSZAP().repaint();
  }