import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureColourI;
+import jalview.bin.Cache;
import jalview.datamodel.GraphLine;
import jalview.datamodel.features.FeatureAttributes;
import jalview.datamodel.features.FeatureAttributes.Datatype;
import jalview.datamodel.features.FeatureMatcherSet;
import jalview.datamodel.features.FeatureMatcherSetI;
import jalview.io.gff.SequenceOntologyFactory;
+import jalview.io.gff.SequenceOntologyI;
import jalview.schemes.FeatureColour;
import jalview.util.ColorUtils;
import jalview.util.MessageManager;
*/
public class FeatureTypeSettings extends JalviewDialog
{
+ /*
+ * 'top level' Sequence Ontology terms
+ */
+ private final static String SO_ROOTS = "sequence_variant,sequence_attribute,sequence_collection,sequence_feature";
+
private final static String LABEL_18N = MessageManager
.getString("label.label");
private JPanel chooseFiltersPanel;
/*
- * feature types present in Feature Renderer which are
- * sub-types of the one this editor is acting on
+ * the root Sequence Ontology terms (if any) that is a parent of
+ * the current feature type
+ */
+ private String rootSOTerm;
+
+ /*
+ * feature types present in Feature Renderer which have the same Sequence
+ * Ontology root parent as the one this editor is acting on
*/
- private final List<String> subTypes;
+ private final List<String> peerSoTerms;
/*
* if true, filter or colour settings are also applied to
- * any feature sub-types in the Sequence Ontology
+ * any sub-types of rootSOTerm in the Sequence Ontology
*/
private boolean applyFiltersToSubtypes;
this.featureType = theType;
ap = fr.ap;
- /*
- * determine sub-types (if any) of this feature type
- */
- List<String> types = fr.getRenderOrder();
- subTypes = SequenceOntologyFactory.getInstance()
- .getChildTerms(this.featureType, types);
- Collections.sort(subTypes); // sort for ease of reading in tooltip
+ peerSoTerms = findSequenceOntologyPeers(this.featureType);
/*
* save original colours and filters for this feature type
originalFilters.put(theType, fr.getFeatureFilter(theType));
originalColours = new HashMap<>();
originalColours.put(theType, fr.getFeatureColours().get(theType));
- for (String child : subTypes)
+ for (String child : peerSoTerms)
{
originalFilters.put(child, fr.getFeatureFilter(child));
originalColours.put(child, fr.getFeatureColours().get(child));
}
adjusting = true;
-
+
try
{
initialise();
ex.printStackTrace();
return;
}
-
+
updateColoursTab();
-
+
updateFiltersTab();
-
+
adjusting = false;
-
+
colourChanged(false);
-
+
String title = MessageManager
.formatMessage("label.display_settings_for", new String[]
{ theType });
}
/**
+ * Answers a (possibly empty) list of feature types known to the Feature
+ * Renderer which share a top level Sequence Ontology parent with the current
+ * feature type. The current type is not included.
+ *
+ * @return
+ */
+ protected List<String> findSequenceOntologyPeers(String featureType)
+ {
+ List<String> peers = new ArrayList<>();
+
+ /*
+ * first find the SO term (if any) that is the root
+ * parent of the current type
+ */
+ SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ String[] roots = Cache.getDefault("SO_ROOTS", SO_ROOTS).split(",");
+ rootSOTerm = null;
+ for (String root : roots)
+ {
+ if (so.isA(featureType, root.trim()))
+ {
+ rootSOTerm = root;
+ break;
+ }
+ }
+ if (rootSOTerm == null)
+ {
+ /*
+ * feature type is not an SO term
+ */
+ return peers;
+ }
+
+ List<String> types = fr.getRenderOrder();
+ for (String type : types)
+ {
+ if (!type.equals(featureType) && so.isA(type, rootSOTerm))
+ {
+ peers.add(type);
+ }
+
+ }
+ Collections.sort(peers); // sort for ease of reading in tooltip
+ return peers;
+ }
+
+ /**
* Configures the widgets on the Colours tab according to the current feature
* colour scheme
*/
MessageManager.getString("action.colour"), true);
/*
- * option to apply colour to sub-types as well (if there are any)
+ * option to apply colour to peer types as well (if there are any)
*/
- if (!subTypes.isEmpty())
+ if (!peerSoTerms.isEmpty())
{
applyColourToSubtypes = false;
colourByPanel.add(initSubtypesPanel(false));
JPanel toSubtypes = new JPanel(new FlowLayout(FlowLayout.LEFT));
toSubtypes.setBackground(Color.WHITE);
JCheckBox applyToSubtypesCB = new JCheckBox(MessageManager
- .formatMessage("label.apply_to_subtypes", featureType));
+ .formatMessage("label.apply_to_subtypes", rootSOTerm));
applyToSubtypesCB.setToolTipText(getSubtypesTooltip());
applyToSubtypesCB.addActionListener(new ActionListener()
{
fr.setColour(featureType, acg);
if (applyColourToSubtypes)
{
- for (String child : subTypes)
+ for (String child : peerSoTerms)
{
fr.setColour(child, acg);
}
*/
adjusting = true;
float f = Float.parseFloat(thresholdValue.getText());
- f = Float.max(f, this.min);
+ f = Float.max(f, this.min);
f = Float.min(f, this.max);
thresholdValue.setText(String.valueOf(f));
slider.setValue((int) (f * scaleFactor));
outerPanel.setBackground(Color.white);
/*
- * option to apply colour to sub-types as well (if there are any)
+ * option to apply colour to peer types as well (if there are any)
*/
- if (!subTypes.isEmpty())
+ if (!peerSoTerms.isEmpty())
{
applyFiltersToSubtypes = false;
outerPanel.add(initSubtypesPanel(true));
JPanel andOrPanel = new JPanel(new BorderLayout());
andOrPanel.setBackground(Color.white);
-// JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
-// andOrPanel.add(panel1, BorderLayout.WEST);
-// panel1.setBackground(Color.white);
-// panel1.setBorder(BorderFactory.createLineBorder(debugBorderColour));
andFilters = new JRadioButton(MessageManager.getString("label.and"));
orFilters = new JRadioButton(MessageManager.getString("label.or"));
ActionListener actionListener = new ActionListener()
*/
protected String getSubtypesTooltip()
{
- StringBuilder sb = new StringBuilder(20 * subTypes.size());
+ StringBuilder sb = new StringBuilder(20 * peerSoTerms.size());
sb.append(MessageManager.getString("label.apply_also_to"));
- for (String child : subTypes)
+ for (String child : peerSoTerms)
{
sb.append("<br>").append(child);
}
fr.setFeatureFilter(featureType, combined.isEmpty() ? null : combined);
if (applyFiltersToSubtypes)
{
- for (String child : subTypes)
+ for (String child : peerSoTerms)
{
fr.setFeatureFilter(child, combined.isEmpty() ? null : combined);
}