Newer
Older
/* EditMenu.java
*
* created: Thu Dec 3 1998
*
* This file is part of Artemis
*
* Copyright (C) 1998,1999,2000,2001,2002 Genome Research Limited
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/EditMenu.java,v 1.39 2008-01-14 17:18:25 tjc Exp $
**/
package uk.ac.sanger.artemis.components;
import uk.ac.sanger.artemis.*;
import uk.ac.sanger.artemis.sequence.*;
import uk.ac.sanger.artemis.util.*;
import uk.ac.sanger.artemis.components.genebuilder.GeneBuilderFrame;
import uk.ac.sanger.artemis.components.genebuilder.GeneUtils;
import uk.ac.sanger.artemis.components.genebuilder.GeneViewerPanel;
import uk.ac.sanger.artemis.io.ChadoCanonicalGene;
import uk.ac.sanger.artemis.io.Range;
import uk.ac.sanger.artemis.io.RangeVector;
import uk.ac.sanger.artemis.io.Key;
import uk.ac.sanger.artemis.io.Location;
import uk.ac.sanger.artemis.io.Qualifier;
import uk.ac.sanger.artemis.io.QualifierVector;
import uk.ac.sanger.artemis.io.InvalidRelationException;
import uk.ac.sanger.artemis.io.EntryInformation;
import uk.ac.sanger.artemis.io.EntryInformationException;
import uk.ac.sanger.artemis.io.OutOfDateException;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;
import java.text.DecimalFormat;
import java.text.NumberFormat;
/**
* A menu with editing commands.
*
* @author Kim Rutherford
* @version $Id: EditMenu.java,v 1.39 2008-01-14 17:18:25 tjc Exp $
implements EntryGroupChangeListener, EntryChangeListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* The GotoEventSource object that was passed to the constructor.
**/
private GotoEventSource goto_event_source = null;
/**
* The EntryGroup object that was passed to the constructor.
**/
private EntryGroup entry_group = null;
/**
* The BasePlotGroup object that was passed to the constructor.
**/
private BasePlotGroup base_plot_group = null;
public static org.apache.log4j.Logger logger4j =
org.apache.log4j.Logger.getLogger(EditMenu.class);
/**
* Create a new EditMenu object.
* @param frame The JFrame that owns this JMenu.
* @param selection The Selection that the commands in the menu will
* operate on.
* @param goto_event_source The object the we will call makeBaseVisible()
* on.
* @param entry_group The EntryGroup object where new features/entries will
* be added.
* @param base_plot_group The BasePlotGroup associated with this JMenu -
* needed to call getCodonUsageAlgorithm()
* @param menu_name The name of the new menu.
**/
public EditMenu(final JFrame frame,
final Selection selection,
final GotoEventSource goto_event_source,
final EntryGroup entry_group,
final BasePlotGroup base_plot_group,
{
super(frame, menu_name, selection);
this.entry_group = entry_group;
this.goto_event_source = goto_event_source;
this.base_plot_group = base_plot_group;
getEntryGroup().addEntryGroupChangeListener(this);
getEntryGroup().addEntryChangeListener(this);
refreshMenu();
}
/**
* Create a new EditMenu object and use "Edit" as the menu name.
* @param frame The JFrame that owns this JMenu.
* @param selection The Selection that the commands in the menu will
* operate on.
* @param goto_event_source The object the we will call makeBaseVisible()
* on.
* @param entry_group The EntryGroup object where new features/entries will
* be added.
* @param base_plot_group The BasePlotGroup associated with this JMenu -
* needed to call getCodonUsageAlgorithm()
**/
public EditMenu(final JFrame frame,
final Selection selection,
final GotoEventSource goto_event_source,
final EntryGroup entry_group,
final BasePlotGroup base_plot_group,
final DisplayComponent owner)
{
this(frame, selection, goto_event_source, entry_group,
}
/**
* The shortcut for Edit Selected Features.
**/
final static KeyStroke EDIT_FEATURES_KEY =
KeyStroke.getKeyStroke(KeyEvent.VK_E,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); //InputEvent.CTRL_MASK);
final static public int EDIT_FEATURES_KEY_CODE = KeyEvent.VK_E;
/**
* The shortcut for Merge Selected Features.
**/
final static KeyStroke MERGE_FEATURES_KEY =
KeyStroke.getKeyStroke(KeyEvent.VK_M,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); // InputEvent.CTRL_MASK);
final static public int MERGE_FEATURES_KEY_CODE = KeyEvent.VK_M;
/**
* The shortcut for Duplicate Selected Features.
**/
final static KeyStroke DUPLICATE_KEY =
KeyStroke.getKeyStroke(KeyEvent.VK_D,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); // InputEvent.CTRL_MASK);
final static public int DUPLICATE_KEY_CODE = KeyEvent.VK_D;
/**
* The shortcut for Delete Selected Features.
**/
final static KeyStroke DELETE_FEATURES_KEY =
KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); // InputEvent.CTRL_MASK);
final static public int DELETE_FEATURES_KEY_CODE = KeyEvent.VK_DELETE;
/**
* The shortcut for Trim Selected Features.
**/
final static KeyStroke TRIM_FEATURES_KEY =
KeyStroke.getKeyStroke(KeyEvent.VK_T,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); // InputEvent.CTRL_MASK);
final static public int TRIM_FEATURES_KEY_CODE = KeyEvent.VK_T;
/**
* The shortcut for Trim Selected Features To Next Any.
**/
final static KeyStroke TRIM_FEATURES_TO_NEXT_ANY_KEY =
KeyStroke.getKeyStroke(KeyEvent.VK_Y,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); // InputEvent.CTRL_MASK);
final static public int TRIM_FEATURES_TO_NEXT_ANY_KEY_CODE = KeyEvent.VK_Y;
/**
* The shortcut for Extend to Previous Stop Codon.
**/
final static public int EXTEND_TO_PREVIOUS_STOP_CODON_KEY_CODE =
KeyEvent.VK_Q;
final static KeyStroke EXTEND_TO_PREVIOUS_STOP_CODON_KEY =
makeMenuKeyStroke(EXTEND_TO_PREVIOUS_STOP_CODON_KEY_CODE);
/**
* The shortcut for Undo.
**/
final static public int UNDO_KEY_CODE = KeyEvent.VK_U;
final static KeyStroke UNDO_KEY =
KeyStroke.getKeyStroke(UNDO_KEY_CODE,
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()); // InputEvent.CTRL_MASK);
/**
* Implementation of the EntryGroupChangeListener interface. We listen to
* EntryGroupChange events so that we can update the display if entries
* are added or deleted.
**/
public void entryGroupChanged(final EntryGroupChangeEvent event)
{
switch(event.getType())
{
case EntryGroupChangeEvent.ENTRY_ADDED:
case EntryGroupChangeEvent.ENTRY_DELETED:
case EntryGroupChangeEvent.ENTRY_INACTIVE:
case EntryGroupChangeEvent.ENTRY_ACTIVE:
case EntryGroupChangeEvent.NEW_DEFAULT_ENTRY:
refreshMenu();
break;
}
}
/**
* Implementation of the EntryChangeListener interface.
**/
public void entryChanged(final EntryChangeEvent event)
{
if(event.getType() == EntryChangeEvent.NAME_CHANGED)
refreshMenu();
}
/**
* Update the menus to the reflect the current contents of the EntryGroup.
**/
private void refreshMenu()
{
removeAll();
final JMenuItem undo_item = new JMenuItem("Undo");
undo_item.setAccelerator(UNDO_KEY);
undo_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
undo(getParentFrame(), getSelection(), getEntryGroup());
final JMenuItem contig_reordering = new JMenuItem("Contig Reordering");
contig_reordering.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
FeatureDisplay display = (FeatureDisplay)owner;
FeatureVector contig_features = display.getContigs();
final JFrame frame = new JFrame("Contig Tool");
final ContigTool ct = new ContigTool(contig_features,
(FeatureDisplay)owner, jsp,
getSelection());
jsp.setViewportView(ct);
jsp.getViewport().setBackground(Color.white);
jsp.setPreferredSize(new Dimension(display.getWidth(),
ct.getPreferredSize().height+
jsp.getVerticalScrollBar().getPreferredSize().height));
frame.getContentPane().add(jsp, BorderLayout.CENTER);
frame.getContentPane().add(ct.getStatusBar(),
BorderLayout.SOUTH);
frame.pack();
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent event)
{
getSelection().removeSelectionChangeListener(ct);
frame.dispose();
}
});
final JMenuItem edit_feature_item = new JMenuItem("Edit Selected Features");
edit_feature_item.setAccelerator(EDIT_FEATURES_KEY);
edit_feature_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
editSelectedFeatures(getParentFrame(), getEntryGroup(),
getSelection(), goto_event_source);
final JMenuItem edit_subsequence_item = new JMenuItem("Edit Subsequence (and Features)");
edit_subsequence_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
editSubSequence();
final JMenuItem add_qualifiers_item = new JMenuItem("Change Qualifiers Of Selected ...");
add_qualifiers_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
addQualifiers(getParentFrame(), getSelection());
final JMenuItem remove_qualifier_item = new JMenuItem("Remove Qualifier Of Selected ...");
remove_qualifier_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
removeQualifier(getParentFrame(), getSelection());
final JMenuItem convert_qualifier_item = new JMenuItem("Convert Qualifier Of Selected ...");
convert_qualifier_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
convertQualifier(getParentFrame(), getSelection());
}
});
final JMenuItem merge_features_item = new JMenuItem("Merge Selected Features");
merge_features_item.setAccelerator(MERGE_FEATURES_KEY);
merge_features_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
mergeFeatures(getParentFrame(), getSelection(), getEntryGroup());
final JMenuItem unmerge_feature_item = new JMenuItem("Unmerge Selected Feature");
unmerge_feature_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
unmergeFeature(getParentFrame(), getSelection(), getEntryGroup());
final JMenuItem unmerge_all_feature_item = new JMenuItem("Unmerge All Feature Segments");
if(GeneUtils.isDatabaseEntry(entry_group))
unmerge_all_feature_item.setEnabled(false);
unmerge_all_feature_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
unmergeAllFeature(getParentFrame(), getSelection(), getEntryGroup());
}
});
final JMenuItem duplicate_item = new JMenuItem("Duplicate Selected Features");
duplicate_item.setAccelerator(DUPLICATE_KEY);
duplicate_item.addActionListener(new ActionListener()
duplicateFeatures(getParentFrame(), getSelection(),
getEntryGroup());
}
});
final JMenuItem delete_features_item = new JMenuItem("Delete Selected Features");
delete_features_item.setAccelerator(DELETE_FEATURES_KEY);
delete_features_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
deleteSelectedFeatures(getParentFrame(), getSelection(),
getEntryGroup());
final JMenuItem delete_segments_item = new JMenuItem("Delete Selected Exons");
delete_segments_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
deleteSelectedSegments();
final JMenuItem delete_introns_item =
new JMenuItem("Remove Introns of Selected Features");
delete_introns_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
removeIntrons();
final JMenuItem edit_header_item = new JMenuItem("Edit Header Of Default Entry");
edit_header_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
editHeader();
final JMenu move_features_menu = new JMenu("Move Selected Features To");
final JMenu copy_features_menu = new JMenu("Copy Selected Features To");
if(entry_group == null || getEntryGroup().size() == 0)
{
move_features_menu.add(new JMenuItem("(No Entries Currently)"));
copy_features_menu.add(new JMenuItem("(No Entries Currently)"));
}
else
{
for(int i = 0 ; i < getEntryGroup().size() ; ++i)
{
final Entry this_entry = getEntryGroup().elementAt(i);
String entry_name = this_entry.getName();
if(entry_name == null)
final JMenuItem move_to_item = new JMenuItem(entry_name);
move_to_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
// unselect, move, then reselect (for speed)
final FeatureVector selected_features =
getSelection().getAllFeatures();
getSelection().clear();
moveFeatures(selected_features, this_entry);
getSelection().set(selected_features);
move_features_menu.add(move_to_item);
final JMenuItem copy_to_item = new JMenuItem(entry_name);
copy_to_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
copyFeatures(getSelection().getAllFeatures(), this_entry);
copy_features_menu.add(copy_to_item);
final JMenuItem trim_to_any_item = new JMenuItem("Trim Selected Features To Any");
trim_to_any_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event) {
EditMenu.trimSelected(getParentFrame(), getSelection(),
getEntryGroup(), true, false);
final JMenuItem trim_item = new JMenuItem("Trim Selected Features To Met");
trim_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
EditMenu.trimSelected(getParentFrame(), getSelection(),
getEntryGroup(), false, false);
final JMenuItem trim_to_next_any_item =
new JMenuItem("Trim Selected Features To Next Any");
trim_to_next_any_item.setAccelerator(TRIM_FEATURES_TO_NEXT_ANY_KEY);
trim_to_next_any_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
EditMenu.trimSelected(getParentFrame(), getSelection(),
getEntryGroup(), true, true);
final JMenuItem trim_to_next_item = new JMenuItem("Trim Selected Features To Next Met");
trim_to_next_item.setAccelerator(TRIM_FEATURES_KEY);
trim_to_next_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
EditMenu.trimSelected(getParentFrame(), getSelection(),
getEntryGroup(), false, true);
final JMenuItem extend_to_prev_stop_item =
new JMenuItem("Extend to Previous Stop Codon");
extend_to_prev_stop_item.setAccelerator(EXTEND_TO_PREVIOUS_STOP_CODON_KEY);
extend_to_prev_stop_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
extendToORF(getParentFrame(), getSelection(),
getEntryGroup(), false);
final JMenuItem extend_to_next_stop_item = new JMenuItem("Extend to Next Stop Codon");
extend_to_next_stop_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
extendToORF(getParentFrame(), getSelection(),
getEntryGroup(), true);
final JMenuItem fix_stop_codons_item = new JMenuItem("Fix Stop Codons");
fix_stop_codons_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
fixStopCodons();
final JMenuItem extend_to_next_stop_and_fix_item = new JMenuItem("Extend to Next Stop Codon and Fix");
extend_to_next_stop_and_fix_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
extendToORF(getParentFrame(), getSelection(),
getEntryGroup(), true);
fixStopCodons();
}
});
final JMenuItem auto_gene_name_item = new JMenuItem("Automatically Create Gene Names");
auto_gene_name_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
autoGeneName();
final JMenuItem fix_gene_names_item = new JMenuItem("Fix Gene Names");
fix_gene_names_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
fixGeneNames(getParentFrame(), getEntryGroup(),
getSelection());
final JMenuItem reverse_complement_item = new JMenuItem("Reverse And Complement");
reverse_complement_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
reverseAndComplement();
final JMenuItem reverse_complement_range_item = new JMenuItem("Reverse And Complement Selected Contig");
reverse_complement_range_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
if(getEntryGroup().isReadOnly())
{
final String message =
"one or more of the entries or features are read only - " +
"cannot continue";
new MessageDialog(getParentFrame(), message);
return;
}
final FeatureVector selected_features = getSelection().getAllFeatures();
if(selected_features.size() == 1)
{
final Feature selection_feature = selected_features.elementAt(0);
final YesNoDialog dialog =
new YesNoDialog (getParentFrame (),
"Are you sure you want to reverse complement this " +
"region "+ selection_feature.getFirstBase()+".."+
selection_feature.getLastBase()+"?");
if(!dialog.getResult())
return;
try
{
getEntryGroup().getBases().reverseComplement(selection_feature);
}
catch(ReadOnlyException roe)
{
final String message =
"one or more of the features is read-only or is in a " +
"read-only entry - cannot continue";
new MessageDialog(null, message);
return;
}
}
else
{
final String message =
"Select a single contig to reverse and complement";
new MessageDialog(null, message);
return;
}
}
});
final JMenuItem delete_bases_item = new JMenuItem("Delete Selected Bases");
delete_bases_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
deleteSelectedBases();
final JMenuItem add_bases_item = new JMenuItem("Add Bases At Selection");
add_bases_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
addBases();
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
final JMenuItem replace_bases_item = new JMenuItem("Replace Bases At Selection");
replace_bases_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
MarkerRange marker_range = getSelection ().getMarkerRange ();
int start = getSelection().getHighestBaseOfSelection().getPosition();
boolean hasDeleted = deleteSelectedBases();
if(!hasDeleted)
return;
if(!marker_range.isForwardMarker())
{
try
{
marker_range = new MarkerRange(
getEntryGroup().getBases().getReverseStrand(),
start,start+1);
}
catch(OutOfRangeException e)
{
e.printStackTrace();
return;
}
}
getSelection ().setMarkerRange (marker_range);
addBases();
getSelection ().setMarkerRange (null);
}
});
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
if(Options.getOptions().getPropertyTruthValue("val_mode"))
{
add(edit_feature_item);
add(edit_subsequence_item);
addSeparator();
add(edit_header_item);
addSeparator();
}
if(Options.getOptions().getUndoLevels() > 0)
{
add(undo_item);
addSeparator();
}
if(!Options.getOptions().getPropertyTruthValue("val_mode"))
{
add(edit_feature_item);
add(edit_subsequence_item);
addSeparator();
add(edit_header_item);
addSeparator();
}
add(add_qualifiers_item);
add(remove_qualifier_item);
add(merge_features_item);
add(unmerge_feature_item);
add(delete_features_item);
add(delete_segments_item);
add(delete_introns_item);
addSeparator();
add(move_features_menu);
add(copy_features_menu);
addSeparator();
add(trim_item);
add(trim_to_any_item);
add(trim_to_next_item);
add(trim_to_next_any_item);
add(extend_to_prev_stop_item);
add(extend_to_next_stop_item);
add(fix_stop_codons_item);
add(extend_to_next_stop_and_fix_item);
addSeparator();
add(auto_gene_name_item);
add(fix_gene_names_item);
add(reverse_complement_item);
add(reverse_complement_range_item);
add(delete_bases_item);
add(add_bases_item);
if(Options.readWritePossible())
{
final JMenuItem add_bases_from_file_item = new JMenuItem("Add Bases From File ...");
add_bases_from_file_item.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
addBasesFromFile();
add(add_bases_from_file_item);
if(owner instanceof FeatureDisplay)
{
add(new JSeparator());
add(contig_reordering);
}
}
/**
* Undo the last change by calling ActionController.undo().
* @param frame The Frame to use for MessageDialog components.
* @param selection The current Selection - needs to be cleared before undo
* @param entry_group Used to get the ActionController for calling
* ActionController.undo().
**/
private static void undo(final JFrame frame,
final Selection selection,
final EntryGroup entry_group)
{
// undo disabled
if(Options.getOptions().getUndoLevels() == 0)
// clear the selection because something in the selection might
// disappear after the undo() eg. create a feature, select it then undo
if(entry_group.getActionController().canUndo())
selection.clear();
if(!entry_group.getActionController().undo())
new MessageDialog(frame, "sorry - no further undo information");
}
/**
* Open an edit window (FeatureEdit) for each of the selected features.
* The edit component will listen for feature change events and update
* itself.
* @param frame The JFrame to use for MessageDialog components.
* @param selection The selected features to edit.
* @param entry_group Used to get the ActionController for calling
* startAction() and endAction().
**/
protected static void editSelectedFeatures(final JFrame frame,
final EntryGroup entry_group,
final Selection selection,
final GotoEventSource goto_event_source)
{
final int MAX_SELECTED_FEATURES = 25;
final FeatureVector features_to_edit = selection.getAllFeatures();
if(features_to_edit.size() > MAX_SELECTED_FEATURES)
new MessageDialog(frame, "warning: only editing the first " +
MAX_SELECTED_FEATURES + " selected features");
for(int i = 0; i < features_to_edit.size() && i < MAX_SELECTED_FEATURES;
++i)
{
final Feature selection_feature = features_to_edit.elementAt(i);
featureEdit = editSelectedFeatures(entry_group, selection, goto_event_source,
selection_feature, null, null);
if(featureEdit)
selection.set(features_to_edit);
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
public static boolean editSelectedFeatures(
final EntryGroup entry_group,
final Selection selection,
final GotoEventSource goto_event_source,
final Feature selection_feature,
final ActionListener cancel_listener,
final ActionListener apply_listener)
{
if(selection_feature.getEmblFeature() instanceof GFFStreamFeature &&
((GFFStreamFeature)selection_feature.getEmblFeature()).getChadoGene() != null)
{
new GeneBuilderFrame(selection_feature, entry_group,
selection, goto_event_source);
return false;
}
else
{
final JFrame edit_frame = new JFrame("Artemis Feature Edit: " +
selection_feature.getIDString() +
(selection_feature.isReadOnly() ?
" - (read only)" :
""));
final FeatureEdit fe = new FeatureEdit(selection_feature, entry_group,
selection, goto_event_source, edit_frame);
edit_frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent event)
{
fe.stopListening();
edit_frame.dispose();
}
});
if(cancel_listener != null)
fe.addCancelActionListener(cancel_listener);
if(apply_listener != null)
fe.addApplyActionListener(apply_listener);
edit_frame.getContentPane().add(fe);
edit_frame.pack();
Utilities.centreFrame(edit_frame);
edit_frame.setVisible(true);
return true;
}
}
/**
* Create a new EntryEdit component that contains only the selected
* sequence and the features in the selected range.
**/
private void editSubSequence()
{
if(getSelection().isEmpty())
new MessageDialog(getParentFrame(), "nothing selected");
final Range range = getSelection().getSelectionRange();
final EntryGroup new_entry_group = getEntryGroup().truncate(range);
new EntryEdit(new_entry_group).setVisible(true);
}
/**
* Open a EntryHeaderEdit window for the default entry.
**/
private void editHeader()
{
final Entry default_entry = getEntryGroup().getDefaultEntry();
if(default_entry == null)
{
final String message = "there is no default entry";
new MessageDialog(getParentFrame(), message);
}
else
{
if(default_entry.isReadOnly())
{
new MessageDialog(getParentFrame(),
"the default entry is read-only " +
"- cannot continue");
new EntryHeaderEdit(entry_group, default_entry);
}
}
/**
* Merge the selected features into one Feature. If there are selected
* segments then the owning Feature of each segment will be the Feature
* that is merged. This method will create a new Feature.
* @param frame The JFrame to use for MessageDialog components.
* @param selection The Selection containing the features to merge.
* @param entry_group Used to get the ActionController for calling
* startAction() and endAction().
**/
protected static void mergeFeatures(final JFrame frame,
final Selection selection,
final EntryGroup entry_group)
{
try
{
entry_group.getActionController().startAction();
if(!checkForSelectionFeatures(frame, selection, 10,
"really merge all (>10) " + "selected features?"))
final FeatureVector features_to_merge = selection.getAllFeatures();
if(features_to_merge.size() < 2)
{
new MessageDialog(frame,
"nothing to merge - select more than one feature");
final Feature merge_feature = features_to_merge.elementAt(0);
for(int i = 1; i < features_to_merge.size(); ++i)
{
final Feature this_feature = features_to_merge.elementAt(i);
if(this_feature.isForwardFeature() !=
merge_feature.isForwardFeature())
{
new MessageDialog(frame,
"all the features in a merge must be on the " +
"same strand");
if(!this_feature.getKey().equals(merge_feature.getKey()))
{
new MessageDialog(frame,
"all the features in a merge must have the " +
"same key");
if(Options.getOptions().isNoddyMode())
{
new YesNoDialog(frame, "Are you sure you want to merge the selected " +
"features?");
if(!dialog.getResult())
//
// GFF merge
if(merge_feature.getEmblFeature() instanceof GFFStreamFeature)
{
if(!merge_feature.getKey().equals(DatabaseDocument.EXONMODEL) &&
!merge_feature.getKey().equals("pseudogenic_exon"))
{
new MessageDialog(frame,"The features in a merge should be "+
DatabaseDocument.EXONMODEL+
" or pseudogenic_exon features");
return;
}
gffMergeFeatures(features_to_merge, merge_feature,
selection, entry_group);