X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FJalview2XML.java;h=87b8d8739d14ffa980928d7abe43fcacca6c6f70;hb=7e82e1fed011077e5cd4cc40ac8ad3519d7c47a8;hp=4fffe6f101f54312cd7a839bcb8dca8e08c02244;hpb=173f77ac7161e8866ddfe6b5689d61a83f459cfc;p=jalview.git diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java index 4fffe6f..87b8d87 100644 --- a/src/jalview/gui/Jalview2XML.java +++ b/src/jalview/gui/Jalview2XML.java @@ -37,6 +37,10 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.datamodel.StructureViewerModel; import jalview.datamodel.StructureViewerModel.StructureData; +import jalview.datamodel.features.FeatureMatcher; +import jalview.datamodel.features.FeatureMatcherI; +import jalview.datamodel.features.FeatureMatcherSet; +import jalview.datamodel.features.FeatureMatcherSetI; import jalview.ext.varna.RnaModel; import jalview.gui.StructureViewer.ViewerType; import jalview.io.DataSourceType; @@ -48,6 +52,8 @@ import jalview.schemabinding.version2.Annotation; import jalview.schemabinding.version2.AnnotationColours; import jalview.schemabinding.version2.AnnotationElement; import jalview.schemabinding.version2.CalcIdParam; +import jalview.schemabinding.version2.Colour; +import jalview.schemabinding.version2.CompoundMatcher; import jalview.schemabinding.version2.DBRef; import jalview.schemabinding.version2.Features; import jalview.schemabinding.version2.Group; @@ -60,6 +66,8 @@ import jalview.schemabinding.version2.MapListFrom; import jalview.schemabinding.version2.MapListTo; import jalview.schemabinding.version2.Mapping; import jalview.schemabinding.version2.MappingChoice; +import jalview.schemabinding.version2.MatchCondition; +import jalview.schemabinding.version2.MatcherSet; import jalview.schemabinding.version2.OtherData; import jalview.schemabinding.version2.PdbentryItem; import jalview.schemabinding.version2.Pdbids; @@ -75,6 +83,9 @@ import jalview.schemabinding.version2.ThresholdLine; import jalview.schemabinding.version2.Tree; import jalview.schemabinding.version2.UserColours; import jalview.schemabinding.version2.Viewport; +import jalview.schemabinding.version2.types.ColourThreshTypeType; +import jalview.schemabinding.version2.types.FeatureMatcherByType; +import jalview.schemabinding.version2.types.NoValueColour; import jalview.schemes.AnnotationColourGradient; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemeProperty; @@ -83,10 +94,12 @@ import jalview.schemes.ResidueProperties; import jalview.schemes.UserColourScheme; import jalview.structure.StructureSelectionManager; import jalview.structures.models.AAStructureBindingModel; +import jalview.util.Format; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.util.StringUtils; import jalview.util.jarInputStreamProvider; +import jalview.util.matcher.Condition; import jalview.viewmodel.AlignmentViewport; import jalview.viewmodel.ViewportRanges; import jalview.viewmodel.seqfeatures.FeatureRendererSettings; @@ -115,6 +128,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; @@ -216,34 +230,6 @@ public class Jalview2XML } } - void clearSeqRefs() - { - if (_cleartables) - { - if (seqRefIds != null) - { - seqRefIds.clear(); - } - if (seqsToIds != null) - { - seqsToIds.clear(); - } - if (incompleteSeqs != null) - { - incompleteSeqs.clear(); - } - // seqRefIds = null; - // seqsToIds = null; - } - else - { - // do nothing - warn("clearSeqRefs called when _cleartables was not set. Doing nothing."); - // seqRefIds = new Hashtable(); - // seqsToIds = new IdentityHashMap(); - } - } - void initSeqRefs() { if (seqsToIds == null) @@ -907,15 +893,33 @@ public class Jalview2XML } if (sf.otherDetails != null) { - String key; - Iterator keys = sf.otherDetails.keySet().iterator(); - while (keys.hasNext()) + /* + * save feature attributes, which may be simple strings or + * map valued (have sub-attributes) + */ + for (Entry entry : sf.otherDetails.entrySet()) { - key = keys.next(); - OtherData keyValue = new OtherData(); - keyValue.setKey(key); - keyValue.setValue(sf.otherDetails.get(key).toString()); - features.addOtherData(keyValue); + String key = entry.getKey(); + Object value = entry.getValue(); + if (value instanceof Map) + { + for (Entry subAttribute : ((Map) value) + .entrySet()) + { + OtherData otherData = new OtherData(); + otherData.setKey(key); + otherData.setKey2(subAttribute.getKey()); + otherData.setValue(subAttribute.getValue().toString()); + features.addOtherData(otherData); + } + } + else + { + OtherData otherData = new OtherData(); + otherData.setKey(key); + otherData.setValue(value.toString()); + features.addOtherData(otherData); + } } } @@ -1098,13 +1102,13 @@ public class Jalview2XML { TreePanel tp = (TreePanel) frames[t]; - if (tp.treeCanvas.av.getAlignment() == jal) + if (tp.getTreeCanvas().getViewport().getAlignment() == jal) { Tree tree = new Tree(); tree.setTitle(tp.getTitle()); tree.setCurrentTree((av.getCurrentTree() == tp.getTree())); tree.setNewick(tp.getTree().print()); - tree.setThreshold(tp.treeCanvas.threshold); + tree.setThreshold(tp.getTreeCanvas().getThreshold()); tree.setFitToWindow(tp.fitToWindow.getState()); tree.setFontName(tp.getTreeFont().getName()); @@ -1243,7 +1247,7 @@ public class Jalview2XML { view.setComplementId(av.getCodingComplement().getViewId()); } - view.setViewName(av.viewName); + view.setViewName(av.getViewName()); view.setGatheredViews(av.isGatherViewsHere()); Rectangle size = ap.av.getExplodedGeometry(); @@ -1341,19 +1345,33 @@ public class Jalview2XML { jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings(); - String[] renderOrder = ap.getSeqPanel().seqCanvas - .getFeatureRenderer().getRenderOrder() - .toArray(new String[0]); + FeatureRenderer fr = ap.getSeqPanel().seqCanvas + .getFeatureRenderer(); + String[] renderOrder = fr.getRenderOrder().toArray(new String[0]); Vector settingsAdded = new Vector<>(); if (renderOrder != null) { for (String featureType : renderOrder) { - FeatureColourI fcol = ap.getSeqPanel().seqCanvas - .getFeatureRenderer().getFeatureStyle(featureType); Setting setting = new Setting(); setting.setType(featureType); + + /* + * save any filter for the feature type + */ + FeatureMatcherSetI filter = fr.getFeatureFilter(featureType); + if (filter != null) { + Iterator filters = filter.getMatchers().iterator(); + FeatureMatcherI firstFilter = filters.next(); + setting.setMatcherSet(Jalview2XML.marshalFilter( + firstFilter, filters, filter.isAnded())); + } + + /* + * save colour scheme for the feature type + */ + FeatureColourI fcol = fr.getFeatureStyle(featureType); if (!fcol.isSimpleColour()) { setting.setColour(fcol.getMaxColour().getRGB()); @@ -1361,8 +1379,25 @@ public class Jalview2XML setting.setMin(fcol.getMin()); setting.setMax(fcol.getMax()); setting.setColourByLabel(fcol.isColourByLabel()); + if (fcol.isColourByAttribute()) + { + setting.setAttributeName(fcol.getAttributeName()); + } setting.setAutoScale(fcol.isAutoScaled()); setting.setThreshold(fcol.getThreshold()); + Color noColour = fcol.getNoColour(); + if (noColour == null) + { + setting.setNoValueColour(NoValueColour.NONE); + } + else if (noColour.equals(fcol.getMaxColour())) + { + setting.setNoValueColour(NoValueColour.MAX); + } + else + { + setting.setNoValueColour(NoValueColour.MIN); + } // -1 = No threshold, 0 = Below, 1 = Above setting.setThreshstate(fcol.isAboveThreshold() ? 1 : (fcol.isBelowThreshold() ? 0 : -1)); @@ -1374,7 +1409,7 @@ public class Jalview2XML setting.setDisplay( av.getFeaturesDisplayed().isVisible(featureType)); - float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer() + float rorder = fr .getOrder(featureType); if (rorder > -1) { @@ -1386,8 +1421,7 @@ public class Jalview2XML } // is groups actually supposed to be a map here ? - Iterator en = ap.getSeqPanel().seqCanvas - .getFeatureRenderer().getFeatureGroups().iterator(); + Iterator en = fr.getFeatureGroups().iterator(); Vector groupsAdded = new Vector<>(); while (en.hasNext()) { @@ -1398,8 +1432,7 @@ public class Jalview2XML } Group g = new Group(); g.setName(grp); - g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas - .getFeatureRenderer().checkGroupVisibility(grp, false)) + g.setDisplay(((Boolean) fr.checkGroupVisibility(grp, false)) .booleanValue()); fs.addGroup(g); groupsAdded.addElement(grp); @@ -1417,9 +1450,10 @@ public class Jalview2XML } else { - ArrayList hiddenRegions = hidden.getHiddenColumnsCopy(); - for (int[] region : hiddenRegions) + Iterator hiddenRegions = hidden.iterator(); + while (hiddenRegions.hasNext()) { + int[] region = hiddenRegions.next(); HiddenColumns hc = new HiddenColumns(); hc.setStart(region[0]); hc.setEnd(region[1]); @@ -2295,6 +2329,7 @@ public class Jalview2XML jarInputStreamProvider jprovider = createjarInputStreamProvider(file); af = loadJalviewAlign(jprovider); + af.setMenusForViewport(); } catch (MalformedURLException e) { @@ -2989,19 +3024,46 @@ public class Jalview2XML features[f].getEnd(), features[f].getScore(), features[f].getFeatureGroup()); sf.setStatus(features[f].getStatus()); + + /* + * load any feature attributes - include map-valued attributes + */ + Map> mapAttributes = new HashMap<>(); for (int od = 0; od < features[f].getOtherDataCount(); od++) { OtherData keyValue = features[f].getOtherData(od); - if (keyValue.getKey().startsWith("LINK")) + String attributeName = keyValue.getKey(); + String attributeValue = keyValue.getValue(); + if (attributeName.startsWith("LINK")) { - sf.addLink(keyValue.getValue()); + sf.addLink(attributeValue); } else { - sf.setValue(keyValue.getKey(), keyValue.getValue()); + String subAttribute = keyValue.getKey2(); + if (subAttribute == null) + { + // simple string-valued attribute + sf.setValue(attributeName, attributeValue); + } + else + { + // attribute 'key' has sub-attribute 'key2' + if (!mapAttributes.containsKey(attributeName)) + { + mapAttributes.put(attributeName, new HashMap<>()); + } + mapAttributes.get(attributeName).put(subAttribute, + attributeValue); + } } - } + for (Entry> mapAttribute : mapAttributes + .entrySet()) + { + sf.setValue(mapAttribute.getKey(), mapAttribute.getValue()); + } + // adds feature to datasequence's feature set (since Jalview 2.10) al.getSequenceAt(i).addSequenceFeature(sf); } @@ -3701,11 +3763,11 @@ public class Jalview2XML tp.setTitle(tree.getTitle()); tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree.getWidth(), tree.getHeight())); - tp.av = av; // af.viewport; // TODO: verify 'associate with all + tp.setViewport(av); // af.viewport; // TODO: verify 'associate with all // views' // works still - tp.treeCanvas.av = av; // af.viewport; - tp.treeCanvas.ap = ap; // af.alignPanel; + tp.getTreeCanvas().setViewport(av); // af.viewport; + tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel; } if (tp == null) @@ -3733,7 +3795,7 @@ public class Jalview2XML tp.showBootstrap(tree.getShowBootstrap()); tp.showDistances(tree.getShowDistances()); - tp.treeCanvas.threshold = tree.getThreshold(); + tp.getTreeCanvas().setThreshold(tree.getThreshold()); if (tree.getCurrentTree()) { @@ -4249,7 +4311,8 @@ public class Jalview2XML StructureData filedat = oldFiles.get(id); String pdbFile = filedat.getFilePath(); SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]); - binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE); + binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE, + null); binding.addSequenceForStructFile(pdbFile, seq); } // and add the AlignmentPanel's reference to the view panel @@ -4465,7 +4528,7 @@ public class Jalview2XML if (view.getViewName() != null) { - af.viewport.viewName = view.getViewName(); + af.viewport.setViewName(view.getViewName()); af.setInitialTabVisible(); } af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(), @@ -4576,9 +4639,11 @@ public class Jalview2XML af.viewport.setShowGroupConservation(false); } - // recover featre settings + // recover feature settings if (jms.getFeatureSettings() != null) { + FeatureRenderer fr = af.alignPanel.getSeqPanel().seqCanvas + .getFeatureRenderer(); FeaturesDisplayed fdi; af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed()); String[] renderOrder = new String[jms.getFeatureSettings() @@ -4590,14 +4655,51 @@ public class Jalview2XML .getSettingCount(); fs++) { Setting setting = jms.getFeatureSettings().getSetting(fs); + String featureType = setting.getType(); + + /* + * restore feature filters (if any) + */ + MatcherSet filters = setting.getMatcherSet(); + if (filters != null) + { + FeatureMatcherSetI filter = Jalview2XML + .unmarshalFilter(featureType, filters); + if (!filter.isEmpty()) + { + fr.setFeatureFilter(featureType, filter); + } + } + + /* + * restore feature colour scheme + */ + Color maxColour = new Color(setting.getColour()); if (setting.hasMincolour()) { - FeatureColourI gc = setting.hasMin() - ? new FeatureColour(new Color(setting.getMincolour()), - new Color(setting.getColour()), setting.getMin(), - setting.getMax()) - : new FeatureColour(new Color(setting.getMincolour()), - new Color(setting.getColour()), 0, 1); + /* + * minColour is always set unless a simple colour + * (including for colour by label though it doesn't use it) + */ + Color minColour = new Color(setting.getMincolour()); + Color noValueColour = minColour; + NoValueColour noColour = setting.getNoValueColour(); + if (noColour == NoValueColour.NONE) + { + noValueColour = null; + } + else if (noColour == NoValueColour.MAX) + { + noValueColour = maxColour; + } + float min = setting.hasMin() ? setting.getMin() : 0f; + float max = setting.hasMin() ? setting.getMax() : 1f; + FeatureColourI gc = new FeatureColour(minColour, maxColour, + noValueColour, min, max); + if (setting.getAttributeNameCount() > 0) + { + gc.setAttributeName(setting.getAttributeName()); + } if (setting.hasThreshold()) { gc.setThreshold(setting.getThreshold()); @@ -4622,26 +4724,26 @@ public class Jalview2XML gc.setColourByLabel(setting.getColourByLabel()); } // and put in the feature colour table. - featureColours.put(setting.getType(), gc); + featureColours.put(featureType, gc); } else { - featureColours.put(setting.getType(), - new FeatureColour(new Color(setting.getColour()))); + featureColours.put(featureType, + new FeatureColour(maxColour)); } - renderOrder[fs] = setting.getType(); + renderOrder[fs] = featureType; if (setting.hasOrder()) { - featureOrder.put(setting.getType(), setting.getOrder()); + featureOrder.put(featureType, setting.getOrder()); } else { - featureOrder.put(setting.getType(), new Float( + featureOrder.put(featureType, new Float( fs / jms.getFeatureSettings().getSettingCount())); } if (setting.getDisplay()) { - fdi.setVisible(setting.getType()); + fdi.setVisible(featureType); } } Map fgtable = new Hashtable<>(); @@ -4655,9 +4757,7 @@ public class Jalview2XML // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder); FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder, fgtable, featureColours, 1.0f, featureOrder); - af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer() - .transferSettings(frs); - + fr.transferSettings(frs); } if (view.getHiddenColumnsCount() > 0) @@ -5341,28 +5441,25 @@ public class Jalview2XML } - public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap, - boolean keepSeqRefs) + /** + * Provides a 'copy' of an alignment view (on action New View) by 'saving' the + * view as XML (but not to file), and then reloading it + * + * @param ap + * @return + */ + public AlignmentPanel copyAlignPanel(AlignmentPanel ap) { initSeqRefs(); JalviewModel jm = saveState(ap, null, null, null); - if (!keepSeqRefs) - { - clearSeqRefs(); - jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null); - } - else - { - uniqueSetSuffix = ""; - jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't - // overwrite the - // view we just - // copied - } + uniqueSetSuffix = ""; + jm.getJalviewModelSequence().getViewport(0).setId(null); + // we don't overwrite the view we just copied + if (this.frefedSequence == null) { - frefedSequence = new Vector(); + frefedSequence = new Vector<>(); } viewportsAdded.clear(); @@ -5382,32 +5479,8 @@ public class Jalview2XML return af.alignPanel; } - /** - * flag indicating if hashtables should be cleared on finalization TODO this - * flag may not be necessary - */ - private final boolean _cleartables = true; - private Hashtable jvids2vobj; - /* - * (non-Javadoc) - * - * @see java.lang.Object#finalize() - */ - @Override - protected void finalize() throws Throwable - { - // really make sure we have no buried refs left. - if (_cleartables) - { - clearSeqRefs(); - } - this.seqRefIds = null; - this.seqsToIds = null; - super.finalize(); - } - private void warn(String msg) { warn(msg, null); @@ -5638,4 +5711,289 @@ public class Jalview2XML { return counter++; } + + /** + * Populates an XML model of the feature colour scheme for one feature type + * + * @param featureType + * @param fcol + * @return + */ + protected static jalview.schemabinding.version2.Colour marshalColour( + String featureType, FeatureColourI fcol) + { + jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour(); + if (fcol.isSimpleColour()) + { + col.setRGB(Format.getHexString(fcol.getColour())); + } + else + { + col.setRGB(Format.getHexString(fcol.getMaxColour())); + col.setMin(fcol.getMin()); + col.setMax(fcol.getMax()); + col.setMinRGB(jalview.util.Format.getHexString(fcol.getMinColour())); + col.setAutoScale(fcol.isAutoScaled()); + col.setThreshold(fcol.getThreshold()); + col.setColourByLabel(fcol.isColourByLabel()); + col.setThreshType(fcol.isAboveThreshold() ? ColourThreshTypeType.ABOVE + : (fcol.isBelowThreshold() ? ColourThreshTypeType.BELOW + : ColourThreshTypeType.NONE)); + if (fcol.isColourByAttribute()) + { + col.setAttributeName(fcol.getAttributeName()); + } + Color noColour = fcol.getNoColour(); + if (noColour == null) + { + col.setNoValueColour(NoValueColour.NONE); + } + else if (noColour == fcol.getMaxColour()) + { + col.setNoValueColour(NoValueColour.MAX); + } + else + { + col.setNoValueColour(NoValueColour.MIN); + } + } + col.setName(featureType); + return col; + } + + /** + * Populates an XML model of the feature filter(s) for one feature type + * + * @param firstMatcher + * the first (or only) match condition) + * @param filter + * remaining match conditions (if any) + * @param and + * if true, conditions are and-ed, else or-ed + */ + protected static MatcherSet marshalFilter(FeatureMatcherI firstMatcher, + Iterator filters, boolean and) + { + MatcherSet result = new MatcherSet(); + + if (filters.hasNext()) + { + /* + * compound matcher + */ + CompoundMatcher compound = new CompoundMatcher(); + compound.setAnd(and); + MatcherSet matcher1 = marshalFilter(firstMatcher, + Collections.emptyIterator(), and); + compound.addMatcherSet(matcher1); + FeatureMatcherI nextMatcher = filters.next(); + MatcherSet matcher2 = marshalFilter(nextMatcher, filters, and); + compound.addMatcherSet(matcher2); + result.setCompoundMatcher(compound); + } + else + { + /* + * single condition matcher + */ + MatchCondition matcherModel = new MatchCondition(); + matcherModel.setCondition( + firstMatcher.getMatcher().getCondition().getStableName()); + matcherModel.setValue(firstMatcher.getMatcher().getPattern()); + if (firstMatcher.isByAttribute()) + { + matcherModel.setBy(FeatureMatcherByType.BYATTRIBUTE); + matcherModel.setAttributeName(firstMatcher.getAttribute()); + } + else if (firstMatcher.isByLabel()) + { + matcherModel.setBy(FeatureMatcherByType.BYLABEL); + } + else if (firstMatcher.isByScore()) + { + matcherModel.setBy(FeatureMatcherByType.BYSCORE); + } + result.setMatchCondition(matcherModel); + } + + return result; + } + + /** + * Loads one XML model of a feature filter to a Jalview object + * + * @param featureType + * @param matcherSetModel + * @return + */ + protected static FeatureMatcherSetI unmarshalFilter( + String featureType, MatcherSet matcherSetModel) + { + FeatureMatcherSetI result = new FeatureMatcherSet(); + try + { + unmarshalFilterConditions(result, matcherSetModel, true); + } catch (IllegalStateException e) + { + // mixing AND and OR conditions perhaps + System.err.println( + String.format("Error reading filter conditions for '%s': %s", + featureType, e.getMessage())); + // return as much as was parsed up to the error + } + + return result; + } + + /** + * Adds feature match conditions to matcherSet as unmarshalled from XML + * (possibly recursively for compound conditions) + * + * @param matcherSet + * @param matcherSetModel + * @param and + * if true, multiple conditions are AND-ed, else they are OR-ed + * @throws IllegalStateException + * if AND and OR conditions are mixed + */ + protected static void unmarshalFilterConditions( + FeatureMatcherSetI matcherSet, MatcherSet matcherSetModel, + boolean and) + { + MatchCondition mc = matcherSetModel.getMatchCondition(); + if (mc != null) + { + /* + * single condition + */ + FeatureMatcherByType filterBy = mc.getBy(); + Condition cond = Condition.fromString(mc.getCondition()); + String pattern = mc.getValue(); + FeatureMatcherI matchCondition = null; + if (filterBy == FeatureMatcherByType.BYLABEL) + { + matchCondition = FeatureMatcher.byLabel(cond, pattern); + } + else if (filterBy == FeatureMatcherByType.BYSCORE) + { + matchCondition = FeatureMatcher.byScore(cond, pattern); + + } + else if (filterBy == FeatureMatcherByType.BYATTRIBUTE) + { + String[] attNames = mc.getAttributeName(); + matchCondition = FeatureMatcher.byAttribute(cond, pattern, + attNames); + } + + /* + * note this throws IllegalStateException if AND-ing to a + * previously OR-ed compound condition, or vice versa + */ + if (and) + { + matcherSet.and(matchCondition); + } + else + { + matcherSet.or(matchCondition); + } + } + else + { + /* + * compound condition + */ + MatcherSet[] matchers = matcherSetModel.getCompoundMatcher() + .getMatcherSet(); + boolean anded = matcherSetModel.getCompoundMatcher().getAnd(); + if (matchers.length == 2) + { + unmarshalFilterConditions(matcherSet, matchers[0], anded); + unmarshalFilterConditions(matcherSet, matchers[1], anded); + } + else + { + System.err.println("Malformed compound filter condition"); + } + } + } + + /** + * Loads one XML model of a feature colour to a Jalview object + * + * @param colourModel + * @return + */ + protected static FeatureColourI unmarshalColour( + jalview.schemabinding.version2.Colour colourModel) + { + FeatureColourI colour = null; + + if (colourModel.hasMax()) + { + Color mincol = null; + Color maxcol = null; + Color noValueColour = null; + + try + { + mincol = new Color(Integer.parseInt(colourModel.getMinRGB(), 16)); + maxcol = new Color(Integer.parseInt(colourModel.getRGB(), 16)); + } catch (Exception e) + { + Cache.log.warn("Couldn't parse out graduated feature color.", e); + } + + NoValueColour noCol = colourModel.getNoValueColour(); + if (noCol == NoValueColour.MIN) + { + noValueColour = mincol; + } + else if (noCol == NoValueColour.MAX) + { + noValueColour = maxcol; + } + + colour = new FeatureColour(mincol, maxcol, noValueColour, + colourModel.getMin(), + colourModel.getMax()); + String[] attributes = colourModel.getAttributeName(); + if (attributes != null && attributes.length > 0) + { + colour.setAttributeName(attributes); + } + if (colourModel.hasAutoScale()) + { + colour.setAutoScaled(colourModel.getAutoScale()); + } + if (colourModel.hasColourByLabel()) + { + colour.setColourByLabel(colourModel.getColourByLabel()); + } + if (colourModel.hasThreshold()) + { + colour.setThreshold(colourModel.getThreshold()); + } + ColourThreshTypeType ttyp = colourModel.getThreshType(); + if (ttyp != null) + { + if (ttyp == ColourThreshTypeType.ABOVE) + { + colour.setAboveThreshold(true); + } + else if (ttyp == ColourThreshTypeType.BELOW) + { + colour.setBelowThreshold(true); + } + } + } + else + { + Color color = new Color(Integer.parseInt(colourModel.getRGB(), 16)); + colour = new FeatureColour(color); + } + + return colour; + } }