From: gmungoc Date: Mon, 7 Nov 2016 15:58:24 +0000 (+0000) Subject: Merge branch 'develop' into features/JAL-2295setChimeraAttributes X-Git-Tag: Release_2_11_0~62^2~71 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=8c04eddb0471d585f31292accfef12acf021b825;hp=e8276f5598621d3f7e19c6bdbc49276706322c43;p=jalview.git Merge branch 'develop' into features/JAL-2295setChimeraAttributes --- diff --git a/help/html/colourSchemes/abovePID.html b/help/html/colourSchemes/abovePID.html index 614764b..ad47dae 100755 --- a/help/html/colourSchemes/abovePID.html +++ b/help/html/colourSchemes/abovePID.html @@ -36,9 +36,10 @@ td {

Selecting this option causes the colour scheme to be applied to only those residues that occur in that column more than a certain - percentage of the time. For instance selecting the threshold to be - 100 will only colour those columns with 100 % identity. This - threshold option can be applied to the Zappo, Taylor, Hydrophobicity - and User colour schemes.

+ percentage of the time. For instance, selecting the threshold to be + 100 will only colour those columns with 100% identity.

+

To be coloured, a residue must match the consensus (most commonly occurring) residue for the column (or joint equal consensus).

+

The percentage calculation may include or exclude gaps in the column, depending on the option selected for the consensus calculation.

+

With a threshold of 0, colouring is unchanged (including non-consensus residues).

diff --git a/help/html/webServices/urllinks.html b/help/html/webServices/urllinks.html index 0a4c650..1a1f0d0 100644 --- a/help/html/webServices/urllinks.html +++ b/help/html/webServices/urllinks.html @@ -28,7 +28,7 @@ and the desktop application are able to open URLs as 'popups' in your web browser.
Double-clicking on the ID of a sequence will open the first URL that can be generated from its sequence ID. - This is often the SRS site, but you can easily configure your own sequence URL links.

@@ -40,10 +40,10 @@

Configuring URL Links
URL links are defined in the "Connections" tab of the Jalview desktop - preferences, or specified as applet - parameters.
By default the item "SRS" is added + href="../features/preferences.html">Jalview desktop + preferences, or specified as applet + parameters.
By default the item "EMBL-EBI Search" is added to this link menu. This link will show a web page in your default browser with the selected sequence id as part of the URL.
In the preferences dialog box, click new to add a @@ -51,9 +51,9 @@ to remove it.
You can name the link, this will be displayed on a new menu item under the "Link" menu when you right click on a sequence id.
The URL string must contain a - token that can be replaced with a sequence ID. The simplest token is + token that can be replaced with a sequence ID or DB accession ID. The simplest token is "$SEQUENCE_ID$", which will be replaced by the chosen - sequence id when you click on it. + sequence id when you click on it.

eg.
UniRef100 = @@ -61,15 +61,16 @@ Swissprot = http://www.expasy.org/uniprot/$SEQUENCE_ID$

Links will also be made for any database cross references associated with the sequence where the database name exactly matches a URL link - name. In this case, the $SEQUENCE_ID$ string will be replaced with + name. In this case, the $DB_ACCESSION$ string will be replaced with the accession string for the database cross-reference, rather than - the sequence ID for the sequence (since Jalview 2.4). + the sequence ID for the sequence (since Jalview 2.10.1).

Regular Expression Substitution
A url may contain a string of the form $SEQUENCE_ID=/regular - expression/=$. In this case, the regular expression will be - applied to the full sequence ID string and the resulting match will + expression/=$ or $DB_ACCESSION=/regular expression/=$. + In this case, the regular expression will be + applied to the full sequence ID or DB accession ID string and the resulting match will be inserted into the URL. Groups of parentheses can be used to specify which regions of the regular expression will be used to generate the URL: diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index bd8f63a..1262536 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -789,9 +789,9 @@ label.hide_columns_containing = Hide columns containing label.hide_columns_not_containing = Hide columns that do not contain option.trim_retrieved_seqs = Trim retrieved sequences label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences. -label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=//=$ -label.use_sequence_id_2 = to embed sequence id in URL -label.use_sequence_id_3 = Use $SEQUENCE_NAME$ similarly to embed sequence name +label.use_sequence_id_1 = Use $DB_ACCESSION$ or $DB_ACCESSION=//=$ +label.use_sequence_id_2 = to embed accession id in URL +label.use_sequence_id_3 = Use $SEQUENCE_ID$ similarly to embed sequence id label.use_sequence_id_4 = label.ws_parameters_for = Parameters for {0} label.switch_server = Switch server @@ -1146,7 +1146,7 @@ warn.user_defined_width_requirements = The user defined width for the\nannotatio label.couldnt_create_sequence_fetcher = Couldn't create SequenceFetcher warn.couldnt_create_sequence_fetcher_client = Could not create the sequence fetcher client. Check error logs for details. warn.server_didnt_pass_validation = Service did not pass validation.\nCheck the Jalview Console for more details. -warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$ or a regex $SEQUENCE_ID=//=$ +warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$, $DB_ACCESSION$, or a regex warn.urls_not_contacted = URLs that could not be contacted warn.urls_no_jaba = URLs without any JABA Services info.validate_jabaws_server = Validate JabaWS Server ?\n(Look in console output for results) @@ -1270,3 +1270,7 @@ status.exporting_alignment_as_x_file = Exporting alignment as {0} file label.column = Column label.cant_map_cds = Unable to map CDS to protein\nCDS missing or incomplete label.operation_failed = Operation failed +label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB accessions +label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window: +label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'. +label.do_not_display_again = Do not display this message again diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 754d94d..50bfd24 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -720,10 +720,10 @@ label.select_columns_containing = Seleccione las columnas que contengan label.select_columns_not_containing = Seleccione las columnas que no contengan option.trim_retrieved_seqs = Ajustar las secuencias recuperadas label.trim_retrieved_sequences = Cuando la secuencia de referencia es más larga que la secuencia con la que está trabajando, sólo se mantienen las subsecuencias relevantes. -label.use_sequence_id_1 = Utilice $SEQUENCE_ID$ o $SEQUENCE_ID=//=$ -label.use_sequence_id_2 = para embeber el id de la secuencia en una URL -label.use_sequence_id_3 = Utilice $SEQUENCE_NAME$ de manera similar para embeber -label.use_sequence_id_4 = el nombre de la secuencia +label.use_sequence_id_1 = Utilice $DB_ACCESSION$ o $DB_ACCESSION=//=$ +label.use_sequence_id_2 = para embeber el ID de accesión en una URL +label.use_sequence_id_3 = Utilice $SEQUENCE_ID$ de manera similar para embeber +label.use_sequence_id_4 = el ID de la secuencia label.ws_parameters_for = Parámetros para {0} label.switch_server = Cambiar servidor label.open_jabaws_web_page = Abra el página principal del servidor JABAWS en un navegador web @@ -1070,7 +1070,7 @@ warn.user_defined_width_requirements = La anchura definida por el usuario para l label.couldnt_create_sequence_fetcher = No es posible crear SequenceFetcher warn.couldnt_create_sequence_fetcher_client = No es posible crear el cliente de recuperador de secuencias. Comprueba el fichero de log para más detalles. warn.server_didnt_pass_validation = El servicio no ha pasado la validaci\u00F3n.\nCompruebe la consola de Jalview para m\u00E1s detalles. -warn.url_must_contain = La URL de la secuencia debe contener $SEQUENCE_ID$ o un regex $SEQUENCE_ID=//=$ +warn.url_must_contain = La URL de la secuencia debe contener $SEQUENCE_ID$, $DB_ACCESSION$ o un regex info.validate_jabaws_server = \u00BFValidar el servidor JabaWS?\n(Consulte la consola de salida para obtener los resultados) label.test_server = ¿Probar servidor? info.you_want_jalview_to_find_uniprot_accessions = \u00BFDesea que Jalview encuentre\nUniprot Accession ids para los nombres de secuencias dados? @@ -1269,3 +1269,7 @@ status.exporting_alignment_as_x_file = Exportando alineamiento como fichero tipo label.column = Columna label.cant_map_cds = No se pudo mapear CDS a proteína\nDatos CDS faltantes o incompletos label.operation_failed = Operación fallada +label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza más para accesiones DB +label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias: +label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'. +label.do_not_display_again = No mostrar este mensaje de nuevo \ No newline at end of file diff --git a/src/MCview/PDBChain.java b/src/MCview/PDBChain.java index 7774dac..34f09c8 100755 --- a/src/MCview/PDBChain.java +++ b/src/MCview/PDBChain.java @@ -31,6 +31,7 @@ import jalview.schemes.ColourSchemeI; import jalview.schemes.ResidueProperties; import jalview.structure.StructureImportSettings; import jalview.structure.StructureMapping; +import jalview.util.Comparison; import java.awt.Color; import java.util.List; @@ -146,7 +147,9 @@ public class PDBChain pdbpos++; } - if (as.astr1.charAt(i) == as.astr2.charAt(i)) + boolean sameResidue = Comparison.compareChars(as.astr1.charAt(i), + as.astr2.charAt(i), false); + if (sameResidue) { if (pdbpos >= residues.size()) { diff --git a/src/jalview/analysis/AlignSeq.java b/src/jalview/analysis/AlignSeq.java index 3ad3188..f7e8f2e 100755 --- a/src/jalview/analysis/AlignSeq.java +++ b/src/jalview/analysis/AlignSeq.java @@ -620,7 +620,10 @@ public class AlignSeq { if ((i + (j * len)) < astr1.length()) { - if (astr1.charAt(i + (j * len)) == astr2.charAt(i + (j * len)) + boolean sameChar = Comparison.compareChars( + astr1.charAt(i + (j * len)), astr2.charAt(i + (j * len)), + false); + if (sameChar && !jalview.util.Comparison.isGap(astr1.charAt(i + (j * len)))) { diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java index 7b0d4fb..45e39cc 100644 --- a/src/jalview/appletgui/APopupMenu.java +++ b/src/jalview/appletgui/APopupMenu.java @@ -29,7 +29,6 @@ import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; -import jalview.datamodel.DBRefEntry; import jalview.datamodel.PDBEntry; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; @@ -59,6 +58,7 @@ import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -253,122 +253,9 @@ public class APopupMenu extends java.awt.PopupMenu implements if (links != null && links.size() > 0) { - Menu linkMenu = new Menu(MessageManager.getString("action.link")); - for (int i = 0; i < links.size(); i++) - { - String link = links.elementAt(i); - UrlLink urlLink = new UrlLink(link); - if (!urlLink.isValid()) - { - System.err.println(urlLink.getInvalidMessage()); - continue; - } - final String target = urlLink.getTarget(); // link.substring(0, - // link.indexOf("|")); - final String label = urlLink.getLabel(); - if (seq != null && urlLink.isDynamic()) - { - - // collect matching db-refs - DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs( - seq.getDBRefs(), new String[] { target }); - // collect id string too - String id = seq.getName(); - String descr = seq.getDescription(); - if (descr != null && descr.length() < 1) - { - descr = null; - } - if (dbr != null) - { - for (int r = 0; r < dbr.length; r++) - { - if (id != null && dbr[r].getAccessionId().equals(id)) - { - // suppress duplicate link creation for the bare sequence ID - // string with this link - id = null; - } - // create Bare ID link for this RUL - String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), - true); - if (urls != null) - { - for (int u = 0; u < urls.length; u += 2) - { - addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]); - } - } - } - } - if (id != null) - { - // create Bare ID link for this RUL - String[] urls = urlLink.makeUrls(id, true); - if (urls != null) - { - for (int u = 0; u < urls.length; u += 2) - { - addshowLink(linkMenu, label, urls[u + 1]); - } - } - // addshowLink(linkMenu, target, url_pref + id + url_suff); - } - // Now construct URLs from description but only try to do it for regex - // URL links - if (descr != null && urlLink.getRegexReplace() != null) - { - // create link for this URL from description only if regex matches - String[] urls = urlLink.makeUrls(descr, true); - if (urls != null) - { - for (int u = 0; u < urls.length; u += 2) - { - addshowLink(linkMenu, label, urls[u + 1]); - } - } - } - } - else - { - addshowLink(linkMenu, target, urlLink.getUrl_prefix()); // link.substring(link.lastIndexOf("|")+1)); - } - /* - * final String url; - * - * if (link.indexOf("$SEQUENCE_ID$") > -1) { // Substitute SEQUENCE_ID - * string and any matching database reference accessions String url_pref - * = link.substring(link.indexOf("|") + 1, - * link.indexOf("$SEQUENCE_ID$")); - * - * String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13); - * // collect matching db-refs DBRefEntry[] dbr = - * jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new - * String[]{target}); // collect id string too String id = - * seq.getName(); if (id.indexOf("|") > -1) { id = - * id.substring(id.lastIndexOf("|") + 1); } if (dbr!=null) { for (int - * r=0;r 0) - { - if (seq != null) - { - seqMenu.add(linkMenu); - } - else - { - add(linkMenu); - } - } + addFeatureLinks(seq, links); } + // TODO: add group link menu entry here if (seq != null) { @@ -414,6 +301,71 @@ public class APopupMenu extends java.awt.PopupMenu implements } /** + * Adds a 'Link' menu item with a sub-menu item for each hyperlink provided. + * + * @param seq + * @param links + */ + void addFeatureLinks(final SequenceI seq, List links) + { + Menu linkMenu = new Menu(MessageManager.getString("action.link")); + Map> linkset = new LinkedHashMap>(); + + for (String link : links) + { + UrlLink urlLink = null; + try + { + urlLink = new UrlLink(link); + } catch (Exception foo) + { + System.err.println("Exception for URLLink '" + link + "': " + + foo.getMessage()); + continue; + } + + if (!urlLink.isValid()) + { + System.err.println(urlLink.getInvalidMessage()); + continue; + } + + urlLink.createLinksFromSeq(seq, linkset); + } + + addshowLinks(linkMenu, linkset.values()); + + // disable link menu if there are no valid entries + if (linkMenu.getItemCount() > 0) + { + linkMenu.setEnabled(true); + } + else + { + linkMenu.setEnabled(false); + } + + if (seq != null) + { + seqMenu.add(linkMenu); + } + else + { + add(linkMenu); + } + + } + + private void addshowLinks(Menu linkMenu, Collection> linkset) + { + for (List linkstrset : linkset) + { + // split linkstr into label and url + addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3)); + } + } + + /** * Build menus for annotation types that may be shown or hidden, and for * 'reference annotations' that may be added to the alignment. */ diff --git a/src/jalview/appletgui/IdPanel.java b/src/jalview/appletgui/IdPanel.java index 2cb3060..182f20e 100755 --- a/src/jalview/appletgui/IdPanel.java +++ b/src/jalview/appletgui/IdPanel.java @@ -246,7 +246,14 @@ public class IdPanel extends Panel implements MouseListener, url = null; continue; } - ; + + if (urlLink.usesDBAccession()) + { + // this URL requires an accession id, not the name of a sequence + url = null; + continue; + } + if (!urlLink.isValid()) { System.err.println(urlLink.getInvalidMessage()); diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 3f457ea..28606f1 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -20,6 +20,9 @@ */ package jalview.gui; +import static jalview.util.UrlConstants.EMBLEBI_STRING; +import static jalview.util.UrlConstants.SEQUENCE_ID; + import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; @@ -75,6 +78,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; +import java.util.ListIterator; import java.util.StringTokenizer; import java.util.Vector; import java.util.concurrent.ExecutorService; @@ -82,9 +86,12 @@ import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; import javax.swing.AbstractAction; +import javax.swing.Box; +import javax.swing.BoxLayout; import javax.swing.DefaultDesktopManager; import javax.swing.DesktopManager; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDesktopPane; @@ -382,6 +389,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements showNews.setVisible(false); + checkURLLinks(); + this.addWindowListener(new WindowAdapter() { @Override @@ -2256,6 +2265,84 @@ public class Desktop extends jalview.jbgui.GDesktop implements new Thread(jvq).start(); } + public void checkURLLinks() + { + // Thread off the URL link checker + addDialogThread(new Runnable() + { + @Override + public void run() + { + if (Cache.getDefault("CHECKURLLINKS", true)) + { + // check what the actual links are - if it's just the default don't + // bother with the warning + Vector links = Preferences.sequenceURLLinks; + + // only need to check links if there is one with a + // SEQUENCE_ID which is not the default EMBL_EBI link + ListIterator li = links.listIterator(); + boolean check = false; + List urls = new ArrayList(); + while (li.hasNext()) + { + String link = li.next(); + if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING)) + { + check = true; + int barPos = link.indexOf("|"); + String urlMsg = barPos == -1 ? link : link.substring(0, + barPos) + ": " + link.substring(barPos + 1); + urls.add(new JLabel(urlMsg)); + } + } + if (!check) + { + return; + } + + // ask user to check in case URL links use old style tokens + // ($SEQUENCE_ID$ for sequence id _or_ accession id) + JPanel msgPanel = new JPanel(); + msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS)); + msgPanel.add(Box.createVerticalGlue()); + JLabel msg = new JLabel( + MessageManager + .getString("label.SEQUENCE_ID_for_DB_ACCESSION1")); + JLabel msg2 = new JLabel( + MessageManager + .getString("label.SEQUENCE_ID_for_DB_ACCESSION2")); + msgPanel.add(msg); + for (JLabel url : urls) + { + msgPanel.add(url); + } + msgPanel.add(msg2); + + final JCheckBox jcb = new JCheckBox( + MessageManager.getString("label.do_not_display_again")); + jcb.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + // update Cache settings for "don't show this again" + boolean showWarningAgain = !jcb.isSelected(); + Cache.setProperty("CHECKURLLINKS", + Boolean.valueOf(showWarningAgain).toString()); + } + }); + msgPanel.add(jcb); + + JOptionPane.showMessageDialog(Desktop.desktop, msgPanel, + MessageManager + .getString("label.SEQUENCE_ID_no_longer_used"), + JOptionPane.WARNING_MESSAGE); + } + } + }); + } + /** * Proxy class for JDesktopPane which optionally displays the current memory * usage and highlights the desktop area with a red bar if free memory runs diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index a65be7b..e321a74 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -225,7 +225,14 @@ public class IdPanel extends JPanel implements MouseListener, url = null; continue; } - ; + + if (urlLink.usesDBAccession()) + { + // this URL requires an accession id, not the name of a sequence + url = null; + continue; + } + if (!urlLink.isValid()) { jalview.bin.Cache.log.error(urlLink.getInvalidMessage()); diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 7b70ff0..bb816cd 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -54,7 +54,6 @@ import jalview.schemes.TaylorColourScheme; import jalview.schemes.TurnColourScheme; import jalview.schemes.UserColourScheme; import jalview.schemes.ZappoColourScheme; -import jalview.util.DBRefUtils; import jalview.util.GroupUrlLink; import jalview.util.GroupUrlLink.UrlStringTooLongException; import jalview.util.MessageManager; @@ -63,8 +62,8 @@ import jalview.util.UrlLink; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Hashtable; import java.util.LinkedHashMap; @@ -617,7 +616,8 @@ public class PopupMenu extends JPopupMenu void addFeatureLinks(final SequenceI seq, List links) { JMenu linkMenu = new JMenu(MessageManager.getString("action.link")); - List linkset = new ArrayList(); + Map> linkset = new LinkedHashMap>(); + for (String link : links) { UrlLink urlLink = null; @@ -629,80 +629,28 @@ public class PopupMenu extends JPopupMenu Cache.log.error("Exception for URLLink '" + link + "'", foo); continue; } - ; + if (!urlLink.isValid()) { Cache.log.error(urlLink.getInvalidMessage()); continue; } - final String label = urlLink.getLabel(); - - // collect id string too - String id = seq.getName(); - String descr = seq.getDescription(); - if (descr != null && descr.length() < 1) - { - descr = null; - } - if (seq != null && urlLink.usesSeqId()) // link is ID - { - // collect matching db-refs - DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(), - new String[] { urlLink.getTarget() }); - - // if there are any dbrefs which match up with the link - if (dbr != null) - { - for (int r = 0; r < dbr.length; r++) - { - if (id != null && dbr[r].getAccessionId().equals(id)) - { - // suppress duplicate link creation for the bare sequence ID - // string with this link - id = null; - } - // create Bare ID link for this URL - createBareURLLink(urlLink, dbr[r].getAccessionId(), linkset, - linkMenu, label, true); - } - } + urlLink.createLinksFromSeq(seq, linkset); + } - // Create urls from description but only for URL links which are regex - // links - if (descr != null && urlLink.getRegexReplace() != null) - { - // create link for this URL from description where regex matches - createBareURLLink(urlLink, descr, linkset, linkMenu, label, false); - } - - } - else if (seq != null && !urlLink.usesSeqId()) // link is name - { - if (id != null) - { - // create Bare ID link for this URL - createBareURLLink(urlLink, id, linkset, linkMenu, label, false); - } - // Create urls from description but only for URL links which are regex - // links - if (descr != null && urlLink.getRegexReplace() != null) - { - // create link for this URL from description where regex matches - createBareURLLink(urlLink, descr, linkset, linkMenu, label, false); - } - } - else - { - if (!linkset.contains(label + "|" + urlLink.getUrl_prefix())) - { - linkset.add(label + "|" + urlLink.getUrl_prefix()); - // Add a non-dynamic link - addshowLink(linkMenu, label, urlLink.getUrl_prefix()); - } - } + addshowLinks(linkMenu, linkset.values()); + // disable link menu if there are no valid entries + if (linkMenu.getItemCount() > 0) + { + linkMenu.setEnabled(true); } + else + { + linkMenu.setEnabled(false); + } + if (sequence != null) { sequenceMenu.add(linkMenu); @@ -711,36 +659,11 @@ public class PopupMenu extends JPopupMenu { add(linkMenu); } - } - /* - * Create a bare URL Link - */ - private void createBareURLLink(UrlLink urlLink, String id, - List linkset, JMenu linkMenu, String label, - Boolean addSepToLabel) - { - String[] urls = urlLink.makeUrls(id, true); - if (urls != null) - { - for (int u = 0; u < urls.length; u += 2) - { - if (!linkset.contains(urls[u] + "|" + urls[u + 1])) - { - linkset.add(urls[u] + "|" + urls[u + 1]); - if (addSepToLabel) - { - addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]); - } - else - { - addshowLink(linkMenu, label, urls[u + 1]); - } - } - } - } } + + /** * Add annotation types to 'Show annotations' and/or 'Hide annotations' menus. * "All" is added first, followed by a separator. Then add any annotation @@ -1015,6 +938,15 @@ public class PopupMenu extends JPopupMenu } } + private void addshowLinks(JMenu linkMenu, Collection> linkset) + { + for (List linkstrset : linkset) + { + // split linkstr into label and url + addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3)); + } + } + /** * add a show URL menu item to the given linkMenu * diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index b57b951..3bffd3a 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -20,10 +20,9 @@ */ package jalview.gui; +import static jalview.util.UrlConstants.DB_ACCESSION; import static jalview.util.UrlConstants.EMBLEBI_STRING; -import static jalview.util.UrlConstants.OLD_EMBLEBI_STRING; import static jalview.util.UrlConstants.SEQUENCE_ID; -import static jalview.util.UrlConstants.SEQUENCE_NAME; import static jalview.util.UrlConstants.SRS_STRING; import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; @@ -127,10 +126,10 @@ public class Preferences extends GPreferences String name = st.nextToken(); String url = st.nextToken(); // check for '|' within a regex - int rxstart = url.indexOf("$" + SEQUENCE_ID + "$"); + int rxstart = url.indexOf("$" + DB_ACCESSION + "$"); if (rxstart == -1) { - rxstart = url.indexOf("$" + SEQUENCE_NAME + "$"); + rxstart = url.indexOf("$" + SEQUENCE_ID + "$"); } while (rxstart == -1 && url.indexOf("/=$") == -1) { @@ -149,12 +148,6 @@ public class Preferences extends GPreferences { sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos); } - // upgrade old EMBL-EBI link - int emblPos = sequenceURLLinks.indexOf(OLD_EMBLEBI_STRING); - if (emblPos > -1) - { - sequenceURLLinks.setElementAt(EMBLEBI_STRING, emblPos); - } } /** @@ -574,6 +567,7 @@ public class Preferences extends GPreferences else { Cache.applicationProperties.remove("SEQUENCE_LINKS"); + sequenceURLLinks.clear(); } Cache.applicationProperties.setProperty("USE_PROXY", diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java index 07b88bf..89f1068 100644 --- a/src/jalview/io/SequenceAnnotationReport.java +++ b/src/jalview/io/SequenceAnnotationReport.java @@ -24,10 +24,11 @@ import jalview.datamodel.DBRefEntry; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; import jalview.io.gff.GffConstants; -import jalview.util.DBRefUtils; import jalview.util.UrlLink; import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -206,16 +207,17 @@ public class SequenceAnnotationReport { try { - for (String[] urllink : createLinksFrom(null, urlstring)) + for (List urllink : createLinksFrom(null, urlstring)) { sb.append("
" - + (urllink[0].toLowerCase().equals( - urllink[1].toLowerCase()) ? urllink[0] - : (urllink[0] + ":" + urllink[1])) + + (urllink.get(0).toLowerCase() + .equals(urllink.get(1).toLowerCase()) ? urllink + .get(0) : (urllink.get(0) + ":" + urllink + .get(1))) + "
"); } } catch (Exception x) @@ -234,124 +236,22 @@ public class SequenceAnnotationReport * * @param seq * @param link - * @return String[][] { String[] { link target, link label, dynamic component - * inserted (if any), url }} + * @return Collection< List > { List { link target, link + * label, dynamic component inserted (if any), url }} */ - String[][] createLinksFrom(SequenceI seq, String link) + Collection> createLinksFrom(SequenceI seq, String link) { - List urlSets = new ArrayList(); - List uniques = new ArrayList(); + Map> urlSets = new LinkedHashMap>(); UrlLink urlLink = new UrlLink(link); if (!urlLink.isValid()) { System.err.println(urlLink.getInvalidMessage()); return null; } - if (seq != null && urlLink.isDynamic()) - { - urlSets.addAll(createDynamicLinks(seq, urlLink, uniques)); - } - else - { - String target = urlLink.getTarget(); - String label = urlLink.getLabel(); - String unq = label + "|" + urlLink.getUrl_prefix(); - if (!uniques.contains(unq)) - { - uniques.add(unq); - urlSets.add(new String[] { target, label, null, - urlLink.getUrl_prefix() }); - } - } - - return urlSets.toArray(new String[][] {}); - } - /** - * Formats and returns a list of dynamic href links - * - * @param seq - * @param urlLink - * @param uniques - */ - List createDynamicLinks(SequenceI seq, UrlLink urlLink, - List uniques) - { - List result = new ArrayList(); - final String target = urlLink.getTarget(); - final String label = urlLink.getLabel(); + urlLink.createLinksFromSeq(seq, urlSets); - // collect matching db-refs - DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(), - new String[] { target }); - // collect id string too - String id = seq.getName(); - String descr = seq.getDescription(); - if (descr != null && descr.length() < 1) - { - descr = null; - } - if (dbr != null) - { - for (int r = 0; r < dbr.length; r++) - { - if (id != null && dbr[r].getAccessionId().equals(id)) - { - // suppress duplicate link creation for the bare sequence ID - // string with this link - id = null; - } - // create Bare ID link for this URL - String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true); - if (urls != null) - { - for (int u = 0; u < urls.length; u += 2) - { - String unq = urls[u] + "|" + urls[u + 1]; - if (!uniques.contains(unq)) - { - result.add(new String[] { target, label, urls[u], urls[u + 1] }); - uniques.add(unq); - } - } - } - } - } - if (id != null) - { - // create Bare ID link for this URL - String[] urls = urlLink.makeUrls(id, true); - if (urls != null) - { - for (int u = 0; u < urls.length; u += 2) - { - String unq = urls[u] + "|" + urls[u + 1]; - if (!uniques.contains(unq)) - { - result.add(new String[] { target, label, urls[u], urls[u + 1] }); - uniques.add(unq); - } - } - } - } - if (descr != null && urlLink.getRegexReplace() != null) - { - // create link for this URL from description only if regex matches - String[] urls = urlLink.makeUrls(descr, true); - if (urls != null) - { - for (int u = 0; u < urls.length; u += 2) - { - String unq = urls[u] + "|" + urls[u + 1]; - if (!uniques.contains(unq)) - { - result.add(new String[] { target, label, urls[u], urls[u + 1] }); - uniques.add(unq); - } - } - } - } - return result; + return urlSets.values(); } public void createSequenceAnnotationReport(final StringBuffer tip, diff --git a/src/jalview/jbgui/GSequenceLink.java b/src/jalview/jbgui/GSequenceLink.java index b27752e..2689946 100755 --- a/src/jalview/jbgui/GSequenceLink.java +++ b/src/jalview/jbgui/GSequenceLink.java @@ -67,7 +67,7 @@ public class GSequenceLink extends Panel } }); urlTB.setFont(JvSwingUtils.getLabelFont()); - urlTB.setText("http://www."); + urlTB.setText("http://"); urlTB.setBounds(new Rectangle(78, 40, 309, 23)); urlTB.addKeyListener(new KeyAdapter() { diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java index 7e691be..cad2303 100644 --- a/src/jalview/structure/StructureSelectionManager.java +++ b/src/jalview/structure/StructureSelectionManager.java @@ -391,7 +391,7 @@ public class StructureSelectionManager registerPDBFile(pdb.getId().trim(), pdbFile); } // if PDBId is unavailable then skip SIFTS mapping execution path - isMapUsingSIFTs = pdb.isPPDBIdAvailable(); + isMapUsingSIFTs = isMapUsingSIFTs && pdb.isPPDBIdAvailable(); } catch (Exception ex) { diff --git a/src/jalview/util/Comparison.java b/src/jalview/util/Comparison.java index 0beb45b..5269d4f 100644 --- a/src/jalview/util/Comparison.java +++ b/src/jalview/util/Comparison.java @@ -415,4 +415,35 @@ public class Comparison .size()]); return isNucleotide(oneDArray); } + + /** + * Compares two chars either case sensitively or case insensitively depending + * on the caseSensitive flag + * + * @param c1 + * first char + * @param c2 + * second char to compare with + * @param caseSensitive + * if true comparison will be case sensitive otherwise its not + * @return + */ + public static boolean compareChars(char c1, char c2, boolean caseSensitive) + { + boolean sameCase = (Character.isUpperCase(c1) && Character + .isUpperCase(c2)) + || (Character.isLowerCase(c1) && Character.isLowerCase(c2)); + if (sameCase) + { + return c1 == c2; + } + else if (caseSensitive) + { + return false; + } + else + { + return Character.toUpperCase(c1) == Character.toUpperCase(c2); + } + } } diff --git a/src/jalview/util/DBRefUtils.java b/src/jalview/util/DBRefUtils.java index e6aa472..04cb75e 100755 --- a/src/jalview/util/DBRefUtils.java +++ b/src/jalview/util/DBRefUtils.java @@ -100,14 +100,14 @@ public class DBRefUtils HashSet srcs = new HashSet(); for (String src : sources) { - srcs.add(src); + srcs.add(src.toUpperCase()); } List res = new ArrayList(); for (DBRefEntry dbr : dbrefs) { String source = getCanonicalName(dbr.getSource()); - if (srcs.contains(source)) + if (srcs.contains(source.toUpperCase())) { res.add(dbr); } diff --git a/src/jalview/util/Platform.java b/src/jalview/util/Platform.java index 3fb384f..49dc7ff 100644 --- a/src/jalview/util/Platform.java +++ b/src/jalview/util/Platform.java @@ -30,6 +30,10 @@ import java.awt.event.MouseEvent; */ public class Platform { + private static Boolean isAMac = null; + + private static Boolean isHeadless = null; + /** * sorry folks - Macs really are different * @@ -37,15 +41,21 @@ public class Platform */ public static boolean isAMac() { - return java.lang.System.getProperty("os.name").indexOf("Mac") > -1; + if (isAMac == null) + { + isAMac = System.getProperty("os.name").indexOf("Mac") > -1; + } + return isAMac.booleanValue(); } public static boolean isHeadless() { - String hdls = java.lang.System.getProperty("java.awt.headless"); - - return hdls != null && hdls.equals("true"); + if (isHeadless == null) + { + isHeadless = "true".equals(System.getProperty("java.awt.headless")); + } + return isHeadless; } /** @@ -89,8 +99,28 @@ public class Platform */ public static boolean isControlDown(MouseEvent e) { - if (isAMac()) + boolean aMac = isAMac(); + return isControlDown(e, aMac); + } + + /** + * Overloaded version of method (to allow unit testing) + * + * @param e + * @param aMac + * @return + */ + protected static boolean isControlDown(MouseEvent e, boolean aMac) + { + if (aMac) { + /* + * answer false for right mouse button + */ + if (e.isPopupTrigger()) + { + return false; + } return (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() & e .getModifiers()) != 0; // could we use e.isMetaDown() here? diff --git a/src/jalview/util/UrlConstants.java b/src/jalview/util/UrlConstants.java index ce6d980..1910bff 100644 --- a/src/jalview/util/UrlConstants.java +++ b/src/jalview/util/UrlConstants.java @@ -29,22 +29,17 @@ public class UrlConstants /* * Sequence ID string */ - public static final String SEQUENCE_ID = "SEQUENCE_ID"; + public static final String DB_ACCESSION = "DB_ACCESSION"; /* * Sequence Name string */ - public static final String SEQUENCE_NAME = "SEQUENCE_NAME"; - - /* - * Default sequence URL link string for EMBL-EBI search - */ - public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_NAME$"; + public static final String SEQUENCE_ID = "SEQUENCE_ID"; /* * Default sequence URL link string for EMBL-EBI search */ - public static final String OLD_EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$"; + public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$"; /* * Default sequence URL link string for SRS diff --git a/src/jalview/util/UrlLink.java b/src/jalview/util/UrlLink.java index 872f432..3ee6432 100644 --- a/src/jalview/util/UrlLink.java +++ b/src/jalview/util/UrlLink.java @@ -20,9 +20,15 @@ */ package jalview.util; +import static jalview.util.UrlConstants.DB_ACCESSION; import static jalview.util.UrlConstants.SEQUENCE_ID; -import static jalview.util.UrlConstants.SEQUENCE_NAME; +import jalview.datamodel.DBRefEntry; +import jalview.datamodel.SequenceI; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.Vector; public class UrlLink @@ -33,19 +39,33 @@ public class UrlLink * Jalview 2.4 extension allows regular expressions to be used to parse ID * strings and replace the result in the URL. Regex's operate on the whole ID * string given to the matchURL method, if no regex is supplied, then only - * text following the first pipe symbol will be susbstituted. Usage + * text following the first pipe symbol will be substituted. Usage * documentation todo. */ - private String url_suffix, url_prefix, target, label, regexReplace; + + // Internal constants + private static final String SEP = "|"; + + private static final String DELIM = "$"; + + private String urlSuffix; + + private String urlPrefix; + + private String target; + + private String label; + + private String regexReplace; private boolean dynamic = false; - private boolean uses_seq_id = false; + private boolean usesDBaccession = false; private String invalidMessage = null; /** - * parse the given linkString of the form '