2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.analysis.AlignmentSorter;
24 import jalview.analysis.AlignmentUtils;
25 import jalview.analysis.CrossRef;
26 import jalview.analysis.Dna;
27 import jalview.analysis.ParseProperties;
28 import jalview.analysis.SequenceIdMatcher;
29 import jalview.api.AlignExportSettingI;
30 import jalview.api.AlignViewControllerGuiI;
31 import jalview.api.AlignViewControllerI;
32 import jalview.api.AlignViewportI;
33 import jalview.api.AlignmentViewPanel;
34 import jalview.api.FeatureSettingsControllerI;
35 import jalview.api.SplitContainerI;
36 import jalview.api.ViewStyleI;
37 import jalview.api.analysis.SimilarityParamsI;
38 import jalview.bin.Cache;
39 import jalview.bin.Jalview;
40 import jalview.commands.CommandI;
41 import jalview.commands.EditCommand;
42 import jalview.commands.EditCommand.Action;
43 import jalview.commands.OrderCommand;
44 import jalview.commands.RemoveGapColCommand;
45 import jalview.commands.RemoveGapsCommand;
46 import jalview.commands.SlideSequencesCommand;
47 import jalview.commands.TrimRegionCommand;
48 import jalview.datamodel.AlignedCodonFrame;
49 import jalview.datamodel.Alignment;
50 import jalview.datamodel.AlignmentAnnotation;
51 import jalview.datamodel.AlignmentExportData;
52 import jalview.datamodel.AlignmentI;
53 import jalview.datamodel.AlignmentOrder;
54 import jalview.datamodel.AlignmentView;
55 import jalview.datamodel.ColumnSelection;
56 import jalview.datamodel.HiddenColumns;
57 import jalview.datamodel.HiddenMarkovModel;
58 import jalview.datamodel.HiddenSequences;
59 import jalview.datamodel.PDBEntry;
60 import jalview.datamodel.SeqCigar;
61 import jalview.datamodel.Sequence;
62 import jalview.datamodel.SequenceGroup;
63 import jalview.datamodel.SequenceI;
64 import jalview.gui.ColourMenuHelper.ColourChangeListener;
65 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
66 import jalview.io.AlignmentProperties;
67 import jalview.io.AnnotationFile;
68 import jalview.io.BioJsHTMLOutput;
69 import jalview.io.DataSourceType;
70 import jalview.io.FileFormat;
71 import jalview.io.FileFormatI;
72 import jalview.io.FileFormats;
73 import jalview.io.FileLoader;
74 import jalview.io.FileParse;
75 import jalview.io.FormatAdapter;
76 import jalview.io.HMMFile;
77 import jalview.io.HtmlSvgOutput;
78 import jalview.io.IdentifyFile;
79 import jalview.io.JPredFile;
80 import jalview.io.JalviewFileChooser;
81 import jalview.io.JalviewFileView;
82 import jalview.io.JnetAnnotationMaker;
83 import jalview.io.NewickFile;
84 import jalview.io.ScoreMatrixFile;
85 import jalview.io.TCoffeeScoreFile;
86 import jalview.jbgui.GAlignFrame;
87 import jalview.schemes.ColourSchemeI;
88 import jalview.schemes.ColourSchemes;
89 import jalview.schemes.ResidueColourScheme;
90 import jalview.schemes.TCoffeeColourScheme;
91 import jalview.util.MessageManager;
92 import jalview.viewmodel.AlignmentViewport;
93 import jalview.viewmodel.ViewportRanges;
94 import jalview.ws.DBRefFetcher;
95 import jalview.ws.DBRefFetcher.FetchFinishedListenerI;
96 import jalview.ws.jws1.Discoverer;
97 import jalview.ws.jws2.Jws2Discoverer;
98 import jalview.ws.jws2.jabaws2.Jws2Instance;
99 import jalview.ws.seqfetcher.DbSourceProxy;
101 import java.awt.BorderLayout;
102 import java.awt.Component;
103 import java.awt.Rectangle;
104 import java.awt.Toolkit;
105 import java.awt.datatransfer.Clipboard;
106 import java.awt.datatransfer.DataFlavor;
107 import java.awt.datatransfer.StringSelection;
108 import java.awt.datatransfer.Transferable;
109 import java.awt.dnd.DnDConstants;
110 import java.awt.dnd.DropTargetDragEvent;
111 import java.awt.dnd.DropTargetDropEvent;
112 import java.awt.dnd.DropTargetEvent;
113 import java.awt.dnd.DropTargetListener;
114 import java.awt.event.ActionEvent;
115 import java.awt.event.ActionListener;
116 import java.awt.event.FocusAdapter;
117 import java.awt.event.FocusEvent;
118 import java.awt.event.ItemEvent;
119 import java.awt.event.ItemListener;
120 import java.awt.event.KeyAdapter;
121 import java.awt.event.KeyEvent;
122 import java.awt.event.MouseEvent;
123 import java.awt.print.PageFormat;
124 import java.awt.print.PrinterJob;
125 import java.beans.PropertyChangeEvent;
127 import java.io.FileWriter;
128 import java.io.PrintWriter;
130 import java.util.ArrayList;
131 import java.util.Arrays;
132 import java.util.Deque;
133 import java.util.Enumeration;
134 import java.util.HashMap;
135 import java.util.Hashtable;
136 import java.util.List;
137 import java.util.Map;
138 import java.util.Vector;
140 import javax.swing.JCheckBoxMenuItem;
141 import javax.swing.JEditorPane;
142 import javax.swing.JInternalFrame;
143 import javax.swing.JLayeredPane;
144 import javax.swing.JMenu;
145 import javax.swing.JMenuItem;
146 import javax.swing.JScrollPane;
147 import javax.swing.SwingUtilities;
153 * @version $Revision$
155 public class AlignFrame extends GAlignFrame implements DropTargetListener,
156 IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
159 Map<String, Float> distribution = new HashMap<>(); // temporary
161 public static final int DEFAULT_WIDTH = 700;
163 public static final int DEFAULT_HEIGHT = 500;
166 * The currently displayed panel (selected tabbed view if more than one)
168 public AlignmentPanel alignPanel;
170 AlignViewport viewport;
172 ViewportRanges vpRanges;
174 public AlignViewControllerI avc;
176 List<AlignmentPanel> alignPanels = new ArrayList<>();
179 * Last format used to load or save alignments in this window
181 FileFormatI currentFileFormat = null;
184 * Current filename for this alignment
186 String fileName = null;
190 * Creates a new AlignFrame object with specific width and height.
196 public AlignFrame(AlignmentI al, int width, int height)
198 this(al, null, width, height);
202 * Creates a new AlignFrame object with specific width, height and
208 * @param sequenceSetId
210 public AlignFrame(AlignmentI al, int width, int height,
211 String sequenceSetId)
213 this(al, null, width, height, sequenceSetId);
217 * Creates a new AlignFrame object with specific width, height and
223 * @param sequenceSetId
226 public AlignFrame(AlignmentI al, int width, int height,
227 String sequenceSetId, String viewId)
229 this(al, null, width, height, sequenceSetId, viewId);
233 * new alignment window with hidden columns
237 * @param hiddenColumns
238 * ColumnSelection or null
240 * Width of alignment frame
244 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns,
245 int width, int height)
247 this(al, hiddenColumns, width, height, null);
251 * Create alignment frame for al with hiddenColumns, a specific width and
252 * height, and specific sequenceId
255 * @param hiddenColumns
258 * @param sequenceSetId
261 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns,
262 int width, int height, String sequenceSetId)
264 this(al, hiddenColumns, width, height, sequenceSetId, null);
268 * Create alignment frame for al with hiddenColumns, a specific width and
269 * height, and specific sequenceId
272 * @param hiddenColumns
275 * @param sequenceSetId
280 public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns,
281 int width, int height, String sequenceSetId, String viewId)
283 setSize(width, height);
285 if (al.getDataset() == null)
290 viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
292 alignPanel = new AlignmentPanel(this, viewport);
294 addAlignmentPanel(alignPanel, true);
298 public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
299 HiddenColumns hiddenColumns, int width, int height)
301 setSize(width, height);
303 if (al.getDataset() == null)
308 viewport = new AlignViewport(al, hiddenColumns);
310 if (hiddenSeqs != null && hiddenSeqs.length > 0)
312 viewport.hideSequence(hiddenSeqs);
314 alignPanel = new AlignmentPanel(this, viewport);
315 addAlignmentPanel(alignPanel, true);
320 * Make a new AlignFrame from existing alignmentPanels
327 public AlignFrame(AlignmentPanel ap)
331 addAlignmentPanel(ap, false);
336 * initalise the alignframe from the underlying viewport data and the
341 if (!Jalview.isHeadlessMode())
343 progressBar = new ProgressBar(this.statusPanel, this.statusBar);
346 vpRanges = viewport.getRanges();
347 avc = new jalview.controller.AlignViewController(this, viewport,
349 if (viewport.getAlignmentConservationAnnotation() == null)
351 // BLOSUM62Colour.setEnabled(false);
352 conservationMenuItem.setEnabled(false);
353 modifyConservation.setEnabled(false);
354 // PIDColour.setEnabled(false);
355 // abovePIDThreshold.setEnabled(false);
356 // modifyPID.setEnabled(false);
359 String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT",
362 if (sortby.equals("Id"))
364 sortIDMenuItem_actionPerformed(null);
366 else if (sortby.equals("Pairwise Identity"))
368 sortPairwiseMenuItem_actionPerformed(null);
372 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
374 setMenusFromViewport(viewport);
375 buildSortByAnnotationScoresMenu();
376 calculateTree.addActionListener(new ActionListener()
380 public void actionPerformed(ActionEvent e)
388 if (Desktop.desktop != null)
390 this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
391 addServiceListeners();
395 if (viewport.getWrapAlignment())
397 wrapMenuItem_actionPerformed(null);
400 if (jalview.bin.Cache.getDefault("SHOW_OVERVIEW", false))
402 this.overviewMenuItem_actionPerformed(null);
407 final List<AlignmentPanel> selviews = new ArrayList<>();
408 final List<AlignmentPanel> origview = new ArrayList<>();
409 final String menuLabel = MessageManager
410 .getString("label.copy_format_from");
411 ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
412 new ViewSetProvider()
416 public AlignmentPanel[] getAllAlignmentPanels()
419 origview.add(alignPanel);
420 // make an array of all alignment panels except for this one
421 List<AlignmentPanel> aps = new ArrayList<>(
422 Arrays.asList(Desktop.getAlignmentPanels(null)));
423 aps.remove(AlignFrame.this.alignPanel);
424 return aps.toArray(new AlignmentPanel[aps.size()]);
426 }, selviews, new ItemListener()
430 public void itemStateChanged(ItemEvent e)
432 if (origview.size() > 0)
434 final AlignmentPanel ap = origview.get(0);
437 * Copy the ViewStyle of the selected panel to 'this one'.
438 * Don't change value of 'scaleProteinAsCdna' unless copying
441 ViewStyleI vs = selviews.get(0).getAlignViewport()
443 boolean fromSplitFrame = selviews.get(0)
444 .getAlignViewport().getCodingComplement() != null;
447 vs.setScaleProteinAsCdna(ap.getAlignViewport()
448 .getViewStyle().isScaleProteinAsCdna());
450 ap.getAlignViewport().setViewStyle(vs);
453 * Also rescale ViewStyle of SplitFrame complement if there is
454 * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy
455 * the whole ViewStyle (allow cDNA protein to have different
458 AlignViewportI complement = ap.getAlignViewport()
459 .getCodingComplement();
460 if (complement != null && vs.isScaleProteinAsCdna())
462 AlignFrame af = Desktop.getAlignFrameFor(complement);
463 ((SplitFrame) af.getSplitViewContainer())
465 af.setMenusForViewport();
469 ap.setSelected(true);
470 ap.alignFrame.setMenusForViewport();
475 if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase()
476 .indexOf("devel") > -1
477 || Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase()
478 .indexOf("test") > -1)
480 formatMenu.add(vsel);
482 addFocusListener(new FocusAdapter()
485 public void focusGained(FocusEvent e)
487 Jalview.setCurrentAlignFrame(AlignFrame.this);
493 private void buildHMMERMenu()
495 hmmerMenu.removeAll();
497 hmmerMenu.add(autoAlignSeqs);
498 hmmerMenu.addSeparator();
500 hmmerMenu.add(hmmAlign);
501 hmmerMenu.add(hmmBuild);
502 hmmerMenu.add(hmmSearch);
507 * Change the filename and format for the alignment, and enable the 'reload'
508 * button functionality.
515 public void setFileName(String file, FileFormatI format)
518 setFileFormat(format);
519 reload.setEnabled(true);
523 * Add a KeyListener with handlers for various KeyPressed and KeyReleased
526 void addKeyListener()
528 addKeyListener(new KeyAdapter()
531 public void keyPressed(KeyEvent evt)
533 if (viewport.cursorMode
534 && ((evt.getKeyCode() >= KeyEvent.VK_0 && evt.getKeyCode() <= KeyEvent.VK_9) || (evt
535 .getKeyCode() >= KeyEvent.VK_NUMPAD0 && evt
536 .getKeyCode() <= KeyEvent.VK_NUMPAD9))
537 && Character.isDigit(evt.getKeyChar()))
539 alignPanel.getSeqPanel().numberPressed(evt.getKeyChar());
542 switch (evt.getKeyCode())
545 case 27: // escape key
546 deselectAllSequenceMenuItem_actionPerformed(null);
550 case KeyEvent.VK_DOWN:
551 if (evt.isAltDown() || !viewport.cursorMode)
553 moveSelectedSequences(false);
555 if (viewport.cursorMode)
557 alignPanel.getSeqPanel().moveCursor(0, 1);
562 if (evt.isAltDown() || !viewport.cursorMode)
564 moveSelectedSequences(true);
566 if (viewport.cursorMode)
568 alignPanel.getSeqPanel().moveCursor(0, -1);
573 case KeyEvent.VK_LEFT:
574 if (evt.isAltDown() || !viewport.cursorMode)
576 slideSequences(false, alignPanel.getSeqPanel().getKeyboardNo1());
580 alignPanel.getSeqPanel().moveCursor(-1, 0);
585 case KeyEvent.VK_RIGHT:
586 if (evt.isAltDown() || !viewport.cursorMode)
588 slideSequences(true, alignPanel.getSeqPanel().getKeyboardNo1());
592 alignPanel.getSeqPanel().moveCursor(1, 0);
596 case KeyEvent.VK_SPACE:
597 if (viewport.cursorMode)
599 alignPanel.getSeqPanel().insertGapAtCursor(
600 evt.isControlDown() || evt.isShiftDown()
605 // case KeyEvent.VK_A:
606 // if (viewport.cursorMode)
608 // alignPanel.seqPanel.insertNucAtCursor(false,"A");
609 // //System.out.println("A");
613 * case KeyEvent.VK_CLOSE_BRACKET: if (viewport.cursorMode) {
614 * System.out.println("closing bracket"); } break;
616 case KeyEvent.VK_DELETE:
617 case KeyEvent.VK_BACK_SPACE:
618 if (!viewport.cursorMode)
620 cut_actionPerformed(null);
624 alignPanel.getSeqPanel().deleteGapAtCursor(
625 evt.isControlDown() || evt.isShiftDown()
632 if (viewport.cursorMode)
634 alignPanel.getSeqPanel().setCursorRow();
638 if (viewport.cursorMode && !evt.isControlDown())
640 alignPanel.getSeqPanel().setCursorColumn();
644 if (viewport.cursorMode)
646 alignPanel.getSeqPanel().setCursorPosition();
650 case KeyEvent.VK_ENTER:
651 case KeyEvent.VK_COMMA:
652 if (viewport.cursorMode)
654 alignPanel.getSeqPanel().setCursorRowAndColumn();
659 if (viewport.cursorMode)
661 alignPanel.getSeqPanel().setSelectionAreaAtCursor(true);
665 if (viewport.cursorMode)
667 alignPanel.getSeqPanel().setSelectionAreaAtCursor(false);
672 viewport.cursorMode = !viewport.cursorMode;
673 statusBar.setText(MessageManager.formatMessage(
674 "label.keyboard_editing_mode",
675 new String[] { (viewport.cursorMode ? "on" : "off") }));
676 if (viewport.cursorMode)
678 alignPanel.getSeqPanel().seqCanvas.cursorX = vpRanges
680 alignPanel.getSeqPanel().seqCanvas.cursorY = vpRanges
683 alignPanel.getSeqPanel().seqCanvas.repaint();
689 Help.showHelpWindow();
690 } catch (Exception ex)
692 ex.printStackTrace();
697 boolean toggleSeqs = !evt.isControlDown();
698 boolean toggleCols = !evt.isShiftDown();
699 toggleHiddenRegions(toggleSeqs, toggleCols);
704 boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
705 boolean modifyExisting = true; // always modify, don't clear
706 // evt.isShiftDown();
707 boolean invertHighlighted = evt.isAltDown();
708 avc.markHighlightedColumns(invertHighlighted, modifyExisting,
712 case KeyEvent.VK_PAGE_UP:
713 if (viewport.getWrapAlignment())
715 vpRanges.scrollUp(true);
722 case KeyEvent.VK_PAGE_DOWN:
723 if (viewport.getWrapAlignment())
725 vpRanges.scrollUp(false);
736 public void keyReleased(KeyEvent evt)
738 switch (evt.getKeyCode())
740 case KeyEvent.VK_LEFT:
741 if (evt.isAltDown() || !viewport.cursorMode)
743 viewport.firePropertyChange("alignment", null, viewport
744 .getAlignment().getSequences());
748 case KeyEvent.VK_RIGHT:
749 if (evt.isAltDown() || !viewport.cursorMode)
751 viewport.firePropertyChange("alignment", null, viewport
752 .getAlignment().getSequences());
760 public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
762 ap.alignFrame = this;
763 avc = new jalview.controller.AlignViewController(this, viewport,
768 PaintRefresher.Register(ap, ap.av.getSequenceSetId());
770 int aSize = alignPanels.size();
772 tabbedPane.setVisible(aSize > 1 || ap.av.viewName != null);
774 if (aSize == 1 && ap.av.viewName == null)
776 this.getContentPane().add(ap, BorderLayout.CENTER);
782 setInitialTabVisible();
785 expandViews.setEnabled(true);
786 gatherViews.setEnabled(true);
787 tabbedPane.addTab(ap.av.viewName, ap);
789 ap.setVisible(false);
794 if (ap.av.isPadGaps())
796 ap.av.getAlignment().padGaps();
798 ap.av.updateConservation(ap);
799 ap.av.updateConsensus(ap);
800 ap.av.updateStrucConsensus(ap);
804 public void setInitialTabVisible()
806 expandViews.setEnabled(true);
807 gatherViews.setEnabled(true);
808 tabbedPane.setVisible(true);
809 AlignmentPanel first = alignPanels.get(0);
810 tabbedPane.addTab(first.av.viewName, first);
811 this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
814 public AlignViewport getViewport()
819 /* Set up intrinsic listeners for dynamically generated GUI bits. */
820 private void addServiceListeners()
822 final java.beans.PropertyChangeListener thisListener;
823 Desktop.instance.addJalviewPropertyChangeListener("services",
824 thisListener = new java.beans.PropertyChangeListener()
827 public void propertyChange(PropertyChangeEvent evt)
829 // // System.out.println("Discoverer property change.");
830 // if (evt.getPropertyName().equals("services"))
832 SwingUtilities.invokeLater(new Runnable()
839 .println("Rebuild WS Menu for service change");
840 BuildWebServiceMenu();
847 addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
850 public void internalFrameClosed(
851 javax.swing.event.InternalFrameEvent evt)
853 // System.out.println("deregistering discoverer listener");
854 Desktop.instance.removeJalviewPropertyChangeListener("services",
856 closeMenuItem_actionPerformed(true);
859 // Finally, build the menu once to get current service state
860 new Thread(new Runnable()
865 BuildWebServiceMenu();
871 * Configure menu items that vary according to whether the alignment is
872 * nucleotide or protein
874 public void setGUINucleotide()
876 AlignmentI al = getViewport().getAlignment();
877 boolean nucleotide = al.isNucleotide();
879 showTranslation.setVisible(nucleotide);
880 showReverse.setVisible(nucleotide);
881 showReverseComplement.setVisible(nucleotide);
882 conservationMenuItem.setEnabled(!nucleotide);
883 modifyConservation.setEnabled(!nucleotide
884 && conservationMenuItem.isSelected());
885 showGroupConservation.setEnabled(!nucleotide);
887 showComplementMenuItem.setText(nucleotide ? MessageManager
888 .getString("label.protein") : MessageManager
889 .getString("label.nucleotide"));
893 * set up menus for the current viewport. This may be called after any
894 * operation that affects the data in the current view (selection changed,
895 * etc) to update the menus to reflect the new state.
898 public void setMenusForViewport()
900 setMenusFromViewport(viewport);
904 * Need to call this method when tabs are selected for multiple views, or when
905 * loading from Jalview2XML.java
910 void setMenusFromViewport(AlignViewport av)
912 padGapsMenuitem.setSelected(av.isPadGaps());
913 colourTextMenuItem.setSelected(av.isShowColourText());
914 abovePIDThreshold.setSelected(av.getAbovePIDThreshold());
915 modifyPID.setEnabled(abovePIDThreshold.isSelected());
916 conservationMenuItem.setSelected(av.getConservationSelected());
917 modifyConservation.setEnabled(conservationMenuItem.isSelected());
918 seqLimits.setSelected(av.getShowJVSuffix());
919 idRightAlign.setSelected(av.isRightAlignIds());
920 centreColumnLabelsMenuItem.setState(av.isCentreColumnLabels());
921 renderGapsMenuItem.setSelected(av.isRenderGaps());
922 wrapMenuItem.setSelected(av.getWrapAlignment());
923 scaleAbove.setVisible(av.getWrapAlignment());
924 scaleLeft.setVisible(av.getWrapAlignment());
925 scaleRight.setVisible(av.getWrapAlignment());
926 annotationPanelMenuItem.setState(av.isShowAnnotation());
928 * Show/hide annotations only enabled if annotation panel is shown
930 showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
931 hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
932 showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
933 hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
934 viewBoxesMenuItem.setSelected(av.getShowBoxes());
935 viewTextMenuItem.setSelected(av.getShowText());
936 showNonconservedMenuItem.setSelected(av.getShowUnconserved());
937 showGroupConsensus.setSelected(av.isShowGroupConsensus());
938 showGroupConservation.setSelected(av.isShowGroupConservation());
939 showConsensusHistogram.setSelected(av.isShowConsensusHistogram());
940 showSequenceLogo.setSelected(av.isShowSequenceLogo());
941 normaliseSequenceLogo.setSelected(av.isNormaliseSequenceLogo());
942 showInformationHistogram.setSelected(av.isShowInformationHistogram());
943 showHMMSequenceLogo.setSelected(av.isShowHMMSequenceLogo());
944 normaliseHMMSequenceLogo.setSelected(av.isNormaliseHMMSequenceLogo());
946 ColourMenuHelper.setColourSelected(colourMenu,
947 av.getGlobalColourScheme());
949 showSeqFeatures.setSelected(av.isShowSequenceFeatures());
950 hiddenMarkers.setState(av.getShowHiddenMarkers());
951 applyToAllGroups.setState(av.getColourAppliesToAllGroups());
952 showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
953 showDbRefsMenuitem.setSelected(av.isShowDBRefs());
954 autoCalculate.setSelected(av.autoCalculateConsensus);
955 sortByTree.setSelected(av.sortByTree);
956 listenToViewSelections.setSelected(av.followSelection);
958 showProducts.setEnabled(canShowProducts());
959 setGroovyEnabled(Desktop.getGroovyConsole() != null);
965 * Set the enabled state of the 'Run Groovy' option in the Calculate menu
969 public void setGroovyEnabled(boolean b)
971 runGroovy.setEnabled(b);
974 private IProgressIndicator progressBar;
979 * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
982 public void setProgressBar(String message, long id)
984 progressBar.setProgressBar(message, id);
988 public void registerHandler(final long id,
989 final IProgressIndicatorHandler handler)
991 progressBar.registerHandler(id, handler);
996 * @return true if any progress bars are still active
999 public boolean operationInProgress()
1001 return progressBar.operationInProgress();
1005 public void setStatus(String text)
1007 statusBar.setText(text);
1011 * Added so Castor Mapping file can obtain Jalview Version
1013 public String getVersion()
1015 return jalview.bin.Cache.getProperty("VERSION");
1018 public FeatureRenderer getFeatureRenderer()
1020 return alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer();
1024 public void fetchSequence_actionPerformed(ActionEvent e)
1026 new jalview.gui.SequenceFetcher(this);
1030 public void addFromFile_actionPerformed(ActionEvent e)
1032 Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
1036 public void reload_actionPerformed(ActionEvent e)
1038 if (fileName != null)
1040 // TODO: JAL-1108 - ensure all associated frames are closed regardless of
1041 // originating file's format
1042 // TODO: work out how to recover feature settings for correct view(s) when
1043 // file is reloaded.
1044 if (FileFormat.Jalview.equals(currentFileFormat))
1046 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1047 for (int i = 0; i < frames.length; i++)
1049 if (frames[i] instanceof AlignFrame && frames[i] != this
1050 && ((AlignFrame) frames[i]).fileName != null
1051 && ((AlignFrame) frames[i]).fileName.equals(fileName))
1055 frames[i].setSelected(true);
1056 Desktop.instance.closeAssociatedWindows();
1057 } catch (java.beans.PropertyVetoException ex)
1063 Desktop.instance.closeAssociatedWindows();
1065 FileLoader loader = new FileLoader();
1066 DataSourceType protocol = fileName.startsWith("http:") ? DataSourceType.URL
1067 : DataSourceType.FILE;
1068 loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
1072 Rectangle bounds = this.getBounds();
1074 FileLoader loader = new FileLoader();
1075 DataSourceType protocol = fileName.startsWith("http:") ? DataSourceType.URL
1076 : DataSourceType.FILE;
1077 AlignFrame newframe = loader.LoadFileWaitTillLoaded(fileName,
1078 protocol, currentFileFormat);
1080 newframe.setBounds(bounds);
1081 if (featureSettings != null && featureSettings.isShowing())
1083 final Rectangle fspos = featureSettings.frame.getBounds();
1084 // TODO: need a 'show feature settings' function that takes bounds -
1085 // need to refactor Desktop.addFrame
1086 newframe.featureSettings_actionPerformed(null);
1087 final FeatureSettings nfs = newframe.featureSettings;
1088 SwingUtilities.invokeLater(new Runnable()
1093 nfs.frame.setBounds(fspos);
1096 this.featureSettings.close();
1097 this.featureSettings = null;
1099 this.closeMenuItem_actionPerformed(true);
1105 public void addFromText_actionPerformed(ActionEvent e)
1107 Desktop.instance.inputTextboxMenuItem_actionPerformed(viewport
1112 public void addFromURL_actionPerformed(ActionEvent e)
1114 Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
1118 public void save_actionPerformed(ActionEvent e)
1120 if (fileName == null || (currentFileFormat == null)
1121 || fileName.startsWith("http"))
1123 saveAs_actionPerformed(null);
1127 saveAlignment(fileName, currentFileFormat);
1138 public void saveAs_actionPerformed(ActionEvent e)
1140 String format = currentFileFormat == null ? null : currentFileFormat
1142 JalviewFileChooser chooser = JalviewFileChooser.forWrite(
1143 Cache.getProperty("LAST_DIRECTORY"), format);
1145 chooser.setFileView(new JalviewFileView());
1146 chooser.setDialogTitle(MessageManager
1147 .getString("label.save_alignment_to_file"));
1148 chooser.setToolTipText(MessageManager.getString("action.save"));
1150 int value = chooser.showSaveDialog(this);
1152 if (value == JalviewFileChooser.APPROVE_OPTION)
1154 currentFileFormat = chooser.getSelectedFormat();
1155 while (currentFileFormat == null)
1158 .showInternalMessageDialog(
1161 .getString("label.select_file_format_before_saving"),
1163 .getString("label.file_format_not_specified"),
1164 JvOptionPane.WARNING_MESSAGE);
1165 currentFileFormat = chooser.getSelectedFormat();
1166 value = chooser.showSaveDialog(this);
1167 if (value != JalviewFileChooser.APPROVE_OPTION)
1173 fileName = chooser.getSelectedFile().getPath();
1175 Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
1177 Cache.setProperty("LAST_DIRECTORY", fileName);
1178 saveAlignment(fileName, currentFileFormat);
1182 public boolean saveAlignment(String file, FileFormatI format)
1184 boolean success = true;
1186 if (FileFormat.Jalview.equals(format))
1188 String shortName = title;
1190 if (shortName.indexOf(java.io.File.separatorChar) > -1)
1192 shortName = shortName.substring(shortName
1193 .lastIndexOf(java.io.File.separatorChar) + 1);
1196 success = new Jalview2XML().saveAlignment(this, file, shortName);
1198 statusBar.setText(MessageManager.formatMessage(
1199 "label.successfully_saved_to_file_in_format", new Object[] {
1200 fileName, format }));
1205 AlignmentExportData exportData = getAlignmentForExport(format,
1207 if (exportData.getSettings().isCancelled())
1211 FormatAdapter f = new FormatAdapter(alignPanel,
1212 exportData.getSettings());
1213 String output = f.formatSequences(
1215 exportData.getAlignment(), // class cast exceptions will
1216 // occur in the distant future
1217 exportData.getOmitHidden(), exportData.getStartEndPostions(),
1218 f.getCacheSuffixDefault(format), viewport.getAlignment()
1219 .getHiddenColumns());
1229 PrintWriter out = new PrintWriter(new FileWriter(file));
1233 this.setTitle(file);
1234 statusBar.setText(MessageManager.formatMessage(
1235 "label.successfully_saved_to_file_in_format",
1236 new Object[] { fileName, format.getName() }));
1237 } catch (Exception ex)
1240 ex.printStackTrace();
1247 JvOptionPane.showInternalMessageDialog(this, MessageManager
1248 .formatMessage("label.couldnt_save_file",
1249 new Object[] { fileName }), MessageManager
1250 .getString("label.error_saving_file"),
1251 JvOptionPane.WARNING_MESSAGE);
1257 private void warningMessage(String warning, String title)
1259 if (new jalview.util.Platform().isHeadless())
1261 System.err.println("Warning: " + title + "\nWarning: " + warning);
1266 JvOptionPane.showInternalMessageDialog(this, warning, title,
1267 JvOptionPane.WARNING_MESSAGE);
1279 protected void outputText_actionPerformed(ActionEvent e)
1281 FileFormatI fileFormat = FileFormats.getInstance().forName(
1282 e.getActionCommand());
1283 AlignmentExportData exportData = getAlignmentForExport(fileFormat,
1285 if (exportData.getSettings().isCancelled())
1289 CutAndPasteTransfer cap = new CutAndPasteTransfer();
1290 cap.setForInput(null);
1293 FileFormatI format = fileFormat;
1294 cap.setText(new FormatAdapter(alignPanel, exportData.getSettings())
1295 .formatSequences(format, exportData.getAlignment(),
1296 exportData.getOmitHidden(),
1298 .getStartEndPostions(), viewport
1299 .getAlignment().getHiddenColumns()));
1300 Desktop.addInternalFrame(cap, MessageManager.formatMessage(
1301 "label.alignment_output_command",
1302 new Object[] { e.getActionCommand() }), 600, 500);
1303 } catch (OutOfMemoryError oom)
1305 new OOMWarning("Outputting alignment as " + e.getActionCommand(), oom);
1311 public static AlignmentExportData getAlignmentForExport(
1312 FileFormatI format, AlignViewportI viewport,
1313 AlignExportSettingI exportSettings)
1315 AlignmentI alignmentToExport = null;
1316 AlignExportSettingI settings = exportSettings;
1317 String[] omitHidden = null;
1319 HiddenSequences hiddenSeqs = viewport.getAlignment()
1320 .getHiddenSequences();
1322 alignmentToExport = viewport.getAlignment();
1324 boolean hasHiddenSeqs = hiddenSeqs.getSize() > 0;
1325 if (settings == null)
1327 settings = new AlignExportSettings(hasHiddenSeqs,
1328 viewport.hasHiddenColumns(), format);
1330 // settings.isExportAnnotations();
1332 if (viewport.hasHiddenColumns() && !settings.isExportHiddenColumns())
1334 omitHidden = viewport.getViewAsString(false,
1335 settings.isExportHiddenSequences());
1338 int[] alignmentStartEnd = new int[2];
1339 if (hasHiddenSeqs && settings.isExportHiddenSequences())
1341 alignmentToExport = hiddenSeqs.getFullAlignment();
1345 alignmentToExport = viewport.getAlignment();
1347 alignmentStartEnd = alignmentToExport
1348 .getVisibleStartAndEndIndex(viewport.getAlignment()
1350 .getHiddenRegions());
1351 AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
1352 omitHidden, alignmentStartEnd, settings);
1363 protected void htmlMenuItem_actionPerformed(ActionEvent e)
1365 HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
1366 htmlSVG.exportHTML(null);
1370 public void bioJSMenuItem_actionPerformed(ActionEvent e)
1372 BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
1373 bjs.exportHTML(null);
1376 public void createImageMap(File file, String image)
1378 alignPanel.makePNGImageMap(file, image);
1388 public void createPNG(File f)
1390 alignPanel.makePNG(f);
1400 public void createEPS(File f)
1402 alignPanel.makeEPS(f);
1406 public void createSVG(File f)
1408 alignPanel.makeSVG(f);
1412 public void pageSetup_actionPerformed(ActionEvent e)
1414 PrinterJob printJob = PrinterJob.getPrinterJob();
1415 PrintThread.pf = printJob.pageDialog(printJob.defaultPage());
1425 public void printMenuItem_actionPerformed(ActionEvent e)
1427 // Putting in a thread avoids Swing painting problems
1428 PrintThread thread = new PrintThread(alignPanel);
1433 public void exportFeatures_actionPerformed(ActionEvent e)
1435 new AnnotationExporter().exportFeatures(alignPanel);
1439 public void exportAnnotations_actionPerformed(ActionEvent e)
1441 new AnnotationExporter().exportAnnotations(alignPanel);
1445 public void associatedData_actionPerformed(ActionEvent e)
1447 // Pick the tree file
1448 JalviewFileChooser chooser = new JalviewFileChooser(
1449 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
1450 chooser.setFileView(new JalviewFileView());
1451 chooser.setDialogTitle(MessageManager
1452 .getString("label.load_jalview_annotations"));
1453 chooser.setToolTipText(MessageManager
1454 .getString("label.load_jalview_annotations"));
1456 int value = chooser.showOpenDialog(null);
1458 if (value == JalviewFileChooser.APPROVE_OPTION)
1460 String choice = chooser.getSelectedFile().getPath();
1461 jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
1462 loadJalviewDataFile(choice, null, null, null);
1468 * Close the current view or all views in the alignment frame. If the frame
1469 * only contains one view then the alignment will be removed from memory.
1471 * @param closeAllTabs
1474 public void closeMenuItem_actionPerformed(boolean closeAllTabs)
1476 if (alignPanels != null && alignPanels.size() < 2)
1478 closeAllTabs = true;
1483 if (alignPanels != null)
1487 if (this.isClosed())
1489 // really close all the windows - otherwise wait till
1490 // setClosed(true) is called
1491 for (int i = 0; i < alignPanels.size(); i++)
1493 AlignmentPanel ap = alignPanels.get(i);
1500 closeView(alignPanel);
1507 * this will raise an INTERNAL_FRAME_CLOSED event and this method will
1508 * be called recursively, with the frame now in 'closed' state
1510 this.setClosed(true);
1512 } catch (Exception ex)
1514 ex.printStackTrace();
1519 * Close the specified panel and close up tabs appropriately.
1521 * @param panelToClose
1523 public void closeView(AlignmentPanel panelToClose)
1525 int index = tabbedPane.getSelectedIndex();
1526 int closedindex = tabbedPane.indexOfComponent(panelToClose);
1527 alignPanels.remove(panelToClose);
1528 panelToClose.closePanel();
1529 panelToClose = null;
1531 tabbedPane.removeTabAt(closedindex);
1532 tabbedPane.validate();
1534 if (index > closedindex || index == tabbedPane.getTabCount())
1536 // modify currently selected tab index if necessary.
1540 this.tabSelectionChanged(index);
1546 void updateEditMenuBar()
1549 if (viewport.getHistoryList().size() > 0)
1551 undoMenuItem.setEnabled(true);
1552 CommandI command = viewport.getHistoryList().peek();
1553 undoMenuItem.setText(MessageManager.formatMessage(
1554 "label.undo_command",
1555 new Object[] { command.getDescription() }));
1559 undoMenuItem.setEnabled(false);
1560 undoMenuItem.setText(MessageManager.getString("action.undo"));
1563 if (viewport.getRedoList().size() > 0)
1565 redoMenuItem.setEnabled(true);
1567 CommandI command = viewport.getRedoList().peek();
1568 redoMenuItem.setText(MessageManager.formatMessage(
1569 "label.redo_command",
1570 new Object[] { command.getDescription() }));
1574 redoMenuItem.setEnabled(false);
1575 redoMenuItem.setText(MessageManager.getString("action.redo"));
1580 public void addHistoryItem(CommandI command)
1582 if (command.getSize() > 0)
1584 viewport.addToHistoryList(command);
1585 viewport.clearRedoList();
1586 updateEditMenuBar();
1587 viewport.updateHiddenColumns();
1588 // viewport.hasHiddenColumns = (viewport.getColumnSelection() != null
1589 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1590 // viewport.getColumnSelection()
1591 // .getHiddenColumns().size() > 0);
1597 * @return alignment objects for all views
1599 AlignmentI[] getViewAlignments()
1601 if (alignPanels != null)
1603 AlignmentI[] als = new AlignmentI[alignPanels.size()];
1605 for (AlignmentPanel ap : alignPanels)
1607 als[i++] = ap.av.getAlignment();
1611 if (viewport != null)
1613 return new AlignmentI[] { viewport.getAlignment() };
1625 protected void undoMenuItem_actionPerformed(ActionEvent e)
1627 if (viewport.getHistoryList().isEmpty())
1631 CommandI command = viewport.getHistoryList().pop();
1632 viewport.addToRedoList(command);
1633 command.undoCommand(getViewAlignments());
1635 AlignmentViewport originalSource = getOriginatingSource(command);
1636 updateEditMenuBar();
1638 if (originalSource != null)
1640 if (originalSource != viewport)
1643 .warn("Implementation worry: mismatch of viewport origin for undo");
1645 originalSource.updateHiddenColumns();
1646 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1648 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1649 // viewport.getColumnSelection()
1650 // .getHiddenColumns().size() > 0);
1651 originalSource.firePropertyChange("alignment", null, originalSource
1652 .getAlignment().getSequences());
1663 protected void redoMenuItem_actionPerformed(ActionEvent e)
1665 if (viewport.getRedoList().size() < 1)
1670 CommandI command = viewport.getRedoList().pop();
1671 viewport.addToHistoryList(command);
1672 command.doCommand(getViewAlignments());
1674 AlignmentViewport originalSource = getOriginatingSource(command);
1675 updateEditMenuBar();
1677 if (originalSource != null)
1680 if (originalSource != viewport)
1683 .warn("Implementation worry: mismatch of viewport origin for redo");
1685 originalSource.updateHiddenColumns();
1686 // originalSource.hasHiddenColumns = (viewport.getColumnSelection() !=
1688 // && viewport.getColumnSelection().getHiddenColumns() != null &&
1689 // viewport.getColumnSelection()
1690 // .getHiddenColumns().size() > 0);
1691 originalSource.firePropertyChange("alignment", null, originalSource
1692 .getAlignment().getSequences());
1696 AlignmentViewport getOriginatingSource(CommandI command)
1698 AlignmentViewport originalSource = null;
1699 // For sequence removal and addition, we need to fire
1700 // the property change event FROM the viewport where the
1701 // original alignment was altered
1702 AlignmentI al = null;
1703 if (command instanceof EditCommand)
1705 EditCommand editCommand = (EditCommand) command;
1706 al = editCommand.getAlignment();
1707 List<Component> comps = PaintRefresher.components.get(viewport
1708 .getSequenceSetId());
1710 for (Component comp : comps)
1712 if (comp instanceof AlignmentPanel)
1714 if (al == ((AlignmentPanel) comp).av.getAlignment())
1716 originalSource = ((AlignmentPanel) comp).av;
1723 if (originalSource == null)
1725 // The original view is closed, we must validate
1726 // the current view against the closed view first
1729 PaintRefresher.validateSequences(al, viewport.getAlignment());
1732 originalSource = viewport;
1735 return originalSource;
1744 public void moveSelectedSequences(boolean up)
1746 SequenceGroup sg = viewport.getSelectionGroup();
1752 viewport.getAlignment().moveSelectedSequencesByOne(sg,
1753 viewport.getHiddenRepSequences(), up);
1754 alignPanel.paintAlignment(true);
1757 synchronized void slideSequences(boolean right, int size)
1759 List<SequenceI> sg = new ArrayList<>();
1760 if (viewport.cursorMode)
1762 sg.add(viewport.getAlignment().getSequenceAt(
1763 alignPanel.getSeqPanel().seqCanvas.cursorY));
1765 else if (viewport.getSelectionGroup() != null
1766 && viewport.getSelectionGroup().getSize() != viewport
1767 .getAlignment().getHeight())
1769 sg = viewport.getSelectionGroup().getSequences(
1770 viewport.getHiddenRepSequences());
1778 List<SequenceI> invertGroup = new ArrayList<>();
1780 for (SequenceI seq : viewport.getAlignment().getSequences())
1782 if (!sg.contains(seq))
1784 invertGroup.add(seq);
1788 SequenceI[] seqs1 = sg.toArray(new SequenceI[0]);
1790 SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1791 for (int i = 0; i < invertGroup.size(); i++)
1793 seqs2[i] = invertGroup.get(i);
1796 SlideSequencesCommand ssc;
1799 ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1,
1800 size, viewport.getGapCharacter());
1804 ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2,
1805 size, viewport.getGapCharacter());
1808 int groupAdjustment = 0;
1809 if (ssc.getGapsInsertedBegin() && right)
1811 if (viewport.cursorMode)
1813 alignPanel.getSeqPanel().moveCursor(size, 0);
1817 groupAdjustment = size;
1820 else if (!ssc.getGapsInsertedBegin() && !right)
1822 if (viewport.cursorMode)
1824 alignPanel.getSeqPanel().moveCursor(-size, 0);
1828 groupAdjustment = -size;
1832 if (groupAdjustment != 0)
1834 viewport.getSelectionGroup().setStartRes(
1835 viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1836 viewport.getSelectionGroup().setEndRes(
1837 viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1841 * just extend the last slide command if compatible; but not if in
1842 * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
1844 boolean appendHistoryItem = false;
1845 Deque<CommandI> historyList = viewport.getHistoryList();
1846 boolean inSplitFrame = getSplitViewContainer() != null;
1847 if (!inSplitFrame && historyList != null && historyList.size() > 0
1848 && historyList.peek() instanceof SlideSequencesCommand)
1850 appendHistoryItem = ssc
1851 .appendSlideCommand((SlideSequencesCommand) historyList
1855 if (!appendHistoryItem)
1857 addHistoryItem(ssc);
1870 protected void copy_actionPerformed(ActionEvent e)
1873 if (viewport.getSelectionGroup() == null)
1877 // TODO: preserve the ordering of displayed alignment annotation in any
1878 // internal paste (particularly sequence associated annotation)
1879 SequenceI[] seqs = viewport.getSelectionAsNewSequence();
1880 String[] omitHidden = null;
1882 if (viewport.hasHiddenColumns())
1884 omitHidden = viewport.getViewAsString(true);
1887 String output = new FormatAdapter().formatSequences(FileFormat.Fasta,
1888 seqs, omitHidden, null);
1890 StringSelection ss = new StringSelection(output);
1894 jalview.gui.Desktop.internalCopy = true;
1895 // Its really worth setting the clipboard contents
1896 // to empty before setting the large StringSelection!!
1897 Toolkit.getDefaultToolkit().getSystemClipboard()
1898 .setContents(new StringSelection(""), null);
1900 Toolkit.getDefaultToolkit().getSystemClipboard()
1901 .setContents(ss, Desktop.instance);
1902 } catch (OutOfMemoryError er)
1904 new OOMWarning("copying region", er);
1908 ArrayList<int[]> hiddenColumns = null;
1909 if (viewport.hasHiddenColumns())
1911 hiddenColumns = new ArrayList<>();
1912 int hiddenOffset = viewport.getSelectionGroup().getStartRes(), hiddenCutoff = viewport
1913 .getSelectionGroup().getEndRes();
1914 for (int[] region : viewport.getAlignment().getHiddenColumns()
1915 .getHiddenRegions())
1917 if (region[0] >= hiddenOffset && region[1] <= hiddenCutoff)
1919 hiddenColumns.add(new int[] { region[0] - hiddenOffset,
1920 region[1] - hiddenOffset });
1925 Desktop.jalviewClipboard = new Object[] { seqs,
1926 viewport.getAlignment().getDataset(), hiddenColumns };
1927 statusBar.setText(MessageManager.formatMessage(
1928 "label.copied_sequences_to_clipboard", new Object[] { Integer
1929 .valueOf(seqs.length).toString() }));
1939 protected void pasteNew_actionPerformed(ActionEvent e)
1951 protected void pasteThis_actionPerformed(ActionEvent e)
1957 * Paste contents of Jalview clipboard
1959 * @param newAlignment
1960 * true to paste to a new alignment, otherwise add to this.
1962 void paste(boolean newAlignment)
1964 boolean externalPaste = true;
1967 Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
1968 Transferable contents = c.getContents(this);
1970 if (contents == null)
1979 str = (String) contents.getTransferData(DataFlavor.stringFlavor);
1980 if (str.length() < 1)
1985 format = new IdentifyFile().identify(str, DataSourceType.PASTE);
1987 } catch (OutOfMemoryError er)
1989 new OOMWarning("Out of memory pasting sequences!!", er);
1993 SequenceI[] sequences;
1994 boolean annotationAdded = false;
1995 AlignmentI alignment = null;
1997 if (Desktop.jalviewClipboard != null)
1999 // The clipboard was filled from within Jalview, we must use the
2001 // And dataset from the copied alignment
2002 SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
2003 // be doubly sure that we create *new* sequence objects.
2004 sequences = new SequenceI[newseq.length];
2005 for (int i = 0; i < newseq.length; i++)
2007 sequences[i] = new Sequence(newseq[i]);
2009 alignment = new Alignment(sequences);
2010 externalPaste = false;
2014 // parse the clipboard as an alignment.
2015 alignment = new FormatAdapter().readFile(str, DataSourceType.PASTE,
2017 sequences = alignment.getSequencesArray();
2021 ArrayList<Integer> newGraphGroups = new ArrayList<>();
2027 if (Desktop.jalviewClipboard != null)
2029 // dataset is inherited
2030 alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
2034 // new dataset is constructed
2035 alignment.setDataset(null);
2037 alwidth = alignment.getWidth() + 1;
2041 AlignmentI pastedal = alignment; // preserve pasted alignment object
2042 // Add pasted sequences and dataset into existing alignment.
2043 alignment = viewport.getAlignment();
2044 alwidth = alignment.getWidth() + 1;
2045 // decide if we need to import sequences from an existing dataset
2046 boolean importDs = Desktop.jalviewClipboard != null
2047 && Desktop.jalviewClipboard[1] != alignment.getDataset();
2048 // importDs==true instructs us to copy over new dataset sequences from
2049 // an existing alignment
2050 Vector newDs = (importDs) ? new Vector() : null; // used to create
2051 // minimum dataset set
2053 for (int i = 0; i < sequences.length; i++)
2057 newDs.addElement(null);
2059 SequenceI ds = sequences[i].getDatasetSequence(); // null for a simple
2061 if (importDs && ds != null)
2063 if (!newDs.contains(ds))
2065 newDs.setElementAt(ds, i);
2066 ds = new Sequence(ds);
2067 // update with new dataset sequence
2068 sequences[i].setDatasetSequence(ds);
2072 ds = sequences[newDs.indexOf(ds)].getDatasetSequence();
2077 // copy and derive new dataset sequence
2078 sequences[i] = sequences[i].deriveSequence();
2079 alignment.getDataset().addSequence(
2080 sequences[i].getDatasetSequence());
2081 // TODO: avoid creation of duplicate dataset sequences with a
2082 // 'contains' method using SequenceI.equals()/SequenceI.contains()
2084 alignment.addSequence(sequences[i]); // merges dataset
2088 newDs.clear(); // tidy up
2090 if (alignment.getAlignmentAnnotation() != null)
2092 for (AlignmentAnnotation alan : alignment
2093 .getAlignmentAnnotation())
2095 if (alan.graphGroup > fgroup)
2097 fgroup = alan.graphGroup;
2101 if (pastedal.getAlignmentAnnotation() != null)
2103 // Add any annotation attached to alignment.
2104 AlignmentAnnotation[] alann = pastedal.getAlignmentAnnotation();
2105 for (int i = 0; i < alann.length; i++)
2107 annotationAdded = true;
2108 if (alann[i].sequenceRef == null && !alann[i].autoCalculated)
2110 AlignmentAnnotation newann = new AlignmentAnnotation(alann[i]);
2111 if (newann.graphGroup > -1)
2113 if (newGraphGroups.size() <= newann.graphGroup
2114 || newGraphGroups.get(newann.graphGroup) == null)
2116 for (int q = newGraphGroups.size(); q <= newann.graphGroup; q++)
2118 newGraphGroups.add(q, null);
2120 newGraphGroups.set(newann.graphGroup, new Integer(
2123 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2127 newann.padAnnotation(alwidth);
2128 alignment.addAnnotation(newann);
2138 addHistoryItem(new EditCommand(
2139 MessageManager.getString("label.add_sequences"),
2140 Action.PASTE, sequences, 0, alignment.getWidth(), alignment));
2142 // Add any annotations attached to sequences
2143 for (int i = 0; i < sequences.length; i++)
2145 if (sequences[i].getAnnotation() != null)
2147 AlignmentAnnotation newann;
2148 for (int a = 0; a < sequences[i].getAnnotation().length; a++)
2150 annotationAdded = true;
2151 newann = sequences[i].getAnnotation()[a];
2152 newann.adjustForAlignment();
2153 newann.padAnnotation(alwidth);
2154 if (newann.graphGroup > -1)
2156 if (newann.graphGroup > -1)
2158 if (newGraphGroups.size() <= newann.graphGroup
2159 || newGraphGroups.get(newann.graphGroup) == null)
2161 for (int q = newGraphGroups.size(); q <= newann.graphGroup; q++)
2163 newGraphGroups.add(q, null);
2165 newGraphGroups.set(newann.graphGroup, new Integer(
2168 newann.graphGroup = newGraphGroups.get(newann.graphGroup)
2172 alignment.addAnnotation(sequences[i].getAnnotation()[a]); // annotation
2177 .setAnnotationIndex(sequences[i].getAnnotation()[a], a);
2184 // propagate alignment changed.
2185 vpRanges.setEndSeq(alignment.getHeight());
2186 if (annotationAdded)
2188 // Duplicate sequence annotation in all views.
2189 AlignmentI[] alview = this.getViewAlignments();
2190 for (int i = 0; i < sequences.length; i++)
2192 AlignmentAnnotation sann[] = sequences[i].getAnnotation();
2197 for (int avnum = 0; avnum < alview.length; avnum++)
2199 if (alview[avnum] != alignment)
2201 // duplicate in a view other than the one with input focus
2202 int avwidth = alview[avnum].getWidth() + 1;
2203 // this relies on sann being preserved after we
2204 // modify the sequence's annotation array for each duplication
2205 for (int a = 0; a < sann.length; a++)
2207 AlignmentAnnotation newann = new AlignmentAnnotation(
2209 sequences[i].addAlignmentAnnotation(newann);
2210 newann.padAnnotation(avwidth);
2211 alview[avnum].addAnnotation(newann); // annotation was
2212 // duplicated earlier
2213 // TODO JAL-1145 graphGroups are not updated for sequence
2214 // annotation added to several views. This may cause
2216 alview[avnum].setAnnotationIndex(newann, a);
2221 buildSortByAnnotationScoresMenu();
2223 viewport.firePropertyChange("alignment", null,
2224 alignment.getSequences());
2225 if (alignPanels != null)
2227 for (AlignmentPanel ap : alignPanels)
2229 ap.validateAnnotationDimensions(false);
2234 alignPanel.validateAnnotationDimensions(false);
2240 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2242 String newtitle = new String("Copied sequences");
2244 if (Desktop.jalviewClipboard != null
2245 && Desktop.jalviewClipboard[2] != null)
2247 List<int[]> hc = (List<int[]>) Desktop.jalviewClipboard[2];
2248 for (int[] region : hc)
2250 af.viewport.hideColumns(region[0], region[1]);
2254 // >>>This is a fix for the moment, until a better solution is
2256 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2258 alignPanel.getSeqPanel().seqCanvas
2259 .getFeatureRenderer());
2261 // TODO: maintain provenance of an alignment, rather than just make the
2262 // title a concatenation of operations.
2265 if (title.startsWith("Copied sequences"))
2271 newtitle = newtitle.concat("- from " + title);
2276 newtitle = new String("Pasted sequences");
2279 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH,
2284 } catch (Exception ex)
2286 ex.printStackTrace();
2287 System.out.println("Exception whilst pasting: " + ex);
2288 // could be anything being pasted in here
2294 protected void expand_newalign(ActionEvent e)
2298 AlignmentI alignment = AlignmentUtils.expandContext(getViewport()
2299 .getAlignment(), -1);
2300 AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
2302 String newtitle = new String("Flanking alignment");
2304 if (Desktop.jalviewClipboard != null
2305 && Desktop.jalviewClipboard[2] != null)
2307 List<int[]> hc = (List<int[]>) Desktop.jalviewClipboard[2];
2308 for (int region[] : hc)
2310 af.viewport.hideColumns(region[0], region[1]);
2314 // >>>This is a fix for the moment, until a better solution is
2316 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
2318 alignPanel.getSeqPanel().seqCanvas
2319 .getFeatureRenderer());
2321 // TODO: maintain provenance of an alignment, rather than just make the
2322 // title a concatenation of operations.
2324 if (title.startsWith("Copied sequences"))
2330 newtitle = newtitle.concat("- from " + title);
2334 Desktop.addInternalFrame(af, newtitle, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2336 } catch (Exception ex)
2338 ex.printStackTrace();
2339 System.out.println("Exception whilst pasting: " + ex);
2340 // could be anything being pasted in here
2341 } catch (OutOfMemoryError oom)
2343 new OOMWarning("Viewing flanking region of alignment", oom);
2354 protected void cut_actionPerformed(ActionEvent e)
2356 copy_actionPerformed(null);
2357 delete_actionPerformed(null);
2367 protected void delete_actionPerformed(ActionEvent evt)
2370 SequenceGroup sg = viewport.getSelectionGroup();
2377 * If the cut affects all sequences, warn, remove highlighted columns
2379 if (sg.getSize() == viewport.getAlignment().getHeight())
2381 boolean isEntireAlignWidth = (((sg.getEndRes() - sg.getStartRes()) + 1) == viewport
2382 .getAlignment().getWidth()) ? true : false;
2383 if (isEntireAlignWidth)
2385 int confirm = JvOptionPane.showConfirmDialog(this,
2386 MessageManager.getString("warn.delete_all"), // $NON-NLS-1$
2387 MessageManager.getString("label.delete_all"), // $NON-NLS-1$
2388 JvOptionPane.OK_CANCEL_OPTION);
2390 if (confirm == JvOptionPane.CANCEL_OPTION
2391 || confirm == JvOptionPane.CLOSED_OPTION)
2396 viewport.getColumnSelection().removeElements(sg.getStartRes(),
2397 sg.getEndRes() + 1);
2399 SequenceI[] cut = sg.getSequences()
2400 .toArray(new SequenceI[sg.getSize()]);
2402 addHistoryItem(new EditCommand(
2403 MessageManager.getString("label.cut_sequences"), Action.CUT,
2404 cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
2405 viewport.getAlignment()));
2407 viewport.setSelectionGroup(null);
2408 viewport.sendSelection();
2409 viewport.getAlignment().deleteGroup(sg);
2411 viewport.firePropertyChange("alignment", null, viewport.getAlignment()
2413 if (viewport.getAlignment().getHeight() < 1)
2417 this.setClosed(true);
2418 } catch (Exception ex)
2431 protected void deleteGroups_actionPerformed(ActionEvent e)
2433 if (avc.deleteGroups())
2435 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
2436 alignPanel.updateAnnotation();
2437 alignPanel.paintAlignment(true);
2448 public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2450 SequenceGroup sg = new SequenceGroup();
2452 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2454 sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
2457 sg.setEndRes(viewport.getAlignment().getWidth() - 1);
2458 viewport.setSelectionGroup(sg);
2459 viewport.sendSelection();
2460 // JAL-2034 - should delegate to
2461 // alignPanel to decide if overview needs
2463 alignPanel.paintAlignment(false);
2464 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2474 public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
2476 if (viewport.cursorMode)
2478 alignPanel.getSeqPanel().keyboardNo1 = null;
2479 alignPanel.getSeqPanel().keyboardNo2 = null;
2481 viewport.setSelectionGroup(null);
2482 viewport.getColumnSelection().clear();
2483 viewport.setSelectionGroup(null);
2484 alignPanel.getSeqPanel().seqCanvas.highlightSearchResults(null);
2485 alignPanel.getIdPanel().getIdCanvas().searchResults = null;
2486 // JAL-2034 - should delegate to
2487 // alignPanel to decide if overview needs
2489 alignPanel.paintAlignment(false);
2490 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2491 viewport.sendSelection();
2501 public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
2503 SequenceGroup sg = viewport.getSelectionGroup();
2507 selectAllSequenceMenuItem_actionPerformed(null);
2512 for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2514 sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
2516 // JAL-2034 - should delegate to
2517 // alignPanel to decide if overview needs
2520 alignPanel.paintAlignment(true);
2521 PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
2522 viewport.sendSelection();
2526 public void invertColSel_actionPerformed(ActionEvent e)
2528 viewport.invertColumnSelection();
2529 alignPanel.paintAlignment(true);
2530 viewport.sendSelection();
2540 public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
2542 trimAlignment(true);
2552 public void remove2RightMenuItem_actionPerformed(ActionEvent e)
2554 trimAlignment(false);
2557 void trimAlignment(boolean trimLeft)
2559 ColumnSelection colSel = viewport.getColumnSelection();
2562 if (!colSel.isEmpty())
2566 column = colSel.getMin();
2570 column = colSel.getMax();
2574 if (viewport.getSelectionGroup() != null)
2576 seqs = viewport.getSelectionGroup().getSequencesAsArray(
2577 viewport.getHiddenRepSequences());
2581 seqs = viewport.getAlignment().getSequencesArray();
2584 TrimRegionCommand trimRegion;
2587 trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
2588 column, viewport.getAlignment());
2589 vpRanges.setStartRes(0);
2593 trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
2594 column, viewport.getAlignment());
2597 statusBar.setText(MessageManager.formatMessage(
2598 "label.removed_columns",
2599 new String[] { Integer.valueOf(trimRegion.getSize())
2602 addHistoryItem(trimRegion);
2604 for (SequenceGroup sg : viewport.getAlignment().getGroups())
2606 if ((trimLeft && !sg.adjustForRemoveLeft(column))
2607 || (!trimLeft && !sg.adjustForRemoveRight(column)))
2609 viewport.getAlignment().deleteGroup(sg);
2613 viewport.firePropertyChange("alignment", null, viewport
2614 .getAlignment().getSequences());
2625 public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
2627 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2630 if (viewport.getSelectionGroup() != null)
2632 seqs = viewport.getSelectionGroup().getSequencesAsArray(
2633 viewport.getHiddenRepSequences());
2634 start = viewport.getSelectionGroup().getStartRes();
2635 end = viewport.getSelectionGroup().getEndRes();
2639 seqs = viewport.getAlignment().getSequencesArray();
2642 RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
2643 "Remove Gapped Columns", seqs, start, end,
2644 viewport.getAlignment());
2646 addHistoryItem(removeGapCols);
2648 statusBar.setText(MessageManager.formatMessage(
2649 "label.removed_empty_columns",
2650 new Object[] { Integer.valueOf(removeGapCols.getSize())
2653 // This is to maintain viewport position on first residue
2654 // of first sequence
2655 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2656 int startRes = seq.findPosition(vpRanges.getStartRes());
2657 // ShiftList shifts;
2658 // viewport.getAlignment().removeGaps(shifts=new ShiftList());
2659 // edit.alColumnChanges=shifts.getInverse();
2660 // if (viewport.hasHiddenColumns)
2661 // viewport.getColumnSelection().compensateForEdits(shifts);
2662 vpRanges.setStartRes(seq.findIndex(startRes) - 1);
2663 viewport.firePropertyChange("alignment", null, viewport.getAlignment()
2675 public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
2677 int start = 0, end = viewport.getAlignment().getWidth() - 1;
2680 if (viewport.getSelectionGroup() != null)
2682 seqs = viewport.getSelectionGroup().getSequencesAsArray(
2683 viewport.getHiddenRepSequences());
2684 start = viewport.getSelectionGroup().getStartRes();
2685 end = viewport.getSelectionGroup().getEndRes();
2689 seqs = viewport.getAlignment().getSequencesArray();
2692 // This is to maintain viewport position on first residue
2693 // of first sequence
2694 SequenceI seq = viewport.getAlignment().getSequenceAt(0);
2695 int startRes = seq.findPosition(vpRanges.getStartRes());
2697 addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
2698 viewport.getAlignment()));
2700 vpRanges.setStartRes(seq.findIndex(startRes) - 1);
2702 viewport.firePropertyChange("alignment", null, viewport.getAlignment()
2714 public void padGapsMenuitem_actionPerformed(ActionEvent e)
2716 viewport.setPadGaps(padGapsMenuitem.isSelected());
2717 viewport.firePropertyChange("alignment", null, viewport.getAlignment()
2728 public void findMenuItem_actionPerformed(ActionEvent e)
2734 * Create a new view of the current alignment.
2737 public void newView_actionPerformed(ActionEvent e)
2739 newView(null, true);
2743 * Creates and shows a new view of the current alignment.
2746 * title of newly created view; if null, one will be generated
2747 * @param copyAnnotation
2748 * if true then duplicate all annnotation, groups and settings
2749 * @return new alignment panel, already displayed.
2751 public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
2754 * Create a new AlignmentPanel (with its own, new Viewport)
2756 AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel,
2758 if (!copyAnnotation)
2761 * remove all groups and annotation except for the automatic stuff
2763 newap.av.getAlignment().deleteAllGroups();
2764 newap.av.getAlignment().deleteAllAnnotations(false);
2767 newap.av.setGatherViewsHere(false);
2769 if (viewport.viewName == null)
2771 viewport.viewName = MessageManager
2772 .getString("label.view_name_original");
2776 * Views share the same edits undo and redo stacks
2778 newap.av.setHistoryList(viewport.getHistoryList());
2779 newap.av.setRedoList(viewport.getRedoList());
2782 * Views share the same mappings; need to deregister any new mappings
2783 * created by copyAlignPanel, and register the new reference to the shared
2786 newap.av.replaceMappings(viewport.getAlignment());
2789 * start up cDNA consensus (if applicable) now mappings are in place
2791 if (newap.av.initComplementConsensus())
2793 newap.refresh(true); // adjust layout of annotations
2796 newap.av.viewName = getNewViewName(viewTitle);
2798 addAlignmentPanel(newap, true);
2799 newap.alignmentChanged();
2801 if (alignPanels.size() == 2)
2803 viewport.setGatherViewsHere(true);
2805 tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);
2810 * Make a new name for the view, ensuring it is unique within the current
2811 * sequenceSetId. (This used to be essential for Jalview Project archives, but
2812 * these now use viewId. Unique view names are still desirable for usability.)
2817 protected String getNewViewName(String viewTitle)
2819 int index = Desktop.getViewCount(viewport.getSequenceSetId());
2820 boolean addFirstIndex = false;
2821 if (viewTitle == null || viewTitle.trim().length() == 0)
2823 viewTitle = MessageManager.getString("action.view");
2824 addFirstIndex = true;
2828 index = 1;// we count from 1 if given a specific name
2830 String newViewName = viewTitle + ((addFirstIndex) ? " " + index : "");
2832 List<Component> comps = PaintRefresher.components.get(viewport
2833 .getSequenceSetId());
2835 List<String> existingNames = getExistingViewNames(comps);
2837 while (existingNames.contains(newViewName))
2839 newViewName = viewTitle + " " + (++index);
2845 * Returns a list of distinct view names found in the given list of
2846 * components. View names are held on the viewport of an AlignmentPanel.
2851 protected List<String> getExistingViewNames(List<Component> comps)
2853 List<String> existingNames = new ArrayList<>();
2854 for (Component comp : comps)
2856 if (comp instanceof AlignmentPanel)
2858 AlignmentPanel ap = (AlignmentPanel) comp;
2859 if (!existingNames.contains(ap.av.viewName))
2861 existingNames.add(ap.av.viewName);
2865 return existingNames;
2869 * Explode tabbed views into separate windows.
2872 public void expandViews_actionPerformed(ActionEvent e)
2874 Desktop.explodeViews(this);
2878 * Gather views in separate windows back into a tabbed presentation.
2881 public void gatherViews_actionPerformed(ActionEvent e)
2883 Desktop.instance.gatherViews(this);
2893 public void font_actionPerformed(ActionEvent e)
2895 new FontChooser(alignPanel);
2905 protected void seqLimit_actionPerformed(ActionEvent e)
2907 viewport.setShowJVSuffix(seqLimits.isSelected());
2909 alignPanel.getIdPanel().getIdCanvas()
2910 .setPreferredSize(alignPanel.calculateIdWidth());
2911 alignPanel.paintAlignment(true);
2915 public void idRightAlign_actionPerformed(ActionEvent e)
2917 viewport.setRightAlignIds(idRightAlign.isSelected());
2918 alignPanel.paintAlignment(true);
2922 public void centreColumnLabels_actionPerformed(ActionEvent e)
2924 viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
2925 alignPanel.paintAlignment(true);
2931 * @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
2934 protected void followHighlight_actionPerformed()
2937 * Set the 'follow' flag on the Viewport (and scroll to position if now
2940 final boolean state = this.followHighlightMenuItem.getState();
2941 viewport.setFollowHighlight(state);
2944 alignPanel.scrollToPosition(viewport.getSearchResults(), false);
2955 protected void colourTextMenuItem_actionPerformed(ActionEvent e)
2957 viewport.setColourText(colourTextMenuItem.isSelected());
2958 alignPanel.paintAlignment(true);
2968 public void wrapMenuItem_actionPerformed(ActionEvent e)
2970 scaleAbove.setVisible(wrapMenuItem.isSelected());
2971 scaleLeft.setVisible(wrapMenuItem.isSelected());
2972 scaleRight.setVisible(wrapMenuItem.isSelected());
2973 viewport.setWrapAlignment(wrapMenuItem.isSelected());
2974 alignPanel.updateLayout();
2978 public void showAllSeqs_actionPerformed(ActionEvent e)
2980 viewport.showAllHiddenSeqs();
2984 public void showAllColumns_actionPerformed(ActionEvent e)
2986 viewport.showAllHiddenColumns();
2988 viewport.sendSelection();
2992 public void hideSelSequences_actionPerformed(ActionEvent e)
2994 viewport.hideAllSelectedSeqs();
2995 // alignPanel.paintAlignment(true);
2999 * called by key handler and the hide all/show all menu items
3004 private void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
3007 boolean hide = false;
3008 SequenceGroup sg = viewport.getSelectionGroup();
3009 if (!toggleSeqs && !toggleCols)
3011 // Hide everything by the current selection - this is a hack - we do the
3012 // invert and then hide
3013 // first check that there will be visible columns after the invert.
3014 if (viewport.hasSelectedColumns()
3015 || (sg != null && sg.getSize() > 0 && sg.getStartRes() <= sg
3018 // now invert the sequence set, if required - empty selection implies
3019 // that no hiding is required.
3022 invertSequenceMenuItem_actionPerformed(null);
3023 sg = viewport.getSelectionGroup();
3027 viewport.expandColSelection(sg, true);
3028 // finally invert the column selection and get the new sequence
3030 invertColSel_actionPerformed(null);
3037 if (sg != null && sg.getSize() != viewport.getAlignment().getHeight())
3039 hideSelSequences_actionPerformed(null);
3042 else if (!(toggleCols && viewport.hasSelectedColumns()))
3044 showAllSeqs_actionPerformed(null);
3050 if (viewport.hasSelectedColumns())
3052 hideSelColumns_actionPerformed(null);
3055 viewport.setSelectionGroup(sg);
3060 showAllColumns_actionPerformed(null);
3069 * jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
3070 * event.ActionEvent)
3073 public void hideAllButSelection_actionPerformed(ActionEvent e)
3075 toggleHiddenRegions(false, false);
3076 viewport.sendSelection();
3083 * jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
3087 public void hideAllSelection_actionPerformed(ActionEvent e)
3089 SequenceGroup sg = viewport.getSelectionGroup();
3090 viewport.expandColSelection(sg, false);
3091 viewport.hideAllSelectedSeqs();
3092 viewport.hideSelectedColumns();
3093 alignPanel.paintAlignment(true);
3094 viewport.sendSelection();
3101 * jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
3105 public void showAllhidden_actionPerformed(ActionEvent e)
3107 viewport.showAllHiddenColumns();
3108 viewport.showAllHiddenSeqs();
3109 alignPanel.paintAlignment(true);
3110 viewport.sendSelection();
3114 public void hideSelColumns_actionPerformed(ActionEvent e)
3116 viewport.hideSelectedColumns();
3117 alignPanel.paintAlignment(true);
3118 viewport.sendSelection();
3122 public void hiddenMarkers_actionPerformed(ActionEvent e)
3124 viewport.setShowHiddenMarkers(hiddenMarkers.isSelected());
3135 protected void scaleAbove_actionPerformed(ActionEvent e)
3137 viewport.setScaleAboveWrapped(scaleAbove.isSelected());
3138 alignPanel.paintAlignment(true);
3148 protected void scaleLeft_actionPerformed(ActionEvent e)
3150 viewport.setScaleLeftWrapped(scaleLeft.isSelected());
3151 alignPanel.paintAlignment(true);
3161 protected void scaleRight_actionPerformed(ActionEvent e)
3163 viewport.setScaleRightWrapped(scaleRight.isSelected());
3164 alignPanel.paintAlignment(true);
3174 public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
3176 viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
3177 alignPanel.paintAlignment(true);
3187 public void viewTextMenuItem_actionPerformed(ActionEvent e)
3189 viewport.setShowText(viewTextMenuItem.isSelected());
3190 alignPanel.paintAlignment(true);
3200 protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
3202 viewport.setRenderGaps(renderGapsMenuItem.isSelected());
3203 alignPanel.paintAlignment(true);
3206 public FeatureSettings featureSettings;
3209 public FeatureSettingsControllerI getFeatureSettingsUI()
3211 return featureSettings;
3215 public void featureSettings_actionPerformed(ActionEvent e)
3217 if (featureSettings != null)
3219 featureSettings.close();
3220 featureSettings = null;
3222 if (!showSeqFeatures.isSelected())
3224 // make sure features are actually displayed
3225 showSeqFeatures.setSelected(true);
3226 showSeqFeatures_actionPerformed(null);
3228 featureSettings = new FeatureSettings(this);
3232 * Set or clear 'Show Sequence Features'
3238 public void showSeqFeatures_actionPerformed(ActionEvent evt)
3240 viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
3241 alignPanel.paintAlignment(true);
3242 if (alignPanel.getOverviewPanel() != null)
3244 alignPanel.getOverviewPanel().updateOverviewImage();
3249 * Action on toggle of the 'Show annotations' menu item. This shows or hides
3250 * the annotations panel as a whole.
3252 * The options to show/hide all annotations should be enabled when the panel
3253 * is shown, and disabled when the panel is hidden.
3258 public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
3260 final boolean setVisible = annotationPanelMenuItem.isSelected();
3261 viewport.setShowAnnotation(setVisible);
3262 this.showAllSeqAnnotations.setEnabled(setVisible);
3263 this.hideAllSeqAnnotations.setEnabled(setVisible);
3264 this.showAllAlAnnotations.setEnabled(setVisible);
3265 this.hideAllAlAnnotations.setEnabled(setVisible);
3266 alignPanel.updateLayout();
3270 public void alignmentProperties()
3272 JEditorPane editPane = new JEditorPane("text/html", "");
3273 editPane.setEditable(false);
3274 StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
3276 editPane.setText(MessageManager.formatMessage("label.html_content",
3277 new Object[] { contents.toString() }));
3278 JInternalFrame frame = new JInternalFrame();
3279 frame.getContentPane().add(new JScrollPane(editPane));
3281 Desktop.addInternalFrame(frame, MessageManager.formatMessage(
3282 "label.alignment_properties", new Object[] { getTitle() }),
3293 public void overviewMenuItem_actionPerformed(ActionEvent e)
3295 if (alignPanel.overviewPanel != null)
3300 JInternalFrame frame = new JInternalFrame();
3301 OverviewPanel overview = new OverviewPanel(alignPanel);
3302 frame.setContentPane(overview);
3303 Desktop.addInternalFrame(frame, MessageManager.formatMessage(
3304 "label.overview_params", new Object[] { this.getTitle() }),
3305 true, frame.getWidth(), frame.getHeight(), true, true);
3307 frame.setLayer(JLayeredPane.PALETTE_LAYER);
3308 frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
3311 public void internalFrameClosed(
3312 javax.swing.event.InternalFrameEvent evt)
3314 alignPanel.setOverviewPanel(null);
3318 alignPanel.setOverviewPanel(overview);
3322 public void textColour_actionPerformed()
3324 new TextColourChooser().chooseColour(alignPanel, null);
3328 * public void covariationColour_actionPerformed() {
3330 * CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
3334 public void annotationColour_actionPerformed()
3336 new AnnotationColourChooser(viewport, alignPanel);
3340 public void annotationColumn_actionPerformed(ActionEvent e)
3342 new AnnotationColumnChooser(viewport, alignPanel);
3346 * Action on the user checking or unchecking the option to apply the selected
3347 * colour scheme to all groups. If unchecked, groups may have their own
3348 * independent colour schemes.
3353 public void applyToAllGroups_actionPerformed(boolean selected)
3355 viewport.setColourAppliesToAllGroups(selected);
3359 * Action on user selecting a colour from the colour menu
3362 * the name (not the menu item label!) of the colour scheme
3365 public void changeColour_actionPerformed(String name)
3368 * 'User Defined' opens a panel to configure or load a
3369 * user-defined colour scheme
3371 if (ResidueColourScheme.USER_DEFINED.equals(name))
3373 new UserDefinedColours(alignPanel);
3378 * otherwise set the chosen colour scheme (or null for 'None')
3380 ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
3381 viewport.getAlignment(), viewport.getHiddenRepSequences());
3386 * Actions on setting or changing the alignment colour scheme
3391 public void changeColour(ColourSchemeI cs)
3393 // TODO: pull up to controller method
3394 ColourMenuHelper.setColourSelected(colourMenu, cs);
3396 viewport.setGlobalColourScheme(cs);
3398 alignPanel.paintAlignment(true);
3402 * Show the PID threshold slider panel
3405 protected void modifyPID_actionPerformed()
3407 SliderPanel.setPIDSliderSource(alignPanel,
3408 viewport.getResidueShading(), alignPanel.getViewName());
3409 SliderPanel.showPIDSlider();
3413 * Show the Conservation slider panel
3416 protected void modifyConservation_actionPerformed()
3418 SliderPanel.setConservationSlider(alignPanel,
3419 viewport.getResidueShading(), alignPanel.getViewName());
3420 SliderPanel.showConservationSlider();
3424 * Action on selecting or deselecting (Colour) By Conservation
3427 public void conservationMenuItem_actionPerformed(boolean selected)
3429 modifyConservation.setEnabled(selected);
3430 viewport.setConservationSelected(selected);
3431 viewport.getResidueShading().setConservationApplied(selected);
3433 changeColour(viewport.getGlobalColourScheme());
3436 modifyConservation_actionPerformed();
3440 SliderPanel.hideConservationSlider();
3445 * Action on selecting or deselecting (Colour) Above PID Threshold
3448 public void abovePIDThreshold_actionPerformed(boolean selected)
3450 modifyPID.setEnabled(selected);
3451 viewport.setAbovePIDThreshold(selected);
3454 viewport.getResidueShading().setThreshold(0,
3455 viewport.isIgnoreGapsConsensus());
3458 changeColour(viewport.getGlobalColourScheme());
3461 modifyPID_actionPerformed();
3465 SliderPanel.hidePIDSlider();
3476 public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
3478 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3479 AlignmentSorter.sortByPID(viewport.getAlignment(), viewport
3480 .getAlignment().getSequenceAt(0));
3481 addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
3482 viewport.getAlignment()));
3483 alignPanel.paintAlignment(true);
3493 public void sortIDMenuItem_actionPerformed(ActionEvent e)
3495 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3496 AlignmentSorter.sortByID(viewport.getAlignment());
3497 addHistoryItem(new OrderCommand("ID Sort", oldOrder,
3498 viewport.getAlignment()));
3499 alignPanel.paintAlignment(true);
3509 public void sortLengthMenuItem_actionPerformed(ActionEvent e)
3511 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3512 AlignmentSorter.sortByLength(viewport.getAlignment());
3513 addHistoryItem(new OrderCommand("Length Sort", oldOrder,
3514 viewport.getAlignment()));
3515 alignPanel.paintAlignment(true);
3525 public void sortGroupMenuItem_actionPerformed(ActionEvent e)
3527 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3528 AlignmentSorter.sortByGroup(viewport.getAlignment());
3529 addHistoryItem(new OrderCommand("Group Sort", oldOrder,
3530 viewport.getAlignment()));
3532 alignPanel.paintAlignment(true);
3542 public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
3544 new RedundancyPanel(alignPanel, this);
3554 public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
3556 if ((viewport.getSelectionGroup() == null)
3557 || (viewport.getSelectionGroup().getSize() < 2))
3559 JvOptionPane.showInternalMessageDialog(this, MessageManager
3560 .getString("label.you_must_select_least_two_sequences"),
3561 MessageManager.getString("label.invalid_selection"),
3562 JvOptionPane.WARNING_MESSAGE);
3566 JInternalFrame frame = new JInternalFrame();
3567 frame.setContentPane(new PairwiseAlignPanel(viewport));
3568 Desktop.addInternalFrame(frame,
3569 MessageManager.getString("action.pairwise_alignment"), 600,
3575 public void autoCalculate_actionPerformed(ActionEvent e)
3577 viewport.autoCalculateConsensus = autoCalculate.isSelected();
3578 if (viewport.autoCalculateConsensus)
3580 viewport.firePropertyChange("alignment", null, viewport
3581 .getAlignment().getSequences());
3586 public void sortByTreeOption_actionPerformed(ActionEvent e)
3588 viewport.sortByTree = sortByTree.isSelected();
3592 protected void listenToViewSelections_actionPerformed(ActionEvent e)
3594 viewport.followSelection = listenToViewSelections.isSelected();
3598 * Constructs a tree panel and adds it to the desktop
3601 * tree type (NJ or AV)
3603 * name of score model used to compute the tree
3605 * parameters for the distance or similarity calculation
3607 void newTreePanel(String type, String modelName, SimilarityParamsI options)
3609 String frameTitle = "";
3612 boolean onSelection = false;
3613 if (viewport.getSelectionGroup() != null
3614 && viewport.getSelectionGroup().getSize() > 0)
3616 SequenceGroup sg = viewport.getSelectionGroup();
3618 /* Decide if the selection is a column region */
3619 for (SequenceI _s : sg.getSequences())
3621 if (_s.getLength() < sg.getEndRes())
3627 .getString("label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
3629 .getString("label.sequences_selection_not_aligned"),
3630 JvOptionPane.WARNING_MESSAGE);
3639 if (viewport.getAlignment().getHeight() < 2)
3645 tp = new TreePanel(alignPanel, type, modelName, options);
3646 frameTitle = tp.getPanelTitle() + (onSelection ? " on region" : "");
3648 frameTitle += " from ";
3650 if (viewport.viewName != null)
3652 frameTitle += viewport.viewName + " of ";
3655 frameTitle += this.title;
3657 Desktop.addInternalFrame(tp, frameTitle, 600, 500);
3668 public void addSortByOrderMenuItem(String title,
3669 final AlignmentOrder order)
3671 final JMenuItem item = new JMenuItem(MessageManager.formatMessage(
3672 "action.by_title_param", new Object[] { title }));
3674 item.addActionListener(new java.awt.event.ActionListener()
3677 public void actionPerformed(ActionEvent e)
3679 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3681 // TODO: JBPNote - have to map order entries to curent SequenceI
3683 AlignmentSorter.sortBy(viewport.getAlignment(), order);
3685 addHistoryItem(new OrderCommand(order.getName(), oldOrder, viewport
3688 alignPanel.paintAlignment(true);
3694 * Add a new sort by annotation score menu item
3697 * the menu to add the option to
3699 * the label used to retrieve scores for each sequence on the
3702 public void addSortByAnnotScoreMenuItem(JMenu sort,
3703 final String scoreLabel)
3705 final JMenuItem item = new JMenuItem(scoreLabel);
3707 item.addActionListener(new java.awt.event.ActionListener()
3710 public void actionPerformed(ActionEvent e)
3712 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3713 AlignmentSorter.sortByAnnotationScore(scoreLabel,
3714 viewport.getAlignment());// ,viewport.getSelectionGroup());
3715 addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
3716 viewport.getAlignment()));
3717 alignPanel.paintAlignment(true);
3723 * last hash for alignment's annotation array - used to minimise cost of
3726 protected int _annotationScoreVectorHash;
3729 * search the alignment and rebuild the sort by annotation score submenu the
3730 * last alignment annotation vector hash is stored to minimize cost of
3731 * rebuilding in subsequence calls.
3735 public void buildSortByAnnotationScoresMenu()
3737 if (viewport.getAlignment().getAlignmentAnnotation() == null)
3742 if (viewport.getAlignment().getAlignmentAnnotation().hashCode() != _annotationScoreVectorHash)
3744 sortByAnnotScore.removeAll();
3745 // almost certainly a quicker way to do this - but we keep it simple
3746 Hashtable scoreSorts = new Hashtable();
3747 AlignmentAnnotation aann[];
3748 for (SequenceI sqa : viewport.getAlignment().getSequences())
3750 aann = sqa.getAnnotation();
3751 for (int i = 0; aann != null && i < aann.length; i++)
3753 if (aann[i].hasScore() && aann[i].sequenceRef != null)
3755 scoreSorts.put(aann[i].label, aann[i].label);
3759 Enumeration labels = scoreSorts.keys();
3760 while (labels.hasMoreElements())
3762 addSortByAnnotScoreMenuItem(sortByAnnotScore,
3763 (String) labels.nextElement());
3765 sortByAnnotScore.setVisible(scoreSorts.size() > 0);
3768 _annotationScoreVectorHash = viewport.getAlignment()
3769 .getAlignmentAnnotation().hashCode();
3774 * Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
3775 * TreePanel with an appropriate <code>jalview.analysis.AlignmentSorter</code>
3776 * call. Listeners are added to remove the menu item when the treePanel is
3777 * closed, and adjust the tree leaf to sequence mapping when the alignment is
3781 public void buildTreeSortMenu()
3783 sortByTreeMenu.removeAll();
3785 List<Component> comps = PaintRefresher.components.get(viewport
3786 .getSequenceSetId());
3787 List<TreePanel> treePanels = new ArrayList<>();
3788 for (Component comp : comps)
3790 if (comp instanceof TreePanel)
3792 treePanels.add((TreePanel) comp);
3796 if (treePanels.size() < 1)
3798 sortByTreeMenu.setVisible(false);
3802 sortByTreeMenu.setVisible(true);
3804 for (final TreePanel tp : treePanels)
3806 final JMenuItem item = new JMenuItem(tp.getTitle());
3807 item.addActionListener(new java.awt.event.ActionListener()
3810 public void actionPerformed(ActionEvent e)
3812 tp.sortByTree_actionPerformed();
3813 addHistoryItem(tp.sortAlignmentIn(alignPanel));
3818 sortByTreeMenu.add(item);
3822 public boolean sortBy(AlignmentOrder alorder, String undoname)
3824 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
3825 AlignmentSorter.sortBy(viewport.getAlignment(), alorder);
3826 if (undoname != null)
3828 addHistoryItem(new OrderCommand(undoname, oldOrder,
3829 viewport.getAlignment()));
3831 alignPanel.paintAlignment(true);
3836 * Work out whether the whole set of sequences or just the selected set will
3837 * be submitted for multiple alignment.
3840 public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
3842 // Now, check we have enough sequences
3843 AlignmentView msa = null;
3845 if ((viewport.getSelectionGroup() != null)
3846 && (viewport.getSelectionGroup().getSize() > 1))
3848 // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to
3849 // some common interface!
3851 * SequenceGroup seqs = viewport.getSelectionGroup(); int sz; msa = new
3852 * SequenceI[sz = seqs.getSize(false)];
3854 * for (int i = 0; i < sz; i++) { msa[i] = (SequenceI)
3855 * seqs.getSequenceAt(i); }
3857 msa = viewport.getAlignmentView(true);
3859 else if (viewport.getSelectionGroup() != null
3860 && viewport.getSelectionGroup().getSize() == 1)
3862 int option = JvOptionPane.showConfirmDialog(this,
3863 MessageManager.getString("warn.oneseq_msainput_selection"),
3864 MessageManager.getString("label.invalid_selection"),
3865 JvOptionPane.OK_CANCEL_OPTION);
3866 if (option == JvOptionPane.OK_OPTION)
3868 msa = viewport.getAlignmentView(false);
3873 msa = viewport.getAlignmentView(false);
3879 * Decides what is submitted to a secondary structure prediction service: the
3880 * first sequence in the alignment, or in the current selection, or, if the
3881 * alignment is 'aligned' (ie padded with gaps), then the currently selected
3882 * region or the whole alignment. (where the first sequence in the set is the
3883 * one that the prediction will be for).
3885 public AlignmentView gatherSeqOrMsaForSecStrPrediction()
3887 AlignmentView seqs = null;
3889 if ((viewport.getSelectionGroup() != null)
3890 && (viewport.getSelectionGroup().getSize() > 0))
3892 seqs = viewport.getAlignmentView(true);
3896 seqs = viewport.getAlignmentView(false);
3898 // limit sequences - JBPNote in future - could spawn multiple prediction
3900 // TODO: viewport.getAlignment().isAligned is a global state - the local
3901 // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
3902 if (!viewport.getAlignment().isAligned(false))
3904 seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
3905 // TODO: if seqs.getSequences().length>1 then should really have warned
3919 protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
3921 // Pick the tree file
3922 JalviewFileChooser chooser = new JalviewFileChooser(
3923 jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
3924 chooser.setFileView(new JalviewFileView());
3925 chooser.setDialogTitle(MessageManager
3926 .getString("label.select_newick_like_tree_file"));
3927 chooser.setToolTipText(MessageManager.getString("label.load_tree_file"));
3929 int value = chooser.showOpenDialog(null);
3931 if (value == JalviewFileChooser.APPROVE_OPTION)
3933 String filePath = chooser.getSelectedFile().getPath();
3934 Cache.setProperty("LAST_DIRECTORY", filePath);
3935 NewickFile fin = null;
3938 fin = new NewickFile(filePath, DataSourceType.FILE);
3939 viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
3940 } catch (Exception ex)
3947 .getString("label.problem_reading_tree_file"),
3948 JvOptionPane.WARNING_MESSAGE);
3949 ex.printStackTrace();
3951 if (fin != null && fin.hasWarningMessage())
3953 JvOptionPane.showMessageDialog(Desktop.desktop, fin
3954 .getWarningMessage(), MessageManager
3955 .getString("label.possible_problem_with_tree_file"),
3956 JvOptionPane.WARNING_MESSAGE);
3961 public TreePanel showNewickTree(NewickFile nf, String treeTitle)
3963 return showNewickTree(nf, treeTitle, 600, 500, 4, 5);
3966 public TreePanel showNewickTree(NewickFile nf, String treeTitle, int w,
3967 int h, int x, int y)
3969 return showNewickTree(nf, treeTitle, null, w, h, x, y);
3973 * Add a treeviewer for the tree extracted from a Newick file object to the
3974 * current alignment view
3981 * Associated alignment input data (or null)
3990 * @return TreePanel handle
3992 public TreePanel showNewickTree(NewickFile nf, String treeTitle,
3993 AlignmentView input, int w, int h, int x, int y)
3995 TreePanel tp = null;
4001 if (nf.getTree() != null)
4003 tp = new TreePanel(alignPanel, nf, treeTitle, input);
4009 tp.setLocation(x, y);
4012 Desktop.addInternalFrame(tp, treeTitle, w, h);
4014 } catch (Exception ex)
4016 ex.printStackTrace();
4022 private boolean buildingMenu = false;
4025 * Generates menu items and listener event actions for web service clients
4028 public void BuildWebServiceMenu()
4030 while (buildingMenu)
4034 System.err.println("Waiting for building menu to finish.");
4036 } catch (Exception e)
4040 final AlignFrame me = this;
4041 buildingMenu = true;
4042 new Thread(new Runnable()
4047 final List<JMenuItem> legacyItems = new ArrayList<>();
4050 // System.err.println("Building ws menu again "
4051 // + Thread.currentThread());
4052 // TODO: add support for context dependent disabling of services based
4054 // alignment and current selection
4055 // TODO: add additional serviceHandle parameter to specify abstract
4057 // class independently of AbstractName
4058 // TODO: add in rediscovery GUI function to restart discoverer
4059 // TODO: group services by location as well as function and/or
4061 // object broker mechanism.
4062 final Vector<JMenu> wsmenu = new Vector<>();
4063 final IProgressIndicator af = me;
4066 * do not i18n these strings - they are hard-coded in class
4067 * compbio.data.msa.Category, Jws2Discoverer.isRecalculable() and
4068 * SequenceAnnotationWSClient.initSequenceAnnotationWSClient()
4070 final JMenu msawsmenu = new JMenu("Alignment");
4071 final JMenu secstrmenu = new JMenu(
4072 "Secondary Structure Prediction");
4073 final JMenu seqsrchmenu = new JMenu("Sequence Database Search");
4074 final JMenu analymenu = new JMenu("Analysis");
4075 final JMenu dismenu = new JMenu("Protein Disorder");
4076 // JAL-940 - only show secondary structure prediction services from
4077 // the legacy server
4078 if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
4080 Discoverer.services != null && (Discoverer.services.size() > 0))
4082 // TODO: refactor to allow list of AbstractName/Handler bindings to
4084 // stored or retrieved from elsewhere
4085 // No MSAWS used any more:
4086 // Vector msaws = null; // (Vector)
4087 // Discoverer.services.get("MsaWS");
4088 Vector secstrpr = (Vector) Discoverer.services
4090 if (secstrpr != null)
4092 // Add any secondary structure prediction services
4093 for (int i = 0, j = secstrpr.size(); i < j; i++)
4095 final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) secstrpr
4097 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
4098 .getServiceClient(sh);
4099 int p = secstrmenu.getItemCount();
4100 impl.attachWSMenuEntry(secstrmenu, me);
4101 int q = secstrmenu.getItemCount();
4102 for (int litm = p; litm < q; litm++)
4104 legacyItems.add(secstrmenu.getItem(litm));
4110 // Add all submenus in the order they should appear on the web
4112 wsmenu.add(msawsmenu);
4113 wsmenu.add(secstrmenu);
4114 wsmenu.add(dismenu);
4115 wsmenu.add(analymenu);
4116 // No search services yet
4117 // wsmenu.add(seqsrchmenu);
4119 javax.swing.SwingUtilities.invokeLater(new Runnable()
4126 webService.removeAll();
4127 // first, add discovered services onto the webservices menu
4128 if (wsmenu.size() > 0)
4130 for (int i = 0, j = wsmenu.size(); i < j; i++)
4132 webService.add(wsmenu.get(i));
4137 webService.add(me.webServiceNoServices);
4139 // TODO: move into separate menu builder class.
4140 boolean new_sspred = false;
4141 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
4143 Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
4144 if (jws2servs != null)
4146 if (jws2servs.hasServices())
4148 jws2servs.attachWSMenuEntry(webService, me);
4149 for (Jws2Instance sv : jws2servs.getServices())
4151 if (sv.description.toLowerCase().contains("jpred"))
4153 for (JMenuItem jmi : legacyItems)
4155 jmi.setVisible(false);
4161 if (jws2servs.isRunning())
4163 JMenuItem tm = new JMenuItem(
4164 "Still discovering JABA Services");
4165 tm.setEnabled(false);
4170 build_urlServiceMenu(me.webService);
4171 build_fetchdbmenu(webService);
4172 for (JMenu item : wsmenu)
4174 if (item.getItemCount() == 0)
4176 item.setEnabled(false);
4180 item.setEnabled(true);
4183 } catch (Exception e)
4186 .debug("Exception during web service menu building process.",
4191 } catch (Exception e)
4194 buildingMenu = false;
4201 * construct any groupURL type service menu entries.
4205 private void build_urlServiceMenu(JMenu webService)
4207 // TODO: remove this code when 2.7 is released
4208 // DEBUG - alignmentView
4210 * JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
4211 * AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
4213 * @Override public void actionPerformed(ActionEvent e) {
4214 * jalview.datamodel.AlignmentView
4215 * .testSelectionViews(af.viewport.getAlignment(),
4216 * af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
4218 * }); webService.add(testAlView);
4220 // TODO: refactor to RestClient discoverer and merge menu entries for
4221 // rest-style services with other types of analysis/calculation service
4222 // SHmmr test client - still being implemented.
4223 // DEBUG - alignmentView
4225 for (jalview.ws.rest.RestClient client : jalview.ws.rest.RestClient
4228 client.attachWSMenuEntry(
4229 JvSwingUtils.findOrCreateMenu(webService, client.getAction()),
4235 * Searches the alignment sequences for xRefs and builds the Show
4236 * Cross-References menu (formerly called Show Products), with database
4237 * sources for which cross-references are found (protein sources for a
4238 * nucleotide alignment and vice versa)
4240 * @return true if Show Cross-references menu should be enabled
4242 public boolean canShowProducts()
4244 SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
4245 AlignmentI dataset = viewport.getAlignment().getDataset();
4247 showProducts.removeAll();
4248 final boolean dna = viewport.getAlignment().isNucleotide();
4250 if (seqs == null || seqs.length == 0)
4252 // nothing to see here.
4256 boolean showp = false;
4259 List<String> ptypes = new CrossRef(seqs, dataset)
4260 .findXrefSourcesForSequences(dna);
4262 for (final String source : ptypes)
4265 final AlignFrame af = this;
4266 JMenuItem xtype = new JMenuItem(source);
4267 xtype.addActionListener(new ActionListener()
4270 public void actionPerformed(ActionEvent e)
4272 showProductsFor(af.viewport.getSequenceSelection(), dna, source);
4275 showProducts.add(xtype);
4277 showProducts.setVisible(showp);
4278 showProducts.setEnabled(showp);
4279 } catch (Exception e)
4282 .warn("canShowProducts threw an exception - please report to help@jalview.org",
4290 * Finds and displays cross-references for the selected sequences (protein
4291 * products for nucleotide sequences, dna coding sequences for peptides).
4294 * the sequences to show cross-references for
4296 * true if from a nucleotide alignment (so showing proteins)
4298 * the database to show cross-references for
4300 protected void showProductsFor(final SequenceI[] sel,
4301 final boolean _odna, final String source)
4303 new Thread(CrossRefAction.showProductsFor(sel, _odna, source, this))
4308 * Construct and display a new frame containing the translation of this
4309 * frame's DNA sequences to their aligned protein (amino acid) equivalents.
4312 public void showTranslation_actionPerformed(ActionEvent e)
4314 AlignmentI al = null;
4317 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
4319 al = dna.translateCdna();
4320 } catch (Exception ex)
4322 jalview.bin.Cache.log.error(
4323 "Exception during translation. Please report this !", ex);
4324 final String msg = MessageManager
4325 .getString("label.error_when_translating_sequences_submit_bug_report");
4326 final String errorTitle = MessageManager
4327 .getString("label.implementation_error")
4328 + MessageManager.getString("label.translation_failed");
4329 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4330 JvOptionPane.ERROR_MESSAGE);
4333 if (al == null || al.getHeight() == 0)
4335 final String msg = MessageManager
4336 .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
4337 final String errorTitle = MessageManager
4338 .getString("label.translation_failed");
4339 JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
4340 JvOptionPane.WARNING_MESSAGE);
4344 AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
4345 af.setFileFormat(this.currentFileFormat);
4346 final String newTitle = MessageManager.formatMessage(
4347 "label.translation_of_params",
4348 new Object[] { this.getTitle() });
4349 af.setTitle(newTitle);
4350 if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
4352 final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
4353 viewport.openSplitFrame(af, new Alignment(seqs));
4357 Desktop.addInternalFrame(af, newTitle, DEFAULT_WIDTH,
4364 * Set the file format
4368 public void setFileFormat(FileFormatI format)
4370 this.currentFileFormat = format;
4374 * Try to load a features file onto the alignment.
4377 * contents or path to retrieve file
4379 * access mode of file (see jalview.io.AlignFile)
4380 * @return true if features file was parsed correctly.
4382 public boolean parseFeaturesFile(String file, DataSourceType sourceType)
4384 return avc.parseFeaturesFile(file, sourceType,
4385 Cache.getDefault("RELAXEDSEQIDMATCHING", false));
4390 public void refreshFeatureUI(boolean enableIfNecessary)
4392 // note - currently this is only still here rather than in the controller
4393 // because of the featureSettings hard reference that is yet to be
4395 if (enableIfNecessary)
4397 viewport.setShowSequenceFeatures(true);
4398 showSeqFeatures.setSelected(true);
4404 public void dragEnter(DropTargetDragEvent evt)
4409 public void dragExit(DropTargetEvent evt)
4414 public void dragOver(DropTargetDragEvent evt)
4419 public void dropActionChanged(DropTargetDragEvent evt)
4424 public void drop(DropTargetDropEvent evt)
4426 // JAL-1552 - acceptDrop required before getTransferable call for
4427 // Java's Transferable for native dnd
4428 evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
4429 Transferable t = evt.getTransferable();
4430 List<String> files = new ArrayList<>();
4431 List<DataSourceType> protocols = new ArrayList<>();
4435 Desktop.transferFromDropTarget(files, protocols, evt, t);
4436 } catch (Exception e)
4438 e.printStackTrace();
4444 // check to see if any of these files have names matching sequences in
4446 SequenceIdMatcher idm = new SequenceIdMatcher(viewport
4447 .getAlignment().getSequencesArray());
4449 * Object[] { String,SequenceI}
4451 ArrayList<Object[]> filesmatched = new ArrayList<>();
4452 ArrayList<String> filesnotmatched = new ArrayList<>();
4453 for (int i = 0; i < files.size(); i++)
4455 String file = files.get(i).toString();
4457 DataSourceType protocol = FormatAdapter.checkProtocol(file);
4458 if (protocol == DataSourceType.FILE)
4460 File fl = new File(file);
4461 pdbfn = fl.getName();
4463 else if (protocol == DataSourceType.URL)
4465 URL url = new URL(file);
4466 pdbfn = url.getFile();
4468 if (pdbfn.length() > 0)
4470 // attempt to find a match in the alignment
4471 SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
4472 int l = 0, c = pdbfn.indexOf(".");
4473 while (mtch == null && c != -1)
4478 } while ((c = pdbfn.indexOf(".", l)) > l);
4481 pdbfn = pdbfn.substring(0, l);
4483 mtch = idm.findAllIdMatches(pdbfn);
4487 FileFormatI type = null;
4490 type = new IdentifyFile().identify(file, protocol);
4491 } catch (Exception ex)
4495 if (type != null && type.isStructureFile())
4497 filesmatched.add(new Object[] { file, protocol, mtch });
4501 // File wasn't named like one of the sequences or wasn't a PDB file.
4502 filesnotmatched.add(file);
4506 if (filesmatched.size() > 0)
4508 if (Cache.getDefault("AUTOASSOCIATE_PDBANDSEQS", false)
4514 "label.automatically_associate_structure_files_with_sequences_same_name",
4515 new Object[] { Integer
4521 .getString("label.automatically_associate_structure_files_by_name"),
4522 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION)
4525 for (Object[] fm : filesmatched)
4527 // try and associate
4528 // TODO: may want to set a standard ID naming formalism for
4529 // associating PDB files which have no IDs.
4530 for (SequenceI toassoc : (SequenceI[]) fm[2])
4532 PDBEntry pe = new AssociatePdbFileWithSeq()
4533 .associatePdbWithSeq((String) fm[0],
4534 (DataSourceType) fm[1], toassoc, false,
4538 System.err.println("Associated file : "
4539 + ((String) fm[0]) + " with "
4540 + toassoc.getDisplayId(true));
4544 alignPanel.paintAlignment(true);
4548 if (filesnotmatched.size() > 0)
4551 && (Cache.getDefault(
4552 "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false) || JvOptionPane
4558 "label.ignore_unmatched_dropped_files_info",
4559 new Object[] { Integer
4566 .getString("label.ignore_unmatched_dropped_files"),
4567 JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
4571 for (String fn : filesnotmatched)
4573 loadJalviewDataFile(fn, null, null, null);
4577 } catch (Exception ex)
4579 ex.printStackTrace();
4585 * Attempt to load a "dropped" file or URL string, by testing in turn for
4587 * <li>an Annotation file</li>
4588 * <li>a JNet file</li>
4589 * <li>a features file</li>
4590 * <li>else try to interpret as an alignment file</li>
4594 * either a filename or a URL string.
4596 public void loadJalviewDataFile(String file, DataSourceType sourceType,
4597 FileFormatI format, SequenceI assocSeq)
4601 if (sourceType == null)
4603 sourceType = FormatAdapter.checkProtocol(file);
4605 // if the file isn't identified, or not positively identified as some
4606 // other filetype (PFAM is default unidentified alignment file type) then
4607 // try to parse as annotation.
4608 boolean isAnnotation = (format == null || FileFormat.Pfam
4609 .equals(format)) ? new AnnotationFile()
4610 .annotateAlignmentView(viewport, file, sourceType) : false;
4614 // first see if its a T-COFFEE score file
4615 TCoffeeScoreFile tcf = null;
4618 tcf = new TCoffeeScoreFile(file, sourceType);
4621 if (tcf.annotateAlignment(viewport.getAlignment(), true))
4624 changeColour(new TCoffeeColourScheme(viewport.getAlignment()));
4625 isAnnotation = true;
4627 .setText(MessageManager
4628 .getString("label.successfully_pasted_tcoffee_scores_to_alignment"));
4632 // some problem - if no warning its probable that the ID matching
4633 // process didn't work
4637 tcf.getWarningMessage() == null ? MessageManager
4638 .getString("label.check_file_matches_sequence_ids_alignment")
4639 : tcf.getWarningMessage(),
4641 .getString("label.problem_reading_tcoffee_score_file"),
4642 JvOptionPane.WARNING_MESSAGE);
4649 } catch (Exception x)
4652 .debug("Exception when processing data source as T-COFFEE score file",
4658 // try to see if its a JNet 'concise' style annotation file *before*
4660 // try to parse it as a features file
4663 format = new IdentifyFile().identify(file, sourceType);
4665 if (FileFormat.ScoreMatrix == format)
4667 ScoreMatrixFile sm = new ScoreMatrixFile(new FileParse(file,
4670 // todo: i18n this message
4672 .setText(MessageManager.formatMessage(
4673 "label.successfully_loaded_matrix",
4674 sm.getMatrixName()));
4676 else if (FileFormat.HMMER3.equals(format))
4678 HMMFile hmmFile = new HMMFile(new FileParse(file, sourceType)); // TODO
4685 HiddenMarkovModel hmm = hmmFile.getHMM();
4686 AlignmentAnnotation annotation = hmm.createAnnotation(
4687 getViewport().getAlignment().getWidth());
4688 getViewport().getAlignment().addAnnotation(annotation);
4689 annotation.setHMM(hmm);
4690 int length = getViewport().getAlignment().getWidth();
4691 Sequence consensus = hmm.getConsensusSequence(length);
4692 SequenceI[] consensusArr = new Sequence[] { consensus };
4693 AlignmentI newAlignment = new Alignment(consensusArr);
4694 newAlignment.append(getViewport().getAlignment());
4695 getViewport().setAlignment(newAlignment);
4696 isAnnotation = true;
4697 alignPanel.repaint();
4700 else if (FileFormat.Jnet.equals(format))
4702 JPredFile predictions = new JPredFile(file, sourceType);
4703 new JnetAnnotationMaker();
4704 JnetAnnotationMaker.add_annotation(predictions,
4705 viewport.getAlignment(), 0, false);
4706 SequenceI repseq = viewport.getAlignment().getSequenceAt(0);
4707 viewport.getAlignment().setSeqrep(repseq);
4708 HiddenColumns cs = new HiddenColumns();
4709 cs.hideInsertionsFor(repseq);
4710 viewport.getAlignment().setHiddenColumns(cs);
4711 isAnnotation = true;
4713 // else if (IdentifyFile.FeaturesFile.equals(format))
4714 else if (FileFormat.Features.equals(format))
4716 if (parseFeaturesFile(file, sourceType))
4718 alignPanel.paintAlignment(true);
4723 new FileLoader().LoadFile(viewport, file, sourceType, format);
4730 alignPanel.adjustAnnotationHeight();
4731 viewport.updateSequenceIdColours();
4732 buildSortByAnnotationScoresMenu();
4733 alignPanel.paintAlignment(true);
4735 } catch (Exception ex)
4737 ex.printStackTrace();
4738 } catch (OutOfMemoryError oom)
4743 } catch (Exception x)
4748 + (sourceType != null ? (sourceType == DataSourceType.PASTE ? "from clipboard."
4749 : "using " + sourceType + " from " + file)
4751 + (format != null ? "(parsing as '" + format
4752 + "' file)" : ""), oom, Desktop.desktop);
4757 * Method invoked by the ChangeListener on the tabbed pane, in other words
4758 * when a different tabbed pane is selected by the user or programmatically.
4761 public void tabSelectionChanged(int index)
4765 alignPanel = alignPanels.get(index);
4766 viewport = alignPanel.av;
4767 avc.setViewportAndAlignmentPanel(viewport, alignPanel);
4768 setMenusFromViewport(viewport);
4772 * 'focus' any colour slider that is open to the selected viewport
4774 if (viewport.getConservationSelected())
4776 SliderPanel.setConservationSlider(alignPanel,
4777 viewport.getResidueShading(), alignPanel.getViewName());
4781 SliderPanel.hideConservationSlider();
4783 if (viewport.getAbovePIDThreshold())
4785 SliderPanel.setPIDSliderSource(alignPanel,
4786 viewport.getResidueShading(), alignPanel.getViewName());
4790 SliderPanel.hidePIDSlider();
4794 * If there is a frame linked to this one in a SplitPane, switch it to the
4795 * same view tab index. No infinite recursion of calls should happen, since
4796 * tabSelectionChanged() should not get invoked on setting the selected
4797 * index to an unchanged value. Guard against setting an invalid index
4798 * before the new view peer tab has been created.
4800 final AlignViewportI peer = viewport.getCodingComplement();
4803 AlignFrame linkedAlignFrame = ((AlignViewport) peer).getAlignPanel().alignFrame;
4804 if (linkedAlignFrame.tabbedPane.getTabCount() > index)
4806 linkedAlignFrame.tabbedPane.setSelectedIndex(index);
4812 * On right mouse click on view tab, prompt for and set new view name.
4815 public void tabbedPane_mousePressed(MouseEvent e)
4817 if (e.isPopupTrigger())
4819 String msg = MessageManager.getString("label.enter_view_name");
4820 String reply = JvOptionPane.showInternalInputDialog(this, msg, msg,
4821 JvOptionPane.QUESTION_MESSAGE);
4825 viewport.viewName = reply;
4826 // TODO warn if reply is in getExistingViewNames()?
4827 tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
4832 public AlignViewport getCurrentView()
4838 * Open the dialog for regex description parsing.
4841 protected void extractScores_actionPerformed(ActionEvent e)
4843 ParseProperties pp = new jalview.analysis.ParseProperties(
4844 viewport.getAlignment());
4845 // TODO: verify regex and introduce GUI dialog for version 2.5
4846 // if (pp.getScoresFromDescription("col", "score column ",
4847 // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
4849 if (pp.getScoresFromDescription("description column",
4850 "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
4852 buildSortByAnnotationScoresMenu();
4860 * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
4864 protected void showDbRefs_actionPerformed(ActionEvent e)
4866 viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
4872 * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
4876 protected void showNpFeats_actionPerformed(ActionEvent e)
4878 viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
4882 * find the viewport amongst the tabs in this alignment frame and close that
4887 public boolean closeView(AlignViewportI av)
4891 this.closeMenuItem_actionPerformed(false);
4894 Component[] comp = tabbedPane.getComponents();
4895 for (int i = 0; comp != null && i < comp.length; i++)
4897 if (comp[i] instanceof AlignmentPanel)
4899 if (((AlignmentPanel) comp[i]).av == av)
4902 closeView((AlignmentPanel) comp[i]);
4910 protected void build_fetchdbmenu(JMenu webService)
4912 // Temporary hack - DBRef Fetcher always top level ws entry.
4913 // TODO We probably want to store a sequence database checklist in
4914 // preferences and have checkboxes.. rather than individual sources selected
4916 final JMenu rfetch = new JMenu(
4917 MessageManager.getString("action.fetch_db_references"));
4918 rfetch.setToolTipText(MessageManager
4919 .getString("label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
4920 webService.add(rfetch);
4922 final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
4923 MessageManager.getString("option.trim_retrieved_seqs"));
4924 trimrs.setToolTipText(MessageManager
4925 .getString("label.trim_retrieved_sequences"));
4926 trimrs.setSelected(Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true));
4927 trimrs.addActionListener(new ActionListener()
4930 public void actionPerformed(ActionEvent e)
4932 trimrs.setSelected(trimrs.isSelected());
4933 Cache.setProperty("TRIM_FETCHED_DATASET_SEQS",
4934 Boolean.valueOf(trimrs.isSelected()).toString());
4938 JMenuItem fetchr = new JMenuItem(
4939 MessageManager.getString("label.standard_databases"));
4940 fetchr.setToolTipText(MessageManager
4941 .getString("label.fetch_embl_uniprot"));
4942 fetchr.addActionListener(new ActionListener()
4946 public void actionPerformed(ActionEvent e)
4948 new Thread(new Runnable()
4953 boolean isNucleotide = alignPanel.alignFrame.getViewport()
4954 .getAlignment().isNucleotide();
4955 DBRefFetcher dbRefFetcher = new DBRefFetcher(alignPanel.av
4956 .getSequenceSelection(), alignPanel.alignFrame, null,
4957 alignPanel.alignFrame.featureSettings, isNucleotide);
4958 dbRefFetcher.addListener(new FetchFinishedListenerI()
4961 public void finished()
4963 AlignFrame.this.setMenusForViewport();
4966 dbRefFetcher.fetchDBRefs(false);
4974 final AlignFrame me = this;
4975 new Thread(new Runnable()
4980 final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
4981 .getSequenceFetcherSingleton(me);
4982 javax.swing.SwingUtilities.invokeLater(new Runnable()
4987 String[] dbclasses = sf.getOrderedSupportedSources();
4988 // sf.getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);
4989 // jalview.util.QuickSort.sort(otherdb, otherdb);
4990 List<DbSourceProxy> otherdb;
4991 JMenu dfetch = new JMenu();
4992 JMenu ifetch = new JMenu();
4993 JMenuItem fetchr = null;
4994 int comp = 0, icomp = 0, mcomp = 15;
4995 String mname = null;
4997 for (String dbclass : dbclasses)
4999 otherdb = sf.getSourceProxy(dbclass);
5000 // add a single entry for this class, or submenu allowing 'fetch
5002 if (otherdb == null || otherdb.size() < 1)
5006 // List<DbSourceProxy> dbs=otherdb;
5007 // otherdb=new ArrayList<DbSourceProxy>();
5008 // for (DbSourceProxy db:dbs)
5010 // if (!db.isA(DBRefSource.ALIGNMENTDB)
5014 mname = "From " + dbclass;
5016 if (otherdb.size() == 1)
5018 final DbSourceProxy[] dassource = otherdb
5019 .toArray(new DbSourceProxy[0]);
5020 DbSourceProxy src = otherdb.get(0);
5021 fetchr = new JMenuItem(src.getDbSource());
5022 fetchr.addActionListener(new ActionListener()
5026 public void actionPerformed(ActionEvent e)
5028 new Thread(new Runnable()
5034 boolean isNucleotide = alignPanel.alignFrame
5035 .getViewport().getAlignment()
5037 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5038 alignPanel.av.getSequenceSelection(),
5039 alignPanel.alignFrame, dassource,
5040 alignPanel.alignFrame.featureSettings,
5043 .addListener(new FetchFinishedListenerI()
5046 public void finished()
5048 AlignFrame.this.setMenusForViewport();
5051 dbRefFetcher.fetchDBRefs(false);
5057 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5058 MessageManager.formatMessage(
5059 "label.fetch_retrieve_from",
5060 new Object[] { src.getDbName() })));
5066 final DbSourceProxy[] dassource = otherdb
5067 .toArray(new DbSourceProxy[0]);
5069 DbSourceProxy src = otherdb.get(0);
5070 fetchr = new JMenuItem(MessageManager.formatMessage(
5071 "label.fetch_all_param",
5072 new Object[] { src.getDbSource() }));
5073 fetchr.addActionListener(new ActionListener()
5076 public void actionPerformed(ActionEvent e)
5078 new Thread(new Runnable()
5084 boolean isNucleotide = alignPanel.alignFrame
5085 .getViewport().getAlignment()
5087 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5088 alignPanel.av.getSequenceSelection(),
5089 alignPanel.alignFrame, dassource,
5090 alignPanel.alignFrame.featureSettings,
5093 .addListener(new FetchFinishedListenerI()
5096 public void finished()
5098 AlignFrame.this.setMenusForViewport();
5101 dbRefFetcher.fetchDBRefs(false);
5107 fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
5108 MessageManager.formatMessage(
5109 "label.fetch_retrieve_from_all_sources",
5111 Integer.valueOf(otherdb.size())
5112 .toString(), src.getDbSource(),
5113 src.getDbName() })));
5116 // and then build the rest of the individual menus
5117 ifetch = new JMenu(MessageManager.formatMessage(
5118 "label.source_from_db_source",
5119 new Object[] { src.getDbSource() }));
5121 String imname = null;
5123 for (DbSourceProxy sproxy : otherdb)
5125 String dbname = sproxy.getDbName();
5126 String sname = dbname.length() > 5 ? dbname.substring(0,
5127 5) + "..." : dbname;
5128 String msname = dbname.length() > 10 ? dbname.substring(
5129 0, 10) + "..." : dbname;
5132 imname = MessageManager.formatMessage(
5133 "label.from_msname", new Object[] { sname });
5135 fetchr = new JMenuItem(msname);
5136 final DbSourceProxy[] dassrc = { sproxy };
5137 fetchr.addActionListener(new ActionListener()
5141 public void actionPerformed(ActionEvent e)
5143 new Thread(new Runnable()
5149 boolean isNucleotide = alignPanel.alignFrame
5150 .getViewport().getAlignment()
5152 DBRefFetcher dbRefFetcher = new DBRefFetcher(
5153 alignPanel.av.getSequenceSelection(),
5154 alignPanel.alignFrame, dassrc,
5155 alignPanel.alignFrame.featureSettings,
5158 .addListener(new FetchFinishedListenerI()
5161 public void finished()
5163 AlignFrame.this.setMenusForViewport();
5166 dbRefFetcher.fetchDBRefs(false);
5172 fetchr.setToolTipText("<html>"
5173 + MessageManager.formatMessage(
5174 "label.fetch_retrieve_from", new Object[]
5178 if (++icomp >= mcomp || i == (otherdb.size()))
5180 ifetch.setText(MessageManager.formatMessage(
5181 "label.source_to_target", imname, sname));
5183 ifetch = new JMenu();
5191 if (comp >= mcomp || dbi >= (dbclasses.length))
5193 dfetch.setText(MessageManager.formatMessage(
5194 "label.source_to_target", mname, dbclass));
5196 dfetch = new JMenu();
5209 * Left justify the whole alignment.
5212 protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
5214 AlignmentI al = viewport.getAlignment();
5216 viewport.firePropertyChange("alignment", null, al);
5220 * Right justify the whole alignment.
5223 protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
5225 AlignmentI al = viewport.getAlignment();
5227 viewport.firePropertyChange("alignment", null, al);
5231 public void setShowSeqFeatures(boolean b)
5233 showSeqFeatures.setSelected(b);
5234 viewport.setShowSequenceFeatures(b);
5241 * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
5242 * awt.event.ActionEvent)
5245 protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
5247 viewport.setShowUnconserved(showNonconservedMenuItem.getState());
5248 alignPanel.paintAlignment(true);
5255 * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
5259 protected void showGroupConsensus_actionPerformed(ActionEvent e)
5261 viewport.setShowGroupConsensus(showGroupConsensus.getState());
5262 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5270 * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
5271 * .event.ActionEvent)
5274 protected void showGroupConservation_actionPerformed(ActionEvent e)
5276 viewport.setShowGroupConservation(showGroupConservation.getState());
5277 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5284 * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
5285 * .event.ActionEvent)
5288 protected void showConsensusHistogram_actionPerformed(ActionEvent e)
5290 viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
5291 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5298 * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
5299 * .event.ActionEvent)
5302 protected void showSequenceLogo_actionPerformed(ActionEvent e)
5304 viewport.setShowSequenceLogo(showSequenceLogo.getState());
5305 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5309 protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
5311 showSequenceLogo.setState(true);
5312 viewport.setShowSequenceLogo(true);
5313 viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
5314 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5318 protected void showInformationHistogram_actionPerformed(ActionEvent e)
5320 viewport.setShowInformationHistogram(
5321 showInformationHistogram.getState());
5322 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5326 protected void showHMMSequenceLogo_actionPerformed(ActionEvent e)
5328 viewport.setShowHMMSequenceLogo(showHMMSequenceLogo.getState());
5329 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5333 protected void normaliseHMMSequenceLogo_actionPerformed(ActionEvent e)
5335 showHMMSequenceLogo.setState(true);
5336 viewport.setShowHMMSequenceLogo(true);
5337 viewport.setNormaliseHMMSequenceLogo(normaliseSequenceLogo.getState());
5338 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5342 protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
5344 alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
5351 * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
5352 * .event.ActionEvent)
5355 protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
5357 if (avc.makeGroupsFromSelection())
5359 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5360 alignPanel.updateAnnotation();
5361 alignPanel.paintAlignment(true);
5365 public void clearAlignmentSeqRep()
5367 // TODO refactor alignmentseqrep to controller
5368 if (viewport.getAlignment().hasSeqrep())
5370 viewport.getAlignment().setSeqrep(null);
5371 PaintRefresher.Refresh(this, viewport.getSequenceSetId());
5372 alignPanel.updateAnnotation();
5373 alignPanel.paintAlignment(true);
5378 protected void createGroup_actionPerformed(ActionEvent e)
5380 if (avc.createGroup())
5382 alignPanel.alignmentChanged();
5387 protected void unGroup_actionPerformed(ActionEvent e)
5391 alignPanel.alignmentChanged();
5396 * make the given alignmentPanel the currently selected tab
5398 * @param alignmentPanel
5400 public void setDisplayedView(AlignmentPanel alignmentPanel)
5402 if (!viewport.getSequenceSetId().equals(
5403 alignmentPanel.av.getSequenceSetId()))
5407 .getString("error.implementation_error_cannot_show_view_alignment_frame"));
5409 if (tabbedPane != null
5410 && tabbedPane.getTabCount() > 0
5411 && alignPanels.indexOf(alignmentPanel) != tabbedPane
5412 .getSelectedIndex())
5414 tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
5419 * Action on selection of menu options to Show or Hide annotations.
5422 * @param forSequences
5423 * update sequence-related annotations
5424 * @param forAlignment
5425 * update non-sequence-related annotations
5428 protected void setAnnotationsVisibility(boolean visible,
5429 boolean forSequences, boolean forAlignment)
5431 AlignmentAnnotation[] anns = alignPanel.getAlignment()
5432 .getAlignmentAnnotation();
5437 for (AlignmentAnnotation aa : anns)
5440 * don't display non-positional annotations on an alignment
5442 if (aa.annotations == null)
5446 boolean apply = (aa.sequenceRef == null && forAlignment)
5447 || (aa.sequenceRef != null && forSequences);
5450 aa.visible = visible;
5453 alignPanel.validateAnnotationDimensions(true);
5454 alignPanel.alignmentChanged();
5458 * Store selected annotation sort order for the view and repaint.
5461 protected void sortAnnotations_actionPerformed()
5463 this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
5465 .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
5466 alignPanel.paintAlignment(true);
5471 * @return alignment panels in this alignment frame
5473 public List<? extends AlignmentViewPanel> getAlignPanels()
5475 return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
5479 * Open a new alignment window, with the cDNA associated with this (protein)
5480 * alignment, aligned as is the protein.
5482 protected void viewAsCdna_actionPerformed()
5484 // TODO no longer a menu action - refactor as required
5485 final AlignmentI alignment = getViewport().getAlignment();
5486 List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
5487 if (mappings == null)
5491 List<SequenceI> cdnaSeqs = new ArrayList<>();
5492 for (SequenceI aaSeq : alignment.getSequences())
5494 for (AlignedCodonFrame acf : mappings)
5496 SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
5500 * There is a cDNA mapping for this protein sequence - add to new
5501 * alignment. It will share the same dataset sequence as other mapped
5502 * cDNA (no new mappings need to be created).
5504 final Sequence newSeq = new Sequence(dnaSeq);
5505 newSeq.setDatasetSequence(dnaSeq);
5506 cdnaSeqs.add(newSeq);
5510 if (cdnaSeqs.size() == 0)
5512 // show a warning dialog no mapped cDNA
5515 AlignmentI cdna = new Alignment(cdnaSeqs.toArray(new SequenceI[cdnaSeqs
5517 GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
5518 AlignFrame.DEFAULT_HEIGHT);
5519 cdna.alignAs(alignment);
5520 String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
5522 Desktop.addInternalFrame(alignFrame, newtitle,
5523 AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
5527 * Set visibility of dna/protein complement view (available when shown in a
5533 protected void showComplement_actionPerformed(boolean show)
5535 SplitContainerI sf = getSplitViewContainer();
5538 sf.setComplementVisible(this, show);
5543 * Generate the reverse (optionally complemented) of the selected sequences,
5544 * and add them to the alignment
5547 protected void showReverse_actionPerformed(boolean complement)
5549 AlignmentI al = null;
5552 Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
5553 al = dna.reverseCdna(complement);
5554 viewport.addAlignment(al, "");
5555 addHistoryItem(new EditCommand(
5556 MessageManager.getString("label.add_sequences"),
5557 Action.PASTE, al.getSequencesArray(), 0, al.getWidth(),
5558 viewport.getAlignment()));
5559 } catch (Exception ex)
5561 System.err.println(ex.getMessage());
5567 * Try to run a script in the Groovy console, having first ensured that this
5568 * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
5569 * be targeted at this alignment.
5572 protected void runGroovy_actionPerformed()
5574 Jalview.setCurrentAlignFrame(this);
5575 groovy.ui.Console console = Desktop.getGroovyConsole();
5576 if (console != null)
5580 console.runScript();
5581 } catch (Exception ex)
5583 System.err.println((ex.toString()));
5585 .showInternalMessageDialog(Desktop.desktop, MessageManager
5586 .getString("label.couldnt_run_groovy_script"),
5588 .getString("label.groovy_support_failed"),
5589 JvOptionPane.ERROR_MESSAGE);
5594 System.err.println("Can't run Groovy script as console not found");
5599 * Hides columns containing (or not containing) a specified feature, provided
5600 * that would not leave all columns hidden
5602 * @param featureType
5603 * @param columnsContaining
5606 public boolean hideFeatureColumns(String featureType,
5607 boolean columnsContaining)
5609 boolean notForHiding = avc.markColumnsContainingFeatures(
5610 columnsContaining, false, false, featureType);
5613 if (avc.markColumnsContainingFeatures(!columnsContaining, false,
5614 false, featureType))
5616 getViewport().hideSelectedColumns();
5624 protected void selectHighlightedColumns_actionPerformed(
5625 ActionEvent actionEvent)
5627 // include key modifier check in case user selects from menu
5628 avc.markHighlightedColumns(
5629 (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0,
5631 (actionEvent.getModifiers() & (ActionEvent.META_MASK | ActionEvent.CTRL_MASK)) != 0);
5635 * Rebuilds the Colour menu, including any user-defined colours which have
5636 * been loaded either on startup or during the session
5638 public void buildColourMenu()
5640 colourMenu.removeAll();
5642 colourMenu.add(applyToAllGroups);
5643 colourMenu.add(textColour);
5644 colourMenu.addSeparator();
5646 ColourMenuHelper.addMenuItems(colourMenu, this,
5647 viewport.getAlignment(), false);
5649 colourMenu.addSeparator();
5650 colourMenu.add(conservationMenuItem);
5651 colourMenu.add(modifyConservation);
5652 colourMenu.add(abovePIDThreshold);
5653 colourMenu.add(modifyPID);
5654 colourMenu.add(annotationColour);
5656 ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
5657 ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
5661 * Open a dialog (if not already open) that allows the user to select and
5662 * calculate PCA or Tree analysis
5664 protected void openTreePcaDialog()
5666 if (alignPanel.getCalculationDialog() == null)
5668 new CalculationChooser(AlignFrame.this);
5673 class PrintThread extends Thread
5677 public PrintThread(AlignmentPanel ap)
5682 static PageFormat pf;
5687 PrinterJob printJob = PrinterJob.getPrinterJob();
5691 printJob.setPrintable(ap, pf);
5695 printJob.setPrintable(ap);
5698 if (printJob.printDialog())
5703 } catch (Exception PrintException)
5705 PrintException.printStackTrace();