2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
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.
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.
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
20 package jalview.appletgui;
25 import java.awt.event.*;
27 import jalview.analysis.*;
28 import jalview.commands.*;
29 import jalview.datamodel.*;
30 import jalview.schemes.*;
31 import jalview.util.UrlLink;
32 import jalview.io.AppletFormatAdapter;
34 public class APopupMenu
35 extends java.awt.PopupMenu implements ActionListener, ItemListener
37 Menu groupMenu = new Menu();
38 MenuItem editGroupName = new MenuItem();
39 protected MenuItem clustalColour = new MenuItem();
40 protected MenuItem zappoColour = new MenuItem();
41 protected MenuItem taylorColour = new MenuItem();
42 protected MenuItem hydrophobicityColour = new MenuItem();
43 protected MenuItem helixColour = new MenuItem();
44 protected MenuItem strandColour = new MenuItem();
45 protected MenuItem turnColour = new MenuItem();
46 protected MenuItem buriedColour = new MenuItem();
47 protected CheckboxMenuItem abovePIDColour = new CheckboxMenuItem();
48 protected MenuItem userDefinedColour = new MenuItem();
49 protected MenuItem PIDColour = new MenuItem();
50 protected MenuItem BLOSUM62Colour = new MenuItem();
51 MenuItem noColourmenuItem = new MenuItem();
52 protected CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
54 final AlignmentPanel ap;
55 MenuItem unGroupMenuItem = new MenuItem();
56 MenuItem nucleotideMenuItem = new MenuItem();
57 Menu colourMenu = new Menu();
58 CheckboxMenuItem showBoxes = new CheckboxMenuItem();
59 CheckboxMenuItem showText = new CheckboxMenuItem();
60 CheckboxMenuItem showColourText = new CheckboxMenuItem();
61 Menu editMenu = new Menu("Edit");
62 MenuItem copy = new MenuItem("Copy (Jalview Only)");
63 MenuItem cut = new MenuItem("Cut (Jalview Only)");
64 MenuItem toUpper = new MenuItem("To Upper Case");
65 MenuItem toLower = new MenuItem("To Lower Case");
66 MenuItem toggleCase = new MenuItem("Toggle Case");
67 Menu outputmenu = new Menu();
68 Menu seqMenu = new Menu();
69 MenuItem pdb = new MenuItem();
70 MenuItem hideSeqs = new MenuItem();
71 MenuItem repGroup = new MenuItem();
72 MenuItem sequenceName = new MenuItem("Edit Name/Description");
73 MenuItem sequenceFeature = new MenuItem("Create Sequence Feature");
74 MenuItem editSequence = new MenuItem("Edit Sequence");
77 MenuItem revealAll = new MenuItem();
78 Menu menu1 = new Menu();
80 public APopupMenu(AlignmentPanel apanel, final Sequence seq, Vector links)
82 ///////////////////////////////////////////////////////////
83 // If this is activated from the sequence panel, the user may want to
84 // edit or annotate a particular residue. Therefore display the residue menu
86 // If from the IDPanel, we must display the sequence menu
87 //////////////////////////////////////////////////////////
101 for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length;
104 MenuItem item = new MenuItem(jalview.io.AppletFormatAdapter.
105 WRITEABLE_FORMATS[i]);
107 item.addActionListener(this);
108 outputmenu.add(item);
111 SequenceGroup sg = ap.av.getSelectionGroup();
113 if (sg != null && sg.getSize() > 0)
115 editGroupName.setLabel(sg.getName());
116 showText.setState(sg.getDisplayText());
117 showColourText.setState(sg.getColourText());
118 showBoxes.setState(sg.getDisplayBoxes());
119 if (!ap.av.alignment.getGroups().contains(sg))
121 groupMenu.remove(unGroupMenuItem);
131 if (links != null && links.size()>0)
133 Menu linkMenu = new Menu("Link");
135 for (int i = 0; i < links.size(); i++)
137 link = links.elementAt(i).toString();
138 UrlLink urlLink = new UrlLink(link);
139 if (!urlLink.isValid())
141 System.err.println(urlLink.getInvalidMessage());
144 final String target = urlLink.getTarget(); // link.substring(0, link.indexOf("|"));
145 final String label = urlLink.getLabel();
146 if (urlLink.isDynamic())
149 // collect matching db-refs
150 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new String[]{target});
151 // collect id string too
152 String id = seq.getName();
155 for (int r=0;r<dbr.length; r++)
157 if (id!=null && dbr[r].getAccessionId().equals(id))
159 // suppress duplicate link creation for the bare sequence ID string with this link
162 // create Bare ID link for this RUL
163 String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
166 for (int u=0; u<urls.length; u+=2)
168 addshowLink(linkMenu, label+"|"+urls[u],urls[u+1]);
175 // create Bare ID link for this RUL
176 String[] urls = urlLink.makeUrls(id, true);
179 for (int u=0; u<urls.length; u+=2)
181 addshowLink(linkMenu, label,urls[u+1]);
184 // addshowLink(linkMenu, target, url_pref + id + url_suff);
187 addshowLink(linkMenu, target, urlLink.getUrl_prefix()); // link.substring(link.lastIndexOf("|")+1));
191 if (link.indexOf("$SEQUENCE_ID$") > -1)
193 // Substitute SEQUENCE_ID string and any matching database reference accessions
194 String url_pref = link.substring(link.indexOf("|") + 1,
195 link.indexOf("$SEQUENCE_ID$"));
197 String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
199 // collect matching db-refs
200 DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new String[]{target});
201 // collect id string too
202 String id = seq.getName();
203 if (id.indexOf("|") > -1)
205 id = id.substring(id.lastIndexOf("|") + 1);
209 for (int r=0;r<dbr.length; r++)
211 if (dbr[r].getAccessionId().equals(id))
213 // suppress duplicate link creation for the bare sequence ID string with this link
216 addshowLink(linkMenu, dbr[r].getSource()+"|"+dbr[r].getAccessionId(), target,
217 url_pref+dbr[r].getAccessionId()+url_suff);
222 // create Bare ID link for this RUL
223 addshowLink(linkMenu, target, url_pref + id + url_suff);
226 addshowLink(linkMenu, target, link.substring(link.lastIndexOf("|")+1));
232 seqMenu.add(linkMenu);
241 seqMenu.setLabel(seq.getName());
242 repGroup.setLabel("Represent Group with " + seq.getName());
249 if (!ap.av.hasHiddenRows)
255 * add a show URL menu item to the given linkMenu
257 * @param target - menu label string
258 * @param url - url to open
260 private void addshowLink(Menu linkMenu, final String target, final String url)
262 addshowLink(linkMenu, target, target, url);
265 * add a show URL menu item to the given linkMenu
267 * @param target - URL target window
268 * @param label - menu label string
269 * @param url - url to open
271 private void addshowLink(Menu linkMenu, final String target, final String label, final String url)
273 MenuItem item = new MenuItem(label);
274 item.addActionListener(new java.awt.event.ActionListener()
276 public void actionPerformed(ActionEvent e)
278 ap.alignFrame.showURL(url, target);
285 public void itemStateChanged(ItemEvent evt)
287 if (evt.getSource() == abovePIDColour)
289 abovePIDColour_itemStateChanged();
291 else if (evt.getSource() == showColourText)
293 showColourText_itemStateChanged();
295 else if (evt.getSource() == showText)
297 showText_itemStateChanged();
299 else if (evt.getSource() == showBoxes)
301 showBoxes_itemStateChanged();
305 public void actionPerformed(ActionEvent evt)
307 Object source = evt.getSource();
308 if (source == clustalColour)
310 clustalColour_actionPerformed();
312 else if (source == zappoColour)
314 zappoColour_actionPerformed();
316 else if (source == taylorColour)
318 taylorColour_actionPerformed();
320 else if (source == hydrophobicityColour)
322 hydrophobicityColour_actionPerformed();
324 else if (source == helixColour)
326 helixColour_actionPerformed();
328 else if (source == strandColour)
330 strandColour_actionPerformed();
332 else if (source == turnColour)
334 turnColour_actionPerformed();
336 else if (source == buriedColour)
338 buriedColour_actionPerformed();
340 else if (source == nucleotideMenuItem)
342 nucleotideMenuItem_actionPerformed();
345 else if (source == userDefinedColour)
347 userDefinedColour_actionPerformed();
349 else if (source == PIDColour)
351 PIDColour_actionPerformed();
353 else if (source == BLOSUM62Colour)
355 BLOSUM62Colour_actionPerformed();
357 else if (source == noColourmenuItem)
359 noColourmenuItem_actionPerformed();
361 else if (source == conservationMenuItem)
363 conservationMenuItem_itemStateChanged();
365 else if (source == unGroupMenuItem)
367 unGroupMenuItem_actionPerformed();
370 else if (source == sequenceName)
374 else if (source == pdb)
378 else if (source == hideSeqs)
380 hideSequences(false);
382 else if (source == repGroup)
386 else if (source == revealAll)
388 ap.av.showAllHiddenSeqs();
391 else if (source == editGroupName)
393 EditNameDialog dialog = new EditNameDialog(
394 getGroup().getName(),
395 getGroup().getDescription(),
399 "Edit Group Name / Description",
404 getGroup().setName(dialog.getName().replace(' ', '_'));
405 getGroup().setDescription(dialog.getDescription());
409 else if (source == copy)
411 ap.alignFrame.copy_actionPerformed();
413 else if (source == cut)
415 ap.alignFrame.cut_actionPerformed();
417 else if(source == editSequence)
419 SequenceGroup sg = ap.av.getSelectionGroup();
424 seq = (Sequence) sg.getSequenceAt(0);
426 EditNameDialog dialog = new EditNameDialog(seq.getSequenceAsString(
439 EditCommand editCommand = new EditCommand(
440 "Edit Sequences", EditCommand.REPLACE,
441 dialog.getName().replace(' ', ap.av.getGapCharacter()),
442 sg.getSequencesAsArray(ap.av.hiddenRepSequences),
443 sg.getStartRes(), sg.getEndRes()+1, ap.av.alignment
446 ap.alignFrame.addHistoryItem(editCommand);
448 ap.av.firePropertyChange("alignment", null,
449 ap.av.getAlignment().getSequences());
453 else if (source == toUpper || source == toLower || source == toggleCase)
455 SequenceGroup sg = ap.av.getSelectionGroup();
456 Vector regions = new Vector();
459 int start = sg.getStartRes();
460 int end = sg.getEndRes() + 1;
464 if (ap.av.hasHiddenColumns)
468 start = ap.av.colSel.adjustForHiddenColumns(start);
471 end = ap.av.colSel.getHiddenBoundaryRight(start);
474 end = sg.getEndRes() + 1;
476 if (end > sg.getEndRes())
478 end = sg.getEndRes() + 1;
482 regions.addElement(new int[]
485 if (ap.av.hasHiddenColumns)
487 start = ap.av.colSel.adjustForHiddenColumns(end);
488 start = ap.av.colSel.getHiddenBoundaryLeft(start) + 1;
491 while (end < sg.getEndRes());
493 int[][] startEnd = new int[regions.size()][2];
494 for (int i = 0; i < regions.size(); i++)
496 startEnd[i] = (int[]) regions.elementAt(i);
502 if (source == toggleCase)
504 description = "Toggle Case";
505 caseChange = ChangeCaseCommand.TOGGLE_CASE;
507 else if (source == toUpper)
509 description = "To Upper Case";
510 caseChange = ChangeCaseCommand.TO_UPPER;
514 description = "To Lower Case";
515 caseChange = ChangeCaseCommand.TO_LOWER;
518 ChangeCaseCommand caseCommand = new ChangeCaseCommand(
519 description, sg.getSequencesAsArray(ap.av.hiddenRepSequences),
523 ap.alignFrame.addHistoryItem(caseCommand);
525 ap.av.firePropertyChange("alignment", null,
526 ap.av.getAlignment().getSequences());
530 else if(source == sequenceFeature)
532 SequenceGroup sg = ap.av.getSelectionGroup();
538 int gSize = sg.getSize();
539 SequenceI[] seqs = new SequenceI[gSize];
540 SequenceFeature[] features = new SequenceFeature[gSize];
542 for (int i = 0; i < gSize; i++)
544 seqs[i] = sg.getSequenceAt(i);
545 int start = sg.getSequenceAt(i).findPosition(sg.getStartRes());
546 int end = sg.findEndRes(sg.getSequenceAt(i));
547 features[i] = new SequenceFeature(null, null, null, start, end,
551 if (ap.seqPanel.seqCanvas.getFeatureRenderer()
552 .amendFeatures(seqs, features, true, ap))
554 ap.alignFrame.sequenceFeatures.setState(true);
555 ap.av.showSequenceFeatures(true);
556 ap.highlightSearchResults(null);
566 void outputText(ActionEvent e)
568 CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
570 Frame frame = new Frame();
572 jalview.bin.JalviewLite.addFrame(frame,
573 "Selection output - " + e.getActionCommand(),
576 cap.setText(new jalview.io.AppletFormatAdapter().formatSequences(
577 e.getActionCommand(),
578 new Alignment(ap.av.getSelectionAsNewSequence()),
579 ap.av.showJVSuffix));
585 EditNameDialog dialog = new EditNameDialog(
587 seq.getDescription(),
589 "Sequence Description",
591 "Edit Sequence Name / Description",
596 seq.setName(dialog.getName());
597 seq.setDescription(dialog.getDescription());
598 ap.paintAlignment(false);
604 if(seq.getPDBId()!=null)
606 PDBEntry entry = (PDBEntry)seq.getPDBId().firstElement();
608 if ( ap.av.applet.jmolAvailable )
609 new jalview.appletgui.AppletJmol(entry,
613 AppletFormatAdapter.URL);
615 new MCview.AppletPDBViewer(entry,
619 AppletFormatAdapter.URL);
624 CutAndPasteTransfer cap = new CutAndPasteTransfer(true, ap.alignFrame);
625 cap.setText("Paste your PDB file here.");
626 cap.setPDBImport(seq);
627 Frame frame = new Frame();
629 jalview.bin.JalviewLite.addFrame(frame, "Paste PDB file ", 400, 300);
633 private void jbInit()
636 groupMenu.setLabel("Group");
637 groupMenu.setLabel("Selection");
638 sequenceFeature.addActionListener(this);
640 editGroupName.addActionListener(this);
641 unGroupMenuItem.setLabel("Remove Group");
642 unGroupMenuItem.addActionListener(this);
644 nucleotideMenuItem.setLabel("Nucleotide");
645 nucleotideMenuItem.addActionListener(this);
646 conservationMenuItem.addItemListener(this);
647 abovePIDColour.addItemListener(this);
648 colourMenu.setLabel("Group Colour");
649 showBoxes.setLabel("Boxes");
650 showBoxes.setState(true);
651 showBoxes.addItemListener(this);
652 sequenceName.addActionListener(this);
654 showText.setLabel("Text");
655 showText.addItemListener(this);
656 showColourText.setLabel("Colour Text");
657 showColourText.addItemListener(this);
658 outputmenu.setLabel("Output to Textbox...");
659 seqMenu.setLabel("Sequence");
660 pdb.setLabel("View PDB Structure");
661 hideSeqs.setLabel("Hide Sequences");
662 repGroup.setLabel("Represent Group with");
663 revealAll.setLabel("Reveal All");
664 menu1.setLabel("Group");
669 groupMenu.add(editGroupName);
670 groupMenu.add(editMenu);
671 groupMenu.add(outputmenu);
672 groupMenu.add(sequenceFeature);
673 groupMenu.add(menu1);
675 colourMenu.add(noColourmenuItem);
676 colourMenu.add(clustalColour);
677 colourMenu.add(BLOSUM62Colour);
678 colourMenu.add(PIDColour);
679 colourMenu.add(zappoColour);
680 colourMenu.add(taylorColour);
681 colourMenu.add(hydrophobicityColour);
682 colourMenu.add(helixColour);
683 colourMenu.add(strandColour);
684 colourMenu.add(turnColour);
685 colourMenu.add(buriedColour);
686 colourMenu.add(nucleotideMenuItem);
687 colourMenu.add(userDefinedColour);
688 colourMenu.addSeparator();
689 colourMenu.add(abovePIDColour);
690 colourMenu.add(conservationMenuItem);
692 noColourmenuItem.setLabel("None");
693 noColourmenuItem.addActionListener(this);
695 clustalColour.setLabel("Clustalx colours");
696 clustalColour.addActionListener(this);
697 zappoColour.setLabel("Zappo");
698 zappoColour.addActionListener(this);
699 taylorColour.setLabel("Taylor");
700 taylorColour.addActionListener(this);
701 hydrophobicityColour.setLabel("Hydrophobicity");
702 hydrophobicityColour.addActionListener(this);
703 helixColour.setLabel("Helix propensity");
704 helixColour.addActionListener(this);
705 strandColour.setLabel("Strand propensity");
706 strandColour.addActionListener(this);
707 turnColour.setLabel("Turn propensity");
708 turnColour.addActionListener(this);
709 buriedColour.setLabel("Buried Index");
710 buriedColour.addActionListener(this);
711 abovePIDColour.setLabel("Above % Identity");
713 userDefinedColour.setLabel("User Defined");
714 userDefinedColour.addActionListener(this);
715 PIDColour.setLabel("Percentage Identity");
716 PIDColour.addActionListener(this);
717 BLOSUM62Colour.setLabel("BLOSUM62");
718 BLOSUM62Colour.addActionListener(this);
719 conservationMenuItem.setLabel("Conservation");
722 copy.addActionListener(this);
724 cut.addActionListener(this);
726 editMenu.add(editSequence);
727 editSequence.addActionListener(this);
729 editMenu.add(toUpper);
730 toUpper.addActionListener(this);
731 editMenu.add(toLower);
732 toLower.addActionListener(this);
733 editMenu.add(toggleCase);
734 seqMenu.add(sequenceName);
736 seqMenu.add(repGroup);
737 menu1.add(unGroupMenuItem);
738 menu1.add(colourMenu);
739 menu1.add(showBoxes);
741 menu1.add(showColourText);
742 toggleCase.addActionListener(this);
743 pdb.addActionListener(this);
744 hideSeqs.addActionListener(this);
745 repGroup.addActionListener(this);
746 revealAll.addActionListener(this);
751 ap.paintAlignment(true);
754 protected void clustalColour_actionPerformed()
756 SequenceGroup sg = getGroup();
757 sg.cs = new ClustalxColourScheme(sg.getSequences(ap.av.hiddenRepSequences),
758 ap.av.alignment.getWidth());
762 protected void zappoColour_actionPerformed()
764 getGroup().cs = new ZappoColourScheme();
768 protected void taylorColour_actionPerformed()
770 getGroup().cs = new TaylorColourScheme();
774 protected void hydrophobicityColour_actionPerformed()
776 getGroup().cs = new HydrophobicColourScheme();
780 protected void helixColour_actionPerformed()
782 getGroup().cs = new HelixColourScheme();
786 protected void strandColour_actionPerformed()
788 getGroup().cs = new StrandColourScheme();
792 protected void turnColour_actionPerformed()
794 getGroup().cs = new TurnColourScheme();
798 protected void buriedColour_actionPerformed()
800 getGroup().cs = new BuriedColourScheme();
804 public void nucleotideMenuItem_actionPerformed()
806 getGroup().cs = new NucleotideColourScheme();
810 protected void abovePIDColour_itemStateChanged()
812 SequenceGroup sg = getGroup();
818 if (abovePIDColour.getState())
820 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
821 hiddenRepSequences), 0,
822 ap.av.alignment.getWidth()));
823 int threshold = SliderPanel.setPIDSliderSource(ap, sg.cs,
824 getGroup().getName());
826 sg.cs.setThreshold(threshold, ap.av.getIgnoreGapsConsensus());
828 SliderPanel.showPIDSlider();
831 else // remove PIDColouring
833 sg.cs.setThreshold(0, ap.av.getIgnoreGapsConsensus());
840 protected void userDefinedColour_actionPerformed()
842 new UserDefinedColours(ap, getGroup());
845 protected void PIDColour_actionPerformed()
847 SequenceGroup sg = getGroup();
848 sg.cs = new PIDColourScheme();
849 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
850 hiddenRepSequences), 0,
851 ap.av.alignment.getWidth()));
855 protected void BLOSUM62Colour_actionPerformed()
857 SequenceGroup sg = getGroup();
859 sg.cs = new Blosum62ColourScheme();
861 sg.cs.setConsensus(AAFrequency.calculate(sg.getSequences(ap.av.
862 hiddenRepSequences), 0,
863 ap.av.alignment.getWidth()));
868 protected void noColourmenuItem_actionPerformed()
870 getGroup().cs = null;
874 protected void conservationMenuItem_itemStateChanged()
876 SequenceGroup sg = getGroup();
882 if (conservationMenuItem.getState())
885 Conservation c = new Conservation("Group",
886 ResidueProperties.propHash, 3,
887 sg.getSequences(ap.av.
888 hiddenRepSequences), 0,
889 ap.av.alignment.getWidth());
892 c.verdict(false, ap.av.ConsPercGaps);
894 sg.cs.setConservation(c);
896 SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
897 SliderPanel.showConservationSlider();
899 else // remove ConservationColouring
901 sg.cs.setConservation(null);
907 SequenceGroup getGroup()
909 SequenceGroup sg = ap.av.getSelectionGroup();
911 // this method won't add a new group if it already exists
914 ap.av.alignment.addGroup(sg);
920 void unGroupMenuItem_actionPerformed()
922 SequenceGroup sg = ap.av.getSelectionGroup();
923 ap.av.alignment.deleteGroup(sg);
924 ap.av.setSelectionGroup(null);
925 ap.paintAlignment(true);
928 public void showColourText_itemStateChanged()
930 getGroup().setColourText(showColourText.getState());
934 public void showText_itemStateChanged()
936 getGroup().setDisplayText(showText.getState());
940 public void showBoxes_itemStateChanged()
942 getGroup().setDisplayBoxes(showBoxes.getState());
946 void hideSequences(boolean representGroup)
948 SequenceGroup sg = ap.av.getSelectionGroup();
949 if (sg == null || sg.getSize() < 1)
951 ap.av.hideSequence(new SequenceI[]
956 ap.av.setSelectionGroup(null);
960 ap.av.hideRepSequences(seq, sg);
965 int gsize = sg.getSize();
968 hseqs = new SequenceI[gsize];
971 for (int i = 0; i < gsize; i++)
973 hseqs[index++] = sg.getSequenceAt(i);
976 ap.av.hideSequence(hseqs);