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