From: gmungoc Date: Mon, 8 May 2017 16:01:31 +0000 (+0100) Subject: Merge branch 'develop' into features/JAL-2446NCList X-Git-Tag: Release_2_10_3b1~295 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=a42904684c75b2729d763af933e5a991a3424f67;hp=-c;p=jalview.git Merge branch 'develop' into features/JAL-2446NCList Conflicts: src/jalview/appletgui/IdPanel.java src/jalview/gui/FeatureRenderer.java --- a42904684c75b2729d763af933e5a991a3424f67 diff --combined src/jalview/appletgui/IdPanel.java index 80f03a1,4cc4a3a..39a15b8 --- a/src/jalview/appletgui/IdPanel.java +++ b/src/jalview/appletgui/IdPanel.java @@@ -20,6 -20,7 +20,6 @@@ */ package jalview.appletgui; -import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; @@@ -34,6 -35,7 +34,7 @@@ import java.awt.event.InputEvent import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@@ -55,11 -57,11 +56,11 @@@ public class IdPanel extends Panel impl UrlProviderI urlProvider = null; -- public IdPanel(AlignViewport av, AlignmentPanel parent) ++ public IdPanel(AlignViewport viewport, AlignmentPanel parent) { -- this.av = av; ++ this.av = viewport; alignPanel = parent; -- idCanvas = new IdCanvas(av); ++ idCanvas = new IdCanvas(viewport); setLayout(new BorderLayout()); add(idCanvas, BorderLayout.CENTER); idCanvas.addMouseListener(this); @@@ -70,12 -72,12 +71,12 @@@ // make a list of label,url pairs HashMap urlList = new HashMap(); -- if (av.applet != null) ++ if (viewport.applet != null) { for (int i = 1; i < 10; i++) { -- label = av.applet.getParameter("linkLabel_" + i); -- url = av.applet.getParameter("linkURL_" + i); ++ label = viewport.applet.getParameter("linkLabel_" + i); ++ url = viewport.applet.getParameter("linkURL_" + i); // only add non-null parameters if (label != null) @@@ -87,7 -89,7 +88,7 @@@ if (!urlList.isEmpty()) { // set default as first entry in list -- String defaultUrl = av.applet.getParameter("linkLabel_1"); ++ String defaultUrl = viewport.applet.getParameter("linkLabel_1"); UrlProviderFactoryI factory = new AppletUrlProviderFactory( defaultUrl, urlList); urlProvider = factory.createUrlProvider(); @@@ -104,57 -106,64 +105,57 @@@ SequenceI sequence = av.getAlignment().getSequenceAt(seq); - // look for non-pos features StringBuffer tooltiptext = new StringBuffer(); - if (sequence != null) + if (sequence == null) { - if (sequence.getDescription() != null) + return; + } + if (sequence.getDescription() != null) + { + tooltiptext.append(sequence.getDescription()); + tooltiptext.append("\n"); + } + + for (SequenceFeature sf : sequence.getFeatures() + .getNonPositionalFeatures()) + { + boolean nl = false; + if (sf.getFeatureGroup() != null) { - tooltiptext.append(sequence.getDescription()); - tooltiptext.append("\n"); + tooltiptext.append(sf.getFeatureGroup()); + nl = true; } - - SequenceFeature sf[] = sequence.getSequenceFeatures(); - for (int sl = 0; sf != null && sl < sf.length; sl++) + if (sf.getType() != null) { - if (sf[sl].begin == sf[sl].end && sf[sl].begin == 0) - { - boolean nl = false; - if (sf[sl].getFeatureGroup() != null) - { - tooltiptext.append(sf[sl].getFeatureGroup()); - nl = true; - } - ; - if (sf[sl].getType() != null) - { - tooltiptext.append(" "); - tooltiptext.append(sf[sl].getType()); - nl = true; - } - ; - if (sf[sl].getDescription() != null) - { - tooltiptext.append(" "); - tooltiptext.append(sf[sl].getDescription()); - nl = true; - } - ; - if (!Float.isNaN(sf[sl].getScore()) && sf[sl].getScore() != 0f) - { - tooltiptext.append(" Score = "); - tooltiptext.append(sf[sl].getScore()); - nl = true; - } - ; - if (sf[sl].getStatus() != null && sf[sl].getStatus().length() > 0) - { - tooltiptext.append(" ("); - tooltiptext.append(sf[sl].getStatus()); - tooltiptext.append(")"); - nl = true; - } - ; - if (nl) - { - tooltiptext.append("\n"); - } - } + tooltiptext.append(" "); + tooltiptext.append(sf.getType()); + nl = true; + } + if (sf.getDescription() != null) + { + tooltiptext.append(" "); + tooltiptext.append(sf.getDescription()); + nl = true; + } + if (!Float.isNaN(sf.getScore()) && sf.getScore() != 0f) + { + tooltiptext.append(" Score = "); + tooltiptext.append(sf.getScore()); + nl = true; + } + if (sf.getStatus() != null && sf.getStatus().length() > 0) + { + tooltiptext.append(" ("); + tooltiptext.append(sf.getStatus()); + tooltiptext.append(")"); + nl = true; + } + if (nl) + { + tooltiptext.append("\n"); } } + if (tooltiptext.length() == 0) { // nothing to display - so clear tooltip if one is visible @@@ -217,6 -226,10 +218,10 @@@ String id = sq.getName(); // get the default url with the sequence details filled in + if (urlProvider == null) + { + return; + } String url = urlProvider.getPrimaryUrl(id); String target = urlProvider.getPrimaryTarget(id); try @@@ -275,21 -288,30 +280,29 @@@ if ((e.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) { - Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq); + SequenceI sq = av.getAlignment().getSequenceAt(seq); - // build a new links menu based on the current links + any non-positional - // features + /* + * build a new links menu based on the current links + * and any non-positional features + */ - List nlinks = urlProvider.getLinksForMenu(); + List nlinks; + if (urlProvider != null) + { + nlinks = urlProvider.getLinksForMenu(); + } + else + { + nlinks = new ArrayList(); + } - SequenceFeature sf[] = sq == null ? null : sq.getSequenceFeatures(); - for (int sl = 0; sf != null && sl < sf.length; sl++) + + for (SequenceFeature sf : sq.getFeatures().getNonPositionalFeatures()) { - if (sf[sl].begin == sf[sl].end && sf[sl].begin == 0) + if (sf.links != null) { - if (sf[sl].links != null && sf[sl].links.size() > 0) + for (String link : sf.links) { - for (int l = 0, lSize = sf[sl].links.size(); l < lSize; l++) - { - nlinks.add(sf[sl].links.elementAt(l)); - } + nlinks.add(link); } } } @@@ -402,9 -424,9 +415,9 @@@ boolean up = true; -- public ScrollThread(boolean up) ++ public ScrollThread(boolean isUp) { -- this.up = up; ++ this.up = isUp; start(); } diff --combined src/jalview/gui/FeatureRenderer.java index 56da67c,50a8689..b33ada2 --- a/src/jalview/gui/FeatureRenderer.java +++ b/src/jalview/gui/FeatureRenderer.java @@@ -25,6 -25,7 +25,7 @@@ import jalview.datamodel.SearchResults import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; + import jalview.io.FeaturesFile; import jalview.schemes.FeatureColour; import jalview.util.ColorUtils; import jalview.util.MessageManager; @@@ -42,7 -43,7 +43,8 @@@ import java.awt.event.MouseAdapter import java.awt.event.MouseEvent; import java.util.Arrays; import java.util.Comparator; +import java.util.HashMap; + import java.util.List; import javax.swing.JColorChooser; import javax.swing.JComboBox; @@@ -68,20 -69,19 +70,19 @@@ public class FeatureRenderer extend AlignmentPanel ap; /** - * Creates a new FeatureRenderer object. + * Creates a new FeatureRenderer object * - * @param av - * DOCUMENT ME! + * @param alignPanel */ - public FeatureRenderer(AlignmentPanel ap) + public FeatureRenderer(AlignmentPanel alignPanel) { - super(ap.av); - this.ap = ap; - if (ap != null && ap.getSeqPanel() != null - && ap.getSeqPanel().seqCanvas != null - && ap.getSeqPanel().seqCanvas.fr != null) + super(alignPanel.av); + this.ap = alignPanel; + if (alignPanel.getSeqPanel() != null + && alignPanel.getSeqPanel().seqCanvas != null + && alignPanel.getSeqPanel().seqCanvas.fr != null) { - transferSettings(ap.getSeqPanel().seqCanvas.fr); + transferSettings(alignPanel.getSeqPanel().seqCanvas.fr); } } @@@ -99,15 -99,38 +100,38 @@@ int featureIndex = 0; - boolean amendFeatures(final SequenceI[] sequences, - final SequenceFeature[] features, boolean newFeatures, - final AlignmentPanel ap) + /** + * Presents a dialog allowing the user to add new features, or amend or delete + * existing features. Currently this can be on + *
    + *
  • double-click on a sequence - Amend/Delete features at position
  • + *
  • Create sequence feature from pop-up menu on selected region
  • + *
  • Create features for pattern matches from Find
  • + *
+ * + * @param sequences + * the sequences features are to be created on (if creating + * features), or a single sequence (if amending features) + * @param features + * the current features at the position (if amending), or template + * new features with start/end position set (if creating) + * @param create + * true to create features, false to amend or delete + * @param featureType + * the feature type to set on new features; if null, defaults to the + * type of the last new feature created if any, failing that to + * "feature_1" + * @param alignPanel + * @return + */ + protected boolean amendFeatures(final List sequences, + final List features, boolean create, + final AlignmentPanel alignPanel, String featureType) { featureIndex = 0; - final JPanel bigPanel = new JPanel(new BorderLayout()); - final JComboBox overlaps; + final JPanel mainPanel = new JPanel(new BorderLayout()); final JTextField name = new JTextField(25); final JTextField source = new JTextField(25); final JTextArea description = new JTextArea(3, 25); @@@ -135,14 -158,15 +159,15 @@@ if (col != null) { fcol = new FeatureColour(col); - updateColourButton(bigPanel, colour, new FeatureColour(col)); + updateColourButton(mainPanel, colour, new FeatureColour(col)); } } else { if (fcc == null) { - final String type = features[featureIndex].getType(); + final String ft = features.get(featureIndex).getType(); + final String type = ft == null ? lastFeatureAdded : ft; fcc = new FeatureColourChooser(me, type); fcc.setRequestFocusEnabled(true); fcc.requestFocus(); @@@ -156,7 -180,7 +181,7 @@@ fcol = fcc.getLastColour(); fcc = null; setColour(type, fcol); - updateColourButton(bigPanel, colour, fcol); + updateColourButton(mainPanel, colour, fcol); } }); @@@ -164,26 -188,27 +189,27 @@@ } } }); - JPanel tmp = new JPanel(); - JPanel panel = new JPanel(new GridLayout(3, 1)); + JPanel gridPanel = new JPanel(new GridLayout(3, 1)); - // ///////////////////////////////////// - // /MULTIPLE FEATURES AT SELECTED RESIDUE - if (!newFeatures && features.length > 1) + if (!create && features.size() > 1) { - panel = new JPanel(new GridLayout(4, 1)); - tmp = new JPanel(); - tmp.add(new JLabel(MessageManager.getString("label.select_feature") + /* + * more than one feature at selected position - add a drop-down + * to choose the feature to amend + */ + gridPanel = new JPanel(new GridLayout(4, 1)); + JPanel choosePanel = new JPanel(); + choosePanel.add(new JLabel(MessageManager + .getString("label.select_feature") + ":")); - overlaps = new JComboBox(); - for (int i = 0; i < features.length; i++) + final JComboBox overlaps = new JComboBox(); + for (SequenceFeature sf : features) { - overlaps.addItem(features[i].getType() + "/" - + features[i].getBegin() + "-" + features[i].getEnd() - + " (" + features[i].getFeatureGroup() + ")"); + String text = sf.getType() + "/" + sf.getBegin() + "-" + + sf.getEnd() + " (" + sf.getFeatureGroup() + ")"; + overlaps.addItem(text); } - - tmp.add(overlaps); + choosePanel.add(overlaps); overlaps.addItemListener(new ItemListener() { @@@ -194,17 -219,18 +220,18 @@@ if (index != -1) { featureIndex = index; - name.setText(features[index].getType()); - description.setText(features[index].getDescription()); - source.setText(features[index].getFeatureGroup()); - start.setValue(new Integer(features[index].getBegin())); - end.setValue(new Integer(features[index].getEnd())); + SequenceFeature sf = features.get(index); + name.setText(sf.getType()); + description.setText(sf.getDescription()); + source.setText(sf.getFeatureGroup()); + start.setValue(new Integer(sf.getBegin())); + end.setValue(new Integer(sf.getEnd())); SearchResultsI highlight = new SearchResults(); - highlight.addResult(sequences[0], features[index].getBegin(), - features[index].getEnd()); + highlight.addResult(sequences.get(0), sf.getBegin(), + sf.getEnd()); - ap.getSeqPanel().seqCanvas.highlightSearchResults(highlight); + alignPanel.getSeqPanel().seqCanvas.highlightSearchResults(highlight); } FeatureColourI col = getFeatureStyle(name.getText()); @@@ -214,32 -240,32 +241,32 @@@ .createColourFromName(name.getText())); } oldcol = fcol = col; - updateColourButton(bigPanel, colour, col); + updateColourButton(mainPanel, colour, col); } }); - panel.add(tmp); + gridPanel.add(choosePanel); } // //////// // //////////////////////////////////// - tmp = new JPanel(); - panel.add(tmp); - tmp.add(new JLabel(MessageManager.getString("label.name:"), + JPanel namePanel = new JPanel(); + gridPanel.add(namePanel); + namePanel.add(new JLabel(MessageManager.getString("label.name:"), JLabel.RIGHT)); - tmp.add(name); + namePanel.add(name); - tmp = new JPanel(); - panel.add(tmp); - tmp.add(new JLabel(MessageManager.getString("label.group:"), + JPanel groupPanel = new JPanel(); + gridPanel.add(groupPanel); + groupPanel.add(new JLabel(MessageManager.getString("label.group:"), JLabel.RIGHT)); - tmp.add(source); + groupPanel.add(source); - tmp = new JPanel(); - panel.add(tmp); - tmp.add(new JLabel(MessageManager.getString("label.colour"), + JPanel colourPanel = new JPanel(); + gridPanel.add(colourPanel); + colourPanel.add(new JLabel(MessageManager.getString("label.colour"), JLabel.RIGHT)); - tmp.add(colour); + colourPanel.add(colour); colour.setPreferredSize(new Dimension(150, 15)); colour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 9)); colour.setForeground(Color.black); @@@ -247,50 -273,59 +274,59 @@@ colour.setVerticalAlignment(SwingConstants.CENTER); colour.setHorizontalTextPosition(SwingConstants.CENTER); colour.setVerticalTextPosition(SwingConstants.CENTER); - bigPanel.add(panel, BorderLayout.NORTH); + mainPanel.add(gridPanel, BorderLayout.NORTH); - panel = new JPanel(); - panel.add(new JLabel(MessageManager.getString("label.description:"), + JPanel descriptionPanel = new JPanel(); + descriptionPanel.add(new JLabel(MessageManager + .getString("label.description:"), JLabel.RIGHT)); description.setFont(JvSwingUtils.getTextAreaFont()); description.setLineWrap(true); - panel.add(new JScrollPane(description)); + descriptionPanel.add(new JScrollPane(description)); - if (!newFeatures) + if (!create) { - bigPanel.add(panel, BorderLayout.SOUTH); + mainPanel.add(descriptionPanel, BorderLayout.SOUTH); - panel = new JPanel(); - panel.add(new JLabel(MessageManager.getString("label.start"), + JPanel startEndPanel = new JPanel(); + startEndPanel.add(new JLabel(MessageManager.getString("label.start"), JLabel.RIGHT)); - panel.add(start); - panel.add(new JLabel(MessageManager.getString("label.end"), + startEndPanel.add(start); + startEndPanel.add(new JLabel(MessageManager.getString("label.end"), JLabel.RIGHT)); - panel.add(end); - bigPanel.add(panel, BorderLayout.CENTER); + startEndPanel.add(end); + mainPanel.add(startEndPanel, BorderLayout.CENTER); } else { - bigPanel.add(panel, BorderLayout.CENTER); + mainPanel.add(descriptionPanel, BorderLayout.CENTER); } - if (lastFeatureAdded == null) + SequenceFeature firstFeature = features.get(0); + if (featureType != null) { - if (features[0].type != null) - { - lastFeatureAdded = features[0].type; - } - else + lastFeatureAdded = featureType; + } + else + { + if (lastFeatureAdded == null) { - lastFeatureAdded = "feature_1"; + if (firstFeature.type != null) + { + lastFeatureAdded = firstFeature.type; + } + else + { + lastFeatureAdded = "feature_1"; + } } } if (lastFeatureGroupAdded == null) { - if (features[0].featureGroup != null) + if (firstFeature.featureGroup != null) { - lastFeatureGroupAdded = features[0].featureGroup; + lastFeatureGroupAdded = firstFeature.featureGroup; } else { @@@ -298,43 -333,49 +334,49 @@@ } } - if (newFeatures) + if (create) { name.setText(lastFeatureAdded); source.setText(lastFeatureGroupAdded); } else { - name.setText(features[0].getType()); - source.setText(features[0].getFeatureGroup()); + name.setText(firstFeature.getType()); + source.setText(firstFeature.getFeatureGroup()); } - start.setValue(new Integer(features[0].getBegin())); - end.setValue(new Integer(features[0].getEnd())); - description.setText(features[0].getDescription()); - updateColourButton(bigPanel, colour, + start.setValue(new Integer(firstFeature.getBegin())); + end.setValue(new Integer(firstFeature.getEnd())); + description.setText(firstFeature.getDescription()); + updateColourButton(mainPanel, colour, (oldcol = fcol = getFeatureStyle(name.getText()))); Object[] options; - if (!newFeatures) + if (!create) { - options = new Object[] { "Amend", "Delete", "Cancel" }; + options = new Object[] { MessageManager.getString("label.amend"), + MessageManager.getString("action.delete"), + MessageManager.getString("action.cancel") }; } else { - options = new Object[] { "OK", "Cancel" }; + options = new Object[] { MessageManager.getString("action.ok"), + MessageManager.getString("action.cancel") }; } - String title = newFeatures ? MessageManager + String title = create ? MessageManager .getString("label.create_new_sequence_features") : MessageManager.formatMessage("label.amend_delete_features", - new String[] { sequences[0].getName() }); + new String[] { sequences.get(0).getName() }); + /* + * show the dialog + */ int reply = JvOptionPane.showInternalOptionDialog(Desktop.desktop, - bigPanel, title, JvOptionPane.YES_NO_CANCEL_OPTION, + mainPanel, title, JvOptionPane.YES_NO_CANCEL_OPTION, JvOptionPane.QUESTION_MESSAGE, null, options, MessageManager.getString("action.ok")); - jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile(); + FeaturesFile ffile = new FeaturesFile(); if (reply == JvOptionPane.OK_OPTION && name.getText().length() > 0) { @@@ -348,57 -389,43 +390,69 @@@ } } - if (!newFeatures) + if (!create) { - SequenceFeature sf = features[featureIndex]; + SequenceFeature sf = features.get(featureIndex); if (reply == JvOptionPane.NO_OPTION) { - sequences[0].getDatasetSequence().deleteFeature(sf); + /* + * NO_OPTION corresponds to the Delete button + */ + sequences.get(0).getDatasetSequence().deleteFeature(sf); } else if (reply == JvOptionPane.YES_OPTION) { + /* + * YES_OPTION corresponds to the Amend button + */ + boolean typeChanged = !lastFeatureAdded.equals(sf.type); - sf.type = lastFeatureAdded; - sf.featureGroup = lastFeatureGroupAdded; - sf.description = lastDescriptionAdded; - - setColour(sf.type, fcol); - getFeaturesDisplayed().setVisible(sf.type); - + String newType = lastFeatureAdded; + String newFeatureGroup = lastFeatureGroupAdded; + String newDescription = lastDescriptionAdded; + + setColour(newType, fcol); + getFeaturesDisplayed().setVisible(newType); + int newBegin = sf.begin; + int newEnd = sf.end; try { - sf.begin = ((Integer) start.getValue()).intValue(); - sf.end = ((Integer) end.getValue()).intValue(); + newBegin = ((Integer) start.getValue()).intValue(); + newEnd = ((Integer) end.getValue()).intValue(); } catch (NumberFormatException ex) { + // JSpinner doesn't accept invalid format data :-) + } + + /* + * replace the feature by deleting it and adding a new one + * (to ensure integrity of SequenceFeatures data store) + */ - sequences[0].deleteFeature(sf); ++ sequences.get(0).deleteFeature(sf); + SequenceFeature newSf = new SequenceFeature(newType, + newDescription, newBegin, newEnd, sf.getScore(), + newFeatureGroup); + // ensure any additional properties are copied + if (sf.otherDetails != null) + { + newSf.otherDetails = new HashMap(sf.otherDetails); + } + ffile.parseDescriptionHTML(newSf, false); + // add any additional links not parsed from description + if (sf.links != null) + { + for (String link : sf.links) + { + newSf.addLink(link); + } } + // amend features only gets one sequence to act on - sequences[0].addSequenceFeature(newSf); ++ sequences.get(0).addSequenceFeature(newSf); + - ffile.parseDescriptionHTML(sf, false); + if (typeChanged) + { + findAllFeatures(); + } } } else @@@ -406,14 -433,15 +460,15 @@@ { if (reply == JvOptionPane.OK_OPTION && lastFeatureAdded.length() > 0) { - for (int i = 0; i < sequences.length; i++) + for (int i = 0; i < sequences.size(); i++) { - features[i].type = lastFeatureAdded; + SequenceFeature sf = features.get(i); + sf.type = lastFeatureAdded; // fix for JAL-1538 - always set feature group here - features[i].featureGroup = lastFeatureGroupAdded; - features[i].description = lastDescriptionAdded; - sequences[i].addSequenceFeature(features[i]); - ffile.parseDescriptionHTML(features[i], false); + sf.featureGroup = lastFeatureGroupAdded; + sf.description = lastDescriptionAdded; + sequences.get(i).addSequenceFeature(sf); + ffile.parseDescriptionHTML(sf, false); } if (lastFeatureGroupAdded != null) @@@ -425,7 -453,7 +480,7 @@@ findAllFeatures(false); - ap.paintAlignment(true); + alignPanel.paintAlignment(true); return true; } @@@ -435,7 -463,7 +490,7 @@@ } } - ap.paintAlignment(true); + alignPanel.paintAlignment(true); return true; }