742cd6bbed93f0c61c76d573552f0b810583caa6
[jalview.git] / src / jalview / gui / PopupMenu.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.1)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10  *  
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  * The Jalview Authors are detailed in the 'AUTHORS' file.
18  */
19 package jalview.gui;
20
21 import java.util.*;
22
23 import java.awt.*;
24 import java.awt.event.*;
25
26 import javax.swing.*;
27
28 import jalview.analysis.*;
29 import jalview.commands.*;
30 import jalview.datamodel.*;
31 import jalview.io.*;
32 import jalview.schemes.*;
33 import jalview.util.GroupUrlLink;
34 import jalview.util.GroupUrlLink.UrlStringTooLongException;
35 import jalview.util.MessageManager;\r
36 import jalview.util.UrlLink;
37
38 /**
39  * DOCUMENT ME!
40  * 
41  * @author $author$
42  * @version $Revision: 1.118 $
43  */
44 public class PopupMenu extends JPopupMenu
45 {
46   JMenu groupMenu = new JMenu();
47
48   JMenuItem groupName = new JMenuItem();
49
50   protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();
51
52   protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
53
54   protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
55
56   protected JRadioButtonMenuItem hydrophobicityColour = new JRadioButtonMenuItem();
57
58   protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
59
60   protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
61
62   protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
63
64   protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
65
66   protected JCheckBoxMenuItem abovePIDColour = new JCheckBoxMenuItem();
67
68   protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();
69
70   protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();
71
72   protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
73
74   protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem();
75   protected JRadioButtonMenuItem RNAInteractionColour = new JRadioButtonMenuItem();
76
77   // protected JRadioButtonMenuItem covariationColour = new
78   // JRadioButtonMenuItem();
79
80   JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();
81
82   protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
83
84   AlignmentPanel ap;
85
86   JMenu sequenceMenu = new JMenu();
87
88   JMenuItem sequenceName = new JMenuItem();
89
90   JMenuItem sequenceDetails = new JMenuItem();
91
92   JMenuItem sequenceSelDetails = new JMenuItem();
93
94   SequenceI sequence;
95   JMenuItem createGroupMenuItem = new JMenuItem();
96   JMenuItem unGroupMenuItem = new JMenuItem();
97
98   JMenuItem outline = new JMenuItem();
99
100   JRadioButtonMenuItem nucleotideMenuItem = new JRadioButtonMenuItem();
101
102   JMenu colourMenu = new JMenu();
103
104   JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();
105
106   JCheckBoxMenuItem showText = new JCheckBoxMenuItem();
107
108   JCheckBoxMenuItem showColourText = new JCheckBoxMenuItem();
109
110   JCheckBoxMenuItem displayNonconserved = new JCheckBoxMenuItem();
111
112   JMenu editMenu = new JMenu();
113
114   JMenuItem cut = new JMenuItem();
115
116   JMenuItem copy = new JMenuItem();
117
118   JMenuItem upperCase = new JMenuItem();
119
120   JMenuItem lowerCase = new JMenuItem();
121
122   JMenuItem toggle = new JMenuItem();
123
124   JMenu pdbMenu = new JMenu();
125
126   JMenuItem pdbFromFile = new JMenuItem();
127     // JBPNote: Commented these out - Should add these services via the web services menu system.
128     // JMenuItem ContraFold = new JMenuItem();
129   
130     // JMenuItem RNAFold = new JMenuItem();
131   
132   JMenuItem enterPDB = new JMenuItem();
133
134   JMenuItem discoverPDB = new JMenuItem();
135
136   JMenu outputMenu = new JMenu();
137
138   JMenuItem sequenceFeature = new JMenuItem();
139
140   JMenuItem textColour = new JMenuItem();
141
142   JMenu jMenu1 = new JMenu();
143
144   JMenu structureMenu = new JMenu();
145
146   JMenu viewStructureMenu = new JMenu();
147
148   // JMenu colStructureMenu = new JMenu();
149   JMenuItem editSequence = new JMenuItem();
150
151   // JMenuItem annotationMenuItem = new JMenuItem();
152
153   JMenu groupLinksMenu;
154
155   /**
156    * Creates a new PopupMenu object.
157    * 
158    * @param ap
159    *          DOCUMENT ME!
160    * @param seq
161    *          DOCUMENT ME!
162    */
163   public PopupMenu(final AlignmentPanel ap, Sequence seq, Vector links)
164   {
165     this(ap, seq, links, null);
166   }
167
168   /**
169    * 
170    * @param ap
171    * @param seq
172    * @param links
173    * @param groupLinks
174    */
175   public PopupMenu(final AlignmentPanel ap, final SequenceI seq,
176           Vector links, Vector groupLinks)
177   {
178     // /////////////////////////////////////////////////////////
179     // If this is activated from the sequence panel, the user may want to
180     // edit or annotate a particular residue. Therefore display the residue menu
181     //
182     // If from the IDPanel, we must display the sequence menu
183     // ////////////////////////////////////////////////////////
184     this.ap = ap;
185     sequence = seq;
186
187     ButtonGroup colours = new ButtonGroup();
188     colours.add(noColourmenuItem);
189     colours.add(clustalColour);
190     colours.add(zappoColour);
191     colours.add(taylorColour);
192     colours.add(hydrophobicityColour);
193     colours.add(helixColour);
194     colours.add(strandColour);
195     colours.add(turnColour);
196     colours.add(buriedColour);
197     colours.add(abovePIDColour);
198     colours.add(userDefinedColour);
199     colours.add(PIDColour);
200     colours.add(BLOSUM62Colour);
201     colours.add(purinePyrimidineColour);
202     colours.add(RNAInteractionColour);
203     // colours.add(covariationColour);
204
205     for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++)
206     {
207       JMenuItem item = new JMenuItem(
208               jalview.io.FormatAdapter.WRITEABLE_FORMATS[i]);
209
210       item.addActionListener(new java.awt.event.ActionListener()
211       {
212         public void actionPerformed(ActionEvent e)
213         {
214           outputText_actionPerformed(e);
215         }
216       });
217
218       outputMenu.add(item);
219     }
220
221     try
222     {
223       jbInit();
224     } catch (Exception e)
225     {
226       e.printStackTrace();
227     }
228
229     JMenuItem menuItem;
230     if (seq != null)
231     {
232       sequenceMenu.setText(sequence.getName());
233
234       if (seq.getDatasetSequence().getPDBId() != null
235               && seq.getDatasetSequence().getPDBId().size() > 0)
236       {
237         java.util.Enumeration e = seq.getDatasetSequence().getPDBId()
238                 .elements();
239
240         while (e.hasMoreElements())
241         {
242           final PDBEntry pdb = (PDBEntry) e.nextElement();
243
244           menuItem = new JMenuItem();
245           menuItem.setText(pdb.getId());
246           menuItem.addActionListener(new java.awt.event.ActionListener()
247           {
248             public void actionPerformed(ActionEvent e)
249             {
250               // TODO re JAL-860: optionally open dialog or provide a menu entry
251               // allowing user to open just one structure per sequence
252               new AppJmol(pdb, ap.av.collateForPDB(new PDBEntry[]
253               { pdb })[0], null, ap);
254               // new PDBViewer(pdb, seqs2, null, ap, AppletFormatAdapter.FILE);
255             }
256
257           });
258           viewStructureMenu.add(menuItem);
259
260           /*
261            * menuItem = new JMenuItem(); menuItem.setText(pdb.getId());
262            * menuItem.addActionListener(new java.awt.event.ActionListener() {
263            * public void actionPerformed(ActionEvent e) {
264            * colourByStructure(pdb.getId()); } });
265            * colStructureMenu.add(menuItem);
266            */
267         }
268       }
269       else
270       {
271         if (ap.av.getAlignment().isNucleotide() == false)
272         {
273           structureMenu.remove(viewStructureMenu);
274         }
275         // structureMenu.remove(colStructureMenu);
276       }
277
278       if (ap.av.getAlignment().isNucleotide() == true)
279       {
280         AlignmentAnnotation[] aa = ap.av.getAlignment()
281                 .getAlignmentAnnotation();
282         for (int i = 0; i < aa.length; i++)
283         {
284           if (aa[i].getRNAStruc() != null)
285           {
286             final String rnastruc = aa[i].getRNAStruc();
287             final String structureLine = aa[i].label;
288             menuItem = new JMenuItem();
289             menuItem.setText(MessageManager.formatMessage("label.2d_rna_structure_line", new String[]{structureLine}));\r
290             menuItem.addActionListener(new java.awt.event.ActionListener()
291             
292             {
293               public void actionPerformed(ActionEvent e)
294               {
295                         //System.out.println("1:"+structureLine);
296                         System.out.println("1:sname"+seq.getName());
297                         System.out.println("2:seq"+seq);
298                 
299                         //System.out.println("3:"+seq.getSequenceAsString());
300                         System.out.println("3:strucseq"+rnastruc);
301                         //System.out.println("4:struc"+seq.getRNA());
302                         System.out.println("5:name"+seq.getName());
303                         System.out.println("6:ap"+ap);
304                         new AppVarna(structureLine, seq, seq.getSequenceAsString(), rnastruc, seq
305                             .getName(), ap);
306                         //new AppVarna(seq.getName(),seq,rnastruc,seq.getRNA(), seq.getName(), ap);
307                         System.out.println("end");
308               }
309             });
310             viewStructureMenu.add(menuItem);
311           }
312         }
313
314         // SequenceFeatures[] test = seq.getSequenceFeatures();
315
316         if (seq.getAnnotation() != null)
317         {
318           AlignmentAnnotation seqAnno[] = seq.getAnnotation();
319           for (int i = 0; i < seqAnno.length; i++)
320           {
321             if (seqAnno[i].getRNAStruc() != null)
322             {
323               final String rnastruc = seqAnno[i].getRNAStruc();
324
325               // TODO: make rnastrucF a bit more nice
326               menuItem = new JMenuItem();
327               menuItem.setText(MessageManager.formatMessage("label.2d_rna_sequence_name", new String[]{seq.getName()}));\r
328               menuItem.addActionListener(new java.awt.event.ActionListener()
329               {
330                 public void actionPerformed(ActionEvent e)
331                 {
332                   // TODO: VARNA does'nt print gaps in the sequence
333                 
334                   new AppVarna(seq.getName() + " structure", seq, seq
335                           .getSequenceAsString(), rnastruc, seq.getName(),
336                           ap);
337                 }
338               });
339               viewStructureMenu.add(menuItem);
340             }
341           }
342         }
343
344       }
345
346       menuItem = new JMenuItem(MessageManager.getString("action.hide_sequences"));\r
347       menuItem.addActionListener(new java.awt.event.ActionListener()
348       {
349         public void actionPerformed(ActionEvent e)
350         {
351           hideSequences(false);
352         }
353       });
354       add(menuItem);
355
356       if (ap.av.getSelectionGroup() != null
357               && ap.av.getSelectionGroup().getSize() > 1)
358       {
359         menuItem = new JMenuItem(MessageManager.formatMessage("label.represent_group_with", new String[]{seq.getName()}));\r
360         menuItem.addActionListener(new java.awt.event.ActionListener()
361         {
362           public void actionPerformed(ActionEvent e)
363           {
364             hideSequences(true);
365           }
366         });
367         sequenceMenu.add(menuItem);
368       }
369
370       if (ap.av.hasHiddenRows())
371       {
372         final int index = ap.av.getAlignment().findIndex(seq);
373
374         if (ap.av.adjustForHiddenSeqs(index)
375                 - ap.av.adjustForHiddenSeqs(index - 1) > 1)
376         {
377           menuItem = new JMenuItem(MessageManager.getString("action.reveal_sequences"));\r
378           menuItem.addActionListener(new ActionListener()
379           {
380             public void actionPerformed(ActionEvent e)
381             {
382               ap.av.showSequence(index);
383               if (ap.overviewPanel != null)
384               {
385                 ap.overviewPanel.updateOverviewImage();
386               }
387             }
388           });
389           add(menuItem);
390         }
391       }
392     }
393     // for the case when no sequences are even visible
394     if (ap.av.hasHiddenRows())
395     {
396       {
397         menuItem = new JMenuItem(MessageManager.getString("action.reveal_all"));\r
398         menuItem.addActionListener(new ActionListener()
399         {
400           public void actionPerformed(ActionEvent e)
401           {
402             ap.av.showAllHiddenSeqs();
403             if (ap.overviewPanel != null)
404             {
405               ap.overviewPanel.updateOverviewImage();
406             }
407           }
408         });
409
410         add(menuItem);
411       }
412
413     }
414
415     SequenceGroup sg = ap.av.getSelectionGroup();
416     boolean isDefinedGroup = (sg!=null) ? ap.av.getAlignment().getGroups().contains(sg) : false;
417
418     if (sg != null && sg.getSize() > 0)
419     {      
420       groupName.setText(MessageManager.formatMessage("label.name_param", new String[]{sg.getName()}));\r
421       groupName.setText(MessageManager.getString("label.edit_name_and_description_current_group"));\r
422
423       if (sg.cs instanceof ZappoColourScheme)
424       {
425         zappoColour.setSelected(true);
426       }
427       else if (sg.cs instanceof TaylorColourScheme)
428       {
429         taylorColour.setSelected(true);
430       }
431       else if (sg.cs instanceof PIDColourScheme)
432       {
433         PIDColour.setSelected(true);
434       }
435       else if (sg.cs instanceof Blosum62ColourScheme)
436       {
437         BLOSUM62Colour.setSelected(true);
438       }
439       else if (sg.cs instanceof UserColourScheme)
440       {
441         userDefinedColour.setSelected(true);
442       }
443       else if (sg.cs instanceof HydrophobicColourScheme)
444       {
445         hydrophobicityColour.setSelected(true);
446       }
447       else if (sg.cs instanceof HelixColourScheme)
448       {
449         helixColour.setSelected(true);
450       }
451       else if (sg.cs instanceof StrandColourScheme)
452       {
453         strandColour.setSelected(true);
454       }
455       else if (sg.cs instanceof TurnColourScheme)
456       {
457         turnColour.setSelected(true);
458       }
459       else if (sg.cs instanceof BuriedColourScheme)
460       {
461         buriedColour.setSelected(true);
462       }
463       else if (sg.cs instanceof ClustalxColourScheme)
464       {
465         clustalColour.setSelected(true);
466       }
467       else if (sg.cs instanceof PurinePyrimidineColourScheme)
468       {
469         purinePyrimidineColour.setSelected(true);
470       }
471       
472    
473       /*
474        * else if (sg.cs instanceof CovariationColourScheme) {
475        * covariationColour.setSelected(true); }
476        */
477       else
478       {
479         noColourmenuItem.setSelected(true);
480       }
481
482       if (sg.cs != null && sg.cs.conservationApplied())
483       {
484         conservationMenuItem.setSelected(true);
485       }
486       displayNonconserved.setSelected(sg.getShowNonconserved());
487       showText.setSelected(sg.getDisplayText());
488       showColourText.setSelected(sg.getColourText());
489       showBoxes.setSelected(sg.getDisplayBoxes());
490       // add any groupURLs to the groupURL submenu and make it visible
491       if (groupLinks != null && groupLinks.size() > 0)
492       {
493         buildGroupURLMenu(sg, groupLinks);
494       }
495       // Add a 'show all structures' for the current selection
496       Hashtable<String, PDBEntry> pdbe = new Hashtable<String, PDBEntry>(),reppdb=new Hashtable<String,PDBEntry>();
497       SequenceI sqass = null;
498       for (SequenceI sq : ap.av.getSequenceSelection())
499       {
500         Vector<PDBEntry> pes = (Vector<PDBEntry>) sq.getDatasetSequence()
501                 .getPDBId();
502         if (pes != null)
503         {
504           reppdb.put(pes.get(0).getId(),pes.get(0));
505           for (PDBEntry pe : pes)
506           {
507             pdbe.put(pe.getId(), pe);
508             if (sqass == null)
509             {
510               sqass = sq;
511             }
512           }
513         }
514       }
515       if (pdbe.size() > 0)
516       {
517         final PDBEntry[] pe = pdbe.values().toArray(
518                 new PDBEntry[pdbe.size()]),pr = reppdb.values().toArray(
519                         new PDBEntry[reppdb.size()]);
520         final JMenuItem gpdbview,rpdbview;
521         if (pdbe.size() == 1)
522         {
523           structureMenu.add(gpdbview = new JMenuItem(MessageManager.formatMessage("label.view_structure_for", new String[]{sqass.getDisplayId(false)})));\r
524         }
525         else
526         {
527           structureMenu.add(gpdbview = new JMenuItem(MessageManager.formatMessage("label.view_all_structures", new String[]{new Integer(pdbe.size()).toString()})));          \r
528         }
529         gpdbview.setToolTipText(MessageManager.getString("label.open_new_jmol_view_with_all_structures_associated_current_selection_superimpose_using_alignment"));\r
530         gpdbview.addActionListener(new ActionListener()
531         {
532
533           @Override
534           public void actionPerformed(ActionEvent e)
535           {
536             new AppJmol(ap, pe, ap.av.collateForPDB(pe));
537           }
538         });
539         if (reppdb.size()>1 && reppdb.size()<pdbe.size())
540         {
541           structureMenu.add(rpdbview = new JMenuItem(MessageManager.formatMessage("label.view_all_representative_structures", new String[]{new Integer(reppdb.size()).toString()})));
542           rpdbview.setToolTipText(MessageManager.getString("label.open_new_jmol_view_with_all_representative_structures_associated_current_selection_superimpose_using_alignment"));
543           rpdbview.addActionListener(new ActionListener()
544           {
545
546             @Override
547             public void actionPerformed(ActionEvent e)
548             {
549               new AppJmol(ap, pr, ap.av.collateForPDB(pr));
550             }
551           });
552         }
553       }
554     }
555     else
556     {
557       groupMenu.setVisible(false);
558       editMenu.setVisible(false);
559     }
560
561     if (!isDefinedGroup)
562     {
563       createGroupMenuItem.setVisible(true);
564       unGroupMenuItem.setVisible(false);
565       jMenu1.setText(MessageManager.getString("action.edit_new_group"));\r
566     } else {
567       createGroupMenuItem.setVisible(false);
568       unGroupMenuItem.setVisible(true);
569       jMenu1.setText(MessageManager.getString("action.edit_group"));\r
570     }
571
572     if (seq == null)
573     {
574       sequenceMenu.setVisible(false);
575       structureMenu.setVisible(false);
576     }
577
578     if (links != null && links.size() > 0)
579     {
580
581       JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));\r
582       Vector linkset = new Vector();
583       for (int i = 0; i < links.size(); i++)
584       {
585         String link = links.elementAt(i).toString();
586         UrlLink urlLink = null;
587         try
588         {
589           urlLink = new UrlLink(link);
590         } catch (Exception foo)
591         {
592           jalview.bin.Cache.log.error("Exception for URLLink '" + link
593                   + "'", foo);
594           continue;
595         }
596         ;
597         if (!urlLink.isValid())
598         {
599           jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
600           continue;
601         }
602         final String label = urlLink.getLabel();
603         if (seq != null && urlLink.isDynamic())
604         {
605
606           // collect matching db-refs
607           DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(
608                   seq.getDBRef(), new String[]
609                   { urlLink.getTarget() });
610           // collect id string too
611           String id = seq.getName();
612           String descr = seq.getDescription();
613           if (descr != null && descr.length() < 1)
614           {
615             descr = null;
616           }
617
618           if (dbr != null)
619           {
620             for (int r = 0; r < dbr.length; r++)
621             {
622               if (id != null && dbr[r].getAccessionId().equals(id))
623               {
624                 // suppress duplicate link creation for the bare sequence ID
625                 // string with this link
626                 id = null;
627               }
628               // create Bare ID link for this RUL
629               String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(),
630                       true);
631               if (urls != null)
632               {
633                 for (int u = 0; u < urls.length; u += 2)
634                 {
635                   if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
636                   {
637                     linkset.addElement(urls[u] + "|" + urls[u + 1]);
638                     addshowLink(linkMenu, label + "|" + urls[u],
639                             urls[u + 1]);
640                   }
641                 }
642               }
643             }
644           }
645           if (id != null)
646           {
647             // create Bare ID link for this RUL
648             String[] urls = urlLink.makeUrls(id, true);
649             if (urls != null)
650             {
651               for (int u = 0; u < urls.length; u += 2)
652               {
653                 if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
654                 {
655                   linkset.addElement(urls[u] + "|" + urls[u + 1]);
656                   addshowLink(linkMenu, label, urls[u + 1]);
657                 }
658               }
659             }
660           }
661           // Create urls from description but only for URL links which are regex
662           // links
663           if (descr != null && urlLink.getRegexReplace() != null)
664           {
665             // create link for this URL from description where regex matches
666             String[] urls = urlLink.makeUrls(descr, true);
667             if (urls != null)
668             {
669               for (int u = 0; u < urls.length; u += 2)
670               {
671                 if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
672                 {
673                   linkset.addElement(urls[u] + "|" + urls[u + 1]);
674                   addshowLink(linkMenu, label, urls[u + 1]);
675                 }
676               }
677             }
678           }
679         }
680         else
681         {
682           if (!linkset.contains(label + "|" + urlLink.getUrl_prefix()))
683           {
684             linkset.addElement(label + "|" + urlLink.getUrl_prefix());
685             // Add a non-dynamic link
686             addshowLink(linkMenu, label, urlLink.getUrl_prefix());
687           }
688         }
689       }
690       if (sequence != null)
691       {
692         sequenceMenu.add(linkMenu);
693       }
694       else
695       {
696         add(linkMenu);
697       }
698     }
699   }
700
701   private void buildGroupURLMenu(SequenceGroup sg, Vector groupLinks)
702   {
703
704     // TODO: usability: thread off the generation of group url content so root
705     // menu appears asap
706     // sequence only URLs
707     // ID/regex match URLs
708     groupLinksMenu = new JMenu(MessageManager.getString("action.group_link"));\r
709     JMenu[] linkMenus = new JMenu[]
710     { null, new JMenu(MessageManager.getString("action.ids")), new JMenu(MessageManager.getString("action.sequences")),\r
711         new JMenu(MessageManager.getString("action.ids_sequences")) }; // three types of url that might be\r
712                                           // created.
713     SequenceI[] seqs = ap.av.getSelectionAsNewSequence();
714     String[][] idandseqs = GroupUrlLink.formStrings(seqs);
715     Hashtable commonDbrefs = new Hashtable();
716     for (int sq = 0; sq < seqs.length; sq++)
717     {
718
719       int start = seqs[sq].findPosition(sg.getStartRes()), end = seqs[sq]
720               .findPosition(sg.getEndRes());
721       // just collect ids from dataset sequence
722       // TODO: check if IDs collected from selecton group intersects with the
723       // current selection, too
724       SequenceI sqi = seqs[sq];
725       while (sqi.getDatasetSequence() != null)
726       {
727         sqi = sqi.getDatasetSequence();
728       }
729       DBRefEntry[] dbr = sqi.getDBRef();
730       if (dbr != null && dbr.length > 0)
731       {
732         for (int d = 0; d < dbr.length; d++)
733         {
734           String src = dbr[d].getSource(); // jalview.util.DBRefUtils.getCanonicalName(dbr[d].getSource()).toUpperCase();
735           Object[] sarray = (Object[]) commonDbrefs.get(src);
736           if (sarray == null)
737           {
738             sarray = new Object[2];
739             sarray[0] = new int[]
740             { 0 };
741             sarray[1] = new String[seqs.length];
742
743             commonDbrefs.put(src, sarray);
744           }
745
746           if (((String[]) sarray[1])[sq] == null)
747           {
748             if (!dbr[d].hasMap()
749                     || (dbr[d].getMap().locateMappedRange(start, end) != null))
750             {
751               ((String[]) sarray[1])[sq] = dbr[d].getAccessionId();
752               ((int[]) sarray[0])[0]++;
753             }
754           }
755         }
756       }
757     }
758     // now create group links for all distinct ID/sequence sets.
759     boolean addMenu = false; // indicates if there are any group links to give
760                              // to user
761     for (int i = 0; i < groupLinks.size(); i++)
762     {
763       String link = groupLinks.elementAt(i).toString();
764       GroupUrlLink urlLink = null;
765       try
766       {
767         urlLink = new GroupUrlLink(link);
768       } catch (Exception foo)
769       {
770         jalview.bin.Cache.log.error("Exception for GroupURLLink '" + link
771                 + "'", foo);
772         continue;
773       }
774       ;
775       if (!urlLink.isValid())
776       {
777         jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
778         continue;
779       }
780       final String label = urlLink.getLabel();
781       boolean usingNames = false;
782       // Now see which parts of the group apply for this URL
783       String ltarget = urlLink.getTarget(); // jalview.util.DBRefUtils.getCanonicalName(urlLink.getTarget());
784       Object[] idset = (Object[]) commonDbrefs.get(ltarget.toUpperCase());
785       String[] seqstr, ids; // input to makeUrl
786       if (idset != null)
787       {
788         int numinput = ((int[]) idset[0])[0];
789         String[] allids = ((String[]) idset[1]);
790         seqstr = new String[numinput];
791         ids = new String[numinput];
792         for (int sq = 0, idcount = 0; sq < seqs.length; sq++)
793         {
794           if (allids[sq] != null)
795           {
796             ids[idcount] = allids[sq];
797             seqstr[idcount++] = idandseqs[1][sq];
798           }
799         }
800       }
801       else
802       {
803         // just use the id/seq set
804         seqstr = idandseqs[1];
805         ids = idandseqs[0];
806         usingNames = true;
807       }
808       // and try and make the groupURL!
809
810       Object[] urlset = null;
811       try
812       {
813         urlset = urlLink.makeUrlStubs(ids, seqstr,
814                 "FromJalview" + System.currentTimeMillis(), false);
815       } catch (UrlStringTooLongException e)
816       {
817       }
818       if (urlset != null)
819       {
820         int type = urlLink.getGroupURLType() & 3;
821         // System.out.println(urlLink.getGroupURLType()
822         // +" "+((String[])urlset[3])[0]);
823         // first two bits ofurlLink type bitfield are sequenceids and sequences
824         // TODO: FUTURE: ensure the groupURL menu structure can be generalised
825         addshowLink(linkMenus[type], label
826                 + (((type & 1) == 1) ? ("("
827                         + (usingNames ? "Names" : ltarget) + ")") : ""),
828                 urlLink, urlset);
829         addMenu = true;
830       }
831     }
832     if (addMenu)
833     {
834       groupLinksMenu = new JMenu(MessageManager.getString("action.group_link"));\r
835       for (int m = 0; m < linkMenus.length; m++)
836       {
837         if (linkMenus[m] != null
838                 && linkMenus[m].getMenuComponentCount() > 0)
839         {
840           groupLinksMenu.add(linkMenus[m]);
841         }
842       }
843
844       groupMenu.add(groupLinksMenu);
845     }
846   }
847
848   /**
849    * add a show URL menu item to the given linkMenu
850    * 
851    * @param linkMenu
852    * @param label
853    *          - menu label string
854    * @param url
855    *          - url to open
856    */
857   private void addshowLink(JMenu linkMenu, String label, final String url)
858   {
859     JMenuItem item = new JMenuItem(label);
860     item.setToolTipText(MessageManager.formatMessage("label.open_url_param", new String[]{url}));\r
861     item.addActionListener(new java.awt.event.ActionListener()
862     {
863       public void actionPerformed(ActionEvent e)
864       {
865         new Thread(new Runnable()
866         {
867
868           public void run()
869           {
870             showLink(url);
871           }
872
873         }).start();
874       }
875     });
876
877     linkMenu.add(item);
878   }
879
880   /**
881    * add a late bound groupURL item to the given linkMenu
882    * 
883    * @param linkMenu
884    * @param label
885    *          - menu label string
886    * @param urlgenerator
887    *          GroupURLLink used to generate URL
888    * @param urlstub
889    *          Object array returned from the makeUrlStubs function.
890    */
891   private void addshowLink(JMenu linkMenu, String label,
892           final GroupUrlLink urlgenerator, final Object[] urlstub)
893   {
894     JMenuItem item = new JMenuItem(label);
895     item.setToolTipText(MessageManager.formatMessage("label.open_url_seqs_param", new Object[]{urlgenerator.getUrl_prefix(),urlgenerator.getNumberInvolved(urlstub)}));\r
896     // TODO: put in info about what is being sent.\r
897     item.addActionListener(new java.awt.event.ActionListener()
898     {
899       public void actionPerformed(ActionEvent e)
900       {
901         new Thread(new Runnable()
902         {
903
904           public void run()
905           {
906             try
907             {
908               showLink(urlgenerator.constructFrom(urlstub));
909             } catch (UrlStringTooLongException e)
910             {
911             }
912           }
913
914         }).start();
915       }
916     });
917
918     linkMenu.add(item);
919   }
920
921   /**
922    * DOCUMENT ME!
923    * 
924    * @throws Exception
925    *           DOCUMENT ME!
926    */
927   private void jbInit() throws Exception
928   {
929     groupMenu.setText(MessageManager.getString("label.group"));\r
930     groupMenu.setText(MessageManager.getString("label.selection"));\r
931     groupName.setText(MessageManager.getString("label.name"));\r
932     groupName.addActionListener(new java.awt.event.ActionListener()
933     {
934       public void actionPerformed(ActionEvent e)
935       {
936         groupName_actionPerformed();
937       }
938     });
939     sequenceMenu.setText(MessageManager.getString("label.sequence"));\r
940     sequenceName.setText(MessageManager.getString("label.edit_name_description"));\r
941     sequenceName.addActionListener(new java.awt.event.ActionListener()
942     {
943       public void actionPerformed(ActionEvent e)
944       {
945         sequenceName_actionPerformed();
946       }
947     });
948     sequenceDetails.setText(MessageManager.getString("label.sequence_details") + "...");\r
949     sequenceDetails.addActionListener(new java.awt.event.ActionListener()
950     {
951       public void actionPerformed(ActionEvent e)
952       {
953         sequenceDetails_actionPerformed();
954       }
955     });
956     sequenceSelDetails.setText(MessageManager.getString("label.sequence_details") + "...");\r
957     sequenceSelDetails
958             .addActionListener(new java.awt.event.ActionListener()
959             {
960               public void actionPerformed(ActionEvent e)
961               {
962                 sequenceSelectionDetails_actionPerformed();
963               }
964             });
965     PIDColour.setFocusPainted(false);
966     unGroupMenuItem.setText(MessageManager.getString("action.remove_group"));\r
967     unGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
968     {
969       public void actionPerformed(ActionEvent e)
970       {
971         unGroupMenuItem_actionPerformed();
972       }
973     });
974     createGroupMenuItem.setText(MessageManager.getString("action.create_group"));\r
975     createGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
976     {
977       public void actionPerformed(ActionEvent e)
978       {
979         createGroupMenuItem_actionPerformed();
980       }
981     });
982
983     outline.setText(MessageManager.getString("action.border_colour"));\r
984     outline.addActionListener(new java.awt.event.ActionListener()
985     {
986       public void actionPerformed(ActionEvent e)
987       {
988         outline_actionPerformed();
989       }
990     });
991     nucleotideMenuItem.setText(MessageManager.getString("label.nucleotide"));\r
992     nucleotideMenuItem.addActionListener(new ActionListener()
993     {
994       public void actionPerformed(ActionEvent e)
995       {
996         nucleotideMenuItem_actionPerformed();
997       }
998     });
999     colourMenu.setText(MessageManager.getString("label.group_colour"));\r
1000     showBoxes.setText(MessageManager.getString("action.boxes"));\r
1001     showBoxes.setState(true);
1002     showBoxes.addActionListener(new ActionListener()
1003     {
1004       public void actionPerformed(ActionEvent e)
1005       {
1006         showBoxes_actionPerformed();
1007       }
1008     });
1009     showText.setText(MessageManager.getString("action.text"));\r
1010     showText.setState(true);
1011     showText.addActionListener(new ActionListener()
1012     {
1013       public void actionPerformed(ActionEvent e)
1014       {
1015         showText_actionPerformed();
1016       }
1017     });
1018     showColourText.setText(MessageManager.getString("label.colour_text"));\r
1019     showColourText.addActionListener(new ActionListener()
1020     {
1021       public void actionPerformed(ActionEvent e)
1022       {
1023         showColourText_actionPerformed();
1024       }
1025     });
1026     displayNonconserved.setText(MessageManager.getString("label.show_non_conversed"));\r
1027     displayNonconserved.setState(true);
1028     displayNonconserved.addActionListener(new ActionListener()
1029     {
1030       public void actionPerformed(ActionEvent e)
1031       {
1032         showNonconserved_actionPerformed();
1033       }
1034     });
1035     editMenu.setText(MessageManager.getString("action.edit"));\r
1036     cut.setText(MessageManager.getString("action.cut"));\r
1037     cut.addActionListener(new ActionListener()
1038     {
1039       public void actionPerformed(ActionEvent e)
1040       {
1041         cut_actionPerformed();
1042       }
1043     });
1044     upperCase.setText(MessageManager.getString("label.to_upper_case"));\r
1045     upperCase.addActionListener(new ActionListener()
1046     {
1047       public void actionPerformed(ActionEvent e)
1048       {
1049         changeCase(e);
1050       }
1051     });
1052     copy.setText(MessageManager.getString("action.copy"));\r
1053     copy.addActionListener(new ActionListener()
1054     {
1055       public void actionPerformed(ActionEvent e)
1056       {
1057         copy_actionPerformed();
1058       }
1059     });
1060     lowerCase.setText(MessageManager.getString("label.to_lower_case"));\r
1061     lowerCase.addActionListener(new ActionListener()
1062     {
1063       public void actionPerformed(ActionEvent e)
1064       {
1065         changeCase(e);
1066       }
1067     });
1068     toggle.setText(MessageManager.getString("label.toggle_case"));\r
1069     toggle.addActionListener(new ActionListener()
1070     {
1071       public void actionPerformed(ActionEvent e)
1072       {
1073         changeCase(e);
1074       }
1075     });
1076     pdbMenu.setText(MessageManager.getString("label.associate_structure_with_sequence"));\r
1077     pdbFromFile.setText(MessageManager.getString("label.from_file"));\r
1078     pdbFromFile.addActionListener(new ActionListener()
1079     {
1080       public void actionPerformed(ActionEvent e)
1081       {
1082         pdbFromFile_actionPerformed();
1083       }
1084     });
1085 //    RNAFold.setText("From RNA Fold with predict2D");
1086 //    RNAFold.addActionListener(new ActionListener()
1087 //    {
1088 //      public void actionPerformed(ActionEvent e)
1089 //      {
1090 //        try {
1091 //                      RNAFold_actionPerformed();
1092 //              } catch (Exception e1) {
1093 //                      // TODO Auto-generated catch block
1094 //                      e1.printStackTrace();
1095 //              }
1096 //      }   
1097 //    });
1098 //    ContraFold.setText("From Contra Fold with predict2D");
1099 //    ContraFold.addActionListener(new ActionListener()
1100 //    {
1101 //      public void actionPerformed(ActionEvent e)
1102 //      {
1103 //        try {
1104 //                      ContraFold_actionPerformed();
1105 //              } catch (Exception e1) {
1106 //                      // TODO Auto-generated catch block
1107 //                      e1.printStackTrace();
1108 //              }
1109 //      }   
1110 //    });
1111     enterPDB.setText(MessageManager.getString("label.enter_pdb_id"));\r
1112     enterPDB.addActionListener(new ActionListener()
1113     {
1114       public void actionPerformed(ActionEvent e)
1115       {
1116         enterPDB_actionPerformed();
1117       }
1118     });
1119     discoverPDB.setText(MessageManager.getString("label.discover_pdb_ids"));\r
1120     discoverPDB.addActionListener(new ActionListener()
1121     {
1122       public void actionPerformed(ActionEvent e)
1123       {
1124         discoverPDB_actionPerformed();
1125       }
1126     });
1127     outputMenu.setText(MessageManager.getString("label.out_to_textbox") + "...");\r
1128     sequenceFeature.setText(MessageManager.getString("label.create_sequence_feature"));\r
1129     sequenceFeature.addActionListener(new ActionListener()
1130     {
1131       public void actionPerformed(ActionEvent e)
1132       {
1133         sequenceFeature_actionPerformed();
1134       }
1135     });
1136     textColour.setText(MessageManager.getString("label.text_colour"));\r
1137     textColour.addActionListener(new ActionListener()
1138     {
1139       public void actionPerformed(ActionEvent e)
1140       {
1141         textColour_actionPerformed();
1142       }
1143     });
1144     jMenu1.setText(MessageManager.getString("label.group"));\r
1145     structureMenu.setText(MessageManager.getString("label.structure"));\r
1146     viewStructureMenu.setText(MessageManager.getString("label.view_structure"));\r
1147     // colStructureMenu.setText("Colour By Structure");
1148     editSequence.setText(MessageManager.getString("label.edit_sequence") + "...");\r
1149     editSequence.addActionListener(new ActionListener()
1150     {
1151       public void actionPerformed(ActionEvent actionEvent)
1152       {
1153         editSequence_actionPerformed(actionEvent);
1154       }
1155     });
1156
1157     /*
1158      * annotationMenuItem.setText("By Annotation");
1159      * annotationMenuItem.addActionListener(new ActionListener() { public void
1160      * actionPerformed(ActionEvent actionEvent) {
1161      * annotationMenuItem_actionPerformed(actionEvent); } });
1162      */
1163     groupMenu.add(sequenceSelDetails);
1164     add(groupMenu);
1165     add(sequenceMenu);
1166     this.add(structureMenu);
1167     groupMenu.add(editMenu);
1168     groupMenu.add(outputMenu);
1169     groupMenu.add(sequenceFeature);
1170     groupMenu.add(createGroupMenuItem);
1171     groupMenu.add(unGroupMenuItem);
1172     groupMenu.add(jMenu1);
1173     sequenceMenu.add(sequenceName);
1174     sequenceMenu.add(sequenceDetails);
1175     colourMenu.add(textColour);
1176     colourMenu.add(noColourmenuItem);
1177     colourMenu.add(clustalColour);
1178     colourMenu.add(BLOSUM62Colour);
1179     colourMenu.add(PIDColour);
1180     colourMenu.add(zappoColour);
1181     colourMenu.add(taylorColour);
1182     colourMenu.add(hydrophobicityColour);
1183     colourMenu.add(helixColour);
1184     colourMenu.add(strandColour);
1185     colourMenu.add(turnColour);
1186     colourMenu.add(buriedColour);
1187     colourMenu.add(nucleotideMenuItem);
1188     if (ap.getAlignment().isNucleotide()) {
1189         // JBPNote - commented since the colourscheme isn't functional
1190         //  colourMenu.add(RNAInteractionColour);
1191         colourMenu.add(purinePyrimidineColour);
1192     }
1193     // colourMenu.add(covariationColour);
1194     colourMenu.add(userDefinedColour);
1195
1196     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
1197     {
1198       java.util.Enumeration userColours = jalview.gui.UserDefinedColours
1199               .getUserColourSchemes().keys();
1200
1201       while (userColours.hasMoreElements())
1202       {
1203         JMenuItem item = new JMenuItem(userColours.nextElement().toString());
1204         item.addActionListener(new ActionListener()
1205         {
1206           public void actionPerformed(ActionEvent evt)
1207           {
1208             userDefinedColour_actionPerformed(evt);
1209           }
1210         });
1211         colourMenu.add(item);
1212       }
1213     }
1214
1215     colourMenu.addSeparator();
1216     colourMenu.add(abovePIDColour);
1217     colourMenu.add(conservationMenuItem);
1218     // colourMenu.add(annotationMenuItem);
1219     editMenu.add(copy);
1220     editMenu.add(cut);
1221     editMenu.add(editSequence);
1222     editMenu.add(upperCase);
1223     editMenu.add(lowerCase);
1224     editMenu.add(toggle);
1225     pdbMenu.add(pdbFromFile);
1226     // JBPNote: These shouldn't be added here - should appear in a generic 'apply web service to this sequence menu'
1227     //    pdbMenu.add(RNAFold);
1228     //    pdbMenu.add(ContraFold);
1229     pdbMenu.add(enterPDB);
1230     pdbMenu.add(discoverPDB);
1231     jMenu1.add(groupName);
1232     jMenu1.add(colourMenu);
1233     jMenu1.add(showBoxes);
1234     jMenu1.add(showText);
1235     jMenu1.add(showColourText);
1236     jMenu1.add(outline);
1237     jMenu1.add(displayNonconserved);
1238     structureMenu.add(pdbMenu);
1239     structureMenu.add(viewStructureMenu);
1240     // structureMenu.add(colStructureMenu);
1241     noColourmenuItem.setText(MessageManager.getString("label.none"));\r
1242     noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
1243     {
1244       public void actionPerformed(ActionEvent e)
1245       {
1246         noColourmenuItem_actionPerformed();
1247       }
1248     });
1249
1250     clustalColour.setText(MessageManager.getString("label.clustalx_colours"));\r
1251     clustalColour.addActionListener(new java.awt.event.ActionListener()
1252     {
1253       public void actionPerformed(ActionEvent e)
1254       {
1255         clustalColour_actionPerformed();
1256       }
1257     });
1258     zappoColour.setText(MessageManager.getString("label.zappo"));\r
1259     zappoColour.addActionListener(new java.awt.event.ActionListener()
1260     {
1261       public void actionPerformed(ActionEvent e)
1262       {
1263         zappoColour_actionPerformed();
1264       }
1265     });
1266     taylorColour.setText(MessageManager.getString("label.taylor"));\r
1267     taylorColour.addActionListener(new java.awt.event.ActionListener()
1268     {
1269       public void actionPerformed(ActionEvent e)
1270       {
1271         taylorColour_actionPerformed();
1272       }
1273     });
1274     hydrophobicityColour.setText(MessageManager.getString("label.hydrophobicity"));\r
1275     hydrophobicityColour
1276             .addActionListener(new java.awt.event.ActionListener()
1277             {
1278               public void actionPerformed(ActionEvent e)
1279               {
1280                 hydrophobicityColour_actionPerformed();
1281               }
1282             });
1283     helixColour.setText(MessageManager.getString("label.helix_propensity"));\r
1284     helixColour.addActionListener(new java.awt.event.ActionListener()
1285     {
1286       public void actionPerformed(ActionEvent e)
1287       {
1288         helixColour_actionPerformed();
1289       }
1290     });
1291     strandColour.setText(MessageManager.getString("label.strand_propensity"));\r
1292     strandColour.addActionListener(new java.awt.event.ActionListener()
1293     {
1294       public void actionPerformed(ActionEvent e)
1295       {
1296         strandColour_actionPerformed();
1297       }
1298     });
1299     turnColour.setText(MessageManager.getString("label.turn_propensity"));\r
1300     turnColour.addActionListener(new java.awt.event.ActionListener()
1301     {
1302       public void actionPerformed(ActionEvent e)
1303       {
1304         turnColour_actionPerformed();
1305       }
1306     });
1307     buriedColour.setText(MessageManager.getString("label.buried_index"));\r
1308     buriedColour.addActionListener(new java.awt.event.ActionListener()
1309     {
1310       public void actionPerformed(ActionEvent e)
1311       {
1312         buriedColour_actionPerformed();
1313       }
1314     });
1315     abovePIDColour.setText(MessageManager.getString("label.above_identity_percentage"));\r
1316     abovePIDColour.addActionListener(new java.awt.event.ActionListener()
1317     {
1318       public void actionPerformed(ActionEvent e)
1319       {
1320         abovePIDColour_actionPerformed();
1321       }
1322     });
1323     userDefinedColour.setText(MessageManager.getString("action.user_defined"));\r
1324     userDefinedColour.addActionListener(new java.awt.event.ActionListener()
1325     {
1326       public void actionPerformed(ActionEvent e)
1327       {
1328         userDefinedColour_actionPerformed(e);
1329       }
1330     });
1331     PIDColour.setText(MessageManager.getString("label.percentage_identity"));\r
1332     PIDColour.addActionListener(new java.awt.event.ActionListener()
1333     {
1334       public void actionPerformed(ActionEvent e)
1335       {
1336         PIDColour_actionPerformed();
1337       }
1338     });
1339     BLOSUM62Colour.setText(MessageManager.getString("label.blosum62"));\r
1340     BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
1341     {
1342       public void actionPerformed(ActionEvent e)
1343       {
1344         BLOSUM62Colour_actionPerformed();
1345       }
1346     });
1347     purinePyrimidineColour.setText(MessageManager.getString("label.purine_pyrimidine"));\r
1348     purinePyrimidineColour
1349             .addActionListener(new java.awt.event.ActionListener()
1350             {
1351               public void actionPerformed(ActionEvent e)
1352               {
1353                 purinePyrimidineColour_actionPerformed();
1354               }
1355             });
1356     
1357    
1358     /*
1359      * covariationColour.addActionListener(new java.awt.event.ActionListener() {
1360      * public void actionPerformed(ActionEvent e) {
1361      * covariationColour_actionPerformed(); } });
1362      */
1363
1364     conservationMenuItem.setText(MessageManager.getString("label.conservation"));\r
1365     conservationMenuItem
1366             .addActionListener(new java.awt.event.ActionListener()
1367             {
1368               public void actionPerformed(ActionEvent e)
1369               {
1370                 conservationMenuItem_actionPerformed();
1371               }
1372             });
1373   }
1374
1375   protected void sequenceSelectionDetails_actionPerformed()
1376   {
1377     createSequenceDetailsReport(ap.av.getSequenceSelection());
1378   }
1379
1380   protected void sequenceDetails_actionPerformed()
1381   {
1382     createSequenceDetailsReport(new SequenceI[]
1383     { sequence });
1384   }
1385
1386   public void createSequenceDetailsReport(SequenceI[] sequences)
1387   {
1388     CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
1389     StringBuffer contents = new StringBuffer();
1390     for (SequenceI seq : sequences)
1391     {
1392       contents.append("<p><h2>" + MessageManager.formatMessage("label.create_sequence_details_report_annotation_for", new String[]{seq.getDisplayId(true)})\r
1393               + "</h2></p><p>");
1394       new SequenceAnnotationReport(null)
1395               .createSequenceAnnotationReport(
1396                       contents,
1397                       seq,
1398                       true,
1399                       true,
1400                       false,
1401                       (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr.minmax
1402                               : null);
1403       contents.append("</p>");
1404     }
1405     cap.setText("<html>" + contents.toString() + "</html>");
1406
1407     Desktop.instance.addInternalFrame(cap, MessageManager.formatMessage("label.sequece_details_for", (sequences.length == 1 ? new String[]{sequences[0].getDisplayId(true)}: new String[]{MessageManager.getString("label.selection")}))\r
1408                 ,500, 400);\r
1409
1410   }
1411
1412   protected void showNonconserved_actionPerformed()
1413   {
1414     getGroup().setShowNonconserved(displayNonconserved.isSelected());
1415     refresh();
1416   }
1417
1418   /**
1419    * call to refresh view after settings change
1420    */
1421   void refresh()
1422   {
1423     ap.updateAnnotation();
1424     ap.paintAlignment(true);
1425
1426     PaintRefresher.Refresh(this, ap.av.getSequenceSetId());
1427   }
1428
1429   /**
1430    * DOCUMENT ME!
1431    * 
1432    * @param e
1433    *          DOCUMENT ME!
1434    */
1435   protected void clustalColour_actionPerformed()
1436   {
1437     SequenceGroup sg = getGroup();
1438     sg.cs = new ClustalxColourScheme(sg, ap.av.getHiddenRepSequences());
1439     refresh();
1440   }
1441
1442   /**
1443    * DOCUMENT ME!
1444    * 
1445    * @param e
1446    *          DOCUMENT ME!
1447    */
1448   protected void zappoColour_actionPerformed()
1449   {
1450     getGroup().cs = new ZappoColourScheme();
1451     refresh();
1452   }
1453
1454   /**
1455    * DOCUMENT ME!
1456    * 
1457    * @param e
1458    *          DOCUMENT ME!
1459    */
1460   protected void taylorColour_actionPerformed()
1461   {
1462     getGroup().cs = new TaylorColourScheme();
1463     refresh();
1464   }
1465
1466   /**
1467    * DOCUMENT ME!
1468    * 
1469    * @param e
1470    *          DOCUMENT ME!
1471    */
1472   protected void hydrophobicityColour_actionPerformed()
1473   {
1474     getGroup().cs = new HydrophobicColourScheme();
1475     refresh();
1476   }
1477
1478   /**
1479    * DOCUMENT ME!
1480    * 
1481    * @param e
1482    *          DOCUMENT ME!
1483    */
1484   protected void helixColour_actionPerformed()
1485   {
1486     getGroup().cs = new HelixColourScheme();
1487     refresh();
1488   }
1489
1490   /**
1491    * DOCUMENT ME!
1492    * 
1493    * @param e
1494    *          DOCUMENT ME!
1495    */
1496   protected void strandColour_actionPerformed()
1497   {
1498     getGroup().cs = new StrandColourScheme();
1499     refresh();
1500   }
1501
1502   /**
1503    * DOCUMENT ME!
1504    * 
1505    * @param e
1506    *          DOCUMENT ME!
1507    */
1508   protected void turnColour_actionPerformed()
1509   {
1510     getGroup().cs = new TurnColourScheme();
1511     refresh();
1512   }
1513
1514   /**
1515    * DOCUMENT ME!
1516    * 
1517    * @param e
1518    *          DOCUMENT ME!
1519    */
1520   protected void buriedColour_actionPerformed()
1521   {
1522     getGroup().cs = new BuriedColourScheme();
1523     refresh();
1524   }
1525
1526   /**
1527    * DOCUMENT ME!
1528    * 
1529    * @param e
1530    *          DOCUMENT ME!
1531    */
1532   public void nucleotideMenuItem_actionPerformed()
1533   {
1534     getGroup().cs = new NucleotideColourScheme();
1535     refresh();
1536   }
1537
1538   protected void purinePyrimidineColour_actionPerformed()
1539   {
1540     getGroup().cs = new PurinePyrimidineColourScheme();
1541     refresh();
1542   }
1543
1544
1545   /*
1546    * protected void covariationColour_actionPerformed() { getGroup().cs = new
1547    * CovariationColourScheme(sequence.getAnnotation()[0]); refresh(); }
1548    */
1549   /**
1550    * DOCUMENT ME!
1551    * 
1552    * @param e
1553    *          DOCUMENT ME!
1554    */
1555   protected void abovePIDColour_actionPerformed()
1556   {
1557     SequenceGroup sg = getGroup();
1558     if (sg.cs == null)
1559     {
1560       return;
1561     }
1562
1563     if (abovePIDColour.isSelected())
1564     {
1565       sg.cs.setConsensus(AAFrequency.calculate(
1566               sg.getSequences(ap.av.getHiddenRepSequences()),
1567               sg.getStartRes(), sg.getEndRes() + 1));
1568
1569       int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs, getGroup()
1570               .getName());
1571
1572       sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
1573
1574       SliderPanel.showPIDSlider();
1575     }
1576     else
1577     // remove PIDColouring
1578     {
1579       sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
1580     }
1581
1582     refresh();
1583   }
1584
1585   /**
1586    * DOCUMENT ME!
1587    * 
1588    * @param e
1589    *          DOCUMENT ME!
1590    */
1591   protected void userDefinedColour_actionPerformed(ActionEvent e)
1592   {
1593     SequenceGroup sg = getGroup();
1594
1595     if (e.getSource().equals(userDefinedColour))\r
1596     {
1597       new UserDefinedColours(ap, sg);
1598     }
1599     else
1600     {
1601       UserColourScheme udc = (UserColourScheme) UserDefinedColours
1602               .getUserColourSchemes().get(e.getActionCommand());
1603
1604       sg.cs = udc;
1605     }
1606     refresh();
1607   }
1608
1609   /**
1610    * DOCUMENT ME!
1611    * 
1612    * @param e
1613    *          DOCUMENT ME!
1614    */
1615   protected void PIDColour_actionPerformed()
1616   {
1617     SequenceGroup sg = getGroup();
1618     sg.cs = new PIDColourScheme();
1619     sg.cs.setConsensus(AAFrequency.calculate(
1620             sg.getSequences(ap.av.getHiddenRepSequences()),
1621             sg.getStartRes(), sg.getEndRes() + 1));
1622     refresh();
1623   }
1624
1625   /**
1626    * DOCUMENT ME!
1627    * 
1628    * @param e
1629    *          DOCUMENT ME!
1630    */
1631   protected void BLOSUM62Colour_actionPerformed()
1632   {
1633     SequenceGroup sg = getGroup();
1634
1635     sg.cs = new Blosum62ColourScheme();
1636
1637     sg.cs.setConsensus(AAFrequency.calculate(
1638             sg.getSequences(ap.av.getHiddenRepSequences()),
1639             sg.getStartRes(), sg.getEndRes() + 1));
1640
1641     refresh();
1642   }
1643
1644   /**
1645    * DOCUMENT ME!
1646    * 
1647    * @param e
1648    *          DOCUMENT ME!
1649    */
1650   protected void noColourmenuItem_actionPerformed()
1651   {
1652     getGroup().cs = null;
1653     refresh();
1654   }
1655
1656   /**
1657    * DOCUMENT ME!
1658    * 
1659    * @param e
1660    *          DOCUMENT ME!
1661    */
1662   protected void conservationMenuItem_actionPerformed()
1663   {
1664     SequenceGroup sg = getGroup();
1665     if (sg.cs == null)
1666     {
1667       return;
1668     }
1669
1670     if (conservationMenuItem.isSelected())
1671     {
1672     // JBPNote: Conservation name shouldn't be i18n translated
1673       Conservation c = new Conservation("Group",
1674               ResidueProperties.propHash, 3, sg.getSequences(ap.av
1675                       .getHiddenRepSequences()), sg.getStartRes(),
1676               sg.getEndRes() + 1);
1677
1678       c.calculate();
1679       c.verdict(false, ap.av.getConsPercGaps());
1680
1681       sg.cs.setConservation(c);
1682
1683       SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
1684       SliderPanel.showConservationSlider();
1685     }
1686     else
1687     // remove ConservationColouring
1688     {
1689       sg.cs.setConservation(null);
1690     }
1691
1692     refresh();
1693   }
1694
1695   public void annotationMenuItem_actionPerformed(ActionEvent actionEvent)
1696   {
1697     SequenceGroup sg = getGroup();
1698     if (sg == null)
1699     {
1700       return;
1701     }
1702
1703     AnnotationColourGradient acg = new AnnotationColourGradient(
1704             sequence.getAnnotation()[0], null,
1705             AnnotationColourGradient.NO_THRESHOLD);
1706
1707     acg.setPredefinedColours(true);
1708     sg.cs = acg;
1709
1710     refresh();
1711   }
1712
1713   /**
1714    * DOCUMENT ME!
1715    * 
1716    * @param e
1717    *          DOCUMENT ME!
1718    */
1719   protected void groupName_actionPerformed()
1720   {
1721
1722     SequenceGroup sg = getGroup();
1723     EditNameDialog dialog = new EditNameDialog(sg.getName(),
1724             sg.getDescription(), "       " + MessageManager.getString("label.group_name") + " ",\r
1725             MessageManager.getString("label.group_description") + " ", MessageManager.getString("label.edit_group_name_description"),\r
1726             ap.alignFrame);
1727
1728     if (!dialog.accept)
1729     {
1730       return;
1731     }
1732
1733     sg.setName(dialog.getName());
1734     sg.setDescription(dialog.getDescription());
1735     refresh();
1736   }
1737
1738   /**
1739    * Get selection group - adding it to the alignment if necessary.
1740    * 
1741    * @return sequence group to operate on
1742    */
1743   SequenceGroup getGroup()
1744   {
1745     SequenceGroup sg = ap.av.getSelectionGroup();
1746     // this method won't add a new group if it already exists
1747     if (sg != null)
1748     {
1749       ap.av.getAlignment().addGroup(sg);
1750     }
1751
1752     return sg;
1753   }
1754
1755   /**
1756    * DOCUMENT ME!
1757    * 
1758    * @param e
1759    *          DOCUMENT ME!
1760    */
1761   void sequenceName_actionPerformed()
1762   {
1763     EditNameDialog dialog = new EditNameDialog(sequence.getName(),
1764             sequence.getDescription(), "       " + MessageManager.getString("label.sequence_name") + " ",\r
1765             MessageManager.getString("label.sequence_description") + " ", MessageManager.getString("label.edit_sequence_name_description"),\r
1766             ap.alignFrame);
1767
1768     if (!dialog.accept)
1769     {
1770       return;
1771     }
1772
1773     if (dialog.getName() != null)
1774     {
1775       if (dialog.getName().indexOf(" ") > -1)
1776       {
1777         JOptionPane.showMessageDialog(ap,
1778                 MessageManager.getString("label.spaces_converted_to_backslashes"),\r
1779                 MessageManager.getString("label.no_spaces_allowed_sequence_name"),\r
1780                 JOptionPane.WARNING_MESSAGE);
1781       }
1782
1783       sequence.setName(dialog.getName().replace(' ', '_'));
1784       ap.paintAlignment(false);
1785     }
1786
1787     sequence.setDescription(dialog.getDescription());
1788
1789     ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
1790             .getSequences());
1791
1792   }
1793
1794   /**
1795    * DOCUMENT ME!
1796    * 
1797    * @param e
1798    *          DOCUMENT ME!
1799    */
1800   void unGroupMenuItem_actionPerformed()
1801   {
1802     SequenceGroup sg = ap.av.getSelectionGroup();
1803     ap.av.getAlignment().deleteGroup(sg);
1804     ap.av.setSelectionGroup(null);
1805     refresh();
1806   }
1807   void createGroupMenuItem_actionPerformed()
1808   {
1809     getGroup(); // implicitly creates group - note - should apply defaults / use standard alignment window logic for this
1810     refresh();
1811   }
1812
1813   /**
1814    * DOCUMENT ME!
1815    * 
1816    * @param e
1817    *          DOCUMENT ME!
1818    */
1819   protected void outline_actionPerformed()
1820   {
1821     SequenceGroup sg = getGroup();
1822     Color col = JColorChooser.showDialog(this, MessageManager.getString("label.select_outline_colour"),\r
1823             Color.BLUE);
1824
1825     if (col != null)
1826     {
1827       sg.setOutlineColour(col);
1828     }
1829
1830     refresh();
1831   }
1832
1833   /**
1834    * DOCUMENT ME!
1835    * 
1836    * @param e
1837    *          DOCUMENT ME!
1838    */
1839   public void showBoxes_actionPerformed()
1840   {
1841     getGroup().setDisplayBoxes(showBoxes.isSelected());
1842     refresh();
1843   }
1844
1845   /**
1846    * DOCUMENT ME!
1847    * 
1848    * @param e
1849    *          DOCUMENT ME!
1850    */
1851   public void showText_actionPerformed()
1852   {
1853     getGroup().setDisplayText(showText.isSelected());
1854     refresh();
1855   }
1856
1857   /**
1858    * DOCUMENT ME!
1859    * 
1860    * @param e
1861    *          DOCUMENT ME!
1862    */
1863   public void showColourText_actionPerformed()
1864   {
1865     getGroup().setColourText(showColourText.isSelected());
1866     refresh();
1867   }
1868
1869   public void showLink(String url)
1870   {
1871     try
1872     {
1873       jalview.util.BrowserLauncher.openURL(url);
1874     } catch (Exception ex)
1875     {
1876       JOptionPane
1877               .showInternalMessageDialog(
1878                       Desktop.desktop,
1879                       MessageManager.getString("label.web_browser_not_found_unix"),\r
1880                       MessageManager.getString("label.web_browser_not_found"), JOptionPane.WARNING_MESSAGE);\r
1881
1882       ex.printStackTrace();
1883     }
1884   }
1885
1886   void hideSequences(boolean representGroup)
1887   {
1888     SequenceGroup sg = ap.av.getSelectionGroup();
1889     if (sg == null || sg.getSize() < 1)
1890     {
1891       ap.av.hideSequence(new SequenceI[]
1892       { sequence });
1893       return;
1894     }
1895
1896     ap.av.setSelectionGroup(null);
1897
1898     if (representGroup)
1899     {
1900       ap.av.hideRepSequences(sequence, sg);
1901
1902       return;
1903     }
1904
1905     int gsize = sg.getSize();
1906     SequenceI[] hseqs;
1907
1908     hseqs = new SequenceI[gsize];
1909
1910     int index = 0;
1911     for (int i = 0; i < gsize; i++)
1912     {
1913       hseqs[index++] = sg.getSequenceAt(i);
1914     }
1915
1916     ap.av.hideSequence(hseqs);
1917     // refresh(); TODO: ? needed ?
1918     ap.av.sendSelection();
1919   }
1920
1921   public void copy_actionPerformed()
1922   {
1923     ap.alignFrame.copy_actionPerformed(null);
1924   }
1925
1926   public void cut_actionPerformed()
1927   {
1928     ap.alignFrame.cut_actionPerformed(null);
1929   }
1930
1931   void changeCase(ActionEvent e)
1932   {
1933     Object source = e.getSource();
1934     SequenceGroup sg = ap.av.getSelectionGroup();
1935
1936     if (sg != null)
1937     {
1938       int[][] startEnd = ap.av.getVisibleRegionBoundaries(sg.getStartRes(),
1939               sg.getEndRes() + 1);
1940
1941       String description;
1942       int caseChange;
1943
1944       if (source == toggle)
1945       {
1946         description = MessageManager.getString("label.toggle_case");\r
1947         caseChange = ChangeCaseCommand.TOGGLE_CASE;
1948       }
1949       else if (source == upperCase)
1950       {
1951         description = MessageManager.getString("label.to_upper_case");\r
1952         caseChange = ChangeCaseCommand.TO_UPPER;
1953       }
1954       else
1955       {
1956         description = MessageManager.getString("label.to_lower_case");\r
1957         caseChange = ChangeCaseCommand.TO_LOWER;
1958       }
1959
1960       ChangeCaseCommand caseCommand = new ChangeCaseCommand(description,
1961               sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
1962               startEnd, caseChange);
1963
1964       ap.alignFrame.addHistoryItem(caseCommand);
1965
1966       ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
1967               .getSequences());
1968
1969     }
1970   }
1971
1972   public void outputText_actionPerformed(ActionEvent e)
1973   {
1974     CutAndPasteTransfer cap = new CutAndPasteTransfer();
1975     cap.setForInput(null);
1976     Desktop.addInternalFrame(cap,
1977             MessageManager.formatMessage("label.alignment_output_command", new String[]{e.getActionCommand()}), 600, 500);\r
1978
1979     String[] omitHidden = null;
1980
1981     System.out.println("PROMPT USER HERE"); // TODO: decide if a prompt happens
1982     // or we simply trust the user wants
1983     // wysiwig behaviour
1984     SequenceGroup sg = ap.av.getSelectionGroup();
1985     ColumnSelection csel = new ColumnSelection(ap.av.getColumnSelection());
1986     omitHidden = ap.av.getViewAsString(true);
1987     Alignment oal = new Alignment(ap.av.getSequenceSelection());
1988     AlignmentAnnotation[] nala = ap.av.getAlignment()
1989             .getAlignmentAnnotation();
1990     if (nala != null)
1991     {
1992       for (int i = 0; i < nala.length; i++)
1993       {
1994         AlignmentAnnotation na = nala[i];
1995         oal.addAnnotation(na);
1996       }
1997     }
1998     cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(),
1999             oal, omitHidden, csel, sg));
2000     oal = null;
2001   }
2002
2003   public void pdbFromFile_actionPerformed()
2004   {
2005     jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(
2006             jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
2007     chooser.setFileView(new jalview.io.JalviewFileView());
2008     chooser.setDialogTitle(MessageManager.formatMessage("label.select_pdb_file_for", new String[]{sequence.getDisplayId(false)}));\r
2009     chooser.setToolTipText(MessageManager.formatMessage("label.load_pdb_file_associate_with_sequence", new String[]{new Integer(sequence.getDisplayId(false)).toString()}));\r
2010
2011     int value = chooser.showOpenDialog(null);
2012
2013     if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
2014     {
2015       String choice = chooser.getSelectedFile().getPath();
2016       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
2017       new AssociatePdbFileWithSeq().associatePdbWithSeq(choice,
2018               jalview.io.AppletFormatAdapter.FILE, sequence, true);
2019     }
2020
2021   }
2022     // JBNote: commented out - these won't be instantiated here...!  
2023 //  public void RNAFold_actionPerformed() throws Exception
2024 //  {
2025 //        Predict2D P2D = new Predict2D();
2026 //        P2D.getStructure2DFromRNAFold("toto");
2027 //  }
2028 //  
2029 //  public void ContraFold_actionPerformed() throws Exception
2030 //  {
2031 //        Predict2D P2D = new Predict2D();
2032 //        P2D.getStructure2DFromContraFold("toto");
2033 //  }
2034   public void enterPDB_actionPerformed()
2035   {
2036     String id = JOptionPane.showInternalInputDialog(Desktop.desktop,
2037             MessageManager.getString("label.enter_pdb_id"), MessageManager.getString("label.enter_pdb_id"), JOptionPane.QUESTION_MESSAGE);\r
2038
2039     if (id != null && id.length() > 0)
2040     {
2041       PDBEntry entry = new PDBEntry();
2042       entry.setId(id.toUpperCase());
2043       sequence.getDatasetSequence().addPDBId(entry);
2044     }
2045   }
2046
2047   public void discoverPDB_actionPerformed()
2048   {
2049
2050     final SequenceI[] sequences = ((ap.av.getSelectionGroup() == null) ? new SequenceI[]
2051     { sequence }
2052             : ap.av.getSequenceSelection());
2053     Thread discpdb = new Thread(new Runnable()
2054     {
2055       public void run()
2056       {
2057
2058         new jalview.ws.DBRefFetcher(sequences, ap.alignFrame)
2059                 .fetchDBRefs(false);
2060       }
2061
2062     });
2063     discpdb.start();
2064   }
2065
2066   public void sequenceFeature_actionPerformed()
2067   {
2068     SequenceGroup sg = ap.av.getSelectionGroup();
2069     if (sg == null)
2070     {
2071       return;
2072     }
2073
2074     int rsize = 0, gSize = sg.getSize();
2075     SequenceI[] rseqs, seqs = new SequenceI[gSize];
2076     SequenceFeature[] tfeatures, features = new SequenceFeature[gSize];
2077
2078     for (int i = 0; i < gSize; i++)
2079     {
2080       int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
2081       int end = sg.findEndRes(sg.getSequenceAt(i));
2082       if (start <= end)
2083       {
2084         seqs[rsize] = sg.getSequenceAt(i).getDatasetSequence();
2085         features[rsize] = new SequenceFeature(null, null, null, start, end,
2086                 "Jalview");
2087         rsize++;
2088       }
2089     }
2090     rseqs = new SequenceI[rsize];
2091     tfeatures = new SequenceFeature[rsize];
2092     System.arraycopy(seqs, 0, rseqs, 0, rsize);
2093     System.arraycopy(features, 0, tfeatures, 0, rsize);
2094     features = tfeatures;
2095     seqs = rseqs;
2096     if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
2097             features, true, ap))
2098     {
2099       ap.alignFrame.setShowSeqFeatures(true);
2100       ap.highlightSearchResults(null);
2101     }
2102   }
2103
2104   public void textColour_actionPerformed()
2105   {
2106     SequenceGroup sg = getGroup();
2107     if (sg != null)
2108     {
2109       new TextColourChooser().chooseColour(ap, sg);
2110     }
2111   }
2112
2113   public void colourByStructure(String pdbid)
2114   {
2115     Annotation[] anots = ap.av.getStructureSelectionManager()
2116             .colourSequenceFromStructure(sequence, pdbid);
2117
2118     AlignmentAnnotation an = new AlignmentAnnotation("Structure",
2119             "Coloured by " + pdbid, anots);
2120
2121     ap.av.getAlignment().addAnnotation(an);
2122     an.createSequenceMapping(sequence, 0, true);
2123     // an.adjustForAlignment();
2124     ap.av.getAlignment().setAnnotationIndex(an, 0);
2125
2126     ap.adjustAnnotationHeight();
2127
2128     sequence.addAlignmentAnnotation(an);
2129
2130   }
2131
2132   public void editSequence_actionPerformed(ActionEvent actionEvent)
2133   {
2134     SequenceGroup sg = ap.av.getSelectionGroup();
2135
2136     if (sg != null)
2137     {
2138       if (sequence == null)
2139         sequence = (Sequence) sg.getSequenceAt(0);
2140
2141       EditNameDialog dialog = new EditNameDialog(
2142               sequence.getSequenceAsString(sg.getStartRes(),
2143                       sg.getEndRes() + 1), null, MessageManager.getString("label.edit_sequence"), null,\r
2144                       MessageManager.getString("label.edit_sequence"), ap.alignFrame);\r
2145
2146       if (dialog.accept)
2147       {
2148         EditCommand editCommand = new EditCommand(MessageManager.getString("label.edit_sequences"),\r
2149                 EditCommand.REPLACE, dialog.getName().replace(' ',
2150                         ap.av.getGapCharacter()),
2151                 sg.getSequencesAsArray(ap.av.getHiddenRepSequences()),
2152                 sg.getStartRes(), sg.getEndRes() + 1, ap.av.getAlignment());
2153
2154         ap.alignFrame.addHistoryItem(editCommand);
2155
2156         ap.av.firePropertyChange("alignment", null, ap.av.getAlignment()
2157                 .getSequences());
2158       }
2159     }
2160   }
2161
2162 }