X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAlignFrame.java;h=343d5c751afd745e3337999b85c2c86d2c13f779;hb=2a36d880a6a221c6a46f4a24d10539073e40106d;hp=fcf43011e1a12ca692ba1cdd2dca1fd56ece1a07;hpb=febd250089c9672b66d2c7a5ed0c06e0763c2233;p=jalview.git diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java index fcf4301..343d5c7 100644 --- a/src/jalview/gui/AlignFrame.java +++ b/src/jalview/gui/AlignFrame.java @@ -20,57 +20,6 @@ */ package jalview.gui; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.GridLayout; -import java.awt.Rectangle; -import java.awt.Toolkit; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.awt.dnd.DnDConstants; -import java.awt.dnd.DropTargetDragEvent; -import java.awt.dnd.DropTargetDropEvent; -import java.awt.dnd.DropTargetEvent; -import java.awt.dnd.DropTargetListener; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.print.PageFormat; -import java.awt.print.PrinterJob; -import java.beans.PropertyChangeEvent; -import java.io.File; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Deque; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.List; -import java.util.Set; -import java.util.Vector; - -import javax.swing.JButton; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JEditorPane; -import javax.swing.JInternalFrame; -import javax.swing.JLabel; -import javax.swing.JLayeredPane; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JProgressBar; -import javax.swing.JRadioButtonMenuItem; -import javax.swing.JScrollPane; -import javax.swing.SwingUtilities; - import jalview.analysis.AAFrequency; import jalview.analysis.AlignmentSorter; import jalview.analysis.AlignmentUtils; @@ -83,6 +32,7 @@ import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; +import jalview.api.FeatureSettingsControllerI; import jalview.api.SplitContainerI; import jalview.api.ViewStyleI; import jalview.api.analysis.ScoreModelI; @@ -98,10 +48,12 @@ import jalview.commands.TrimRegionCommand; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.Alignment; import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.AlignmentExportData; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentOrder; import jalview.datamodel.AlignmentView; import jalview.datamodel.ColumnSelection; +import jalview.datamodel.HiddenSequences; import jalview.datamodel.PDBEntry; import jalview.datamodel.SeqCigar; import jalview.datamodel.Sequence; @@ -111,7 +63,6 @@ import jalview.gui.ViewSelectionMenu.ViewSetProvider; import jalview.io.AlignmentProperties; import jalview.io.AnnotationFile; import jalview.io.BioJsHTMLOutput; -import jalview.io.FeaturesFile; import jalview.io.FileLoader; import jalview.io.FormatAdapter; import jalview.io.HtmlSvgOutput; @@ -148,6 +99,52 @@ import jalview.ws.jws2.Jws2Discoverer; import jalview.ws.jws2.jabaws2.Jws2Instance; import jalview.ws.seqfetcher.DbSourceProxy; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DropTargetDragEvent; +import java.awt.dnd.DropTargetDropEvent; +import java.awt.dnd.DropTargetEvent; +import java.awt.dnd.DropTargetListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; +import java.beans.PropertyChangeEvent; +import java.io.File; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Set; +import java.util.Vector; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JEditorPane; +import javax.swing.JInternalFrame; +import javax.swing.JLayeredPane; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + /** * DOCUMENT ME! * @@ -244,6 +241,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, this(al, hiddenColumns, width, height, null); } + /** * Create alignment frame for al with hiddenColumns, a specific width and * height, and specific sequenceId @@ -293,6 +291,28 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, init(); } + public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs, + ColumnSelection hiddenColumns, int width, int height) + { + setSize(width, height); + + if (al.getDataset() == null) + { + al.setDataset(null); + } + + viewport = new AlignViewport(al, hiddenColumns); + + if (hiddenSeqs != null && hiddenSeqs.length > 0) + { + viewport.hideSequence(hiddenSeqs); + } + alignPanel = new AlignmentPanel(this, viewport); + addAlignmentPanel(alignPanel, true); + init(); + } + + /** * Make a new AlignFrame from existing alignmentPanels * @@ -315,6 +335,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, */ void init() { + progressBar = new ProgressBar(this.statusPanel, this.statusBar); + avc = new jalview.controller.AlignViewController(this, viewport, alignPanel); if (viewport.getAlignmentConservationAnnotation() == null) @@ -364,7 +386,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, final List selviews = new ArrayList(); final List origview = new ArrayList(); - ViewSelectionMenu vsel = new ViewSelectionMenu("Transfer colours from", + final String menuLabel = MessageManager + .getString("label.copy_format_from"); + ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel, new ViewSetProvider() { @@ -373,7 +397,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { origview.clear(); origview.add(alignPanel); - return Desktop.getAlignmentPanels(null); + // make an array of all alignment panels except for this one + List aps = new ArrayList( + Arrays.asList(Desktop.getAlignmentPanels(null))); + aps.remove(AlignFrame.this.alignPanel); + return aps.toArray(new AlignmentPanel[aps.size()]); } }, selviews, new ItemListener() { @@ -383,32 +411,43 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, { if (origview.size() > 0) { + final AlignmentPanel ap = origview.get(0); + + /* + * Copy the ViewStyle of the selected panel to 'this one'. + * Don't change value of 'scaleProteinAsCdna' unless copying + * from a SplitFrame. + */ ViewStyleI vs = selviews.get(0).getAlignViewport() .getViewStyle(); - origview.get(0).getAlignViewport().setViewStyle(vs); - AlignViewportI complement = origview.get(0) - .getAlignViewport().getCodingComplement(); - if (complement != null) + boolean fromSplitFrame = selviews.get(0) + .getAlignViewport().getCodingComplement() != null; + if (!fromSplitFrame) + { + vs.setScaleProteinAsCdna(ap.getAlignViewport() + .getViewStyle().isScaleProteinAsCdna()); + } + ap.getAlignViewport().setViewStyle(vs); + + /* + * Also rescale ViewStyle of SplitFrame complement if there is + * one _and_ it is set to 'scaledProteinAsCdna'; we don't copy + * the whole ViewStyle (allow cDNA protein to have different + * fonts) + */ + AlignViewportI complement = ap.getAlignViewport() + .getCodingComplement(); + if (complement != null && vs.isScaleProteinAsCdna()) { AlignFrame af = Desktop.getAlignFrameFor(complement); - if (complement.isNucleotide()) - { - complement.setViewStyle(vs); - vs.setCharWidth(vs.getCharWidth() / 3); - } - else - { - int rw = vs.getCharWidth(); - vs.setCharWidth(rw * 3); - complement.setViewStyle(vs); - vs.setCharWidth(rw); - } - af.alignPanel.updateLayout(); + ((SplitFrame) af.getSplitViewContainer()) + .adjustLayout(); af.setMenusForViewport(); } - origview.get(0).updateLayout(); - origview.get(0).setSelected(true); - origview.get(0).alignFrame.setMenusForViewport(); + + ap.updateLayout(); + ap.setSelected(true); + ap.alignFrame.setMenusForViewport(); } } @@ -856,9 +895,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, updateEditMenuBar(); } - // methods for implementing IProgressIndicator - // need to refactor to a reusable stub class - Hashtable progressBars, progressBarHandlers; + private IProgressIndicator progressBar; /* * (non-Javadoc) @@ -868,78 +905,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public void setProgressBar(String message, long id) { - if (progressBars == null) - { - progressBars = new Hashtable(); - progressBarHandlers = new Hashtable(); - } - - JPanel progressPanel; - Long lId = new Long(id); - GridLayout layout = (GridLayout) statusPanel.getLayout(); - if (progressBars.get(lId) != null) - { - progressPanel = (JPanel) progressBars.get(new Long(id)); - statusPanel.remove(progressPanel); - progressBars.remove(lId); - progressPanel = null; - if (message != null) - { - statusBar.setText(message); - } - if (progressBarHandlers.contains(lId)) - { - progressBarHandlers.remove(lId); - } - layout.setRows(layout.getRows() - 1); - } - else - { - progressPanel = new JPanel(new BorderLayout(10, 5)); - - JProgressBar progressBar = new JProgressBar(); - progressBar.setIndeterminate(true); - - progressPanel.add(new JLabel(message), BorderLayout.WEST); - progressPanel.add(progressBar, BorderLayout.CENTER); - - layout.setRows(layout.getRows() + 1); - statusPanel.add(progressPanel); - - progressBars.put(lId, progressPanel); - } - // update GUI - // setMenusForViewport(); - validate(); + progressBar.setProgressBar(message, id); } @Override public void registerHandler(final long id, final IProgressIndicatorHandler handler) { - if (progressBarHandlers == null || !progressBars.contains(new Long(id))) - { - throw new Error(MessageManager.getString("error.call_setprogressbar_before_registering_handler")); - } - progressBarHandlers.put(new Long(id), handler); - final JPanel progressPanel = (JPanel) progressBars.get(new Long(id)); - if (handler.canCancel()) - { - JButton cancel = new JButton( - MessageManager.getString("action.cancel")); - final IProgressIndicator us = this; - cancel.addActionListener(new ActionListener() - { - - @Override - public void actionPerformed(ActionEvent e) - { - handler.cancelActivity(id); - us.setProgressBar(MessageManager.formatMessage("label.cancelled_params", new Object[]{((JLabel) progressPanel.getComponent(0)).getText()}), id); - } - }); - progressPanel.add(cancel, BorderLayout.EAST); - } + progressBar.registerHandler(id, handler); } /** @@ -949,18 +922,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override public boolean operationInProgress() { - if (progressBars != null && progressBars.size() > 0) - { - return true; - } - return false; + return progressBar.operationInProgress(); } @Override public void setStatus(String text) { statusBar.setText(text); - }; + } /* * Added so Castor Mapping file can obtain Jalview Version @@ -1153,11 +1122,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, .lastIndexOf(java.io.File.separatorChar) + 1); } - /* - * First save any linked Chimera session. - */ - Desktop.instance.saveChimeraSessions(file); - success = new Jalview2XML().saveAlignment(this, file, shortName); statusBar.setText(MessageManager.formatMessage( @@ -1176,30 +1140,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return false; } - String[] omitHidden = null; - - if (viewport.hasHiddenColumns()) + AlignmentExportData exportData = getAlignmentForExport(format, viewport); + if (exportData.getSettings().isCancelled()) { - int reply = JOptionPane - .showInternalConfirmDialog( - Desktop.desktop, - MessageManager - .getString("label.alignment_contains_hidden_columns"), - MessageManager - .getString("action.save_omit_hidden_columns"), - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE); - - if (reply == JOptionPane.YES_OPTION) - { - omitHidden = viewport.getViewAsString(false); - } + return false; } - FormatAdapter f = new FormatAdapter(); + FormatAdapter f = new FormatAdapter(alignPanel, + exportData.getSettings()); String output = f.formatSequences(format, - viewport.getAlignment(), // class cast exceptions will + exportData.getAlignment(), // class cast exceptions will // occur in the distant future - omitHidden, f.getCacheSuffixDefault(format), + exportData.getOmitHidden(), exportData.getStartEndPostions(), + f.getCacheSuffixDefault(format), viewport.getColumnSelection()); if (output == null) @@ -1240,6 +1192,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, return success; } + private void warningMessage(String warning, String title) { if (new jalview.util.Platform().isHeadless()) @@ -1264,33 +1217,22 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void outputText_actionPerformed(ActionEvent e) { - String[] omitHidden = null; - if (viewport.hasHiddenColumns()) + AlignmentExportData exportData = getAlignmentForExport( + e.getActionCommand(), viewport); + if (exportData.getSettings().isCancelled()) { - int reply = JOptionPane - .showInternalConfirmDialog( - Desktop.desktop, - MessageManager - .getString("label.alignment_contains_hidden_columns"), - MessageManager - .getString("action.save_omit_hidden_columns"), - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE); - - if (reply == JOptionPane.YES_OPTION) - { - omitHidden = viewport.getViewAsString(false); - } + return; } - CutAndPasteTransfer cap = new CutAndPasteTransfer(); cap.setForInput(null); - try { - cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(), - viewport.getAlignment(), omitHidden, + cap.setText(new FormatAdapter(alignPanel, exportData.getSettings()) + .formatSequences( + e.getActionCommand(), + exportData.getAlignment(), + exportData.getOmitHidden(), exportData.getStartEndPostions(), viewport.getColumnSelection())); Desktop.addInternalFrame(cap, MessageManager.formatMessage( "label.alignment_output_command", new Object[] @@ -1303,6 +1245,107 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } + public static AlignmentExportData getAlignmentForExport(String exportFomat, + AlignViewportI viewport) + { + AlignmentI alignmentToExport = null; + String[] omitHidden = null; + int[] alignmentStartEnd = new int[2]; + + HiddenSequences hiddenSeqs = viewport.getAlignment() + .getHiddenSequences(); + + + alignmentToExport = viewport.getAlignment(); + alignmentStartEnd = new int[] + { 0, alignmentToExport.getWidth() - 1 }; + + boolean hasHiddenSeqs = hiddenSeqs.getSize() > 0; + AlignExportSettings settings = new AlignExportSettings(hasHiddenSeqs, + viewport.hasHiddenColumns(), exportFomat); + settings.isExportAnnotations(); + + if (viewport.hasHiddenColumns() && !settings.isExportHiddenColumns()) + { + omitHidden = viewport.getViewAsString(false); + } + + if (hasHiddenSeqs && settings.isExportHiddenSequences()) + { + alignmentToExport = hiddenSeqs.getFullAlignment(); + } + else + { + alignmentToExport = viewport.getAlignment(); + alignmentStartEnd = getStartEnd(alignmentStartEnd, viewport + .getColumnSelection().getHiddenColumns()); + } + AlignmentExportData ed = new AlignmentExportData(alignmentToExport, omitHidden, alignmentStartEnd, + settings); + return ed; + } + + private static int[] getStartEnd(int[] aligmentStartEnd, + List hiddenCols) + { + int startPos = aligmentStartEnd[0]; + int endPos = aligmentStartEnd[1]; + + int[] lowestRange = new int[2]; + int[] higestRange = new int[2]; + + for (int[] hiddenCol : hiddenCols) + { + // System.out.println("comparing : " + hiddenCol[0] + "-" + hiddenCol[1]); + + lowestRange = (hiddenCol[0] <= startPos) ? hiddenCol : lowestRange; + higestRange = (hiddenCol[1] >= endPos) ? hiddenCol : higestRange; + } + // System.out.println("min : " + lowestRange[0] + "-" + lowestRange[1]); + // System.out.println("max : " + higestRange[0] + "-" + higestRange[1]); + + if (lowestRange[0] == 0 && lowestRange[1] == 0) + { + startPos = aligmentStartEnd[0]; + } + else + { + startPos = lowestRange[1] + 1; + } + + if (higestRange[0] == 0 && higestRange[1] == 0) + { + endPos = aligmentStartEnd[1]; + } + else + { + endPos = higestRange[0]; + } + + // System.out.println("Export range : " + minPos + " - " + maxPos); + return new int[] + { startPos, endPos }; + } + + public static void main(String[] args) + { + ArrayList hiddenCols = new ArrayList(); + hiddenCols.add(new int[] + { 0, 4 }); + hiddenCols.add(new int[] + { 6, 9 }); + hiddenCols.add(new int[] + { 11, 12 }); + hiddenCols.add(new int[] + { 33, 33 }); + hiddenCols.add(new int[] + { 45, 50 }); + + int[] x = getStartEnd(new int[] + { 0, 50 }, hiddenCols); + // System.out.println("Export range : " + x[0] + " - " + x[1]); + } + /** * DOCUMENT ME! * @@ -1312,17 +1355,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, @Override protected void htmlMenuItem_actionPerformed(ActionEvent e) { - // new HTMLOutput(alignPanel, - // alignPanel.getSeqPanel().seqCanvas.getSequenceRenderer(), - // alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()); new HtmlSvgOutput(null, alignPanel); } @Override public void bioJSMenuItem_actionPerformed(ActionEvent e) { - new BioJsHTMLOutput(alignPanel, - alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()); + BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel); + bjs.exportJalviewAlignmentAsBioJsHtmlFile(); } public void createImageMap(File file, String image) { @@ -1826,7 +1866,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, } String output = new FormatAdapter().formatSequences("Fasta", seqs, - omitHidden); + omitHidden, null); StringSelection ss = new StringSelection(output); @@ -3118,6 +3158,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public FeatureSettings featureSettings; @Override + public FeatureSettingsControllerI getFeatureSettingsUI() + { + return featureSettings; + } + + @Override public void featureSettings_actionPerformed(ActionEvent e) { if (featureSettings != null) @@ -4804,7 +4850,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, // temporary flag until SplitFrame is released boolean asSplitFrame = Cache.getDefault( - Preferences.ENABLE_SPLIT_FRAME, false); + Preferences.ENABLE_SPLIT_FRAME, true); if (asSplitFrame) { /* @@ -4936,7 +4982,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, "label.translation_of_params", new Object[] { this.getTitle() }); af.setTitle(newTitle); - if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, false)) + if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true)) { final SequenceI[] seqs = viewport.getSelectionAsNewSequence(); viewport.openSplitFrame(af, new Alignment(seqs), @@ -4967,41 +5013,29 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, * contents or path to retrieve file * @param type * access mode of file (see jalview.io.AlignFile) - * @return true if features file was parsed corectly. + * @return true if features file was parsed correctly. */ public boolean parseFeaturesFile(String file, String type) { - boolean featuresFile = false; - try - { - featuresFile = new FeaturesFile(file, type).parse(viewport - .getAlignment().getDataset(), alignPanel.getSeqPanel().seqCanvas - .getFeatureRenderer().getFeatureColours(), false, - jalview.bin.Cache.getDefault("RELAXEDSEQIDMATCHING", false)); - } catch (Exception ex) - { - ex.printStackTrace(); - } + return avc.parseFeaturesFile(file, type, + jalview.bin.Cache.getDefault("RELAXEDSEQIDMATCHING", false)); + + } - if (featuresFile) + @Override + public void refreshFeatureUI(boolean enableIfNecessary) + { + // note - currently this is only still here rather than in the controller + // because of the featureSettings hard reference that is yet to be + // abstracted + if (enableIfNecessary) { viewport.setShowSequenceFeatures(true); showSeqFeatures.setSelected(true); - if (alignPanel.getSeqPanel().seqCanvas.fr != null) - { - // update the min/max ranges where necessary - alignPanel.getSeqPanel().seqCanvas.fr.findAllFeatures(true); - } - if (featureSettings != null) - { - featureSettings.setTableData(); - } - alignPanel.paintAlignment(true); } - return featuresFile; - } + } @Override public void dragEnter(DropTargetDragEvent evt) { @@ -5770,8 +5804,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, public void setShowSeqFeatures(boolean b) { - showSeqFeatures.setSelected(true); - viewport.setShowSequenceFeatures(true); + showSeqFeatures.setSelected(b); + viewport.setShowSequenceFeatures(b); } /* @@ -5943,6 +5977,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, for (AlignmentAnnotation aa : alignPanel.getAlignment() .getAlignmentAnnotation()) { + /* + * don't display non-positional annotations on an alignment + */ + if (aa.annotations == null) + { + continue; + } boolean apply = (aa.sequenceRef == null && forAlignment) || (aa.sequenceRef != null && forSequences); if (apply) @@ -5950,7 +5991,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, aa.visible = visible; } } - alignPanel.validateAnnotationDimensions(false); + alignPanel.validateAnnotationDimensions(true); alignPanel.alignmentChanged(); } @@ -6037,6 +6078,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener, sf.setComplementVisible(this, show); } } + } class PrintThread extends Thread