new thread for initting of DBRefFetcher with latest SequenceFetcher
[jalview.git] / src / jalview / gui / PopupMenu.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.gui;
20
21 import java.util.*;
22
23 import java.awt.*;
24 import java.awt.event.*;
25 import javax.swing.*;
26
27 import MCview.*;
28 import jalview.analysis.*;
29 import jalview.commands.*;
30 import jalview.datamodel.*;
31 import jalview.io.*;
32 import jalview.schemes.*;
33 import jalview.util.UrlLink;
34
35 /**
36  * DOCUMENT ME!
37  *
38  * @author $author$
39  * @version $Revision$
40  */
41 public class PopupMenu
42     extends JPopupMenu
43 {
44   JMenu groupMenu = new JMenu();
45   JMenuItem groupName = new JMenuItem();
46   protected JRadioButtonMenuItem clustalColour = new JRadioButtonMenuItem();
47   protected JRadioButtonMenuItem zappoColour = new JRadioButtonMenuItem();
48   protected JRadioButtonMenuItem taylorColour = new JRadioButtonMenuItem();
49   protected JRadioButtonMenuItem hydrophobicityColour = new
50       JRadioButtonMenuItem();
51   protected JRadioButtonMenuItem helixColour = new JRadioButtonMenuItem();
52   protected JRadioButtonMenuItem strandColour = new JRadioButtonMenuItem();
53   protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
54   protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
55   protected JCheckBoxMenuItem abovePIDColour = new JCheckBoxMenuItem();
56   protected JRadioButtonMenuItem userDefinedColour = new JRadioButtonMenuItem();
57   protected JRadioButtonMenuItem PIDColour = new JRadioButtonMenuItem();
58   protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
59   JRadioButtonMenuItem noColourmenuItem = new JRadioButtonMenuItem();
60   protected JCheckBoxMenuItem conservationMenuItem = new JCheckBoxMenuItem();
61   AlignmentPanel ap;
62   JMenu sequenceMenu = new JMenu();
63   JMenuItem sequenceName = new JMenuItem();
64   Sequence sequence;
65   JMenuItem unGroupMenuItem = new JMenuItem();
66   JMenuItem outline = new JMenuItem();
67   JRadioButtonMenuItem nucleotideMenuItem = new JRadioButtonMenuItem();
68   JMenu colourMenu = new JMenu();
69   JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem();
70   JCheckBoxMenuItem showText = new JCheckBoxMenuItem();
71   JCheckBoxMenuItem showColourText = new JCheckBoxMenuItem();
72   JMenu editMenu = new JMenu();
73   JMenuItem cut = new JMenuItem();
74   JMenuItem copy = new JMenuItem();
75   JMenuItem upperCase = new JMenuItem();
76   JMenuItem lowerCase = new JMenuItem();
77   JMenuItem toggle = new JMenuItem();
78   JMenu pdbMenu = new JMenu();
79   JMenuItem pdbFromFile = new JMenuItem();
80   JMenuItem enterPDB = new JMenuItem();
81   JMenuItem discoverPDB = new JMenuItem();
82   JMenu outputMenu = new JMenu();
83   JMenuItem sequenceFeature = new JMenuItem();
84   JMenuItem textColour = new JMenuItem();
85   JMenu jMenu1 = new JMenu();
86   JMenu structureMenu = new JMenu();
87   JMenu viewStructureMenu = new JMenu();
88  // JMenu colStructureMenu = new JMenu();
89   JMenuItem editSequence = new JMenuItem();
90  // JMenuItem annotationMenuItem = new JMenuItem();
91
92   /**
93    * Creates a new PopupMenu object.
94    *
95    * @param ap DOCUMENT ME!
96    * @param seq DOCUMENT ME!
97    */
98   public PopupMenu(final AlignmentPanel ap, Sequence seq, Vector links)
99   {
100     ///////////////////////////////////////////////////////////
101     // If this is activated from the sequence panel, the user may want to
102     // edit or annotate a particular residue. Therefore display the residue menu
103     //
104     // If from the IDPanel, we must display the sequence menu
105     //////////////////////////////////////////////////////////
106     this.ap = ap;
107     sequence = seq;
108
109     ButtonGroup colours = new ButtonGroup();
110     colours.add(noColourmenuItem);
111     colours.add(clustalColour);
112     colours.add(zappoColour);
113     colours.add(taylorColour);
114     colours.add(hydrophobicityColour);
115     colours.add(helixColour);
116     colours.add(strandColour);
117     colours.add(turnColour);
118     colours.add(buriedColour);
119     colours.add(abovePIDColour);
120     colours.add(userDefinedColour);
121     colours.add(PIDColour);
122     colours.add(BLOSUM62Colour);
123
124     for (int i = 0; i < jalview.io.FormatAdapter.WRITEABLE_FORMATS.length; i++)
125     {
126       JMenuItem item = new JMenuItem(jalview.io.FormatAdapter.WRITEABLE_FORMATS[
127                                      i]);
128
129       item.addActionListener(new java.awt.event.ActionListener()
130       {
131         public void actionPerformed(ActionEvent e)
132         {
133           outputText_actionPerformed(e);
134         }
135       });
136
137       outputMenu.add(item);
138     }
139
140     try
141     {
142       jbInit();
143     }
144     catch (Exception e)
145     {
146       e.printStackTrace();
147     }
148
149     if (seq != null)
150     {
151       sequenceMenu.setText(sequence.getName());
152
153       JMenuItem menuItem;
154       if (seq.getDatasetSequence().getPDBId() != null
155           && seq.getDatasetSequence().getPDBId().size()>0)
156       {
157         java.util.Enumeration e = seq.getDatasetSequence().getPDBId().
158             elements();
159
160         while (e.hasMoreElements())
161         {
162           final PDBEntry pdb = (PDBEntry) e.nextElement();
163
164           menuItem = new JMenuItem();
165           menuItem.setText(pdb.getId());
166           menuItem.addActionListener(new java.awt.event.ActionListener()
167           {
168             public void actionPerformed(ActionEvent e)
169             {
170               Vector seqs = new Vector();
171               for (int i = 0; i < ap.av.alignment.getHeight(); i++)
172               {
173                 Vector pdbs = ap.av.alignment.getSequenceAt(i).getDatasetSequence().getPDBId();
174                 if(pdbs==null)
175                   continue;
176
177                 for(int p=0; p<pdbs.size(); p++)
178                 {
179                   PDBEntry p1 = (PDBEntry)pdbs.elementAt(p);
180                   if(p1.getId().equals(pdb.getId()))
181                   {
182                     if (!seqs.contains(ap.av.alignment.getSequenceAt(i)))
183                         seqs.addElement(ap.av.alignment.getSequenceAt(i));
184
185                       continue;
186                   }
187                 }
188               }
189
190               SequenceI [] seqs2 = new SequenceI[seqs.size()];
191               seqs.toArray(seqs2);
192
193               new AppJmol(pdb, seqs2, null, ap);
194               //  new PDBViewer(pdb, seqs2, null, ap, AppletFormatAdapter.FILE);
195             }
196           });
197           viewStructureMenu.add(menuItem);
198
199        /*   menuItem = new JMenuItem();
200           menuItem.setText(pdb.getId());
201           menuItem.addActionListener(new java.awt.event.ActionListener()
202           {
203             public void actionPerformed(ActionEvent e)
204             {
205               colourByStructure(pdb.getId());
206             }
207           });
208           colStructureMenu.add(menuItem);*/
209         }
210       }
211       else
212       {
213         structureMenu.remove(viewStructureMenu);
214        // structureMenu.remove(colStructureMenu);
215       }
216
217       menuItem = new JMenuItem("Hide Sequences");
218       menuItem.addActionListener(new java.awt.event.ActionListener()
219       {
220         public void actionPerformed(ActionEvent e)
221         {
222           hideSequences(false);
223         }
224       });
225       add(menuItem);
226
227       if (ap.av.getSelectionGroup() != null
228           && ap.av.getSelectionGroup().getSize() > 1)
229       {
230         menuItem = new JMenuItem("Represent Group with " + seq.getName());
231         menuItem.addActionListener(new java.awt.event.ActionListener()
232         {
233           public void actionPerformed(ActionEvent e)
234           {
235             hideSequences(true);
236           }
237         });
238         sequenceMenu.add(menuItem);
239       }
240
241       if (ap.av.hasHiddenRows)
242       {
243         final int index = ap.av.alignment.findIndex(seq);
244
245         if (ap.av.adjustForHiddenSeqs(index) -
246             ap.av.adjustForHiddenSeqs(index - 1) > 1)
247         {
248           menuItem = new JMenuItem("Reveal Sequences");
249           menuItem.addActionListener(new ActionListener()
250           {
251             public void actionPerformed(ActionEvent e)
252             {
253               ap.av.showSequence(index);
254               if (ap.overviewPanel != null)
255               {
256                 ap.overviewPanel.updateOverviewImage();
257               }
258             }
259           });
260           add(menuItem);
261         }
262
263         menuItem = new JMenuItem("Reveal All");
264         menuItem.addActionListener(new ActionListener()
265         {
266           public void actionPerformed(ActionEvent e)
267           {
268             ap.av.showAllHiddenSeqs();
269             if (ap.overviewPanel != null)
270             {
271               ap.overviewPanel.updateOverviewImage();
272             }
273           }
274         });
275
276         add(menuItem);
277       }
278
279     }
280
281     SequenceGroup sg = ap.av.getSelectionGroup();
282
283     if (sg != null)
284     {
285       groupName.setText(sg.getName());
286
287       if (sg.cs instanceof ZappoColourScheme)
288       {
289         zappoColour.setSelected(true);
290       }
291       else if (sg.cs instanceof TaylorColourScheme)
292       {
293         taylorColour.setSelected(true);
294       }
295       else if (sg.cs instanceof PIDColourScheme)
296       {
297         PIDColour.setSelected(true);
298       }
299       else if (sg.cs instanceof Blosum62ColourScheme)
300       {
301         BLOSUM62Colour.setSelected(true);
302       }
303       else if (sg.cs instanceof UserColourScheme)
304       {
305         userDefinedColour.setSelected(true);
306       }
307       else if (sg.cs instanceof HydrophobicColourScheme)
308       {
309         hydrophobicityColour.setSelected(true);
310       }
311       else if (sg.cs instanceof HelixColourScheme)
312       {
313         helixColour.setSelected(true);
314       }
315       else if (sg.cs instanceof StrandColourScheme)
316       {
317         strandColour.setSelected(true);
318       }
319       else if (sg.cs instanceof TurnColourScheme)
320       {
321         turnColour.setSelected(true);
322       }
323       else if (sg.cs instanceof BuriedColourScheme)
324       {
325         buriedColour.setSelected(true);
326       }
327       else if (sg.cs instanceof ClustalxColourScheme)
328       {
329         clustalColour.setSelected(true);
330       }
331       else
332       {
333         noColourmenuItem.setSelected(true);
334       }
335
336       if (sg.cs != null && sg.cs.conservationApplied())
337       {
338         conservationMenuItem.setSelected(true);
339       }
340
341       showText.setSelected(sg.getDisplayText());
342       showColourText.setSelected(sg.getColourText());
343       showBoxes.setSelected(sg.getDisplayBoxes());
344     }
345     else
346     {
347       groupMenu.setVisible(false);
348       editMenu.setVisible(false);
349     }
350
351     if (!ap.av.alignment.getGroups().contains(sg))
352     {
353       unGroupMenuItem.setVisible(false);
354     }
355
356     if (seq == null)
357     {
358       sequenceMenu.setVisible(false);
359       structureMenu.setVisible(false);
360     }
361
362     if (links != null && links.size() > 0)
363     {
364       JMenu linkMenu = new JMenu("Link");
365
366       for (int i = 0; i < links.size(); i++)
367       {
368         String link = links.elementAt(i).toString();
369         UrlLink urlLink = null;
370         try {
371           urlLink = new UrlLink(link);
372         } catch (Exception foo) {
373           jalview.bin.Cache.log.error("Exception for URLLink '"+link+"'",foo);
374           continue;
375         };
376         if (!urlLink.isValid())
377         {
378           jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
379           continue;
380         }
381         final String label = urlLink.getLabel();
382         if (urlLink.isDynamic())
383         {
384
385           // collect matching db-refs
386           DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new String[]{urlLink.getTarget()});
387           // collect id string too
388           String id = seq.getName();
389           if (dbr!=null)
390           {
391             for (int r=0;r<dbr.length; r++)
392             {
393               if (id!=null && dbr[r].getAccessionId().equals(id))
394               {
395                 // suppress duplicate link creation for the bare sequence ID string with this link
396                 id = null;
397               }
398               // create Bare ID link for this RUL
399               String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
400               if (urls!=null)
401               {
402                 for (int u=0; u<urls.length; u+=2)
403                 {
404                   addshowLink(linkMenu, label+"|"+urls[u],urls[u+1]); 
405                 }
406               }
407             }
408           }
409           if (id!=null)
410           {
411             // create Bare ID link for this RUL
412             String[] urls = urlLink.makeUrls(id, true);
413             if (urls!=null)
414             {
415               for (int u=0; u<urls.length; u+=2)
416               {
417                 addshowLink(linkMenu, label,  urls[u+1]);
418               }
419             }
420           }
421         } else
422         {
423           // Add a non-dynamic link
424           addshowLink(linkMenu, label, urlLink.getUrl_prefix());
425         }
426       }
427       if (sequence != null)
428       {
429         sequenceMenu.add(linkMenu);
430       }
431       else
432       {
433         add(linkMenu);
434       }
435     }
436   }
437
438   /**
439    * add a show URL menu item to the given linkMenu
440    * @param linkMenu
441    * @param label - menu label string
442    * @param url - url to open
443    */
444   private void addshowLink(JMenu linkMenu, String label, final String url)
445   {
446     JMenuItem item = new JMenuItem(label);
447     item.setToolTipText("open URL: "+url);
448     item.addActionListener(new java.awt.event.ActionListener()
449     {
450       public void actionPerformed(ActionEvent e)
451       {
452         new Thread(new Runnable() {
453
454           public void run()
455           {
456             showLink(url);
457           }
458           
459         }).start();
460       }
461     });
462
463     linkMenu.add(item);    
464   }
465
466   /**
467    * DOCUMENT ME!
468    *
469    * @throws Exception DOCUMENT ME!
470    */
471   private void jbInit()
472       throws Exception
473   {
474     groupMenu.setText("Group");
475     groupMenu.setText("Selection");
476     groupName.setText("Name");
477     groupName.addActionListener(new java.awt.event.ActionListener()
478     {
479       public void actionPerformed(ActionEvent e)
480       {
481         groupName_actionPerformed();
482       }
483     });
484     sequenceMenu.setText("Sequence");
485     sequenceName.setText("Edit Name/Description");
486     sequenceName.addActionListener(new java.awt.event.ActionListener()
487     {
488       public void actionPerformed(ActionEvent e)
489       {
490         sequenceName_actionPerformed();
491       }
492     });
493     PIDColour.setFocusPainted(false);
494     unGroupMenuItem.setText("Remove Group");
495     unGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
496     {
497       public void actionPerformed(ActionEvent e)
498       {
499         unGroupMenuItem_actionPerformed();
500       }
501     });
502
503     outline.setText("Border colour");
504     outline.addActionListener(new java.awt.event.ActionListener()
505     {
506       public void actionPerformed(ActionEvent e)
507       {
508         outline_actionPerformed();
509       }
510     });
511     nucleotideMenuItem.setText("Nucleotide");
512     nucleotideMenuItem.addActionListener(new ActionListener()
513     {
514       public void actionPerformed(ActionEvent e)
515       {
516         nucleotideMenuItem_actionPerformed();
517       }
518     });
519     colourMenu.setText("Group Colour");
520     showBoxes.setText("Boxes");
521     showBoxes.setState(true);
522     showBoxes.addActionListener(new ActionListener()
523     {
524       public void actionPerformed(ActionEvent e)
525       {
526         showBoxes_actionPerformed();
527       }
528     });
529     showText.setText("Text");
530     showText.setState(true);
531     showText.addActionListener(new ActionListener()
532     {
533       public void actionPerformed(ActionEvent e)
534       {
535         showText_actionPerformed();
536       }
537     });
538     showColourText.setText("Colour Text");
539     showColourText.addActionListener(new ActionListener()
540     {
541       public void actionPerformed(ActionEvent e)
542       {
543         showColourText_actionPerformed();
544       }
545     });
546     editMenu.setText("Edit");
547     cut.setText("Cut");
548     cut.addActionListener(new ActionListener()
549     {
550       public void actionPerformed(ActionEvent e)
551       {
552         cut_actionPerformed();
553       }
554     });
555     upperCase.setText("To Upper Case");
556     upperCase.addActionListener(new ActionListener()
557     {
558       public void actionPerformed(ActionEvent e)
559       {
560         changeCase(e);
561       }
562     });
563     copy.setText("Copy");
564     copy.addActionListener(new ActionListener()
565     {
566       public void actionPerformed(ActionEvent e)
567       {
568         copy_actionPerformed();
569       }
570     });
571     lowerCase.setText("To Lower Case");
572     lowerCase.addActionListener(new ActionListener()
573     {
574       public void actionPerformed(ActionEvent e)
575       {
576         changeCase(e);
577       }
578     });
579     toggle.setText("Toggle Case");
580     toggle.addActionListener(new ActionListener()
581     {
582       public void actionPerformed(ActionEvent e)
583       {
584         changeCase(e);
585       }
586     });
587     pdbMenu.setText("Associate Structure with Sequence");
588     pdbFromFile.setText("From File");
589     pdbFromFile.addActionListener(new ActionListener()
590     {
591       public void actionPerformed(ActionEvent e)
592       {
593         pdbFromFile_actionPerformed();
594       }
595     });
596     enterPDB.setText("Enter PDB Id");
597     enterPDB.addActionListener(new ActionListener()
598     {
599       public void actionPerformed(ActionEvent e)
600       {
601         enterPDB_actionPerformed();
602       }
603     });
604     discoverPDB.setText("Discover PDB ids");
605     discoverPDB.addActionListener(new ActionListener()
606     {
607       public void actionPerformed(ActionEvent e)
608       {
609         discoverPDB_actionPerformed();
610       }
611     });
612     outputMenu.setText("Output to Textbox...");
613     sequenceFeature.setText("Create Sequence Feature");
614     sequenceFeature.addActionListener(new ActionListener()
615     {
616       public void actionPerformed(ActionEvent e)
617       {
618         sequenceFeature_actionPerformed();
619       }
620     });
621     textColour.setText("Text Colour");
622     textColour.addActionListener(new ActionListener()
623     {
624       public void actionPerformed(ActionEvent e)
625       {
626         textColour_actionPerformed();
627       }
628     });
629     jMenu1.setText("Group");
630     structureMenu.setText("Structure");
631     viewStructureMenu.setText("View Structure");
632   //  colStructureMenu.setText("Colour By Structure");
633     editSequence.setText("Edit Sequence...");
634     editSequence.addActionListener(new ActionListener()
635     {
636       public void actionPerformed(ActionEvent actionEvent)
637       {
638         editSequence_actionPerformed(actionEvent);
639       }
640     });
641    /* annotationMenuItem.setText("By Annotation");
642     annotationMenuItem.addActionListener(new ActionListener()
643     {
644       public void actionPerformed(ActionEvent actionEvent)
645       {
646         annotationMenuItem_actionPerformed(actionEvent);
647       }
648     });*/
649
650     add(groupMenu);
651
652     add(sequenceMenu);
653     this.add(structureMenu);
654     groupMenu.add(editMenu);
655     groupMenu.add(outputMenu);
656     groupMenu.add(sequenceFeature);
657     groupMenu.add(jMenu1);
658     sequenceMenu.add(sequenceName);
659     colourMenu.add(textColour);
660     colourMenu.add(noColourmenuItem);
661     colourMenu.add(clustalColour);
662     colourMenu.add(BLOSUM62Colour);
663     colourMenu.add(PIDColour);
664     colourMenu.add(zappoColour);
665     colourMenu.add(taylorColour);
666     colourMenu.add(hydrophobicityColour);
667     colourMenu.add(helixColour);
668     colourMenu.add(strandColour);
669     colourMenu.add(turnColour);
670     colourMenu.add(buriedColour);
671     colourMenu.add(nucleotideMenuItem);
672     colourMenu.add(userDefinedColour);
673
674     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
675     {
676       java.util.Enumeration userColours = jalview.gui.UserDefinedColours.
677           getUserColourSchemes().keys();
678
679       while (userColours.hasMoreElements())
680       {
681         JMenuItem item = new JMenuItem(userColours.
682                                        nextElement().toString());
683         item.addActionListener(new ActionListener()
684         {
685           public void actionPerformed(ActionEvent evt)
686           {
687             userDefinedColour_actionPerformed(evt);
688           }
689         });
690         colourMenu.add(item);
691       }
692     }
693
694     colourMenu.addSeparator();
695     colourMenu.add(abovePIDColour);
696     colourMenu.add(conservationMenuItem);
697     //colourMenu.add(annotationMenuItem);
698     editMenu.add(copy);
699     editMenu.add(cut);
700     editMenu.add(editSequence);
701     editMenu.add(upperCase);
702     editMenu.add(lowerCase);
703     editMenu.add(toggle);
704     pdbMenu.add(pdbFromFile);
705     pdbMenu.add(enterPDB);
706     pdbMenu.add(discoverPDB);
707     jMenu1.add(groupName);
708     jMenu1.add(unGroupMenuItem);
709     jMenu1.add(colourMenu);
710     jMenu1.add(showBoxes);
711     jMenu1.add(showText);
712     jMenu1.add(showColourText);
713     jMenu1.add(outline);
714     structureMenu.add(pdbMenu);
715     structureMenu.add(viewStructureMenu);
716    // structureMenu.add(colStructureMenu);
717     noColourmenuItem.setText("None");
718     noColourmenuItem.addActionListener(new java.awt.event.ActionListener()
719     {
720       public void actionPerformed(ActionEvent e)
721       {
722         noColourmenuItem_actionPerformed();
723       }
724     });
725
726     clustalColour.setText("Clustalx colours");
727     clustalColour.addActionListener(new java.awt.event.ActionListener()
728     {
729       public void actionPerformed(ActionEvent e)
730       {
731         clustalColour_actionPerformed();
732       }
733     });
734     zappoColour.setText("Zappo");
735     zappoColour.addActionListener(new java.awt.event.ActionListener()
736     {
737       public void actionPerformed(ActionEvent e)
738       {
739         zappoColour_actionPerformed();
740       }
741     });
742     taylorColour.setText("Taylor");
743     taylorColour.addActionListener(new java.awt.event.ActionListener()
744     {
745       public void actionPerformed(ActionEvent e)
746       {
747         taylorColour_actionPerformed();
748       }
749     });
750     hydrophobicityColour.setText("Hydrophobicity");
751     hydrophobicityColour.addActionListener(new java.awt.event.ActionListener()
752     {
753       public void actionPerformed(ActionEvent e)
754       {
755         hydrophobicityColour_actionPerformed();
756       }
757     });
758     helixColour.setText("Helix propensity");
759     helixColour.addActionListener(new java.awt.event.ActionListener()
760     {
761       public void actionPerformed(ActionEvent e)
762       {
763         helixColour_actionPerformed();
764       }
765     });
766     strandColour.setText("Strand propensity");
767     strandColour.addActionListener(new java.awt.event.ActionListener()
768     {
769       public void actionPerformed(ActionEvent e)
770       {
771         strandColour_actionPerformed();
772       }
773     });
774     turnColour.setText("Turn propensity");
775     turnColour.addActionListener(new java.awt.event.ActionListener()
776     {
777       public void actionPerformed(ActionEvent e)
778       {
779         turnColour_actionPerformed();
780       }
781     });
782     buriedColour.setText("Buried Index");
783     buriedColour.addActionListener(new java.awt.event.ActionListener()
784     {
785       public void actionPerformed(ActionEvent e)
786       {
787         buriedColour_actionPerformed();
788       }
789     });
790     abovePIDColour.setText("Above % Identity");
791     abovePIDColour.addActionListener(new java.awt.event.ActionListener()
792     {
793       public void actionPerformed(ActionEvent e)
794       {
795         abovePIDColour_actionPerformed();
796       }
797     });
798     userDefinedColour.setText("User Defined...");
799     userDefinedColour.addActionListener(new java.awt.event.ActionListener()
800     {
801       public void actionPerformed(ActionEvent e)
802       {
803         userDefinedColour_actionPerformed(e);
804       }
805     });
806     PIDColour.setText("Percentage Identity");
807     PIDColour.addActionListener(new java.awt.event.ActionListener()
808     {
809       public void actionPerformed(ActionEvent e)
810       {
811         PIDColour_actionPerformed();
812       }
813     });
814     BLOSUM62Colour.setText("BLOSUM62");
815     BLOSUM62Colour.addActionListener(new java.awt.event.ActionListener()
816     {
817       public void actionPerformed(ActionEvent e)
818       {
819         BLOSUM62Colour_actionPerformed();
820       }
821     });
822     conservationMenuItem.setText("Conservation");
823     conservationMenuItem.addActionListener(new java.awt.event.ActionListener()
824     {
825       public void actionPerformed(ActionEvent e)
826       {
827         conservationMenuItem_actionPerformed();
828       }
829     });
830   }
831
832   /**
833    * DOCUMENT ME!
834    */
835   void refresh()
836   {
837     ap.paintAlignment(true);
838
839     PaintRefresher.Refresh(this, ap.av.getSequenceSetId());
840   }
841
842   /**
843    * DOCUMENT ME!
844    *
845    * @param e DOCUMENT ME!
846    */
847   protected void clustalColour_actionPerformed()
848   {
849     SequenceGroup sg = getGroup();
850     sg.cs = new ClustalxColourScheme(sg.getSequences(ap.av.hiddenRepSequences),
851                                      ap.av.alignment.getWidth());
852     refresh();
853   }
854
855   /**
856    * DOCUMENT ME!
857    *
858    * @param e DOCUMENT ME!
859    */
860   protected void zappoColour_actionPerformed()
861   {
862     getGroup().cs = new ZappoColourScheme();
863     refresh();
864   }
865
866   /**
867    * DOCUMENT ME!
868    *
869    * @param e DOCUMENT ME!
870    */
871   protected void taylorColour_actionPerformed()
872   {
873     getGroup().cs = new TaylorColourScheme();
874     refresh();
875   }
876
877   /**
878    * DOCUMENT ME!
879    *
880    * @param e DOCUMENT ME!
881    */
882   protected void hydrophobicityColour_actionPerformed()
883   {
884     getGroup().cs = new HydrophobicColourScheme();
885     refresh();
886   }
887
888   /**
889    * DOCUMENT ME!
890    *
891    * @param e DOCUMENT ME!
892    */
893   protected void helixColour_actionPerformed()
894   {
895     getGroup().cs = new HelixColourScheme();
896     refresh();
897   }
898
899   /**
900    * DOCUMENT ME!
901    *
902    * @param e DOCUMENT ME!
903    */
904   protected void strandColour_actionPerformed()
905   {
906     getGroup().cs = new StrandColourScheme();
907     refresh();
908   }
909
910   /**
911    * DOCUMENT ME!
912    *
913    * @param e DOCUMENT ME!
914    */
915   protected void turnColour_actionPerformed()
916   {
917     getGroup().cs = new TurnColourScheme();
918     refresh();
919   }
920
921   /**
922    * DOCUMENT ME!
923    *
924    * @param e DOCUMENT ME!
925    */
926   protected void buriedColour_actionPerformed()
927   {
928     getGroup().cs = new BuriedColourScheme();
929     refresh();
930   }
931
932   /**
933    * DOCUMENT ME!
934    *
935    * @param e DOCUMENT ME!
936    */
937   public void nucleotideMenuItem_actionPerformed()
938   {
939     getGroup().cs = new NucleotideColourScheme();
940     refresh();
941   }
942
943   /**
944    * DOCUMENT ME!
945    *
946    * @param e DOCUMENT ME!
947    */
948   protected void abovePIDColour_actionPerformed()
949   {
950     SequenceGroup sg = getGroup();
951     if (sg.cs == null)
952     {
953       return;
954     }
955
956     if (abovePIDColour.isSelected())
957     {
958       sg.cs.setConsensus(AAFrequency.calculate(
959           sg.getSequences(ap.av.hiddenRepSequences), sg.getStartRes(),
960           sg.getEndRes() + 1));
961
962       int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,
963           getGroup().getName());
964
965       sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
966
967       SliderPanel.showPIDSlider();
968     }
969     else // remove PIDColouring
970     {
971       sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
972     }
973
974     refresh();
975   }
976
977   /**
978    * DOCUMENT ME!
979    *
980    * @param e DOCUMENT ME!
981    */
982   protected void userDefinedColour_actionPerformed(ActionEvent e)
983   {
984     SequenceGroup sg = getGroup();
985
986     if (e.getActionCommand().equals("User Defined..."))
987     {
988       new UserDefinedColours(ap, sg);
989     }
990     else
991     {
992       UserColourScheme udc = (UserColourScheme) UserDefinedColours.
993           getUserColourSchemes().get(e.getActionCommand());
994
995       sg.cs = udc;
996     }
997     refresh();
998   }
999
1000   /**
1001    * DOCUMENT ME!
1002    *
1003    * @param e DOCUMENT ME!
1004    */
1005   protected void PIDColour_actionPerformed()
1006   {
1007     SequenceGroup sg = getGroup();
1008     sg.cs = new PIDColourScheme();
1009     sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
1010         hiddenRepSequences),
1011                                              sg.getStartRes(),
1012                                              sg.getEndRes() + 1));
1013     refresh();
1014   }
1015
1016   /**
1017    * DOCUMENT ME!
1018    *
1019    * @param e DOCUMENT ME!
1020    */
1021   protected void BLOSUM62Colour_actionPerformed()
1022   {
1023     SequenceGroup sg = getGroup();
1024
1025     sg.cs = new Blosum62ColourScheme();
1026
1027     sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
1028         hiddenRepSequences),
1029                                              sg.getStartRes(),
1030                                              sg.getEndRes() + 1));
1031
1032     refresh();
1033   }
1034
1035   /**
1036    * DOCUMENT ME!
1037    *
1038    * @param e DOCUMENT ME!
1039    */
1040   protected void noColourmenuItem_actionPerformed()
1041   {
1042     getGroup().cs = null;
1043     refresh();
1044   }
1045
1046   /**
1047    * DOCUMENT ME!
1048    *
1049    * @param e DOCUMENT ME!
1050    */
1051   protected void conservationMenuItem_actionPerformed()
1052   {
1053     SequenceGroup sg = getGroup();
1054     if (sg.cs == null)
1055     {
1056       return;
1057     }
1058
1059     if (conservationMenuItem.isSelected())
1060     {
1061       Conservation c = new Conservation("Group",
1062                                         ResidueProperties.propHash, 3,
1063                                         sg.getSequences(ap.av.
1064           hiddenRepSequences),
1065                                         sg.getStartRes(),
1066                                         sg.getEndRes() + 1);
1067
1068       c.calculate();
1069       c.verdict(false, ap.av.ConsPercGaps);
1070
1071       sg.cs.setConservation(c);
1072
1073       SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
1074       SliderPanel.showConservationSlider();
1075     }
1076     else // remove ConservationColouring
1077     {
1078       sg.cs.setConservation(null);
1079     }
1080
1081     refresh();
1082   }
1083
1084   public void annotationMenuItem_actionPerformed(ActionEvent actionEvent)
1085   {
1086     SequenceGroup sg = getGroup();
1087     if (sg == null)
1088     {
1089       return;
1090     }
1091
1092     AnnotationColourGradient acg = new AnnotationColourGradient(
1093         sequence.getAnnotation()[0], null, AnnotationColourGradient.NO_THRESHOLD);
1094
1095     acg.predefinedColours = true;
1096     sg.cs = acg;
1097
1098     refresh();
1099   }
1100
1101   /**
1102    * DOCUMENT ME!
1103    *
1104    * @param e DOCUMENT ME!
1105    */
1106   protected void groupName_actionPerformed()
1107   {
1108
1109     SequenceGroup sg = getGroup();
1110     EditNameDialog dialog = new EditNameDialog(sg.getName(),
1111                                                sg.getDescription(),
1112                                                "       Group Name ",
1113                                                "Group Description ",
1114                                                "Edit Group Name/Description");
1115
1116     if (!dialog.accept)
1117     {
1118       return;
1119     }
1120
1121     sg.setName(dialog.getName());
1122     sg.setDescription(dialog.getDescription());
1123   }
1124
1125   /**
1126    * DOCUMENT ME!
1127    *
1128    * @return DOCUMENT ME!
1129    */
1130   SequenceGroup getGroup()
1131   {
1132     SequenceGroup sg = ap.av.getSelectionGroup();
1133     // this method won't add a new group if it already exists
1134     if (sg != null)
1135     {
1136       ap.av.alignment.addGroup(sg);
1137     }
1138
1139     return sg;
1140   }
1141
1142   /**
1143    * DOCUMENT ME!
1144    *
1145    * @param e DOCUMENT ME!
1146    */
1147   void sequenceName_actionPerformed()
1148   {
1149     EditNameDialog dialog = new EditNameDialog(sequence.getName(),
1150                                                sequence.getDescription(),
1151                                                "       Sequence Name ",
1152                                                "Sequence Description ",
1153                                                "Edit Sequence Name/Description");
1154
1155     if (!dialog.accept)
1156     {
1157       return;
1158     }
1159
1160     if (dialog.getName() != null)
1161     {
1162       if (dialog.getName().indexOf(" ") > -1)
1163       {
1164         JOptionPane.showMessageDialog(ap,
1165                                       "Spaces have been converted to \"_\"",
1166                                       "No spaces allowed in Sequence Name",
1167                                       JOptionPane.WARNING_MESSAGE);
1168       }
1169
1170       sequence.setName(dialog.getName().replace(' ', '_'));
1171       ap.paintAlignment(false);
1172     }
1173
1174     sequence.setDescription(dialog.getDescription());
1175
1176     ap.av.firePropertyChange("alignment", null,
1177                              ap.av.getAlignment().getSequences());
1178
1179   }
1180
1181   /**
1182    * DOCUMENT ME!
1183    *
1184    * @param e DOCUMENT ME!
1185    */
1186   void unGroupMenuItem_actionPerformed()
1187   {
1188     SequenceGroup sg = ap.av.getSelectionGroup();
1189     ap.av.alignment.deleteGroup(sg);
1190     ap.av.setSelectionGroup(null);
1191     refresh();
1192   }
1193
1194   /**
1195    * DOCUMENT ME!
1196    *
1197    * @param e DOCUMENT ME!
1198    */
1199   protected void outline_actionPerformed()
1200   {
1201     SequenceGroup sg = getGroup();
1202     Color col = JColorChooser.showDialog(this, "Select Outline Colour",
1203                                          Color.BLUE);
1204
1205     if (col != null)
1206     {
1207       sg.setOutlineColour(col);
1208     }
1209
1210     refresh();
1211   }
1212
1213   /**
1214    * DOCUMENT ME!
1215    *
1216    * @param e DOCUMENT ME!
1217    */
1218   public void showBoxes_actionPerformed()
1219   {
1220     getGroup().setDisplayBoxes(showBoxes.isSelected());
1221     refresh();
1222   }
1223
1224   /**
1225    * DOCUMENT ME!
1226    *
1227    * @param e DOCUMENT ME!
1228    */
1229   public void showText_actionPerformed()
1230   {
1231     getGroup().setDisplayText(showText.isSelected());
1232     refresh();
1233   }
1234
1235   /**
1236    * DOCUMENT ME!
1237    *
1238    * @param e DOCUMENT ME!
1239    */
1240   public void showColourText_actionPerformed()
1241   {
1242     getGroup().setColourText(showColourText.isSelected());
1243     refresh();
1244   }
1245
1246   public void showLink(String url)
1247   {
1248     try
1249     {
1250       jalview.util.BrowserLauncher.openURL(url);
1251     }
1252     catch (Exception ex)
1253     {
1254       JOptionPane.showInternalMessageDialog(Desktop.desktop,
1255                                             "Unixers: Couldn't find default web browser."
1256                                             +
1257           "\nAdd the full path to your browser in Preferences.",
1258                                             "Web browser not found",
1259                                             JOptionPane.WARNING_MESSAGE);
1260
1261       ex.printStackTrace();
1262     }
1263   }
1264
1265   void hideSequences(boolean representGroup)
1266   {
1267     SequenceGroup sg = ap.av.getSelectionGroup();
1268     if (sg == null || sg.getSize() < 1)
1269     {
1270       ap.av.hideSequence(new SequenceI[]
1271                          {sequence});
1272       return;
1273     }
1274
1275     ap.av.setSelectionGroup(null);
1276
1277     if (representGroup)
1278     {
1279       ap.av.hideRepSequences(sequence, sg);
1280
1281       return;
1282     }
1283
1284     int gsize = sg.getSize();
1285     SequenceI[] hseqs;
1286
1287     hseqs = new SequenceI[gsize];
1288
1289     int index = 0;
1290     for (int i = 0; i < gsize; i++)
1291     {
1292       hseqs[index++] = sg.getSequenceAt(i);
1293     }
1294
1295     ap.av.hideSequence(hseqs);
1296   }
1297
1298   public void copy_actionPerformed()
1299   {
1300     ap.alignFrame.copy_actionPerformed(null);
1301   }
1302
1303   public void cut_actionPerformed()
1304   {
1305     ap.alignFrame.cut_actionPerformed(null);
1306   }
1307
1308   void changeCase(ActionEvent e)
1309   {
1310     Object source = e.getSource();
1311     SequenceGroup sg = ap.av.getSelectionGroup();
1312
1313     if (sg != null)
1314     {
1315       int[][] startEnd = ap.av.getVisibleRegionBoundaries(
1316           sg.getStartRes(), sg.getEndRes() + 1);
1317
1318       String description;
1319       int caseChange;
1320
1321       if (source == toggle)
1322       {
1323         description = "Toggle Case";
1324         caseChange = ChangeCaseCommand.TOGGLE_CASE;
1325       }
1326       else if (source == upperCase)
1327       {
1328         description = "To Upper Case";
1329         caseChange = ChangeCaseCommand.TO_UPPER;
1330       }
1331       else
1332       {
1333         description = "To Lower Case";
1334         caseChange = ChangeCaseCommand.TO_LOWER;
1335       }
1336
1337       ChangeCaseCommand caseCommand = new ChangeCaseCommand(
1338           description, sg.getSequencesAsArray(ap.av.hiddenRepSequences),
1339           startEnd, caseChange
1340           );
1341
1342       ap.alignFrame.addHistoryItem(caseCommand);
1343
1344       ap.av.firePropertyChange("alignment", null,
1345                                ap.av.getAlignment().getSequences());
1346
1347     }
1348   }
1349
1350   public void outputText_actionPerformed(ActionEvent e)
1351   {
1352     CutAndPasteTransfer cap = new CutAndPasteTransfer();
1353     cap.setForInput(null);
1354     Desktop.addInternalFrame(cap,
1355                              "Alignment output - " + e.getActionCommand(), 600,
1356                              500);
1357
1358     String[] omitHidden = null;
1359
1360     System.out.println("PROMPT USER HERE"); // TODO: decide if a prompt happens or we simply trust the user wants wysiwig behaviour
1361     SequenceGroup sg = ap.av.getSelectionGroup();
1362     ColumnSelection csel = new ColumnSelection(ap.av.getColumnSelection());
1363     omitHidden = ap.av.getViewAsString(true);
1364     Alignment oal = new Alignment(ap.av.getSequenceSelection());
1365     AlignmentAnnotation[] nala = ap.av.alignment.getAlignmentAnnotation();
1366     for (int i=0; i<nala.length; i++)
1367     {
1368       AlignmentAnnotation na =nala[i];
1369       oal.addAnnotation(na);
1370     }
1371     cap.setText(new FormatAdapter().formatSequences(
1372             e.getActionCommand(),
1373             oal,
1374             omitHidden, csel, sg));
1375     oal=null;
1376   }
1377
1378   public void pdbFromFile_actionPerformed()
1379   {
1380     jalview.io.JalviewFileChooser chooser
1381         = new jalview.io.JalviewFileChooser(jalview.bin.Cache.
1382                                             getProperty(
1383                                                 "LAST_DIRECTORY"));
1384     chooser.setFileView(new jalview.io.JalviewFileView());
1385     chooser.setDialogTitle("Select a PDB file");
1386     chooser.setToolTipText("Load a PDB file");
1387
1388     int value = chooser.showOpenDialog(null);
1389
1390     if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
1391     {
1392       PDBEntry entry = new PDBEntry();
1393       String choice = chooser.getSelectedFile().getPath();
1394       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
1395       try
1396       {
1397         MCview.PDBfile pdbfile = new MCview.PDBfile(choice,
1398             jalview.io.AppletFormatAdapter.FILE);
1399
1400         if (pdbfile.id == null)
1401         {
1402           String reply = JOptionPane.showInternalInputDialog(
1403               Desktop.desktop,
1404               "Couldn't find a PDB id in the file supplied."
1405               + "Please enter an Id to identify this structure.",
1406               "No PDB Id in File", JOptionPane.QUESTION_MESSAGE);
1407           if (reply == null)
1408           {
1409             return;
1410           }
1411
1412           entry.setId(reply);
1413         }
1414         else
1415         {
1416           entry.setId(pdbfile.id);
1417         }
1418       }
1419       catch (java.io.IOException ex)
1420       {
1421         ex.printStackTrace();
1422       }
1423
1424       entry.setFile(choice);
1425       sequence.getDatasetSequence().addPDBId(entry);
1426     }
1427
1428   }
1429
1430   public void enterPDB_actionPerformed()
1431   {
1432     String id = JOptionPane.showInternalInputDialog(Desktop.desktop,
1433         "Enter PDB Id", "Enter PDB Id", JOptionPane.QUESTION_MESSAGE);
1434
1435     if (id != null && id.length() > 0)
1436     {
1437       PDBEntry entry = new PDBEntry();
1438       entry.setId(id.toUpperCase());
1439       sequence.getDatasetSequence()
1440           .addPDBId(entry);
1441     }
1442   }
1443
1444   public void discoverPDB_actionPerformed()
1445   {
1446     
1447     final SequenceI[] sequences = 
1448       ((ap.av.selectionGroup == null) 
1449               ?  new Sequence[]{sequence}
1450       : ap.av.selectionGroup.getSequencesInOrder(ap.av.alignment));
1451     Thread discpdb = new Thread(new Runnable() {
1452       public void run()
1453       {
1454         
1455         new jalview.ws.DBRefFetcher(sequences,
1456                 ap.alignFrame).fetchDBRefs(false);
1457       }
1458       
1459     });
1460     discpdb.start();
1461   }
1462
1463   public void sequenceFeature_actionPerformed()
1464   {
1465     SequenceGroup sg = ap.av.getSelectionGroup();
1466     if (sg == null)
1467     {
1468       return;
1469     }
1470
1471     int gSize = sg.getSize();
1472     SequenceI[] seqs = new SequenceI[gSize];
1473     SequenceFeature[] features = new SequenceFeature[gSize];
1474
1475     for (int i = 0; i < gSize; i++)
1476     {
1477       seqs[i] = sg.getSequenceAt(i).getDatasetSequence();
1478       int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
1479       int end = sg.findEndRes(sg.getSequenceAt(i));
1480       features[i] = new SequenceFeature(null, null, null, start, end, "Jalview");
1481     }
1482
1483     if (ap.seqPanel.seqCanvas.getFeatureRenderer()
1484         .amendFeatures(seqs, features, true, ap))
1485     {
1486       ap.alignFrame.showSeqFeatures.setSelected(true);
1487       ap.av.setShowSequenceFeatures(true);
1488       ap.highlightSearchResults(null);
1489     }
1490   }
1491
1492   public void textColour_actionPerformed()
1493   {
1494     SequenceGroup sg = getGroup();
1495     if (sg != null)
1496     {
1497       new TextColourChooser().chooseColour(ap, sg);
1498     }
1499   }
1500
1501   public void colourByStructure(String pdbid)
1502   {
1503     Annotation [] anots = jalview.structure.StructureSelectionManager.getStructureSelectionManager()
1504         .colourSequenceFromStructure(sequence, pdbid);
1505
1506     AlignmentAnnotation an = new AlignmentAnnotation(
1507       "Structure", "Coloured by "+pdbid, anots);
1508
1509     ap.av.alignment.addAnnotation(an);
1510     an.createSequenceMapping(sequence, 0, true);
1511     //an.adjustForAlignment();
1512     ap.av.alignment.setAnnotationIndex(an,0);
1513
1514     ap.adjustAnnotationHeight();
1515
1516     sequence.addAlignmentAnnotation(an);
1517
1518     }
1519
1520   public void editSequence_actionPerformed(ActionEvent actionEvent)
1521   {
1522       SequenceGroup sg = ap.av.getSelectionGroup();
1523
1524       if(sg!=null)
1525       {
1526         if (sequence == null)
1527           sequence = (Sequence) sg.getSequenceAt(0);
1528
1529         EditNameDialog dialog = new EditNameDialog(
1530             sequence.getSequenceAsString(
1531                 sg.getStartRes(),
1532                 sg.getEndRes() + 1),
1533             null,
1534             "Edit Sequence ",
1535             null,
1536             "Edit Sequence");
1537
1538         if (dialog.accept)
1539         {
1540           EditCommand editCommand = new EditCommand(
1541               "Edit Sequences", EditCommand.REPLACE,
1542               dialog.getName().replace(' ', ap.av.getGapCharacter()),
1543               sg.getSequencesAsArray(ap.av.hiddenRepSequences),
1544               sg.getStartRes(), sg.getEndRes() + 1, ap.av.alignment
1545               );
1546
1547           ap.alignFrame.addHistoryItem(editCommand);
1548
1549           ap.av.firePropertyChange("alignment", null,
1550                                    ap.av.getAlignment().getSequences());
1551         }
1552       }
1553   }
1554
1555
1556 }