/**
   * Sets up transcriptComboBox (pulldown list) with transcript and its parent gene's other
   * transcripts, with transcript selected
   */
  private void setupTranscriptComboBox(AnnotatedFeatureI annot) {
    // could also check for gene change before doing a removeAll
    if (transcriptComboBox.getSelectedItem() == annot) return;
    // adding and removing items causes item events to fire so need to remove
    // listener here - is there any other way to supress firing?
    transcriptComboBox.removeItemListener(transItemListener);
    transcriptComboBox.removeAllItems();
    if (annot == null) {
      transcriptComboBox.addItem("<no feature selected>");
      return;
    }

    // 1 LEVEL ANNOT
    if (annot.isAnnotTop()) {
      transcriptComboBox.addItem(annot);
      return;
    }

    // TRANSCRIPT
    SeqFeatureI gene = annot.getRefFeature();
    Vector transcripts = gene.getFeatures();
    for (int i = 0; i < transcripts.size(); i++)
      transcriptComboBox.addItem(transcripts.elementAt(i));
    transcriptComboBox.setSelectedItem(annot); // transcript
    transcriptComboBox.addItemListener(transItemListener);
  }
  private BaseFineEditor(
      AnnotatedFeatureI editMe, GuiCurationState curationState, SeqFeatureI geneHolder) {

    super((editMe.isForwardStrand() ? "Forward" : "Reverse") + " Strand Exon Editor");
    this.curationState = curationState;
    curationState.getController().addListener(this);
    curationState.getController().addListener(new BaseEditorDataListener());
    szap = curationState.getSZAP();
    transformer = szap.getScaleView().getTransform();
    int seqStart = curationState.getCurationSet().getLow();
    int seqEnd = curationState.getCurationSet().getHigh();

    // FeatureSetI annFeatSet=((DrawableFeatureSet)view.getDrawableSet()).getFeatureSet();
    editorPanel =
        new BaseEditorPanel(
            curationState, this, !editMe.isForwardStrand(), seqStart, seqEnd, geneHolder);

    initGui(editMe); // cant do til after editorPanel made
    // cant do this til after initGui (editorPanel needs to know size)
    editorPanel.displayAnnot(editMe);
    attachListeners();
    showEditRegion();
    displayAnnot(getTransOrOneLevelAnn(editMe));
    translationViewer.repaint();
    setVisible(true);
    // Might just be linux, but bofe gets iconified on close
    if (getState() == Frame.ICONIFIED) setState(Frame.NORMAL);
  }
  private BaseFineEditor(
      AnnotatedFeatureI editMe,
      GuiCurationState curationState,
      SeqFeatureI geneHolder,
      Set<SeqFeatureI> selectedResults) {

    super((editMe.isForwardStrand() ? "Forward" : "Reverse") + " Strand Exon Editor");
    this.curationState = curationState;
    curationState.getController().addListener(this);
    curationState.getController().addListener(new BaseEditorDataListener());
    szap = curationState.getSZAP();
    transformer = szap.getScaleView().getTransform();
    int seqStart = curationState.getCurationSet().getLow();
    int seqEnd = curationState.getCurationSet().getHigh();
    CurationSet s = curationState.getCurationSet();
    // FeatureSetI annFeatSet=((DrawableFeatureSet)view.getDrawableSet()).getFeatureSet();

    // REFACTOR BaseEditorPanel - (what allows for selection and modification of the annotations?)
    // create BaseViewPanel -> have BaseEditorPanel extend it
    // take the header outside of the editorPanel (is it really inside right now?)
    // create a new panel using BaseViewPanel

    /*
     * The viewable components of the new BaseFineEditor (should this be renamed?):
     *
     *  1) The Genomic Strand
     *  2) The Annotations (will these always be a copy of the genomic strand?)
     *         q1) Can annotations also be nucliotides? - A: Yes. Create a separate view for those.
     *         q2) Does it make sense to view both the forward and reverse strand at once?
     *         q3) How do we know what to load - A: highlight the region we want to look at?
     *         q4) Will we expect users to be able to view many annotations at once?
     *         q4) How will the user know which annotation they are looking at? - A: Display the name when hovering over?
     *  3) The Results
     *         q1) See above questions.
     *  4) Result Score information
     *  5) An overview - Right now this is at the transcript (gene model?) level
     *         q1) What should be contained in this view?
     *
     *
     */

    // I think that right now every base in the ede is a copy of the genomic, will that always be
    // the case?
    // is there ever sequence associated with an annotation.
    editorPanel =
        new BaseEditorPanel(
            curationState, this, !editMe.isForwardStrand(), seqStart, seqEnd, geneHolder);

    addResults(selectedResults);
    initGui(editMe); // cant do til after editorPanel made
    // cant do this til after initGui (editorPanel needs to know size)
    editorPanel.displayAnnot(editMe);
    attachListeners();
    showEditRegion();
    displayAnnot(getTransOrOneLevelAnn(editMe));
    translationViewer.repaint();
    setVisible(true);
    // Might just be linux, but bofe gets iconified on close
    if (getState() == Frame.ICONIFIED) setState(Frame.NORMAL);
  }
  /** 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();
      }
    }
  }
  /*  Start AnnotationChangeListenter interface */
  public boolean handleAnnotationChangeEvent(AnnotationChangeEvent evt) {
    if (this.isVisible() && evt.getSource() != this) {
      if (evt.isCompound()) {
        for (int i = 0; i < evt.getNumberOfChildren(); ++i) {
          handleAnnotationChangeEvent(evt.getChildChangeEvent(i));
        }
        reformatAnnotationPanel();
        return true;
      }

      // can probably be done better, this will reformat the panel a lot
      reformatAnnotationPanel();

      if (evt.isEndOfEditSession()) {

        getOverview().updateState();
        setSelection(getSelection());
        updateEditRegion();

        repaint();
        updateTitle();
      }

      if (evt.isAdd()) {
        AnnotatedFeatureI annotToDisplay = null;
        AnnotatedFeatureI gene = evt.getChangedAnnot();
        int trans_count = gene.size();
        for (int i = 0; i < trans_count; ++i) {
          Transcript t = (Transcript) gene.getFeatureAt(i);
          if (evt.isUndo()) {
            // System.out.printf("Attaching %s(%d)\n", t, t.hashCode());
            // addFeatureToPanel(t, getAnnotationPanel());
            if (getSelection() != null && t.getName().equals(getSelection().getName())) {
              annotToDisplay = t;
            }
          }
        }

        if (annotToDisplay == null) {
          annotToDisplay = (AnnotatedFeatureI) evt.getChangedAnnot().getFeatureAt(0);
        } else {
          setSelection(annotToDisplay);
        }

        getOverview().updateState();
      }

      if (evt.isDelete()) {}
    }

    repaint();
    return true;
  }
 /** Both fires off selection event and displays annot */
 private void selectAnnot(AnnotatedFeatureI annot) {
   displayAnnot(getTransOrOneLevelAnn(annot));
   translationViewer.repaint();
   BaseFocusEvent evt = new BaseFocusEvent(this, annot.getStart(), annot);
   getController().handleBaseFocusEvent(evt);
   getSelectionManager().select(annot, this); // sends off selection
 }
  public static void test(
      GuiCurationState curationState, int strand, Selection selection, String type) {

    JFrame frame = new JFrame("TopLevelDemo");

    MultiSequenceAlignerFrame msa =
        MultiSequenceAlignerFrame.makeAligner(
            curationState, strand,
            selection, type);
    msa.setPreferredSize(new Dimension(1000, 800));
    msa.pack();
    msa.setVisible(true);

    AnnotatedFeatureI gai = getFirstAnnot(selection);

    if (gai != null) {
      msa.getPanel().scrollToBase(gai.getStart());
      msa.getPanel().setSelection(gai);
    }
  }
  public void setGene(AnnotatedFeatureI g) {
    this.gene = g;
    if (g == null) return;

    if (!g.isProteinCodingGene()) {
      setText("NOT A PEPTIDE");
      setEnabled(false);
    } else {
      setEnabled(true);

      Hashtable curator_values = Config.getPeptideStates();

      String pep_status = g.getProperty("sp_status");
      PeptideStatus this_status = Config.getPeptideStatus(pep_status);

      JMenuItem item;

      /* these are the computed values that cannot be over-ridden
         by a curator
      */
      item = new JMenuItem(this_status.getText());
      add(item);
      item.addActionListener(this);
      /* these are the possible values to be selected
      by a curator */
      Enumeration e = curator_values.keys();
      while (e.hasMoreElements()) {
        String key = (String) e.nextElement();
        PeptideStatus a_status = (PeptideStatus) curator_values.get(key);
        if (a_status.getPrecedence() >= this_status.getPrecedence()
            && !a_status.getText().equals(this_status.getText())
            && a_status.getCurated()) {
          item = new JMenuItem(a_status.getText());
          add(item);
          item.addActionListener(this);
        }
      }
      setText(this_status.getText());
    }
  }
  /** Scrolls the window to the start/end of the next annotation to the left */
  public void prevAnnotation() {
    int basepair = getVisibleBase();
    int offset = getType().equals("AA") ? 3 : 1;
    basepair += (getVisibleBaseCount() - offset) * getStrand().toInt();

    int position =
        getAnnotationPanel()
            .tierPositionToPixelPosition(getAnnotationPanel().basePairToTierPosition(basepair));

    SeqFeatureI feature = getAnnotationPanel().getPrevFeature(position);

    if (feature != null) {

      // get highest pixel position
      position = getAnnotationPanel().getHigh(feature);

      position =
          getType().equals("AA")
              ? position - (getVisibleBaseCount() / 3)
              : position - getVisibleBaseCount();
      position = getAnnotationPanel().pixelPositionToTierPosition(position);
      int bp = getAnnotationPanel().tierPositionToBasePair(position);
      scrollToBase(bp);

      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()) {
        prevAnnotation();
      }
    }
  }
 public void actionPerformed(ActionEvent e) {
   JMenuItem item = (JMenuItem) e.getSource();
   // This should probably be done in AnnotationEditor changeSpStatus(gene,item...
   gene.addProperty("sp_status", item.getText());
   // AnnotationChangeEvent ace = AnnotationChangeEvent.getSessionDoneEvent(this);
   AnnotSessionDoneEvent de = new AnnotSessionDoneEvent(this);
   //     = new AnnotationChangeEvent(this,
   //                                 gene,
   //                                 FeatureChangeEvent.REDRAW,
   //                                 AnnotationChangeEvent.ANNOTATION,
   //                                 gene);
   getController().handleAnnotationChangeEvent(de);
 }
 /**
  * AssemblyFeature is the only GAI at the moment that has no relation to // a transcript. Dont
  * think they can end up in ede (??). // Would be nice to have an interface that was solely for
  * the exon // trans gene heirarchy? Should we actively make sure AssemblyFeatures dont // get
  * into ede? (filter in AnnotationMenu?) returns null if no transcript can be found.
  */
 private AnnotatedFeatureI getTransOrOneLevelAnn(AnnotatedFeatureI af) {
   if (af != null) {
     if (af.isTranscript()) return af;
     if (af.isExon()) return af.getRefFeature().getAnnotatedFeature();
     if (af.isAnnotTop()) {
       if (af.hasKids()) return af.getFeatureAt(0).getAnnotatedFeature(); // transcript
       else // 1 level annot
       return af;
     }
   }
   return null;
 }
  /**
   * Display AnnotatedFeatureI feature. Exon, Transcript, and Gene are all GenericAnnotationI. No
   * selection event is fired. (selectAnnot fires and displays)
   */
  private void displayAnnot(AnnotatedFeatureI annot) {
    currentAnnot = annot;
    if (currentAnnot == null) {
      transcriptComboBox.removeAllItems();
      transcriptComboBox.addItem("<no feature selected>");
      lengthLabel.setText("Translation length: <no feature selected>");
      upstream_button.setLabel("");
      downstream_button.setLabel("");
      translationViewer.setTranscript(null, editorPanel.getSelectedTier()); // ??
      return;
    }

    // else {
    setupTranscriptComboBox(currentAnnot);

    SeqFeatureI topAnnot = currentAnnot;
    if (topAnnot.isTranscript()) topAnnot = currentAnnot.getRefFeature();
    if (topAnnot.isProteinCodingGene()) {
      String translation = currentAnnot.translate();
      if (translation == null) {
        lengthLabel.setText("Translation length: <no start selected>");
      } else {
        lengthLabel.setText("Translation length: " + currentAnnot.translate().length());
      }
    } else {
      lengthLabel.setText(topAnnot.getFeatureType() + " annotation");
    }
    FeatureSetI holder = (FeatureSetI) topAnnot.getRefFeature();
    neighbor_up = null;
    neighbor_down = null;
    if (holder != null) {

      int index = holder.getFeatureIndex(topAnnot);
      // get next neighbor up that has whole sequence
      for (int i = index - 1; i >= 0 && neighbor_up == null; i--) {
        FeatureSetI gene_sib = (FeatureSetI) holder.getFeatureAt(i);
        if (gene_sib.getFeatureAt(0) instanceof Transcript) {
          Transcript trans = (Transcript) gene_sib.getFeatureAt(0);
          if (trans.haveWholeSequence()) // szap.getCurationSet()))
          neighbor_up = trans;
        }
      }

      // get next neighbor down that has whole sequence
      for (int i = index + 1; i < holder.size() && neighbor_down == null; i++) {
        FeatureSetI gene_sib = (FeatureSetI) holder.getFeatureAt(i);
        if (gene_sib.getFeatureAt(0) instanceof Transcript) {
          Transcript trans = (Transcript) gene_sib.getFeatureAt(0);
          if (trans.haveWholeSequence()) // szap.getCurationSet()))
          neighbor_down = trans;
        }
      }
    }
    upstream_button.setLabel(
        neighbor_up == null
            ? ""
            : "Go to next 5' annotation (" + neighbor_up.getParent().getName() + ")");
    upstream_button.setVisible(neighbor_up != null);
    downstream_button.setLabel(
        neighbor_down == null
            ? ""
            : "Go to next 3' annotation (" + neighbor_down.getParent().getName() + ")");
    downstream_button.setVisible(neighbor_down != null);
    // }
    // todo - translationViewer take in 1 level annot
    if (currentAnnot.isTranscript())
      translationViewer.setTranscript((Transcript) currentAnnot, editorPanel.getSelectedTier());
  }
  private void initGui(AnnotatedFeatureI annot) {
    translationViewer = new TranslationViewer(editorPanel);
    translationViewer.setBackground(Color.black);
    transcriptComboBox = new JComboBox();
    lengthLabel = new JLabel("Translation length: <no feature selected>");
    lengthLabel.setForeground(Color.black);
    findButton = new JButton("Find sequence...");
    clearFindsButton = new JButton("Clear search hits");
    // Disable until we actually get search results
    clearFindsButton.setEnabled(false);

    goToButton = new JButton("GoTo...");
    showIntronBox = new JCheckBox("Show introns in translation viewer", true);
    showIntronBox.setBackground(Color.white);
    followSelectionCheckBox = new JCheckBox("Follow external selection", false);
    followSelectionCheckBox.setBackground(Color.white);
    upstream_button = new JButton();
    downstream_button = new JButton();

    colorSwatch = new JPanel();

    setSize(824, 500);
    JScrollPane pane = new JScrollPane(editorPanel);
    pane.setHorizontalScrollBarPolicy(
        JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); // RAY: SET SCROLL POLICY HERE! WAS
    // HORIZONTAL_SCROLLBAR_NEVER

    // pane.setColumnHeaderView(new BaseFineEditorRowHeader(editorPanel)); // RAY: setRowHeader need
    // to create column header
    pane.setColumnHeaderView(new BaseFineEditorHorizontalColHeader(editorPanel));
    viewport = pane.getViewport();
    colorSwatch.setPreferredSize(new Dimension(10, 10));

    getContentPane().setBackground(Color.white);
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(colorSwatch, "North");
    getContentPane().add(pane, "Center");

    Box transcriptListBox = new Box(BoxLayout.X_AXIS);
    JLabel tranLabel;
    // 1 LEVEL ANNOT
    if (annot.isAnnotTop()) tranLabel = new JLabel("Annotation: ");
    else // 3-level
    tranLabel = new JLabel("Transcript: ");
    tranLabel.setForeground(Color.black);
    transcriptListBox.add(Box.createHorizontalStrut(5));
    transcriptListBox.add(tranLabel);
    transcriptListBox.setBackground(Color.white);
    transcriptComboBox.setMaximumSize(new Dimension(300, 30));
    transcriptListBox.add(transcriptComboBox);
    transcriptListBox.add(Box.createHorizontalGlue());
    transcriptListBox.add(Box.createHorizontalStrut(5));
    transcriptListBox.add(lengthLabel);
    transcriptListBox.add(Box.createHorizontalGlue());

    Box checkboxesTop = new Box(BoxLayout.X_AXIS);
    checkboxesTop.setBackground(Color.white);
    checkboxesTop.add(Box.createHorizontalStrut(5));
    checkboxesTop.add(findButton);
    checkboxesTop.add(Box.createHorizontalStrut(10));
    checkboxesTop.add(clearFindsButton);
    checkboxesTop.add(Box.createHorizontalStrut(15));
    checkboxesTop.add(goToButton);
    checkboxesTop.add(Box.createHorizontalGlue());
    Box checkboxesBottom = new Box(BoxLayout.X_AXIS);
    checkboxesBottom.add(showIntronBox);
    checkboxesBottom.add(Box.createHorizontalGlue());
    checkboxesBottom.add(Box.createHorizontalStrut(10));
    checkboxesBottom.add(followSelectionCheckBox);
    Box checkboxes = new Box(BoxLayout.Y_AXIS);
    checkboxes.add(checkboxesTop);
    checkboxes.add(checkboxesBottom);

    Box labelPanel = new Box(BoxLayout.Y_AXIS);
    labelPanel.setBackground(Color.white);
    labelPanel.add(transcriptListBox);
    labelPanel.add(Box.createVerticalStrut(5));
    labelPanel.add(checkboxes);

    Box navPanel = new Box(BoxLayout.Y_AXIS);
    navPanel.setBackground(Color.white);
    navPanel.add(upstream_button);
    navPanel.add(Box.createVerticalStrut(10));
    navPanel.add(downstream_button);
    navPanel.add(Box.createVerticalGlue());

    Box textBoxes = new Box(BoxLayout.X_AXIS);
    textBoxes.setBackground(Color.white);
    textBoxes.add(labelPanel);
    textBoxes.add(navPanel);

    Box detailPanel = new Box(BoxLayout.Y_AXIS);
    detailPanel.setBackground(Color.white);
    detailPanel.add(translationViewer);
    detailPanel.add(textBoxes);
    getContentPane().add(detailPanel, "South");

    validateTree();
    scrollListener = new FineEditorScrollListener();
    viewport.addChangeListener(scrollListener);

    transcriptComboBox.addKeyListener(
        new KeyAdapter() {
          public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_U && (e.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
              CurationManager.getActiveCurationState().getTransactionManager().undo(this);
            }
          }
        });
  }
  public boolean handleAnnotationChangeEvent(AnnotationChangeEvent evt) {
    if (this.isVisible() && evt.getSource() != this) {
      if (evt.isCompound()) {
        for (int i = 0; i < evt.getNumberOfChildren(); ++i) {
          handleAnnotationChangeEvent(evt.getChildChangeEvent(i));
        }
        return true;
      }

      if (evt.isEndOfEditSession()) {
        // Dont want scrolling on ann change, also sf for redraw is the
        // gene, so it just goes to 1st trans which is problematic.
        displayAnnot(currentAnnot);
        repaint(); // this is the needed repaint after the changes
        return true;
      }

      /*
      AnnotatedFeatureI gene = evt.getChangedAnnot();
      for (Object o : szap.getAnnotations().getFeatures()) {
        AnnotatedFeatureI feat = (AnnotatedFeatureI)o;
        if (feat.getId().equals(gene.getId())) {
          //gene = feat;
          break;
        }
      }
      */

      if (evt.isAdd()) {
        AnnotatedFeatureI annotToDisplay = null;
        AnnotatedFeatureI gene = evt.getChangedAnnot();
        int trans_count = gene.size();
        for (int i = 0; i < trans_count; ++i) {
          Transcript t = (Transcript) gene.getFeatureAt(i);
          if (evt.isUndo()) {
            // System.out.printf("Attaching %s(%d)\n", t, t.hashCode());
            editorPanel.attachAnnot(t);
            if (currentAnnot != null && t.getName().equals(currentAnnot.getName())) {
              annotToDisplay = t;
            }
          }
        }
        if (annotToDisplay == null) {
          annotToDisplay = (AnnotatedFeatureI) evt.getChangedAnnot().getFeatureAt(0);
        }
        displayAnnot(annotToDisplay);
        return true;
      }

      if (evt.isDelete()) {
        AnnotatedFeatureI gene = evt.getChangedAnnot();
        int trans_count = gene.size();
        for (int i = 0; i < trans_count; ++i) {
          if (evt.isUndo()) {
            Transcript t = (Transcript) gene.getFeatureAt(i);
            // System.out.printf("Detaching %s(%d)\n", t, t.hashCode());
            editorPanel.detachTranscript(t);
          }
        }
        return true;
      }

      /*
            // getAnnotation() can be null after a delete - return if null?
            SeqFeatureI sf = evt.getAnnotTop();

            // If the annotation event is not for the editors strand then return
            boolean is_reverse = (sf.getStrand() == -1);
            if (editorPanel.getReverseStrand() != is_reverse)
              return false;

            if (evt.isDelete() && evt.isRootAnnotChange()) {
              AnnotatedFeatureI gene = evt.getChangedAnnot();
              int trans_count = gene.size();
              for (int i = 0; i < trans_count; i++) {
                Transcript t = (Transcript) gene.getFeatureAt (i);
                editorPanel.detachTranscript (t);
                if (t == currentAnnot)
                  currentAnnot = null;
              }
            } else if (evt.isDelete() && evt.isTranscriptChange()) {
              Transcript t = (Transcript) evt.getChangedAnnot();
              editorPanel.detachTranscript (t);
              if (t == currentAnnot)
                currentAnnot = null;
            } else if ((evt.isAdd() || evt.isSplit() || evt.isMerge()) &&
                       evt.isRootAnnotChange()) {
              AnnotatedFeatureI gene = evt.getChangedAnnot();
              int trans_count = gene.size();
              for (int i = 0; i < trans_count; i++) {
                Transcript t = (Transcript) gene.getFeatureAt (i);
                int tier = editorPanel.attachAnnot (t);
              }
            } else if (evt.isAdd() && evt.isTranscriptChange()) {
              Transcript t = (Transcript) evt.getChangedAnnot();
              int tier = editorPanel.attachAnnot (t);
            }
            // Exon split or intron made - same thing isnt it?
            else if (evt.isAdd() && evt.isExonChange()) {
              Transcript t = (Transcript) evt.getParentFeature();
              // removing and adding transcript will force editorPanel
              // to pick up new exon
              editorPanel.detachTranscript(t);
              editorPanel.attachAnnot(t);
            }
            else if (evt.isDelete() && evt.isExonChange()) {
              Transcript t = (Transcript) evt.getParentFeature();
              // removing and adding transcript will force editorPanel to remove exon
              editorPanel.detachTranscript(t);
              editorPanel.attachAnnot(t);
              // or editorPanel.removeFeature((Exon)evt.getSecondFeature());
            }
      //       else if (evt.isReplace()) { //&&evt.isTopAnnotChange - always true of replace
      //         AnnotatedFeatureI old_gene = evt.getReplacedFeature();
      //         AnnotatedFeatureI new_gene = (AnnotatedFeatureI)evt.getChangedFeature();
      //         int trans_count = old_gene.size();
      //         /* This does assume that there are no changes in the number
      //            of transcripts between the old and the new. Might be safer
      //            to separate the 2 loops */
      //         for (int i = 0; i < trans_count; i++) {
      //           Transcript t;
      //           t = (Transcript) old_gene.getFeatureAt (i);
      //           editorPanel.detachTranscript (t);
      //           t = (Transcript) new_gene.getFeatureAt (i);
      //           int tier = editorPanel.attachTranscript (t);
      //         }
      //         // This is so that we don't select a different transcript
      //         AnnotatedFeatureI current_gene = (current_transcript != null ?
      //                                           current_transcript.getGene() : null);
      //         if (current_gene != null && current_gene == old_gene) {
      //           int index = current_gene.getFeatureIndex(current_transcript);
      //           current_transcript = (Transcript) new_gene.getFeatureAt(index);
      //         }
      //       }
      // this isnt possible - all replaces are for top annots
      //       else if (evt.isReplace() && evt.isTranscriptChange()) {
      //         Transcript old_trans = (Transcript)evt.getReplacedFeature();
      //         Transcript new_trans = (Transcript)evt.getChangedFeature();
      //         editorPanel.detachTranscript (old_trans);
      //         int tier = editorPanel.attachTranscript (new_trans);
      //         // This is so that we don't select a different transcript
      //         if (current_transcript != null && current_transcript == old_trans) {
      //           current_transcript = new_trans;
      //         }
      //       }
    }

    return true;
  }
예제 #15
0
  /** For annotations, try to find the appropriate identifier to add to the base URL. */
  protected String generateAnnotURL(AnnotatedFeatureI g, String baseAnnotURL) {
    if (baseAnnotURL == null || baseAnnotURL.equals("")) return null;

    Hashtable id_hash = new Hashtable();

    String id;
    for (int i = 0; i < g.getDbXrefs().size(); i++) {
      DbXref ref = (DbXref) g.getDbXrefs().elementAt(i);
      id = ref.getIdValue();
      // Apparently, if the id starts with FBan we want to replace "FBan" with "CG".
      if (id.startsWith("FBan")) {
        id = id.substring("FBan".length());
        try {
          int cg_num = Integer.parseInt(id);
          id = "CG" + cg_num;
          id_hash.put(id, id);
        } catch (Exception e) {
        }
      } else if (id.startsWith("FB")) { // FBgn, FBab, etc.
        id_hash.put(id, id);
      } else if (id.startsWith("TE")) { // FBgn, FBab, etc.
        id_hash.put(id, id);
      }
    }

    id = getCG(g.getId(), "CG");
    if (id != null) id_hash.put(id, id);
    else {
      id = getCG(g.getId(), "CR");
      if (id != null) id_hash.put(id, id);
      else {
        id = getCG(g.getId(), "FB");
        if (id != null) id_hash.put(id, id);
      }
    }

    id = getCG(g.getName(), "CG");
    if (id != null) id_hash.put(id, id);
    else {
      id = getCG(g.getName(), "CR");
      if (id != null) id_hash.put(id, id);
    }

    for (int i = 0; i < g.getSynonyms().size(); i++) {
      Synonym syn = (Synonym) (g.getSynonyms().elementAt(i));
      id = getCG(syn.getName(), "CG");
      if (id != null) id_hash.put(id, id);
      else {
        id = getCG(syn.getName(), "CR");
        if (id != null) id_hash.put(id, id);
        else {
          id = getCG(g.getId(), "FB");
          if (id != null) id_hash.put(id, id);
        }
      }
    }

    // The code here was glomming together all the elements into one
    // big |ed string, but that's not what the FlyBase annotation report CGI wants.
    // An FB or CG or CR identifier should be sufficient.
    StringBuffer query_str = new StringBuffer();
    for (Enumeration e = id_hash.elements(); e.hasMoreElements(); ) {
      String namepart = (String) e.nextElement();
      //      System.out.println("Considering namepart " + namepart); // DEL
      if (namepart.indexOf("FB") == 0
          || namepart.indexOf("CG") == 0
          || namepart.indexOf("CR") == 0) {
        if (query_str.length() > 0) query_str.replace(0, query_str.length(), namepart);
        else query_str.append(namepart);
        break;
      }
      if (query_str.length() > 0) query_str.append('|');
      query_str.append(namepart);
    }

    // if not FlyBase ID, use the annotation's regular ID
    if (query_str.length() == 0) {
      query_str.append(g.getId());
    }

    String url = null;
    //    System.out.println("generateAnnotUrl: query = " + query_str); // DEL
    if (query_str.length() > 0) {
      // if a custom URL is setup for this type in the tiers file, use that - otherwise use the
      // global
      // one setup in the style file
      FeatureProperty fp = Config.getPropertyScheme().getFeatureProperty(g.getTopLevelType());
      if (fp.getURLString() != null && fp.getURLString().length() > 0) {
        url = fp.getURLString() + g.getId();
      } else {
        url = baseAnnotURL + query_str.toString();
      }
    }

    return url;
  }