From: Jim Procter Date: Thu, 9 Feb 2017 11:50:07 +0000 (+0000) Subject: Merge branch 'develop' into features/JAL-2316 X-Git-Tag: Release_2_10_3b1~346^2 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2Ffeatures%2FJAL-2316;hp=f1258e0b824ba4987b6eeb488d8153e524f4a443;p=jalview.git Merge branch 'develop' into features/JAL-2316 --- diff --git a/examples/exampleFeatures.txt b/examples/exampleFeatures.txt index 2de9817..83dc4b1 100755 --- a/examples/exampleFeatures.txt +++ b/examples/exampleFeatures.txt @@ -1,5 +1,5 @@ ST-TURN-IIL blue|255,0,255|absolute|20.0|95.0|below|66.0 -GAMMA-TURN-CLASSIC red|0,255,255|20.0|95.0|below|66.0 +GAMMA-TURN-CLASSIC lightGray|0,255,255|20.0|95.0|below|66.0 BETA-TURN-IR 9a6a94 BETA-TURN-IL d6a6ca BETA-BULGE 1dc451 diff --git a/help/help.jhm b/help/help.jhm index f69ed00..984c2d1 100755 --- a/help/help.jhm +++ b/help/help.jhm @@ -150,6 +150,9 @@ + + + diff --git a/help/helpTOC.xml b/help/helpTOC.xml index 54abd53..482ccdf 100755 --- a/help/helpTOC.xml +++ b/help/helpTOC.xml @@ -131,6 +131,9 @@ + + + diff --git a/help/html/features/preferences.html b/help/html/features/preferences.html index 6a8c86c..da045ba 100755 --- a/help/html/features/preferences.html +++ b/help/html/features/preferences.html @@ -46,8 +46,13 @@ and displaying structure information.
  • The "Connections" - Preferences tab allows you to change the links made from Jalview - to your default web browser. + Preferences tab allows you to configure Jalview's internet + settings and specify your default web browser. +
  • +
  • The "Links" + Preferences tab shows the currently configured URL + Links shown in the Link submenu in the Sequence + ID popup menu.
  • The "Output" Preferences tab contains settings affecting the export of @@ -212,13 +217,6 @@ Preferences tab

    - URL Link From Sequence ID
    These definitions are - used to generate URLs from a sequence's ID or database cross - references. Read more about configuring - URL links here. -

    -

    Default Browser (Unix)
    Its difficult in Java to detect the default web browser for Unix users. If Jalview can't find your default web browser, enter the name or full path to your web @@ -240,6 +238,33 @@ statement for more information.

    + The "Links" Preferences + tab +

    +

    + This panel shows a table, and two sections - Edit and Filter. + The table shows the available URL link definitions (consisting of a + database, Name, and URL template string), a checkbox In + Menu which indicates if the link is enabled, and Double + Click which marks the link that will be opened if a sequence's ID + is double clicked. The table can be sorted by clicking on the column headers. +

    +

    Edit Links
    This section contains three buttons, + New, Edit and Delete, which allow you to + create, modify and remove user-defined URL links from the Sequence + ID's links submenu. +

    +

    + Filter
    The Filter text box allows you to + quickly show rows in the table containing a particular text string. + The Custom only button limits the entries in the table to + just those you have configured yourself via the Edit + Links buttons. Press Show all to clear any filters. +

    + Read more about configuring + URL links. +

    +

    Output Preferences tab

    @@ -307,7 +332,7 @@ and PDB file association (if available). The Jalview id/start-end option is ignored if Modeller output is selected.

    - Editing Preferences tab + e"Editinge" Preferences tab

    There are currently three options available which can be selected / deselected.

    diff --git a/help/html/webServices/urllinks.html b/help/html/webServices/urllinks.html index 088a539..da5d7dd 100644 --- a/help/html/webServices/urllinks.html +++ b/help/html/webServices/urllinks.html @@ -23,42 +23,55 @@

    -

    Opening URLs from Jalview
    Both the applet 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. + your web browser.

    +

    Double-clicking on the ID of a sequence + will open whichever URL is selected for 'popups' in the "Links" tab of the Jalview desktop + preferences. This is by default the EMBL-EBI site, but you can easily configure your own sequence URL links.

    - Other links for a sequence either derived from any other configured + Other links for a sequence, either derived from any other configured URL links, or imported from the sequence's annotation, are accessed by right clicking to open the sequence pop-up menu, and selecting from the Links submenu.

    Configuring URL Links
    URL - links are defined in the "Connections" tab of the Jalview desktop + links are defined in the "Links" tab of the 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 - new link, and edit to modify an existing link, or delete - 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 or DB accession ID. The simplest token is - "$SEQUENCE_ID$", which will be replaced by the chosen - sequence id when you click on it. + parameters.

    +

    + Default Link Settings
    The "EMBL-EBI Search" + link is the default link shown in the "Link" submenu, and + opened when double-clicking on a sequence ID. When clicked, this + link will show a web page in your default browser with the selected + sequence ID as part of the URL. +

    +

    + Adding additional links
    You can configure your own + links via the Jalview Preferences + dialog. Jalview also provides persistent URLs for many common + bioinformatics databases. These links are downloaded by Jalview from + the identifiers.org website, and the names and URLs are not + user editable.

    - eg.
    UniRef100 = - http://www.ebi.uniprot.org/uniprot-srv/uniRefView.do?proteinAc=$SEQUENCE_ID$&library=uniref100
    - Swissprot = http://www.expasy.org/uniprot/$SEQUENCE_ID$

    + Creating your own URL link URL links are specified as a + template containing special tokens that Jalview will replace with + the Sequence ID or Database Accession of the sequence when you + double click on its ID or open it's Link submenu. + Link URL templates must contain at least one token. +

    + eg.
     UniRef100 =
    +    http://www.ebi.uniprot.org/uniprot-srv/uniRefView.do?proteinAc=$SEQUENCE_ID$&library=uniref100
    + 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 $DB_ACCESSION$ string will be replaced with @@ -83,33 +96,29 @@

    Regular Expression Substitution
    A url may contain a string of the form $SEQUENCE_ID=/regular - 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 + 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: +

    • Each top level parenthesis will yield a URL containing the text matched within that parenthesis.
    • Regions matching sub-parentheses within a top-level parenthesis will be concatenated to form the text inserted into the URL for the top-level parenthesis.
    • - Please Note: -
        -
      • The regular expressions supported by Jalview are those - provided by the Stevesoft - javaregex package. -
      • -
      • Some characters must be escaped when specifying them as - a match within a regular expression.
      • -

      Many Thanks to Bernd Brandt of the Free University of - Amsterdam for testing this new regular-expression expansion - feature! -
      -
    -

    -

    + Please Note: +
      +
    • The regular expressions supported by Jalview are those + provided by the Stevesoft + javaregex package. +
    • +
    • Some characters must be escaped when specifying them as a + match within a regular expression.
    • +

    Many Thanks to Bernd Brandt of the Free University of + Amsterdam for testing the regular-expression expansion feature! diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index 1ba0c79..f720f39 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -138,7 +138,8 @@ action.view_flanking_regions = Show flanking regions label.view_flanking_regions = Show sequence data either side of the subsequences involved in this alignment label.structures_manager = Structures Manager label.nickname = Nickname: -label.url = URL: +label.url = URL +label.url\: = URL: label.input_file_url = Enter URL or Input File label.select_feature = Select feature label.name = Name @@ -413,7 +414,6 @@ label.couldnt_import_as_vamsas_session = Couldn't import {0} as a new vamsas ses label.vamsas_document_import_failed = Vamsas Document Import Failed label.couldnt_locate = Couldn't locate {0} label.url_not_found = URL not found -label.no_link_selected = No link selected label.new_sequence_url_link = New sequence URL link label.cannot_edit_annotations_in_wrapped_view = Cannot edit annotations in wrapped view label.wrapped_view_no_edit = Wrapped view - no edit @@ -1271,4 +1271,21 @@ label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB access 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 +exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name +exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one line +label.filter = Filter text: +action.customfilter = Custom only +action.showall = Show All +label.insert = Insert: +action.seq_id = $SEQUENCE_ID$ +action.db_acc = $DB_ACCESSION$ +label.primary = Double Click +label.inmenu = In Menu +label.id = ID +label.database = Database +label.urltooltip = Only one url, which must use a sequence id, can be selected for the 'On Click' option +label.edit_sequence_url_link = Edit sequence URL link +warn.name_cannot_be_duplicate = User-defined URL names must be unique and cannot be MIRIAM ids +label.invalid_name = Invalid Name ! label.output_seq_details = Output Sequence Details to list all database references +label.urllinks = Links \ No newline at end of file diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 7f769b3..d408fee 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -135,7 +135,8 @@ action.view_flanking_regions = Mostrar flancos label.view_flanking_regions = Mostrar los datos de la secuencia a ambos lados de las subsecuencias implicadas en este alineamiento label.structures_manager = Administrar estructuras label.nickname = Sobrenombre: -label.url = URL: +label.url\: = URL: +label.url = URL label.input_file_url = Introducir URL en el fichero de entrada label.select_feature = Seleccionar característica label.name = Nombre @@ -380,7 +381,6 @@ label.couldnt_import_as_vamsas_session = No se pudo importar {0} como una nueva label.vamsas_document_import_failed = Fallo en la importación del documento Vamsas label.couldnt_locate = No se pudo localizar {0} label.url_not_found = URL no encontrada -label.no_link_selected = Enlace no seleccionado label.new_sequence_url_link = Enlace a una nueva secuencia URL label.cannot_edit_annotations_in_wrapped_view = No se pueden editar anotaciones en vista envolvente label.wrapped_view_no_edit = Vista envolvente - no editar @@ -1271,4 +1271,21 @@ label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza m 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 +exception.url_cannot_have_miriam_id = {0} es una id MIRIAM y no puede ser usada como nombre url personalizado +exception.url_cannot_have_duplicate_id = {0} no puede ser usada como etiqueta en más de un enlace +label.filter = Filtrar texto: +action.customfilter = Sólo personalizado +action.showall = Mostrar todo +label.insert = Insertar: +action.seq_id = $SEQUENCE_ID$ +action.db_acc = $DB_ACCESSION$ +label.primary = Doble clic +label.inmenu = En Menú +label.id = ID +label.database = Base de datos +label.urltooltip = Sólo una url, que debe usar una id de secuencia, puede ser seleccionada en la opción 'On Click' +label.edit_sequence_url_link = Editar link de secuencia URL +warn.name_cannot_be_duplicate = Los nombres URL definidos por el usuario deben ser únicos y no pueden ser ids de MIRIAM +label.invalid_name = Nombre inválido ! label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas +label.urllinks = Enlaces \ No newline at end of file diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java index 055fcf3..8fd317a 100644 --- a/src/jalview/appletgui/APopupMenu.java +++ b/src/jalview/appletgui/APopupMenu.java @@ -210,7 +210,7 @@ public class APopupMenu extends java.awt.PopupMenu implements Menu menu1 = new Menu(); public APopupMenu(AlignmentPanel apanel, final SequenceI seq, - Vector links) + List links) { // ///////////////////////////////////////////////////////// // If this is activated from the sequence panel, the user may want to diff --git a/src/jalview/appletgui/IdPanel.java b/src/jalview/appletgui/IdPanel.java index 182f20e..b03a638 100755 --- a/src/jalview/appletgui/IdPanel.java +++ b/src/jalview/appletgui/IdPanel.java @@ -20,14 +20,13 @@ */ package jalview.appletgui; -import static jalview.util.UrlConstants.EMBLEBI_STRING; -import static jalview.util.UrlConstants.SRS_STRING; - import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; -import jalview.util.UrlLink; +import jalview.urls.api.UrlProviderFactoryI; +import jalview.urls.api.UrlProviderI; +import jalview.urls.applet.AppletUrlProviderFactory; import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; @@ -36,8 +35,8 @@ import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; +import java.util.HashMap; import java.util.List; -import java.util.Vector; public class IdPanel extends Panel implements MouseListener, MouseMotionListener @@ -55,7 +54,7 @@ public class IdPanel extends Panel implements MouseListener, boolean mouseDragging = false; - java.util.Vector links = new java.util.Vector(); + UrlProviderI urlProvider = null; public IdPanel(AlignViewport av, AlignmentPanel parent) { @@ -69,6 +68,9 @@ public class IdPanel extends Panel implements MouseListener, String label, url; // TODO: add in group link parameter + + // make a list of label,url pairs + HashMap urlList = new HashMap(); if (av.applet != null) { for (int i = 1; i < 10; i++) @@ -76,26 +78,22 @@ public class IdPanel extends Panel implements MouseListener, label = av.applet.getParameter("linkLabel_" + i); url = av.applet.getParameter("linkURL_" + i); - if (label != null && url != null) + // only add non-null parameters + if (label != null) { - links.addElement(label + "|" + url); + urlList.put(label, url); } - } - } - { - // upgrade old SRS link - int srsPos = links.indexOf(SRS_STRING); - if (srsPos > -1) + + if (!urlList.isEmpty()) { - links.setElementAt(EMBLEBI_STRING, srsPos); + // set default as first entry in list + String defaultUrl = av.applet.getParameter("linkLabel_1"); + UrlProviderFactoryI factory = new AppletUrlProviderFactory( + defaultUrl, urlList); + urlProvider = factory.createUrlProvider(); } } - if (links.size() < 1) - { - links = new java.util.Vector(); - links.addElement(EMBLEBI_STRING); - } } Tooltip tooltip; @@ -217,7 +215,7 @@ public class IdPanel extends Panel implements MouseListener, return; } - // DEFAULT LINK IS FIRST IN THE LINK LIST + // get the sequence details int seq = alignPanel.seqPanel.findSeq(e); SequenceI sq = av.getAlignment().getSequenceAt(seq); if (sq == null) @@ -226,53 +224,11 @@ public class IdPanel extends Panel implements MouseListener, } String id = sq.getName(); - String target = null; - String url = null; - int i = 0; - while (url == null && i < links.size()) - { - // DEFAULT LINK IS FIRST IN THE LINK LIST - // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED - url = links.elementAt(i++).toString(); - jalview.util.UrlLink urlLink = null; - try - { - urlLink = new UrlLink(url); - target = urlLink.getTarget(); - } catch (Exception foo) - { - System.err.println("Exception for URLLink '" + url + "'"); - foo.printStackTrace(); - 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()); - url = null; - continue; - } - - String urls[] = urlLink.makeUrls(id, true); - if (urls == null || urls[0] == null || urls[0].length() < 1) - { - url = null; - continue; - } - // just take first URL made from regex - url = urls[1]; - } + // get the default url with the sequence details filled in + String url = urlProvider.getPrimaryUrl(id); + String target = urlProvider.getPrimaryTarget(id); try { - alignPanel.alignFrame.showURL(url, target); } catch (Exception ex) { @@ -331,11 +287,8 @@ public class IdPanel extends Panel implements MouseListener, // build a new links menu based on the current links + any non-positional // features - Vector nlinks = new Vector(); - for (int l = 0, lSize = links.size(); l < lSize; l++) - { - nlinks.addElement(links.elementAt(l)); - } + List nlinks = urlProvider.getLinksForMenu(); + SequenceFeature sf[] = sq == null ? null : sq.getSequenceFeatures(); for (int sl = 0; sf != null && sl < sf.length; sl++) { @@ -345,7 +298,7 @@ public class IdPanel extends Panel implements MouseListener, { for (int l = 0, lSize = sf[sl].links.size(); l < lSize; l++) { - nlinks.addElement(sf[sl].links.elementAt(l)); + nlinks.add(sf[sl].links.elementAt(l)); } } } diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index 9363c23..48c1ee9 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -25,6 +25,7 @@ import jalview.gui.UserDefinedColours; import jalview.schemes.ColourSchemes; import jalview.schemes.UserColourScheme; import jalview.structure.StructureImportSettings; +import jalview.urls.IdOrgSettings; import jalview.util.ColorUtils; import jalview.ws.dbsources.das.api.DasSourceRegistryI; import jalview.ws.dbsources.das.datamodel.DasSourceRegistry; @@ -127,6 +128,10 @@ import org.apache.log4j.SimpleLayout; *
  • SORT_ALIGNMENT (No sort|Id|Pairwise Identity)
  • *
  • SEQUENCE_LINKS list of name|URL pairs for opening a url with * $SEQUENCE_ID$
  • + *
  • STORED_LINKS list of name|url pairs which user has entered but are not + * currently used + *
  • DEFAULT_LINK name of single url to be used when user double clicks a + * sequence id (must be in SEQUENCE_LINKS or STORED_LINKS) *
  • GROUP_LINKS list of name|URL[|<separator>] tuples - see * jalview.utils.GroupURLLink for more info
  • *
  • DAS_REGISTRY_URL the registry to query
  • @@ -184,6 +189,8 @@ import org.apache.log4j.SimpleLayout; *
  • STRUCTURE_DISPLAY choose from JMOL (default) or CHIMERA for 3D structure * display
  • *
  • CHIMERA_PATH specify full path to Chimera program (if non-standard)
  • + *
  • ID_ORG_HOSTURL location of jalview service providing identifiers.org urls + *
  • * * * Deprecated settings: @@ -225,6 +232,9 @@ public class Cache public static final String DAS_ACTIVE_SOURCE = "DAS_ACTIVE_SOURCE"; + /** + * Sifts settings + */ public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System .getProperty("user.home") + File.separatorChar @@ -235,6 +245,12 @@ public class Cache private final static String DEFAULT_FAIL_SAFE_PID_THRESHOLD = "30"; /** + * Identifiers.org download settings + */ + private static final String ID_ORG_FILE = System.getProperty("user.home") + + File.separatorChar + ".identifiers.org.ids.json"; + + /** * Allowed values are PDB or mmCIF */ private final static String PDB_DOWNLOAD_FORMAT = PDBEntry.Type.MMCIF @@ -445,6 +461,10 @@ public class Cache "sifts_cache_threshold_in_days", DEFAULT_CACHE_THRESHOLD_IN_DAYS)); + IdOrgSettings.setUrl(getDefault("ID_ORG_HOSTURL", + "http://www.jalview.org/services/identifiers")); + IdOrgSettings.setDownloadLocation(ID_ORG_FILE); + System.out .println("Jalview Version: " + codeVersion + codeInstallation); diff --git a/src/jalview/gui/DasSourceBrowser.java b/src/jalview/gui/DasSourceBrowser.java index 8c8f228..c5ec067 100644 --- a/src/jalview/gui/DasSourceBrowser.java +++ b/src/jalview/gui/DasSourceBrowser.java @@ -453,7 +453,7 @@ public class DasSourceBrowser extends GDasSourceBrowser implements pane12.add(nametf, BorderLayout.EAST); panel.add(pane12, BorderLayout.NORTH); pane12 = new JPanel(new BorderLayout()); - pane12.add(new JLabel(MessageManager.getString("label.url")), + pane12.add(new JLabel(MessageManager.getString("label.url:")), BorderLayout.NORTH); pane12.add(seqs, BorderLayout.SOUTH); pane12.add(urltf, BorderLayout.EAST); diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java index 0321662..dc16a57 100644 --- a/src/jalview/gui/Desktop.java +++ b/src/jalview/gui/Desktop.java @@ -20,7 +20,6 @@ */ package jalview.gui; -import static jalview.util.UrlConstants.EMBLEBI_STRING; import static jalview.util.UrlConstants.SEQUENCE_ID; import jalview.api.AlignViewportI; @@ -39,11 +38,14 @@ import jalview.io.JalviewFileView; import jalview.jbgui.GSplitFrame; import jalview.jbgui.GStructureViewer; import jalview.structure.StructureSelectionManager; +import jalview.urls.IdOrgSettings; import jalview.util.ImageMaker; import jalview.util.MessageManager; import jalview.util.Platform; +import jalview.util.UrlConstants; import jalview.viewmodel.AlignmentViewport; import jalview.ws.params.ParamManager; +import jalview.ws.utils.UrlDownloadClient; import java.awt.BorderLayout; import java.awt.Color; @@ -78,6 +80,7 @@ import java.beans.PropertyChangeListener; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Hashtable; @@ -392,6 +395,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements showNews.setVisible(false); + getIdentifiersOrgData(); + checkURLLinks(); this.addWindowListener(new WindowAdapter() @@ -525,6 +530,29 @@ public class Desktop extends jalview.jbgui.GDesktop implements }); } + public void getIdentifiersOrgData() + { + // Thread off the identifiers fetcher + addDialogThread(new Runnable() + { + @Override + public void run() + { + Cache.log.debug("Downloading data from identifiers.org"); + UrlDownloadClient client = new UrlDownloadClient(); + try + { + client.download(IdOrgSettings.getUrl(), + IdOrgSettings.getDownloadLocation()); + } catch (IOException e) + { + Cache.log.debug("Exception downloading identifiers.org data" + + e.getMessage()); + } + } + }); + } + @Override protected void showNews_actionPerformed(ActionEvent e) { @@ -2290,7 +2318,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements { // check what the actual links are - if it's just the default don't // bother with the warning - Vector links = Preferences.sequenceURLLinks; + List links = Preferences.sequenceUrlLinks + .getLinksForMenu(); // only need to check links if there is one with a // SEQUENCE_ID which is not the default EMBL_EBI link @@ -2300,7 +2329,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements while (li.hasNext()) { String link = li.next(); - if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING)) + if (link.contains(SEQUENCE_ID) + && !link.equals(UrlConstants.DEFAULT_STRING)) { check = true; int barPos = link.indexOf("|"); diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java index 59d12d9..6ae19f0 100755 --- a/src/jalview/gui/IdPanel.java +++ b/src/jalview/gui/IdPanel.java @@ -27,7 +27,6 @@ import jalview.datamodel.SequenceI; import jalview.io.SequenceAnnotationReport; import jalview.util.MessageManager; import jalview.util.Platform; -import jalview.util.UrlLink; import jalview.viewmodel.AlignmentViewport; import java.awt.BorderLayout; @@ -37,9 +36,7 @@ import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.util.List; -import java.util.Vector; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; @@ -199,56 +196,10 @@ public class IdPanel extends JPanel implements MouseListener, return; } - Vector links = Preferences.sequenceURLLinks; - if (links == null || links.size() < 1) - { - return; - } - int seq = alignPanel.getSeqPanel().findSeq(e); - String url = null; - int i = 0; String id = av.getAlignment().getSequenceAt(seq).getName(); - while (url == null && i < links.size()) - { - // DEFAULT LINK IS FIRST IN THE LINK LIST - // BUT IF ITS A REGEX AND DOES NOT MATCH THE NEXT ONE WILL BE TRIED - url = links.elementAt(i++).toString(); - jalview.util.UrlLink urlLink = null; - try - { - urlLink = new UrlLink(url); - } catch (Exception foo) - { - jalview.bin.Cache.log.error("Exception for URLLink '" + url + "'", - foo); - url = null; - continue; - } + String url = Preferences.sequenceUrlLinks.getPrimaryUrl(id); - 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()); - url = null; - continue; - } - - String urls[] = urlLink.makeUrls(id, true); - if (urls == null || urls[0] == null || urls[0].length() < 4) - { - url = null; - continue; - } - // just take first URL made from regex - url = urls[1]; - } try { jalview.util.BrowserLauncher.openURL(url); @@ -375,7 +326,7 @@ public class IdPanel extends JPanel implements MouseListener, Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq2); // build a new links menu based on the current links + any non-positional // features - Vector nlinks = new Vector(Preferences.sequenceURLLinks); + List nlinks = Preferences.sequenceUrlLinks.getLinksForMenu(); SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures(); if (sfs != null) { @@ -387,7 +338,7 @@ public class IdPanel extends JPanel implements MouseListener, { for (int l = 0, lSize = sf.links.size(); l < lSize; l++) { - nlinks.addElement(sf.links.elementAt(l)); + nlinks.add(sf.links.elementAt(l)); } } } diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index d32ff46..cf80a6d 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -20,11 +20,6 @@ */ package jalview.gui; -import static jalview.util.UrlConstants.DB_ACCESSION; -import static jalview.util.UrlConstants.EMBLEBI_STRING; -import static jalview.util.UrlConstants.SEQUENCE_ID; -import static jalview.util.UrlConstants.SRS_STRING; - import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder; import jalview.bin.Cache; import jalview.gui.Help.HelpId; @@ -37,12 +32,18 @@ import jalview.jbgui.GSequenceLink; import jalview.schemes.ColourSchemeI; import jalview.schemes.ColourSchemes; import jalview.schemes.ResidueColourScheme; +import jalview.urls.UrlLinkTableModel; +import jalview.urls.api.UrlProviderFactoryI; +import jalview.urls.api.UrlProviderI; +import jalview.urls.desktop.DesktopUrlProviderFactory; import jalview.util.MessageManager; import jalview.util.Platform; +import jalview.util.UrlConstants; import jalview.ws.sifts.SiftsSettings; import java.awt.BorderLayout; import java.awt.Color; +import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; @@ -51,14 +52,24 @@ import java.awt.event.MouseEvent; import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.StringTokenizer; -import java.util.Vector; import javax.help.HelpSetException; import javax.swing.JColorChooser; import javax.swing.JFileChooser; import javax.swing.JInternalFrame; import javax.swing.JPanel; +import javax.swing.ListSelectionModel; +import javax.swing.RowFilter; +import javax.swing.RowSorter; +import javax.swing.SortOrder; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; import ext.edu.ucsf.rbvi.strucviz2.StructureManager; @@ -104,7 +115,9 @@ public class Preferences extends GPreferences * Holds name and link separated with | character. Sequence ID must be * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$ */ - public static Vector sequenceURLLinks; + public static UrlProviderI sequenceUrlLinks; + + public static UrlLinkTableModel dataModel; /** * Holds name and link separated with | character. Sequence IDS and Sequences @@ -117,40 +130,23 @@ public class Preferences extends GPreferences public static List groupURLLinks; static { - String string = Cache.getDefault("SEQUENCE_LINKS", EMBLEBI_STRING); - sequenceURLLinks = new Vector(); - - try + // get links selected to be in the menu (SEQUENCE_LINKS) + // and links entered by the user but not selected (STORED_LINKS) + String inMenuString = Cache.getDefault("SEQUENCE_LINKS", ""); + String notInMenuString = Cache.getDefault("STORED_LINKS", ""); + String defaultUrl = Cache.getDefault("DEFAULT_URL", + UrlConstants.DEFAULT_LABEL); + + // if both links lists are empty, add the DEFAULT_URL link + // otherwise we assume the default link is in one of the lists + if (inMenuString.isEmpty() && notInMenuString.isEmpty()) { - StringTokenizer st = new StringTokenizer(string, "|"); - while (st.hasMoreElements()) - { - String name = st.nextToken(); - String url = st.nextToken(); - // check for '|' within a regex - int rxstart = url.indexOf("$" + DB_ACCESSION + "$"); - if (rxstart == -1) - { - rxstart = url.indexOf("$" + SEQUENCE_ID + "$"); - } - while (rxstart == -1 && url.indexOf("/=$") == -1) - { - url = url + "|" + st.nextToken(); - } - sequenceURLLinks.addElement(name + "|" + url); - } - } catch (Exception ex) - { - System.out.println(ex + "\nError parsing sequence links"); - } - { - // upgrade old SRS link - int srsPos = sequenceURLLinks.indexOf(SRS_STRING); - if (srsPos > -1) - { - sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos); - } + inMenuString = UrlConstants.DEFAULT_STRING; } + UrlProviderFactoryI factory = new DesktopUrlProviderFactory(defaultUrl, + inMenuString, notInMenuString); + sequenceUrlLinks = factory.createUrlProvider(); + dataModel = new UrlLinkTableModel(sequenceUrlLinks); /** * TODO: reformulate groupURL encoding so two or more can be stored in the @@ -160,8 +156,6 @@ public class Preferences extends GPreferences groupURLLinks = new ArrayList(); } - Vector nameLinks, urlLinks; - JInternalFrame frame; DasSourceBrowser dasSource; @@ -349,20 +343,128 @@ public class Preferences extends GPreferences /* * Set Connections tab defaults */ - nameLinks = new Vector(); - urlLinks = new Vector(); - for (int i = 0; i < sequenceURLLinks.size(); i++) + + // set up sorting + linkUrlTable.setModel(dataModel); + final TableRowSorter sorter = new TableRowSorter<>( + linkUrlTable.getModel()); + linkUrlTable.setRowSorter(sorter); + List sortKeys = new ArrayList<>(); + + UrlLinkTableModel m = (UrlLinkTableModel) linkUrlTable.getModel(); + sortKeys.add(new RowSorter.SortKey(m.getPrimaryColumn(), + SortOrder.DESCENDING)); + sortKeys.add(new RowSorter.SortKey(m.getSelectedColumn(), + SortOrder.DESCENDING)); + sortKeys.add(new RowSorter.SortKey(m.getNameColumn(), + SortOrder.ASCENDING)); + + sorter.setSortKeys(sortKeys); + sorter.sort(); + + // set up filtering + ActionListener onReset; + onReset = new ActionListener() { - String link = sequenceURLLinks.elementAt(i).toString(); - nameLinks.addElement(link.substring(0, link.indexOf("|"))); - urlLinks.addElement(link.substring(link.indexOf("|") + 1)); - } + @Override + public void actionPerformed(ActionEvent e) + { + filterTB.setText(""); + sorter.setRowFilter(RowFilter.regexFilter("")); + } + + }; + doReset.addActionListener(onReset); + + // filter to display only custom urls + final RowFilter customUrlFilter = new RowFilter() + { + @Override + public boolean include( + Entry entry) + { + return ((UrlLinkTableModel) entry.getModel()).isUserEntry(entry); + } + }; + + final TableRowSorter customSorter = new TableRowSorter<>( + linkUrlTable.getModel()); + customSorter.setRowFilter(customUrlFilter); + + ActionListener onCustomOnly; + onCustomOnly = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + filterTB.setText(""); + sorter.setRowFilter(customUrlFilter); + } + }; + userOnly.addActionListener(onCustomOnly); + + filterTB.getDocument().addDocumentListener(new DocumentListener() + { + String caseInsensitiveFlag = "(?i)"; - updateLinkData(); + @Override + public void changedUpdate(DocumentEvent e) + { + sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag + + filterTB.getText())); + } + + @Override + public void removeUpdate(DocumentEvent e) + { + sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag + + filterTB.getText())); + } + + @Override + public void insertUpdate(DocumentEvent e) + { + sorter.setRowFilter(RowFilter.regexFilter(caseInsensitiveFlag + + filterTB.getText())); + } + }); + + // set up list selection functionality + linkUrlTable.getSelectionModel().addListSelectionListener( + new UrlListSelectionHandler()); + + // set up radio buttons + int onClickCol = ((UrlLinkTableModel) linkUrlTable.getModel()) + .getPrimaryColumn(); + String onClickName = linkUrlTable.getColumnName(onClickCol); + linkUrlTable.getColumn(onClickName).setCellRenderer( + new RadioButtonRenderer()); + linkUrlTable.getColumn(onClickName) + .setCellEditor(new RadioButtonEditor()); + + // get boolean columns and resize those to min possible + for (int column = 0; column < linkUrlTable.getColumnCount(); column++) + { + if (linkUrlTable.getModel().getColumnClass(column) + .equals(Boolean.class)) + { + TableColumn tableColumn = linkUrlTable.getColumnModel().getColumn( + column); + int preferredWidth = tableColumn.getMinWidth(); + + TableCellRenderer cellRenderer = linkUrlTable.getCellRenderer(0, + column); + Component c = linkUrlTable.prepareRenderer(cellRenderer, 0, column); + int cwidth = c.getPreferredSize().width + + linkUrlTable.getIntercellSpacing().width; + preferredWidth = Math.max(preferredWidth, cwidth); + + tableColumn.setPreferredWidth(preferredWidth); + } + } useProxy.setSelected(Cache.getDefault("USE_PROXY", false)); - proxyServerTB.setEnabled(useProxy.isSelected()); - proxyPortTB.setEnabled(useProxy.isSelected()); + useProxy_actionPerformed(); // make sure useProxy is correctly initialised proxyServerTB.setText(Cache.getDefault("PROXY_SERVER", "")); proxyPortTB.setText(Cache.getDefault("PROXY_PORT", "")); @@ -554,28 +656,32 @@ public class Preferences extends GPreferences jalview.util.BrowserLauncher.resetBrowser(); - if (nameLinks.size() > 0) + // save user-defined and selected links + String menuLinks = sequenceUrlLinks.writeUrlsAsString(true); + if (menuLinks.isEmpty()) + { + Cache.applicationProperties.remove("SEQUENCE_LINKS"); + } + else { - StringBuffer links = new StringBuffer(); - sequenceURLLinks = new Vector(); - for (int i = 0; i < nameLinks.size(); i++) - { - sequenceURLLinks.addElement(nameLinks.elementAt(i) + "|" - + urlLinks.elementAt(i)); - links.append(sequenceURLLinks.elementAt(i).toString()); - links.append("|"); - } - // remove last "|" - links.setLength(links.length() - 1); Cache.applicationProperties.setProperty("SEQUENCE_LINKS", - links.toString()); + menuLinks.toString()); + } + + String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false); + if (nonMenuLinks.isEmpty()) + { + Cache.applicationProperties.remove("STORED_LINKS"); } else { - Cache.applicationProperties.remove("SEQUENCE_LINKS"); - sequenceURLLinks.clear(); + Cache.applicationProperties.setProperty("STORED_LINKS", + nonMenuLinks.toString()); } + Cache.applicationProperties.setProperty("DEFAULT_URL", + sequenceUrlLinks.getPrimaryUrlId()); + Cache.applicationProperties.setProperty("USE_PROXY", Boolean.toString(useProxy.isSelected())); @@ -756,7 +862,6 @@ public class Preferences extends GPreferences @Override public void newLink_actionPerformed(ActionEvent e) { - GSequenceLink link = new GSequenceLink(); boolean valid = false; while (!valid) @@ -767,10 +872,18 @@ public class Preferences extends GPreferences { if (link.checkValid()) { - nameLinks.addElement(link.getName()); - urlLinks.addElement(link.getURL()); - updateLinkData(); - valid = true; + if (((UrlLinkTableModel) linkUrlTable.getModel()) + .isUniqueName(link.getName())) + { + ((UrlLinkTableModel) linkUrlTable.getModel()).insertRow( + link.getName(), link.getURL()); + valid = true; + } + else + { + link.notifyDuplicate(); + continue; + } } } else @@ -785,36 +898,46 @@ public class Preferences extends GPreferences { GSequenceLink link = new GSequenceLink(); - int index = linkNameList.getSelectedIndex(); + int index = linkUrlTable.getSelectedRow(); if (index == -1) { - JvOptionPane.showInternalMessageDialog(Desktop.desktop, - MessageManager.getString("label.no_link_selected"), - MessageManager.getString("label.no_link_selected"), - JvOptionPane.WARNING_MESSAGE); + // button no longer enabled if row is not selected + Cache.log.debug("Edit with no row selected in linkUrlTable"); return; } - link.setName(nameLinks.elementAt(index).toString()); - link.setURL(urlLinks.elementAt(index).toString()); + int nameCol = ((UrlLinkTableModel) linkUrlTable.getModel()) + .getNameColumn(); + int urlCol = ((UrlLinkTableModel) linkUrlTable.getModel()) + .getUrlColumn(); + String oldName = linkUrlTable.getValueAt(index, nameCol).toString(); + link.setName(oldName); + link.setURL(linkUrlTable.getValueAt(index, urlCol).toString()); boolean valid = false; while (!valid) { - if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link, - MessageManager.getString("label.new_sequence_url_link"), + MessageManager.getString("label.edit_sequence_url_link"), JvOptionPane.OK_CANCEL_OPTION, -1, null) == JvOptionPane.OK_OPTION) { if (link.checkValid()) { - nameLinks.setElementAt(link.getName(), index); - urlLinks.setElementAt(link.getURL(), index); - updateLinkData(); - valid = true; + if ((oldName.equals(link.getName())) + || (((UrlLinkTableModel) linkUrlTable.getModel()) + .isUniqueName(link.getName()))) + { + linkUrlTable.setValueAt(link.getName(), index, nameCol); + linkUrlTable.setValueAt(link.getURL(), index, urlCol); + valid = true; + } + else + { + link.notifyDuplicate(); + continue; + } } } - else { break; @@ -825,26 +948,24 @@ public class Preferences extends GPreferences @Override public void deleteLink_actionPerformed(ActionEvent e) { - int index = linkNameList.getSelectedIndex(); + int index = linkUrlTable.getSelectedRow(); + int modelIndex = -1; if (index == -1) { - JvOptionPane.showInternalMessageDialog(Desktop.desktop, - MessageManager.getString("label.no_link_selected"), - MessageManager.getString("label.no_link_selected"), - JvOptionPane.WARNING_MESSAGE); + // button no longer enabled if row is not selected + Cache.log.debug("Delete with no row selected in linkUrlTable"); return; } - nameLinks.removeElementAt(index); - urlLinks.removeElementAt(index); - updateLinkData(); - } + else + { + modelIndex = linkUrlTable.convertRowIndexToModel(index); + } - void updateLinkData() - { - linkNameList.setListData(nameLinks); - linkURLList.setListData(urlLinks); + // make sure we use the model index to delete, and not the table index + ((UrlLinkTableModel) linkUrlTable.getModel()).removeRow(modelIndex); } + @Override public void defaultBrowser_mouseClicked(MouseEvent e) { @@ -1061,4 +1182,45 @@ public class Preferences extends GPreferences return name.hashCode() + code.hashCode(); } } + + private class UrlListSelectionHandler implements ListSelectionListener + { + + @Override + public void valueChanged(ListSelectionEvent e) + { + ListSelectionModel lsm = (ListSelectionModel) e.getSource(); + + int index = lsm.getMinSelectionIndex(); + if (index == -1) + { + // no selection, so disable delete/edit buttons + editLink.setEnabled(false); + deleteLink.setEnabled(false); + return; + } + int modelIndex = linkUrlTable.convertRowIndexToModel(index); + + // enable/disable edit and delete link buttons + if (((UrlLinkTableModel) linkUrlTable.getModel()) + .isRowDeletable(modelIndex)) + { + deleteLink.setEnabled(true); + } + else + { + deleteLink.setEnabled(false); + } + + if (((UrlLinkTableModel) linkUrlTable.getModel()) + .isRowEditable(modelIndex)) + { + editLink.setEnabled(true); + } + else + { + editLink.setEnabled(false); + } + } +} } diff --git a/src/jalview/gui/WsPreferences.java b/src/jalview/gui/WsPreferences.java index 165e8f2..32671d5 100644 --- a/src/jalview/gui/WsPreferences.java +++ b/src/jalview/gui/WsPreferences.java @@ -454,7 +454,7 @@ public class WsPreferences extends GWsPreferences JTextField urltf = new JTextField(url, 40); JPanel panel = new JPanel(new BorderLayout()); JPanel pane12 = new JPanel(new BorderLayout()); - pane12.add(new JLabel(MessageManager.getString("label.url")), + pane12.add(new JLabel(MessageManager.getString("label.url:")), BorderLayout.CENTER); pane12.add(urltf, BorderLayout.EAST); panel.add(pane12, BorderLayout.NORTH); @@ -574,6 +574,7 @@ public class WsPreferences extends GWsPreferences new Thread(new Runnable() { + @Override public void run() { // force a refresh. @@ -599,6 +600,7 @@ public class WsPreferences extends GWsPreferences new Thread(new Runnable() { + @Override public void run() { progressBar.setVisible(true); @@ -624,6 +626,7 @@ public class WsPreferences extends GWsPreferences new Thread(new Runnable() { + @Override public void run() { long ct = System.currentTimeMillis(); @@ -681,6 +684,7 @@ public class WsPreferences extends GWsPreferences new Thread(new Runnable() { + @Override public void run() { updateWsMenuConfig(false); diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index 90053f5..dda06b4 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -45,6 +45,7 @@ import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import javax.swing.AbstractCellEditor; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.DefaultListCellRenderer; @@ -53,11 +54,11 @@ import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JLabel; -import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; +import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; @@ -67,8 +68,8 @@ import javax.swing.border.EtchedBorder; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; /** * Base class for the Preferences panel. @@ -180,7 +181,21 @@ public class GPreferences extends JPanel /* * Connections tab components */ - protected JList linkURLList = new JList(); + protected JTable linkUrlTable = new JTable(); + + protected JButton editLink = new JButton(); + + protected JButton deleteLink = new JButton(); + + protected JTextField filterTB = new JTextField(); + + protected JButton doReset = new JButton(); + + protected JButton userOnly = new JButton(); + + protected JLabel portLabel = new JLabel(); + + protected JLabel serverLabel = new JLabel(); protected JTextField proxyServerTB = new JTextField(); @@ -188,8 +203,6 @@ public class GPreferences extends JPanel protected JTextField defaultBrowser = new JTextField(); - protected JList linkNameList = new JList(); - protected JCheckBox useProxy = new JCheckBox(); protected JCheckBox usagestats = new JCheckBox(); @@ -285,6 +298,9 @@ public class GPreferences extends JPanel tabbedPane.add(initConnectionsTab(), MessageManager.getString("label.connections")); + tabbedPane.add(initLinksTab(), + MessageManager.getString("label.urllinks")); + tabbedPane.add(initOutputTab(), MessageManager.getString("label.output")); @@ -483,40 +499,196 @@ public class GPreferences extends JPanel { JPanel connectTab = new JPanel(); connectTab.setLayout(new GridBagLayout()); - JLabel serverLabel = new JLabel(); - serverLabel.setText(MessageManager.getString("label.address")); - serverLabel.setHorizontalAlignment(SwingConstants.RIGHT); - serverLabel.setFont(LABEL_FONT); - proxyServerTB.setFont(LABEL_FONT); - proxyPortTB.setFont(LABEL_FONT); - JLabel portLabel = new JLabel(); - portLabel.setFont(LABEL_FONT); - portLabel.setHorizontalAlignment(SwingConstants.RIGHT); - portLabel.setText(MessageManager.getString("label.port")); + + // Label for browser text box JLabel browserLabel = new JLabel(); - browserLabel.setFont(new java.awt.Font("SansSerif", 0, 11)); + browserLabel.setFont(LABEL_FONT); browserLabel.setHorizontalAlignment(SwingConstants.TRAILING); browserLabel.setText(MessageManager .getString("label.default_browser_unix")); defaultBrowser.setFont(LABEL_FONT); defaultBrowser.setText(""); - usagestats.setText(MessageManager - .getString("label.send_usage_statistics")); - usagestats.setFont(LABEL_FONT); - usagestats.setHorizontalAlignment(SwingConstants.RIGHT); - usagestats.setHorizontalTextPosition(SwingConstants.LEADING); - questionnaire.setText(MessageManager - .getString("label.check_for_questionnaires")); - questionnaire.setFont(LABEL_FONT); - questionnaire.setHorizontalAlignment(SwingConstants.RIGHT); - questionnaire.setHorizontalTextPosition(SwingConstants.LEADING); - versioncheck.setText(MessageManager - .getString("label.check_for_latest_version")); - versioncheck.setFont(LABEL_FONT); - versioncheck.setHorizontalAlignment(SwingConstants.RIGHT); - versioncheck.setHorizontalTextPosition(SwingConstants.LEADING); + + defaultBrowser.addMouseListener(new MouseAdapter() + { + @Override + public void mouseClicked(MouseEvent e) + { + if (e.getClickCount() > 1) + { + defaultBrowser_mouseClicked(e); + } + } + }); + + JPanel proxyPanel = initConnTabProxyPanel(); + initConnTabCheckboxes(); + + // Add default Browser text box + connectTab.add(browserLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, + 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, + new Insets(10, 0, 5, 5), 5, 1)); + defaultBrowser.setFont(LABEL_FONT); + defaultBrowser.setText(""); + + connectTab.add(defaultBrowser, new GridBagConstraints(1, 0, 1, 1, 1.0, + 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(10, 0, 5, 10), 30, 1)); + + // Add proxy server panel + connectTab.add(proxyPanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 0.0, + GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, + new Insets(10, 0, 5, 12), 4, 10)); + + // Add usage stats, version check and questionnaire checkboxes + connectTab.add(usagestats, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, + GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(0, 2, 5, 5), 70, 1)); + connectTab.add(questionnaire, new GridBagConstraints(1, 2, 1, 1, 1.0, + 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(0, 2, 5, 10), 70, 1)); + connectTab.add(versioncheck, new GridBagConstraints(0, 3, 1, 1, 1.0, + 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, + new Insets(0, 2, 5, 5), 70, 1)); + + // Add padding so the panel doesn't look ridiculous + JPanel spacePanel = new JPanel(); + connectTab.add(spacePanel, new GridBagConstraints(0, 4, 1, 1, 1.0, 1.0, + GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, + 0, 0, 5), 70, 1)); + + return connectTab; + } + + /** + * Initialises the Links tabbed panel. + * + * @return + */ + private JPanel initLinksTab() + { + JPanel linkTab = new JPanel(); + linkTab.setLayout(new GridBagLayout()); + + // Set up table for Url links + linkUrlTable.setFillsViewportHeight(true); + linkUrlTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); + linkUrlTable.setAutoCreateRowSorter(true); + linkUrlTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + // adjust row height so radio buttons actually fit + // don't do this in the renderer, it causes the awt thread to activate + // constantly + JRadioButton temp = new JRadioButton(); + linkUrlTable.setRowHeight(temp.getMinimumSize().height); + + // Table in scrollpane so that the table is given a scrollbar + JScrollPane linkScrollPane = new JScrollPane(linkUrlTable); + linkScrollPane.setBorder(null); + + // Panel for links functionality + JPanel linkPanel = new JPanel(new GridBagLayout()); + linkPanel.setBorder(new TitledBorder(MessageManager + .getString("label.url_linkfrom_sequence_id"))); + + // Put the Url links panel together + + // Buttons go at top right, resizing only resizes the blank space vertically + JPanel buttonPanel = initLinkTabUrlButtons(); + GridBagConstraints linkConstraints1 = new GridBagConstraints(); + linkConstraints1.insets = new Insets(0, 0, 5, 0); + linkConstraints1.gridx = 0; + linkConstraints1.gridy = 0; + linkConstraints1.weightx = 1.0; + linkConstraints1.fill = GridBagConstraints.HORIZONTAL; + linkTab.add(buttonPanel, linkConstraints1); + + // Links table goes at top left, resizing resizes the table + GridBagConstraints linkConstraints2 = new GridBagConstraints(); + linkConstraints2.insets = new Insets(0, 0, 5, 5); + linkConstraints2.gridx = 0; + linkConstraints2.gridy = 1; + linkConstraints2.weightx = 1.0; + linkConstraints2.weighty = 1.0; + linkConstraints2.fill = GridBagConstraints.BOTH; + linkTab.add(linkScrollPane, linkConstraints2); + + // Filter box and buttons goes at bottom left, resizing resizes the text box + JPanel filterPanel = initLinkTabFilterPanel(); + GridBagConstraints linkConstraints3 = new GridBagConstraints(); + linkConstraints3.insets = new Insets(0, 0, 0, 5); + linkConstraints3.gridx = 0; + linkConstraints3.gridy = 2; + linkConstraints3.weightx = 1.0; + linkConstraints3.fill = GridBagConstraints.HORIZONTAL; + linkTab.add(filterPanel, linkConstraints3); + + return linkTab; + } + + private JPanel initLinkTabFilterPanel() + { + // Filter textbox and reset button + JLabel filterLabel = new JLabel( + MessageManager.getString("label.filter")); + filterLabel.setFont(LABEL_FONT); + filterLabel.setHorizontalAlignment(SwingConstants.RIGHT); + filterLabel.setHorizontalTextPosition(SwingConstants.LEADING); + + filterTB.setFont(LABEL_FONT); + filterTB.setText(""); + + doReset.setText(MessageManager.getString("action.showall")); + userOnly.setText(MessageManager.getString("action.customfilter")); + + // Panel for filter functionality + JPanel filterPanel = new JPanel(new GridBagLayout()); + filterPanel.setBorder(new TitledBorder("Filter")); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.NONE; + gbc.anchor = GridBagConstraints.WEST; + + filterPanel.add(filterLabel, gbc); + + GridBagConstraints gbc1 = new GridBagConstraints(); + gbc1.gridx = 1; + gbc1.gridwidth = 2; + gbc1.fill = GridBagConstraints.HORIZONTAL; + gbc1.anchor = GridBagConstraints.WEST; + gbc1.weightx = 1.0; + filterPanel.add(filterTB, gbc1); + + GridBagConstraints gbc2 = new GridBagConstraints(); + gbc2.gridx = 3; + gbc2.fill = GridBagConstraints.NONE; + gbc2.anchor = GridBagConstraints.WEST; + filterPanel.add(doReset, gbc2); + + GridBagConstraints gbc3 = new GridBagConstraints(); + gbc3.gridx = 4; + gbc3.fill = GridBagConstraints.NONE; + gbc3.anchor = GridBagConstraints.WEST; + filterPanel.add(userOnly, gbc3); + + return filterPanel; + } + + private JPanel initLinkTabUrlButtons() + { + // Buttons for new / edit / delete Url links JButton newLink = new JButton(); newLink.setText(MessageManager.getString("action.new")); + + editLink.setText(MessageManager.getString("action.edit")); + + deleteLink.setText(MessageManager.getString("action.delete")); + + // no current selection, so initially disable delete/edit buttons + editLink.setEnabled(false); + deleteLink.setEnabled(false); + newLink.addActionListener(new java.awt.event.ActionListener() { @Override @@ -525,7 +697,7 @@ public class GPreferences extends JPanel newLink_actionPerformed(e); } }); - JButton editLink = new JButton(); + editLink.setText(MessageManager.getString("action.edit")); editLink.addActionListener(new java.awt.event.ActionListener() { @@ -535,7 +707,7 @@ public class GPreferences extends JPanel editLink_actionPerformed(e); } }); - JButton deleteLink = new JButton(); + deleteLink.setText(MessageManager.getString("action.delete")); deleteLink.addActionListener(new java.awt.event.ActionListener() { @@ -546,55 +718,60 @@ public class GPreferences extends JPanel } }); - linkURLList.addListSelectionListener(new ListSelectionListener() - { - @Override - public void valueChanged(ListSelectionEvent e) - { - int index = linkURLList.getSelectedIndex(); - linkNameList.setSelectedIndex(index); - } - }); + JPanel buttonPanel = new JPanel(new GridBagLayout()); + buttonPanel.setBorder(new TitledBorder("Edit links")); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.fill = GridBagConstraints.NONE; + buttonPanel.add(newLink, gbc); + + GridBagConstraints gbc1 = new GridBagConstraints(); + gbc1.gridx = 1; + gbc1.gridy = 0; + gbc1.fill = GridBagConstraints.NONE; + buttonPanel.add(editLink, gbc1); + + GridBagConstraints gbc2 = new GridBagConstraints(); + gbc2.gridx = 2; + gbc2.gridy = 0; + gbc2.fill = GridBagConstraints.NONE; + buttonPanel.add(deleteLink, gbc2); + + GridBagConstraints gbc3 = new GridBagConstraints(); + gbc3.gridx = 3; + gbc3.gridy = 0; + gbc3.fill = GridBagConstraints.HORIZONTAL; + gbc3.weightx = 1.0; + JPanel spacePanel = new JPanel(); + spacePanel.setBorder(null); + buttonPanel.add(spacePanel, gbc3); + + return buttonPanel; + } - linkNameList.addListSelectionListener(new ListSelectionListener() - { - @Override - public void valueChanged(ListSelectionEvent e) - { - int index = linkNameList.getSelectedIndex(); - linkURLList.setSelectedIndex(index); - } - }); + /** + * Initialises the proxy server panel in the Connections tab + * + * @return the proxy server panel + */ + private JPanel initConnTabProxyPanel() + { + // Label for server text box + serverLabel.setText(MessageManager.getString("label.address")); + serverLabel.setHorizontalAlignment(SwingConstants.RIGHT); + serverLabel.setFont(LABEL_FONT); - JScrollPane linkScrollPane = new JScrollPane(); - linkScrollPane.setBorder(null); - JPanel linkPanel = new JPanel(); - linkPanel.setBorder(new TitledBorder(MessageManager - .getString("label.url_linkfrom_sequence_id"))); - linkPanel.setLayout(new BorderLayout()); - GridLayout gridLayout1 = new GridLayout(); - JPanel editLinkButtons = new JPanel(); - editLinkButtons.setLayout(gridLayout1); - gridLayout1.setRows(3); - linkNameList.setFont(LABEL_FONT); - linkNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - BorderLayout borderLayout3 = new BorderLayout(); - JPanel linkPanel2 = new JPanel(); - linkPanel2.setLayout(borderLayout3); - linkURLList.setFont(LABEL_FONT); - linkURLList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + // Proxy server and port text boxes + proxyServerTB.setFont(LABEL_FONT); + proxyPortTB.setFont(LABEL_FONT); - defaultBrowser.addMouseListener(new MouseAdapter() - { - @Override - public void mouseClicked(MouseEvent e) - { - if (e.getClickCount() > 1) - { - defaultBrowser_mouseClicked(e); - } - } - }); + // Label for Port text box + portLabel.setFont(LABEL_FONT); + portLabel.setHorizontalAlignment(SwingConstants.RIGHT); + portLabel.setText(MessageManager.getString("label.port")); + + // Use proxy server checkbox useProxy.setFont(LABEL_FONT); useProxy.setHorizontalAlignment(SwingConstants.RIGHT); useProxy.setHorizontalTextPosition(SwingConstants.LEADING); @@ -607,56 +784,57 @@ public class GPreferences extends JPanel useProxy_actionPerformed(); } }); - linkPanel.add(editLinkButtons, BorderLayout.EAST); - editLinkButtons.add(newLink, null); - editLinkButtons.add(editLink, null); - editLinkButtons.add(deleteLink, null); - linkPanel.add(linkScrollPane, BorderLayout.CENTER); - linkScrollPane.getViewport().add(linkPanel2, null); - linkPanel2.add(linkURLList, BorderLayout.CENTER); - linkPanel2.add(linkNameList, BorderLayout.WEST); - JPanel jPanel1 = new JPanel(); + + // Make proxy server panel + JPanel proxyPanel = new JPanel(); TitledBorder titledBorder1 = new TitledBorder( MessageManager.getString("label.proxy_server")); - jPanel1.setBorder(titledBorder1); - jPanel1.setLayout(new GridBagLayout()); - jPanel1.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, - 2, 4, 0), 5, 0)); - jPanel1.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, - 0, 4, 0), 11, 6)); - connectTab.add(linkPanel, new GridBagConstraints(0, 0, 2, 1, 1.0, 1.0, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( - 16, 0, 0, 12), 359, -17)); - connectTab.add(jPanel1, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0, - GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( - 21, 0, 35, 12), 4, 6)); - connectTab.add(browserLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, + proxyPanel.setBorder(titledBorder1); + proxyPanel.setLayout(new GridBagLayout()); + proxyPanel.add(serverLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, - new Insets(16, 0, 0, 0), 5, 1)); - jPanel1.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, + new Insets(0, 2, 2, 0), 5, 0)); + proxyPanel.add(portLabel, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, + GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, + 0, 2, 0), 11, 0)); + proxyPanel.add(useProxy, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 2, 5, 185), 2, -4)); - jPanel1.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, - new Insets(0, 2, 4, 2), 54, 1)); - jPanel1.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, - new Insets(0, 2, 4, 0), 263, 1)); - connectTab.add(defaultBrowser, new GridBagConstraints(1, 1, 1, 1, 1.0, - 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, - new Insets(15, 0, 0, 15), 307, 1)); - connectTab.add(usagestats, new GridBagConstraints(0, 4, 1, 1, 1.0, 0.0, - GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, - new Insets(0, 2, 4, 2), 70, 1)); - connectTab.add(questionnaire, new GridBagConstraints(1, 4, 1, 1, 1.0, + proxyPanel.add(proxyPortTB, new GridBagConstraints(3, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, - new Insets(0, 2, 4, 2), 70, 1)); - connectTab.add(versioncheck, new GridBagConstraints(0, 5, 1, 1, 1.0, + new Insets(0, 2, 2, 2), 54, 1)); + proxyPanel.add(proxyServerTB, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, - new Insets(0, 2, 4, 2), 70, 1)); - return connectTab; + new Insets(0, 2, 2, 0), 263, 1)); + + return proxyPanel; + } + + /** + * Initialises the checkboxes in the Connections tab + */ + private void initConnTabCheckboxes() + { + // Usage stats checkbox label + usagestats.setText(MessageManager + .getString("label.send_usage_statistics")); + usagestats.setFont(LABEL_FONT); + usagestats.setHorizontalAlignment(SwingConstants.RIGHT); + usagestats.setHorizontalTextPosition(SwingConstants.LEADING); + + // Questionnaire checkbox label + questionnaire.setText(MessageManager + .getString("label.check_for_questionnaires")); + questionnaire.setFont(LABEL_FONT); + questionnaire.setHorizontalAlignment(SwingConstants.RIGHT); + questionnaire.setHorizontalTextPosition(SwingConstants.LEADING); + + // Check for latest version checkbox label + versioncheck.setText(MessageManager + .getString("label.check_for_latest_version")); + versioncheck.setFont(LABEL_FONT); + versioncheck.setHorizontalAlignment(SwingConstants.RIGHT); + versioncheck.setHorizontalTextPosition(SwingConstants.LEADING); } /** @@ -1357,8 +1535,82 @@ public class GPreferences extends JPanel public void useProxy_actionPerformed() { - proxyServerTB.setEnabled(useProxy.isSelected()); - proxyPortTB.setEnabled(useProxy.isSelected()); + boolean enabled = useProxy.isSelected(); + portLabel.setEnabled(enabled); + serverLabel.setEnabled(enabled); + proxyServerTB.setEnabled(enabled); + proxyPortTB.setEnabled(enabled); + } + + /** + * Customer renderer for JTable: supports column of radio buttons + */ + public class RadioButtonRenderer extends JRadioButton implements + TableCellRenderer + { + public RadioButtonRenderer() + { + setHorizontalAlignment(CENTER); + setToolTipText(MessageManager.getString("label.urltooltip")); + } + + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, boolean isSelected, boolean hasFocus, int row, + int column) + { + setSelected((boolean) value); + + // set colours to match rest of table + if (isSelected) + { + setBackground(table.getSelectionBackground()); + setForeground(table.getSelectionForeground()); + } + else + { + setBackground(table.getBackground()); + setForeground(table.getForeground()); + } + return this; + } } + /** + * Customer cell editor for JTable: supports column of radio buttons in + * conjunction with renderer + */ + public class RadioButtonEditor extends AbstractCellEditor implements + TableCellEditor + { + private JRadioButton button = new JRadioButton(); + + public RadioButtonEditor() + { + button.setHorizontalAlignment(SwingConstants.CENTER); + this.button.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + fireEditingStopped(); + } + }); + } + + @Override + public Component getTableCellEditorComponent(JTable table, + Object value, boolean isSelected, int row, int column) + { + button.setSelected((boolean) value); + return button; + } + + @Override + public Object getCellEditorValue() + { + return button.isSelected(); + } + + } } diff --git a/src/jalview/jbgui/GSequenceLink.java b/src/jalview/jbgui/GSequenceLink.java index dbce5f3..ab3ea2c 100755 --- a/src/jalview/jbgui/GSequenceLink.java +++ b/src/jalview/jbgui/GSequenceLink.java @@ -29,19 +29,48 @@ import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.awt.Panel; import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.BorderFactory; +import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; -public class GSequenceLink extends Panel +public class GSequenceLink extends JPanel { + + JTextField nameTB = new JTextField(); + + JTextField urlTB = new JTextField(); + + JButton insertSeq = new JButton(); + + JButton insertDBAcc = new JButton(); + + JLabel insert = new JLabel(); + + JLabel jLabel1 = new JLabel(); + + JLabel jLabel2 = new JLabel(); + + JLabel jLabel3 = new JLabel(); + + JLabel jLabel4 = new JLabel(); + + JLabel jLabel5 = new JLabel(); + + JLabel jLabel6 = new JLabel(); + + JPanel jPanel1 = new JPanel(); + + GridBagLayout gridBagLayout1 = new GridBagLayout(); + public GSequenceLink() { try @@ -77,23 +106,53 @@ public class GSequenceLink extends Panel urlTB_keyTyped(e); } }); + + insertSeq.setLocation(77, 75); + insertSeq.setSize(141, 24); + insertSeq.setText(MessageManager.getString("action.seq_id")); + insertSeq.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + insertSeq_action(e); + } + }); + + insertDBAcc.setLocation(210, 75); + insertDBAcc.setSize(141, 24); + insertDBAcc.setText(MessageManager.getString("action.db_acc")); + insertDBAcc.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + insertDBAcc_action(e); + } + }); + + insert.setText(MessageManager.getString("label.insert")); + insert.setFont(JvSwingUtils.getLabelFont()); + insert.setHorizontalAlignment(SwingConstants.RIGHT); + insert.setBounds(17, 78, 58, 16); + jLabel1.setFont(JvSwingUtils.getLabelFont()); jLabel1.setHorizontalAlignment(SwingConstants.TRAILING); jLabel1.setText(MessageManager.getString("label.link_name")); jLabel1.setBounds(new Rectangle(4, 10, 71, 24)); jLabel2.setFont(JvSwingUtils.getLabelFont()); jLabel2.setHorizontalAlignment(SwingConstants.TRAILING); - jLabel2.setText(MessageManager.getString("label.url")); + jLabel2.setText(MessageManager.getString("label.url:")); jLabel2.setBounds(new Rectangle(17, 37, 54, 27)); jLabel3.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11)); jLabel3.setText(MessageManager.getString("label.use_sequence_id_1")); - jLabel3.setBounds(new Rectangle(21, 72, 351, 15)); + jLabel3.setBounds(new Rectangle(21, 102, 351, 15)); jLabel4.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11)); jLabel4.setText(MessageManager.getString("label.use_sequence_id_2")); - jLabel4.setBounds(new Rectangle(21, 88, 351, 15)); + jLabel4.setBounds(new Rectangle(21, 118, 351, 15)); jLabel5.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11)); jLabel5.setText(MessageManager.getString("label.use_sequence_id_3")); - jLabel5.setBounds(new Rectangle(21, 106, 351, 15)); + jLabel5.setBounds(new Rectangle(21, 136, 351, 15)); String lastLabel = MessageManager.getString("label.use_sequence_id_4"); if (lastLabel.length() > 0) @@ -101,7 +160,7 @@ public class GSequenceLink extends Panel // e.g. Spanish version has longer text jLabel6.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11)); jLabel6.setText(lastLabel); - jLabel6.setBounds(new Rectangle(21, 122, 351, 15)); + jLabel6.setBounds(new Rectangle(21, 152, 351, 15)); } jPanel1.setBorder(BorderFactory.createEtchedBorder()); @@ -109,16 +168,19 @@ public class GSequenceLink extends Panel jPanel1.add(jLabel1); jPanel1.add(nameTB); jPanel1.add(urlTB); + jPanel1.add(insertSeq); + jPanel1.add(insertDBAcc); + jPanel1.add(insert); jPanel1.add(jLabel2); jPanel1.add(jLabel3); jPanel1.add(jLabel4); jPanel1.add(jLabel5); - int height = 130; + int height = 160; if (lastLabel.length() > 0) { jPanel1.add(jLabel6); - height = 146; + height = 176; } this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, @@ -163,25 +225,13 @@ public class GSequenceLink extends Panel return false; } - JTextField nameTB = new JTextField(); - - JTextField urlTB = new JTextField(); - - JLabel jLabel1 = new JLabel(); - - JLabel jLabel2 = new JLabel(); - - JLabel jLabel3 = new JLabel(); - - JLabel jLabel4 = new JLabel(); - - JLabel jLabel5 = new JLabel(); - - JLabel jLabel6 = new JLabel(); - - JPanel jPanel1 = new JPanel(); - - GridBagLayout gridBagLayout1 = new GridBagLayout(); + public void notifyDuplicate() + { + JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop, + MessageManager.getString("warn.name_cannot_be_duplicate"), + MessageManager.getString("label.invalid_name"), + JvOptionPane.WARNING_MESSAGE); + } public void nameTB_keyTyped(KeyEvent e) { @@ -200,4 +250,23 @@ public class GSequenceLink extends Panel // } } + + public void insertSeq_action(ActionEvent e) + { + insertIntoUrl(insertSeq.getText()); + } + + public void insertDBAcc_action(ActionEvent e) + { + insertIntoUrl(insertDBAcc.getText()); + } + + private void insertIntoUrl(String insertion) + { + int pos = urlTB.getCaretPosition(); + String text = urlTB.getText(); + String newText = text.substring(0, pos) + insertion + + text.substring(pos); + urlTB.setText(newText); + } } diff --git a/src/jalview/urls/CustomUrlProvider.java b/src/jalview/urls/CustomUrlProvider.java new file mode 100644 index 0000000..07f4068 --- /dev/null +++ b/src/jalview/urls/CustomUrlProvider.java @@ -0,0 +1,342 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ + +package jalview.urls; + +import static jalview.util.UrlConstants.DB_ACCESSION; +import static jalview.util.UrlConstants.DELIM; +import static jalview.util.UrlConstants.SEP; +import static jalview.util.UrlConstants.SEQUENCE_ID; + +import jalview.util.MessageManager; +import jalview.util.UrlConstants; +import jalview.util.UrlLink; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.StringTokenizer; + +/** + * + * Implements the UrlProviderI interface for a UrlProvider object which serves + * custom URLs defined by the user + * + * @author $author$ + * @version $Revision$ + */ +public class CustomUrlProvider extends UrlProviderImpl +{ + // Default sequence URL link label for SRS + private static final String SRS_LABEL = "SRS"; + + // map of string ids to urlLinks (selected) + private HashMap selectedUrls; + + // map of string ids to urlLinks (not selected) + private HashMap nonselectedUrls; + + /** + * Construct UrlProvider for custom (user-entered) URLs + * + * @param inMenuUrlList + * list of URLs set to be displayed in menu, in form stored in Cache. + * i.e. SEP delimited string + * @param storedUrlList + * list of custom URLs entered by user but not currently displayed in + * menu, in form stored in Cache + */ + public CustomUrlProvider(String inMenuUrlList, String storedUrlList) + { + try + { + selectedUrls = parseUrlStrings(inMenuUrlList); + nonselectedUrls = parseUrlStrings(storedUrlList); + } catch (Exception ex) + { + System.out + .println(ex.getMessage() + "\nError parsing sequence links"); + } + } + + /** + * Construct UrlProvider for custom (user-entered) URLs + * + * @param urlList + * list of URLs to be displayed in menu, as (label,url) pairs + * @param storedUrlList + * list of custom URLs entered by user but not currently displayed in + * menu, as (label,url) pairs + */ + public CustomUrlProvider(Map inMenuUrlList, + Map storedUrlList) + { + try + { + selectedUrls = parseUrlList(inMenuUrlList); + nonselectedUrls = parseUrlList(storedUrlList); + } catch (Exception ex) + { + System.out + .println(ex.getMessage() + "\nError parsing sequence links"); + } + } + + private HashMap parseUrlStrings(String urlStrings) + { + // cachedUrlList is in form