import java.awt.*;
+import java.awt.event.*;
+
+
+import jalview.appletgui.FeatureSettings.MyCheckbox;
import jalview.datamodel.*;
/**
transparency = fr.transparency;
}
- public Color findFeatureColour(Color initialCol, SequenceI seq, int i)
+
+ static String lastFeatureAdded;
+ static String lastFeatureGroupAdded;
+ static String lastDescriptionAdded;
+
+ int featureIndex = 0;
+ boolean deleteFeature = false;
+ Panel colourPanel;
+ boolean amendFeatures(final SequenceI[] sequences,
+ final SequenceFeature[] features,
+ boolean newFeatures,
+ final AlignmentPanel ap)
{
- overview = true;
- if (!av.showSequenceFeatures)
+ Panel bigPanel = new Panel(new BorderLayout());
+ final TextField name = new TextField(16);
+ final TextField source = new TextField(16);
+ final TextArea description = new TextArea(3, 35);
+ final TextField start = new TextField(8);
+ final TextField end = new TextField(8);
+ final Choice overlaps;
+ Button deleteButton = new Button("Delete");
+ deleteFeature = false;
+
+ colourPanel = new Panel(null);
+ colourPanel.setSize(110,15);
+ final FeatureRenderer fr = this;
+
+ Panel panel = new Panel(new GridLayout(3, 1));
+
+ Panel tmp;
+
+ ///////////////////////////////////////
+ ///MULTIPLE FEATURES AT SELECTED RESIDUE
+ if(!newFeatures && features.length>1)
{
- return initialCol;
+ panel = new Panel(new GridLayout(4, 1));
+ tmp = new Panel();
+ tmp.add(new Label("Select Feature: "));
+ overlaps = new Choice();
+ for(int i=0; i<features.length; i++)
+ {
+ String item = features[i].getType()
+ +"/"+features[i].getBegin()+"-"+features[i].getEnd();
+
+ if(features[i].getFeatureGroup()!=null)
+ item += " ("+features[i].getFeatureGroup()+")";
+
+ overlaps.addItem(item);
+ }
+
+ tmp.add(overlaps);
+
+ overlaps.addItemListener(new java.awt.event.ItemListener()
+ {
+ public void itemStateChanged(java.awt.event.ItemEvent e)
+ {
+ int index = overlaps.getSelectedIndex();
+ if (index != -1)
+ {
+ featureIndex = index;
+ name.setText(features[index].getType());
+ description.setText(features[index].getDescription());
+ source.setText(features[index].getFeatureGroup());
+ start.setText(features[index].getBegin()+"");
+ end.setText(features[index].getEnd()+"");
+
+ SearchResults highlight = new SearchResults();
+ highlight.addResult(sequences[0],
+ features[index].getBegin(),
+ features[index].getEnd());
+
+ ap.seqPanel.seqCanvas.highlightSearchResults(highlight);
+
+ }
+ Color col = getColour(name.getText());
+ if (col == null)
+ {
+ col = new
+ jalview.schemes.UserColourScheme()
+ .createColourFromName(name.getText());
+ }
+
+ colourPanel.setBackground(col);
+ }
+ });
+
+
+ panel.add(tmp);
}
+ //////////
+ //////////////////////////////////////
- lastSequence = seq;
- sequenceFeatures = lastSequence.getSequenceFeatures();
- if (sequenceFeatures == null)
+
+ tmp = new Panel();
+ panel.add(tmp);
+ tmp.add(new Label("Name: ", Label.RIGHT));
+ tmp.add(name);
+
+ tmp = new Panel();
+ panel.add(tmp);
+ tmp.add(new Label("Group: ",Label.RIGHT));
+ tmp.add(source);
+
+ tmp = new Panel();
+ panel.add(tmp);
+ tmp.add(new Label("Colour: ", Label.RIGHT));
+ tmp.add(colourPanel);
+
+ bigPanel.add(panel, BorderLayout.NORTH);
+
+ panel = new Panel();
+ panel.add(new Label("Description: ", Label.RIGHT));
+ panel.add(new ScrollPane().add(description));
+
+ if (!newFeatures)
{
- return initialCol;
+ bigPanel.add(panel, BorderLayout.SOUTH);
+
+ panel = new Panel();
+ panel.add(new Label(" Start:", Label.RIGHT));
+ panel.add(start);
+ panel.add(new Label(" End:", Label.RIGHT));
+ panel.add(end);
+ bigPanel.add(panel, BorderLayout.CENTER);
+ }
+ else
+ {
+ bigPanel.add(panel, BorderLayout.CENTER);
}
- sfSize = sequenceFeatures.length;
+ if (lastFeatureAdded == null)
+ {
+ if (features[0].type != null)
+ {
+ lastFeatureAdded = features[0].type;
+ }
+ else
+ {
+ lastFeatureAdded = "feature_1";
+ }
+ }
- if (jalview.util.Comparison.isGap(lastSequence.getCharAt(i)))
+ if (lastFeatureGroupAdded == null)
{
- return Color.white;
+ if (features[0].featureGroup != null)
+ {
+ lastFeatureGroupAdded = features[0].featureGroup;
+ }
+ else
+ {
+ lastFeatureAdded = "Jalview";
+ }
}
- currentColour = null;
- drawSequence(null, lastSequence, lastSequence.findPosition(i), -1, -1);
+ String title = newFeatures ? "Create New Sequence Feature(s)" :
+ "Amend/Delete Features for "
+ + sequences[0].getName();
- if (currentColour == null)
+ final JVDialog dialog = new JVDialog(ap.alignFrame,
+ title,
+ true,
+ 385,240);
+
+ dialog.setMainPanel(bigPanel);
+
+ if(newFeatures)
{
- return initialCol;
+ name.setText(lastFeatureAdded);
+ source.setText(lastFeatureGroupAdded);
+ }
+ else
+ {
+ dialog.ok.setLabel("Amend");
+ dialog.buttonPanel.add(deleteButton, 1);
+ deleteButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent evt)
+ {
+ deleteFeature = true;
+ dialog.setVisible(false);
+ }
+ });
+ name.setText(features[0].getType());
+ source.setText(features[0].getFeatureGroup());
}
- return new Color( ( (Integer) currentColour).intValue());
+ start.setText(features[0].getBegin()+"");
+ end.setText(features[0].getEnd()+"");
+ description.setText(features[0].getDescription());
+
+ Color col = getColour(name.getText());
+ if (col == null)
+ {
+ col = new
+ jalview.schemes.UserColourScheme()
+ .createColourFromName(name.getText());
+ }
+
+ colourPanel.setBackground(col);
+
+ dialog.setResizable(true);
+
+
+ colourPanel.addMouseListener(new java.awt.event.MouseAdapter()
+ {
+ public void mousePressed(java.awt.event.MouseEvent evt)
+ {
+ new UserDefinedColours(fr, ap.alignFrame);
+ }
+ });
+
+ dialog.setVisible(true);
+
+ jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();
+
+ if (dialog.accept)
+ {
+ //This ensures that the last sequence
+ //is refreshed and new features are rendered
+ lastSeq = null;
+ lastFeatureAdded = name.getText().trim();
+ lastFeatureGroupAdded = source.getText().trim();
+ lastDescriptionAdded = description.getText().replace('\n', ' ');
+ }
+
+ if(lastFeatureGroupAdded !=null && lastFeatureGroupAdded.length()<1)
+ lastFeatureGroupAdded = null;
+
+
+ if (!newFeatures)
+ {
+ SequenceFeature sf = features[featureIndex];
+
+ if (dialog.accept)
+ {
+ sf.type = lastFeatureAdded;
+ sf.featureGroup = lastFeatureGroupAdded;
+ sf.description = lastDescriptionAdded;
+ setColour(sf.type, colourPanel.getBackground());
+ try
+ {
+ sf.begin = Integer.parseInt(start.getText());
+ sf.end = Integer.parseInt(end.getText());
+ }
+ catch (NumberFormatException ex)
+ {}
+
+ ffile.parseDescriptionHTML(sf, false);
+ }
+ if (deleteFeature)
+ {
+ sequences[0].deleteFeature(sf);
+ }
+
+ }
+ else
+ {
+ if (dialog.accept && name.getText().length()>0)
+ {
+ for (int i = 0; i < sequences.length; i++)
+ {
+ features[i].type = lastFeatureAdded;
+ features[i].featureGroup = lastFeatureGroupAdded;
+ features[i].description = lastDescriptionAdded;
+ sequences[i].addSequenceFeature(features[i]);
+ ffile.parseDescriptionHTML(features[i], false);
+ }
+
+ if (av.featuresDisplayed == null)
+ {
+ av.featuresDisplayed = new Hashtable();
+ }
+
+ if (featureGroups == null)
+ {
+ featureGroups = new Hashtable();
+ }
+
+ col = colourPanel.getBackground();
+ setColour(lastFeatureAdded, col);
+
+ if(lastFeatureGroupAdded!=null)
+ {
+ featureGroups.put(lastFeatureGroupAdded, new Boolean(true));
+ av.featuresDisplayed.put(lastFeatureGroupAdded,
+ new Integer(col.getRGB()));
+ }
+ findAllFeatures();
+
+ String [] tro = new String[renderOrder.length];
+ tro[0] = renderOrder[renderOrder.length-1];
+ System.arraycopy(renderOrder,0,tro,1,renderOrder.length-1);
+ renderOrder = tro;
+
+ ap.paintAlignment(true);
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ findAllFeatures();
+
+ ap.paintAlignment(true);
+
+ return true;
}
- /**
- * This is used by the Molecule Viewer to get the accurate colour
- * of the rendered sequence
- */
- boolean overview = false;
- int white = Color.white.getRGB();
- public int findFeatureColour(int initialCol, int seqIndex, int column)
+ public Color findFeatureColour(Color initialCol, SequenceI seq, int i)
{
+ overview = true;
if (!av.showSequenceFeatures)
{
return initialCol;
}
- if (seqIndex != lastSequenceIndex)
+ lastSeq = seq;
+ sequenceFeatures = lastSeq.getSequenceFeatures();
+ if (sequenceFeatures == null)
{
- lastSequence = av.alignment.getSequenceAt(seqIndex);
- lastSequenceIndex = seqIndex;
- sequenceFeatures = lastSequence.getSequenceFeatures();
- if (sequenceFeatures == null)
- {
- return initialCol;
- }
-
- sfSize = sequenceFeatures.length;
+ return initialCol;
}
- if (jalview.util.Comparison.isGap(lastSequence.getCharAt(column)))
+ sfSize = sequenceFeatures.length;
+
+ if (jalview.util.Comparison.isGap(lastSeq.getCharAt(i)))
{
- return Color.white.getRGB();
+ return Color.white;
}
currentColour = null;
- drawSequence(null, lastSequence, lastSequence.findPosition(column), -1, -1);
+ drawSequence(null, lastSeq, lastSeq.findPosition(i), -1, -1);
if (currentColour == null)
{
return initialCol;
}
- return ( (Integer) currentColour).intValue();
+ return new Color( ( (Integer) currentColour).intValue());
}
/**
+ * This is used by the Molecule Viewer to get the accurate colour
+ * of the rendered sequence
+ */
+ boolean overview = false;
+
+
+ /**
* DOCUMENT ME!
*
* @param g DOCUMENT ME!
*/
// String type;
// SequenceFeature sf;
- int lastSequenceIndex = -1;
- SequenceI lastSequence;
+
+ SequenceI lastSeq;
SequenceFeature[] sequenceFeatures;
int sfSize, sfindex, spos, epos;
- public void drawSequence(Graphics g, SequenceI seq,
+ synchronized public void drawSequence(Graphics g, SequenceI seq,
int start, int end, int y1)
{
if (seq.getSequenceFeatures() == null
{
transparencySetter.setTransparency(g, transparency);
}
-
- if (lastSequence == null || seq != lastSequence || sequenceFeatures!=seq.getSequenceFeatures())
+
+ if (lastSeq == null || seq != lastSeq || sequenceFeatures!=seq.getSequenceFeatures())
{
- lastSequence = seq;
+ lastSeq = seq;
sequenceFeatures = seq.getSequenceFeatures();
sfSize = sequenceFeatures.length;
}
}
if (!overview)
{
- spos = lastSequence.findPosition(start);
- epos = lastSequence.findPosition(end);
+ spos = lastSeq.findPosition(start);
+ epos = lastSeq.findPosition(end);
if (g != null)
{
fm = g.getFontMetrics();
{
jalview.schemes.UserColourScheme ucs = new
jalview.schemes.UserColourScheme();
-
+
av.featuresDisplayed = new Hashtable();
Vector allfeatures = new Vector();
for (int i = 0; i < av.alignment.getHeight(); i++)
public Color getColour(String featureType)
{
- return (Color) featureColours.get(featureType);
- }
-
- public void addNewFeature(String name, Color col)
- {
-
- setColour(name, col);
- if (av.featuresDisplayed == null)
+ if (!featureColours.containsKey(featureType))
{
- av.featuresDisplayed = new Hashtable();
+ jalview.schemes.UserColourScheme ucs = new
+ jalview.schemes.UserColourScheme();
+ Color col = ucs.createColourFromName(featureType);
+ featureColours.put(featureType, col);
+ return col;
}
-
- av.featuresDisplayed.put(name, "NOGROUP");
+ else
+ return (Color) featureColours.get(featureType);
}
+
public void setColour(String featureType, Color col)
{
featureColours.put(featureType, col);
av.featuresDisplayed.clear();
}
+ /* if (visibleNew)
+ {
+ if (av.featuresDisplayed != null)
+ {
+ av.featuresDisplayed.clear();
+ }
+ else
+ {
+ av.featuresDisplayed = new Hashtable();
+ }
+ }
+ if (data == null)
+ {
+ return;
+ }*/
+
+
renderOrder = new String[data.length];
if (data.length > 0)
}
}
}
-
- public void featuresAdded()
+ /**
+ * @return a simple list of feature group names or null
+ */
+ public String[] getGroups()
{
- findAllFeatures();
+ buildGroupHash();
+ if (featureGroups!=null)
+ {
+ String[] gps = new String[featureGroups.size()];
+ Enumeration gn = featureGroups.keys();
+ int i=0;
+ while (gn.hasMoreElements())
+ {
+ gps[i++] = (String) gn.nextElement();
+ }
+ return gps;
+ }
+ return null;
+ }
+ /**
+ * get visible or invisible groups
+ * @param visible true to return visible groups, false to return hidden ones.
+ * @return list of groups
+ */
+ public String[] getGroups(boolean visible)
+ {
+ buildGroupHash();
+ if (featureGroups!=null)
+ {
+ Vector gp = new Vector();
+
+ Enumeration gn = featureGroups.keys();
+ while (gn.hasMoreElements())
+ {
+ String nm = (String) gn.nextElement();
+ Boolean state = (Boolean) featureGroups.get(nm);
+ if (state.booleanValue()==visible)
+ {
+ gp.addElement(nm);
+ }
+ }
+ String[] gps = new String[gp.size()];
+ gp.copyInto(gps);
+
+ int i=0;
+ while (gn.hasMoreElements())
+ {
+ gps[i++] = (String) gn.nextElement();
+ }
+ return gps;
+ }
+ return null;
+ }
+ /**
+ * set all feature groups in toset to be visible or invisible
+ * @param toset group names
+ * @param visible the state of the named groups to set
+ */
+ public void setGroupState(String[] toset, boolean visible)
+ {
+ buildGroupHash();
+ if (toset!=null && toset.length>0 && featureGroups!=null)
+ {
+ boolean rdrw = false;
+ for (int i=0;i<toset.length; i++)
+ {
+ Object st = featureGroups.get(toset[i]);
+ if (st!=null)
+ {
+ featureGroups.put(toset[i], new Boolean(visible));
+ rdrw = rdrw || (visible!=((Boolean) st).booleanValue());
+ }
+ }
+ if (rdrw)
+ {
+ if (this.av!=null)
+ if (this.av.featureSettings!=null)
+ {
+ av.featureSettings.rebuildGroups();
+ this.av.featureSettings.resetTable(true);
+ } else {
+ buildFeatureHash();
+ }
+ if (av!=null)
+ {
+ av.alignmentChanged(null);
+ }
+ }
+ }
+ }
+ /**
+ * analyse alignment for groups and hash tables
+ * (used to be embedded in FeatureSettings.setTableData)
+ * @return true if features are on the alignment
+ */
+ public boolean buildGroupHash()
+ {
+ boolean alignmentHasFeatures=false;
+ if (featureGroups == null)
+ {
+ featureGroups = new Hashtable();
+ }
+ Vector allFeatures = new Vector();
+ Vector allGroups = new Vector();
+ SequenceFeature[] tmpfeatures;
+ String group;
+ for (int i = 0; i < av.alignment.getHeight(); i++)
+ {
+ if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
+ {
+ continue;
+ }
+
+ alignmentHasFeatures = true;
+
+ tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
+ int index = 0;
+ while (index < tmpfeatures.length)
+ {
+ if (tmpfeatures[index].getFeatureGroup() != null)
+ {
+ group = tmpfeatures[index].featureGroup;
+ if (!allGroups.contains(group))
+ {
+ allGroups.addElement(group);
+
+ boolean visible = true;
+ if (featureGroups.containsKey(group))
+ {
+ visible = ( (Boolean) featureGroups.get(group)).booleanValue();
+ } else {
+ featureGroups.put(group, new Boolean(visible));
+ }
+ }
+ }
+
+ if (!allFeatures.contains(tmpfeatures[index].getType()))
+ {
+ allFeatures.addElement(tmpfeatures[index].getType());
+ }
+ index++;
+ }
+ }
+
+ return alignmentHasFeatures;
+ }
+ /**
+ * rebuild the featuresDisplayed and renderorder list based on the featureGroups hash and any existing display state
+ * and force a repaint if necessary
+ * @return true if alignment has visible features
+ */
+ public boolean buildFeatureHash() {
+ boolean alignmentHasFeatures=false;
+ if (featureGroups==null)
+ {
+ alignmentHasFeatures = buildGroupHash();
+ }
+ if (!alignmentHasFeatures)
+ return false;
+ Hashtable fdisp = av.featuresDisplayed;
+ Vector allFeatures = new Vector();
+ SequenceFeature[] tmpfeatures;
+ String group;
+ for (int i = 0; i < av.alignment.getHeight(); i++)
+ {
+ if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
+ {
+ continue;
+ }
+
+ alignmentHasFeatures = true;
+
+ tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
+ int index = 0;
+ while (index < tmpfeatures.length)
+ {
+ boolean visible = true;
+ if (tmpfeatures[index].getFeatureGroup() != null)
+ {
+ group = tmpfeatures[index].featureGroup;
+ if (featureGroups.containsKey(group))
+ {
+ visible = ( (Boolean) featureGroups.get(group)).booleanValue();
+ }
+ }
+
+ if (visible && !allFeatures.contains(tmpfeatures[index].getType()))
+ {
+ allFeatures.addElement(tmpfeatures[index].getType());
+ }
+ index++;
+ }
+ }
+ if (allFeatures.size()>0)
+ {
+ String[] neworder = new String[allFeatures.size()];
+ int p=neworder.length-1;
+ for (int i=renderOrder.length-1; i>=0; i--)
+ {
+ if (allFeatures.contains(renderOrder[i]))
+ {
+ neworder[p--] = renderOrder[i];
+ allFeatures.removeElement(renderOrder[i]);
+ } else {
+ av.featuresDisplayed.remove(renderOrder[i]);
+ }
+ }
+ for (int i=allFeatures.size()-1; i>0; i++)
+ {
+ Object e = allFeatures.elementAt(i);
+ if (e!=null)
+ {
+ neworder[p--] = (String) e;
+ av.featuresDisplayed.put(e, getColour((String)e));
+ }
+ }
+ renderOrder = neworder;
+ return true;
+ }
+
+ return alignmentHasFeatures;
}
}