+ try
+ {
+ Desktop.transferFromDropTarget(files, protocols, evt, t);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ if (files != null)
+ {
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ // check to see if any of these files have names matching sequences
+ // in
+ // the alignment
+ SequenceIdMatcher idm = new SequenceIdMatcher(
+ viewport.getAlignment().getSequencesArray());
+ /**
+ * Object[] { String,SequenceI}
+ */
+ ArrayList<Object[]> filesmatched = new ArrayList<>();
+ ArrayList<String> filesnotmatched = new ArrayList<>();
+ for (int i = 0; i < files.size(); i++)
+ {
+ String file = files.get(i).toString();
+ String pdbfn = "";
+ DataSourceType protocol = FormatAdapter.checkProtocol(file);
+ if (protocol == DataSourceType.FILE)
+ {
+ File fl = new File(file);
+ pdbfn = fl.getName();
+ }
+ else if (protocol == DataSourceType.URL)
+ {
+ URL url = new URL(file);
+ pdbfn = url.getFile();
+ }
+ if (pdbfn.length() > 0)
+ {
+ // attempt to find a match in the alignment
+ SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
+ int l = 0, c = pdbfn.indexOf(".");
+ while (mtch == null && c != -1)
+ {
+ do
+ {
+ l = c;
+ } while ((c = pdbfn.indexOf(".", l)) > l);
+ if (l > -1)
+ {
+ pdbfn = pdbfn.substring(0, l);
+ }
+ mtch = idm.findAllIdMatches(pdbfn);
+ }
+ if (mtch != null)
+ {
+ FileFormatI type = null;
+ try
+ {
+ type = new IdentifyFile().identify(file, protocol);
+ } catch (Exception ex)
+ {
+ type = null;
+ }
+ if (type != null && type.isStructureFile())
+ {
+ filesmatched.add(new Object[] { file, protocol, mtch });
+ continue;
+ }
+ }
+ // File wasn't named like one of the sequences or wasn't a PDB
+ // file.
+ filesnotmatched.add(file);
+ }
+ }
+ int assocfiles = 0;
+ if (filesmatched.size() > 0)
+ {
+ boolean autoAssociate = Cache
+ .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
+ if (!autoAssociate)
+ {
+ String msg = MessageManager.formatMessage(
+ "label.automatically_associate_structure_files_with_sequences_same_name",
+ new Object[]
+ { Integer.valueOf(filesmatched.size())
+ .toString() });
+ String ttl = MessageManager.getString(
+ "label.automatically_associate_structure_files_by_name");
+ int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
+ ttl, JvOptionPane.YES_NO_OPTION);
+ autoAssociate = choice == JvOptionPane.YES_OPTION;
+ }
+ if (autoAssociate)
+ {
+ for (Object[] fm : filesmatched)
+ {
+ // try and associate
+ // TODO: may want to set a standard ID naming formalism for
+ // associating PDB files which have no IDs.
+ for (SequenceI toassoc : (SequenceI[]) fm[2])
+ {
+ PDBEntry pe = new AssociatePdbFileWithSeq()
+ .associatePdbWithSeq((String) fm[0],
+ (DataSourceType) fm[1], toassoc, false,
+ Desktop.instance);
+ if (pe != null)
+ {
+ System.err.println("Associated file : "
+ + ((String) fm[0]) + " with "
+ + toassoc.getDisplayId(true));
+ assocfiles++;
+ }
+ }
+ // TODO: do we need to update overview ? only if features are
+ // shown I guess
+ alignPanel.paintAlignment(true, false);
+ }
+ }
+ else
+ {
+ /*
+ * add declined structures as sequences
+ */
+ for (Object[] o : filesmatched)
+ {
+ filesnotmatched.add((String) o[0]);
+ }
+ }
+ }
+ if (filesnotmatched.size() > 0)
+ {
+ if (assocfiles > 0 && (Cache.getDefault(
+ "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
+ || JvOptionPane.showConfirmDialog(thisaf,
+ "<html>" + MessageManager.formatMessage(
+ "label.ignore_unmatched_dropped_files_info",
+ new Object[]
+ { Integer.valueOf(
+ filesnotmatched.size())
+ .toString() })
+ + "</html>",
+ MessageManager.getString(
+ "label.ignore_unmatched_dropped_files"),
+ JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
+ {
+ return;
+ }
+ for (String fn : filesnotmatched)
+ {
+ loadJalviewDataFile(fn, null, null, null);
+ }
+
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+ }).start();
+ }
+ }
+
+ /**
+ * Attempt to load a "dropped" file or URL string, by testing in turn for
+ * <ul>
+ * <li>an Annotation file</li>
+ * <li>a JNet file</li>
+ * <li>a features file</li>
+ * <li>else try to interpret as an alignment file</li>
+ * </ul>
+ *
+ * @param file
+ * either a filename or a URL string.
+ */
+ public void loadJalviewDataFile(String file, DataSourceType sourceType,
+ FileFormatI format, SequenceI assocSeq)
+ {
+ try
+ {
+ if (sourceType == null)
+ {
+ sourceType = FormatAdapter.checkProtocol(file);
+ }
+ // if the file isn't identified, or not positively identified as some
+ // other filetype (PFAM is default unidentified alignment file type) then
+ // try to parse as annotation.
+ boolean isAnnotation = (format == null
+ || FileFormat.Pfam.equals(format))
+ ? new AnnotationFile().annotateAlignmentView(viewport,
+ file, sourceType)
+ : false;
+
+ if (!isAnnotation)
+ {
+ // first see if its a T-COFFEE score file
+ TCoffeeScoreFile tcf = null;
+ try
+ {
+ tcf = new TCoffeeScoreFile(file, sourceType);
+ if (tcf.isValid())
+ {
+ if (tcf.annotateAlignment(viewport.getAlignment(), true))
+ {
+ buildColourMenu();
+ changeColour(
+ new TCoffeeColourScheme(viewport.getAlignment()));
+ isAnnotation = true;
+ statusBar.setText(MessageManager.getString(
+ "label.successfully_pasted_tcoffee_scores_to_alignment"));
+ }
+ else
+ {
+ // some problem - if no warning its probable that the ID matching
+ // process didn't work
+ JvOptionPane.showMessageDialog(Desktop.desktop,
+ tcf.getWarningMessage() == null
+ ? MessageManager.getString(
+ "label.check_file_matches_sequence_ids_alignment")
+ : tcf.getWarningMessage(),
+ MessageManager.getString(
+ "label.problem_reading_tcoffee_score_file"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
+ }
+ else
+ {
+ tcf = null;
+ }
+ } catch (Exception x)
+ {
+ Cache.log.debug(
+ "Exception when processing data source as T-COFFEE score file",
+ x);
+ tcf = null;
+ }
+ if (tcf == null)
+ {
+ // try to see if its a JNet 'concise' style annotation file *before*
+ // we
+ // try to parse it as a features file
+ if (format == null)
+ {
+ format = new IdentifyFile().identify(file, sourceType);
+ }
+ if (FileFormat.ScoreMatrix == format)
+ {
+ ScoreMatrixFile sm = new ScoreMatrixFile(
+ new FileParse(file, sourceType));
+ sm.parse();
+ // todo: i18n this message
+ statusBar.setText(MessageManager.formatMessage(
+ "label.successfully_loaded_matrix",
+ sm.getMatrixName()));
+ }
+ else if (FileFormat.Jnet.equals(format))
+ {
+ JPredFile predictions = new JPredFile(file, sourceType);
+ new JnetAnnotationMaker();
+ JnetAnnotationMaker.add_annotation(predictions,
+ viewport.getAlignment(), 0, false);
+ viewport.getAlignment().setupJPredAlignment();
+ isAnnotation = true;
+ }
+ // else if (IdentifyFile.FeaturesFile.equals(format))
+ else if (FileFormat.Features.equals(format))
+ {
+ if (parseFeaturesFile(file, sourceType))
+ {
+ SplitFrame splitFrame = (SplitFrame) getSplitViewContainer();
+ if (splitFrame != null)
+ {
+ splitFrame.repaint();
+ }
+ else
+ {
+ alignPanel.paintAlignment(true, true);
+ }
+ }
+ }
+ else
+ {
+ new FileLoader().LoadFile(viewport, file, sourceType, format);
+ }
+ }
+ }
+ if (isAnnotation)
+ {
+
+ alignPanel.adjustAnnotationHeight();
+ viewport.updateSequenceIdColours();
+ buildSortByAnnotationScoresMenu();
+ alignPanel.paintAlignment(true, true);
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ } catch (OutOfMemoryError oom)
+ {
+ try
+ {
+ System.gc();
+ } catch (Exception x)
+ {
+ }
+ new OOMWarning(
+ "loading data "
+ + (sourceType != null
+ ? (sourceType == DataSourceType.PASTE
+ ? "from clipboard."
+ : "using " + sourceType + " from "
+ + file)
+ : ".")
+ + (format != null
+ ? "(parsing as '" + format + "' file)"
+ : ""),
+ oom, Desktop.desktop);
+ }
+ }
+
+ /**
+ * Method invoked by the ChangeListener on the tabbed pane, in other words
+ * when a different tabbed pane is selected by the user or programmatically.
+ */
+ @Override
+ public void tabSelectionChanged(int index)
+ {
+ if (index > -1)
+ {
+ alignPanel = alignPanels.get(index);
+ viewport = alignPanel.av;
+ avc.setViewportAndAlignmentPanel(viewport, alignPanel);
+ setMenusFromViewport(viewport);
+ if (featureSettings != null && featureSettings.isOpen()
+ && featureSettings.fr.getViewport() != viewport)
+ {
+ if (viewport.isShowSequenceFeatures())
+ {
+ // refresh the featureSettings to reflect UI change
+ showFeatureSettingsUI();
+ }
+ else
+ {
+ // close feature settings for this view.
+ featureSettings.close();
+ }
+ }
+
+ }
+
+ /*
+ * 'focus' any colour slider that is open to the selected viewport
+ */
+ if (viewport.getConservationSelected())
+ {
+ SliderPanel.setConservationSlider(alignPanel,
+ viewport.getResidueShading(), alignPanel.getViewName());
+ }
+ else
+ {
+ SliderPanel.hideConservationSlider();
+ }
+ if (viewport.getAbovePIDThreshold())
+ {
+ SliderPanel.setPIDSliderSource(alignPanel,
+ viewport.getResidueShading(), alignPanel.getViewName());
+ }
+ else
+ {
+ SliderPanel.hidePIDSlider();
+ }
+
+ /*
+ * If there is a frame linked to this one in a SplitPane, switch it to the
+ * same view tab index. No infinite recursion of calls should happen, since
+ * tabSelectionChanged() should not get invoked on setting the selected
+ * index to an unchanged value. Guard against setting an invalid index
+ * before the new view peer tab has been created.
+ */
+ final AlignViewportI peer = viewport.getCodingComplement();
+ if (peer != null)
+ {
+ AlignFrame linkedAlignFrame = ((AlignViewport) peer)
+ .getAlignPanel().alignFrame;
+ if (linkedAlignFrame.tabbedPane.getTabCount() > index)
+ {
+ linkedAlignFrame.tabbedPane.setSelectedIndex(index);
+ }
+ }
+ }
+
+ /**
+ * On right mouse click on view tab, prompt for and set new view name.
+ */
+ @Override
+ public void tabbedPane_mousePressed(MouseEvent e)
+ {
+ if (e.isPopupTrigger())
+ {
+ String msg = MessageManager.getString("label.enter_view_name");
+ String reply = JvOptionPane.showInternalInputDialog(this, msg, msg,
+ JvOptionPane.QUESTION_MESSAGE);
+
+ if (reply != null)
+ {
+ viewport.setViewName(reply);
+ // TODO warn if reply is in getExistingViewNames()?
+ tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
+ }
+ }
+ }
+
+ public AlignViewport getCurrentView()
+ {
+ return viewport;
+ }
+
+ /**
+ * Open the dialog for regex description parsing.
+ */
+ @Override
+ protected void extractScores_actionPerformed(ActionEvent e)
+ {
+ ParseProperties pp = new jalview.analysis.ParseProperties(
+ viewport.getAlignment());
+ // TODO: verify regex and introduce GUI dialog for version 2.5
+ // if (pp.getScoresFromDescription("col", "score column ",
+ // "\\W*([-+]?\\d*\\.?\\d*e?-?\\d*)\\W+([-+]?\\d*\\.?\\d*e?-?\\d*)",
+ // true)>0)
+ if (pp.getScoresFromDescription("description column",
+ "score in description column ", "\\W*([-+eE0-9.]+)", true) > 0)
+ {
+ buildSortByAnnotationScoresMenu();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
+ * )
+ */
+ @Override
+ protected void showDbRefs_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowDBRefs(showDbRefsMenuitem.isSelected());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
+ * ActionEvent)
+ */
+ @Override
+ protected void showNpFeats_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowNPFeats(showNpFeatsMenuitem.isSelected());
+ }
+
+ /**
+ * find the viewport amongst the tabs in this alignment frame and close that
+ * tab
+ *
+ * @param av
+ */
+ public boolean closeView(AlignViewportI av)
+ {
+ if (viewport == av)
+ {
+ this.closeMenuItem_actionPerformed(false);
+ return true;
+ }
+ Component[] comp = tabbedPane.getComponents();
+ for (int i = 0; comp != null && i < comp.length; i++)
+ {
+ if (comp[i] instanceof AlignmentPanel)
+ {
+ if (((AlignmentPanel) comp[i]).av == av)
+ {
+ // close the view.
+ closeView((AlignmentPanel) comp[i]);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ protected void build_fetchdbmenu(JMenu webService)
+ {
+ // Temporary hack - DBRef Fetcher always top level ws entry.
+ // TODO We probably want to store a sequence database checklist in
+ // preferences and have checkboxes.. rather than individual sources selected
+ // here
+ final JMenu rfetch = new JMenu(
+ MessageManager.getString("action.fetch_db_references"));
+ rfetch.setToolTipText(MessageManager.getString(
+ "label.retrieve_parse_sequence_database_records_alignment_or_selected_sequences"));
+ webService.add(rfetch);
+
+ final JCheckBoxMenuItem trimrs = new JCheckBoxMenuItem(
+ MessageManager.getString("option.trim_retrieved_seqs"));
+ trimrs.setToolTipText(
+ MessageManager.getString("label.trim_retrieved_sequences"));
+ trimrs.setSelected(
+ Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
+ trimrs.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ trimrs.setSelected(trimrs.isSelected());
+ Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
+ Boolean.valueOf(trimrs.isSelected()).toString());
+ };
+ });
+ rfetch.add(trimrs);
+ JMenuItem fetchr = new JMenuItem(
+ MessageManager.getString("label.standard_databases"));
+ fetchr.setToolTipText(
+ MessageManager.getString("label.fetch_embl_uniprot"));
+ fetchr.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ boolean isNucleotide = alignPanel.alignFrame.getViewport()
+ .getAlignment().isNucleotide();
+ DBRefFetcher dbRefFetcher = new DBRefFetcher(
+ alignPanel.av.getSequenceSelection(),
+ alignPanel.alignFrame, null,
+ alignPanel.alignFrame.featureSettings, isNucleotide);
+ dbRefFetcher.addListener(new FetchFinishedListenerI()
+ {
+ @Override
+ public void finished()
+ {
+
+ for (FeatureSettingsModelI srcSettings : dbRefFetcher
+ .getFeatureSettingsModels())
+ {
+
+ alignPanel.av.mergeFeaturesStyle(srcSettings);
+ }
+ AlignFrame.this.setMenusForViewport();
+ }
+ });
+ dbRefFetcher.fetchDBRefs(false);
+ }
+ }).start();
+
+ }
+
+ });
+ rfetch.add(fetchr);
+ final AlignFrame me = this;
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
+ .getSequenceFetcherSingleton(me);
+ javax.swing.SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ String[] dbclasses = sf.getOrderedSupportedSources();
+ // sf.getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);
+ // jalview.util.QuickSort.sort(otherdb, otherdb);
+ List<DbSourceProxy> otherdb;
+ JMenu dfetch = new JMenu();
+ JMenu ifetch = new JMenu();
+ JMenuItem fetchr = null;
+ int comp = 0, icomp = 0, mcomp = 15;
+ String mname = null;
+ int dbi = 0;
+ for (String dbclass : dbclasses)
+ {
+ otherdb = sf.getSourceProxy(dbclass);
+ // add a single entry for this class, or submenu allowing 'fetch
+ // all' or pick one
+ if (otherdb == null || otherdb.size() < 1)
+ {
+ continue;
+ }
+ // List<DbSourceProxy> dbs=otherdb;
+ // otherdb=new ArrayList<DbSourceProxy>();
+ // for (DbSourceProxy db:dbs)
+ // {
+ // if (!db.isA(DBRefSource.ALIGNMENTDB)
+ // }
+ if (mname == null)
+ {
+ mname = "From " + dbclass;
+ }
+ if (otherdb.size() == 1)
+ {
+ final DbSourceProxy[] dassource = otherdb
+ .toArray(new DbSourceProxy[0]);
+ DbSourceProxy src = otherdb.get(0);
+ fetchr = new JMenuItem(src.getDbSource());
+ fetchr.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ new Thread(new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ boolean isNucleotide = alignPanel.alignFrame
+ .getViewport().getAlignment()
+ .isNucleotide();
+ DBRefFetcher dbRefFetcher = new DBRefFetcher(
+ alignPanel.av.getSequenceSelection(),
+ alignPanel.alignFrame, dassource,
+ alignPanel.alignFrame.featureSettings,
+ isNucleotide);
+ dbRefFetcher
+ .addListener(new FetchFinishedListenerI()
+ {
+ @Override
+ public void finished()
+ {
+ FeatureSettingsModelI srcSettings = dassource[0]
+ .getFeatureColourScheme();
+ alignPanel.av.mergeFeaturesStyle(
+ srcSettings);
+ AlignFrame.this.setMenusForViewport();
+ }
+ });
+ dbRefFetcher.fetchDBRefs(false);
+ }
+ }).start();
+ }
+
+ });
+ fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.formatMessage(
+ "label.fetch_retrieve_from", new Object[]
+ { src.getDbName() })));
+ dfetch.add(fetchr);
+ comp++;
+ }
+ else
+ {
+ final DbSourceProxy[] dassource = otherdb
+ .toArray(new DbSourceProxy[0]);
+ // fetch all entry
+ DbSourceProxy src = otherdb.get(0);
+ fetchr = new JMenuItem(MessageManager
+ .formatMessage("label.fetch_all_param", new Object[]
+ { src.getDbSource() }));
+ fetchr.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ new Thread(new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ boolean isNucleotide = alignPanel.alignFrame
+ .getViewport().getAlignment()
+ .isNucleotide();
+ DBRefFetcher dbRefFetcher = new DBRefFetcher(
+ alignPanel.av.getSequenceSelection(),
+ alignPanel.alignFrame, dassource,
+ alignPanel.alignFrame.featureSettings,
+ isNucleotide);
+ dbRefFetcher
+ .addListener(new FetchFinishedListenerI()
+ {
+ @Override
+ public void finished()
+ {
+ AlignFrame.this.setMenusForViewport();
+ }
+ });
+ dbRefFetcher.fetchDBRefs(false);
+ }
+ }).start();
+ }
+ });
+
+ fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.formatMessage(
+ "label.fetch_retrieve_from_all_sources",
+ new Object[]
+ { Integer.valueOf(otherdb.size())
+ .toString(),
+ src.getDbSource(), src.getDbName() })));
+ dfetch.add(fetchr);
+ comp++;
+ // and then build the rest of the individual menus
+ ifetch = new JMenu(MessageManager.formatMessage(
+ "label.source_from_db_source", new Object[]
+ { src.getDbSource() }));
+ icomp = 0;
+ String imname = null;
+ int i = 0;
+ for (DbSourceProxy sproxy : otherdb)
+ {
+ String dbname = sproxy.getDbName();
+ String sname = dbname.length() > 5
+ ? dbname.substring(0, 5) + "..."
+ : dbname;
+ String msname = dbname.length() > 10
+ ? dbname.substring(0, 10) + "..."
+ : dbname;
+ if (imname == null)
+ {
+ imname = MessageManager
+ .formatMessage("label.from_msname", new Object[]
+ { sname });
+ }
+ fetchr = new JMenuItem(msname);
+ final DbSourceProxy[] dassrc = { sproxy };
+ fetchr.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ new Thread(new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ boolean isNucleotide = alignPanel.alignFrame
+ .getViewport().getAlignment()
+ .isNucleotide();
+ DBRefFetcher dbRefFetcher = new DBRefFetcher(
+ alignPanel.av.getSequenceSelection(),
+ alignPanel.alignFrame, dassrc,
+ alignPanel.alignFrame.featureSettings,
+ isNucleotide);
+ dbRefFetcher
+ .addListener(new FetchFinishedListenerI()
+ {
+ @Override
+ public void finished()
+ {
+ AlignFrame.this.setMenusForViewport();
+ }
+ });
+ dbRefFetcher.fetchDBRefs(false);
+ }
+ }).start();
+ }
+
+ });
+ fetchr.setToolTipText(
+ "<html>" + MessageManager.formatMessage(
+ "label.fetch_retrieve_from", new Object[]
+ { dbname }));
+ ifetch.add(fetchr);
+ ++i;
+ if (++icomp >= mcomp || i == (otherdb.size()))
+ {
+ ifetch.setText(MessageManager.formatMessage(
+ "label.source_to_target", imname, sname));
+ dfetch.add(ifetch);
+ ifetch = new JMenu();
+ imname = null;
+ icomp = 0;
+ comp++;
+ }
+ }
+ }
+ ++dbi;
+ if (comp >= mcomp || dbi >= (dbclasses.length))
+ {
+ dfetch.setText(MessageManager.formatMessage(
+ "label.source_to_target", mname, dbclass));
+ rfetch.add(dfetch);
+ dfetch = new JMenu();
+ mname = null;
+ comp = 0;
+ }
+ }
+ }
+ });
+ }
+ }).start();
+
+ }
+
+ /**
+ * Left justify the whole alignment.
+ */
+ @Override
+ protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
+ {
+ AlignmentI al = viewport.getAlignment();
+ al.justify(false);
+ viewport.firePropertyChange("alignment", null, al);
+ }
+
+ /**
+ * Right justify the whole alignment.
+ */
+ @Override
+ protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
+ {
+ AlignmentI al = viewport.getAlignment();
+ al.justify(true);
+ viewport.firePropertyChange("alignment", null, al);
+ }
+
+ @Override
+ public void setShowSeqFeatures(boolean b)
+ {
+ showSeqFeatures.setSelected(b);
+ viewport.setShowSequenceFeatures(b);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
+ * awt.event.ActionEvent)
+ */
+ @Override
+ protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowUnconserved(showNonconservedMenuItem.getState());
+ alignPanel.paintAlignment(false, false);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
+ * .ActionEvent)
+ */
+ @Override
+ protected void showGroupConsensus_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowGroupConsensus(showGroupConsensus.getState());
+ alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
+ * .event.ActionEvent)
+ */
+ @Override
+ protected void showGroupConservation_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowGroupConservation(showGroupConservation.getState());
+ alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
+ * .event.ActionEvent)
+ */
+ @Override
+ protected void showConsensusHistogram_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowConsensusHistogram(showConsensusHistogram.getState());
+ alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
+ * .event.ActionEvent)
+ */
+ @Override
+ protected void showSequenceLogo_actionPerformed(ActionEvent e)
+ {
+ viewport.setShowSequenceLogo(showSequenceLogo.getState());
+ alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+ }
+
+ @Override
+ protected void normaliseSequenceLogo_actionPerformed(ActionEvent e)
+ {
+ showSequenceLogo.setState(true);
+ viewport.setShowSequenceLogo(true);
+ viewport.setNormaliseSequenceLogo(normaliseSequenceLogo.getState());
+ alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+ }
+
+ @Override
+ protected void applyAutoAnnotationSettings_actionPerformed(ActionEvent e)
+ {
+ alignPanel.updateAnnotation(applyAutoAnnotationSettings.getState());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
+ * .event.ActionEvent)
+ */
+ @Override
+ protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
+ {
+ if (avc.makeGroupsFromSelection())
+ {
+ PaintRefresher.Refresh(this, viewport.getSequenceSetId());
+ alignPanel.updateAnnotation();
+ alignPanel.paintAlignment(true,
+ viewport.needToUpdateStructureViews());
+ }
+ }
+
+ public void clearAlignmentSeqRep()
+ {
+ // TODO refactor alignmentseqrep to controller
+ if (viewport.getAlignment().hasSeqrep())
+ {
+ viewport.getAlignment().setSeqrep(null);
+ PaintRefresher.Refresh(this, viewport.getSequenceSetId());
+ alignPanel.updateAnnotation();
+ alignPanel.paintAlignment(true, true);
+ }
+ }
+
+ @Override
+ protected void createGroup_actionPerformed(ActionEvent e)
+ {
+ if (avc.createGroup())
+ {
+ if (applyAutoAnnotationSettings.isSelected())
+ {
+ alignPanel.updateAnnotation(true, false);
+ }
+ alignPanel.alignmentChanged();
+ }
+ }
+
+ @Override
+ protected void unGroup_actionPerformed(ActionEvent e)
+ {
+ if (avc.unGroup())
+ {
+ alignPanel.alignmentChanged();
+ }
+ }
+
+ /**
+ * make the given alignmentPanel the currently selected tab
+ *
+ * @param alignmentPanel
+ */
+ public void setDisplayedView(AlignmentPanel alignmentPanel)
+ {
+ if (!viewport.getSequenceSetId()
+ .equals(alignmentPanel.av.getSequenceSetId()))
+ {
+ throw new Error(MessageManager.getString(
+ "error.implementation_error_cannot_show_view_alignment_frame"));
+ }
+ if (tabbedPane != null && tabbedPane.getTabCount() > 0 && alignPanels
+ .indexOf(alignmentPanel) != tabbedPane.getSelectedIndex())
+ {
+ tabbedPane.setSelectedIndex(alignPanels.indexOf(alignmentPanel));
+ }
+ }
+
+ /**
+ * Action on selection of menu options to Show or Hide annotations.
+ *
+ * @param visible
+ * @param forSequences
+ * update sequence-related annotations
+ * @param forAlignment
+ * update non-sequence-related annotations
+ */
+ @Override
+ protected void setAnnotationsVisibility(boolean visible,
+ boolean forSequences, boolean forAlignment)
+ {
+ AlignmentAnnotation[] anns = alignPanel.getAlignment()
+ .getAlignmentAnnotation();
+ if (anns == null)
+ {
+ return;
+ }
+ for (AlignmentAnnotation aa : anns)
+ {
+ /*
+ * 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)
+ {
+ aa.visible = visible;
+ }
+ }
+ alignPanel.validateAnnotationDimensions(true);
+ alignPanel.alignmentChanged();
+ }
+
+ /**
+ * Store selected annotation sort order for the view and repaint.
+ */
+ @Override
+ protected void sortAnnotations_actionPerformed()
+ {
+ this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
+ this.alignPanel.av
+ .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
+ alignPanel.paintAlignment(false, false);
+ }
+
+ /**
+ *
+ * @return alignment panels in this alignment frame
+ */
+ public List<? extends AlignmentViewPanel> getAlignPanels()
+ {
+ // alignPanels is never null
+ // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
+ return alignPanels;
+ }
+
+ /**
+ * Open a new alignment window, with the cDNA associated with this (protein)
+ * alignment, aligned as is the protein.
+ */
+ protected void viewAsCdna_actionPerformed()
+ {
+ // TODO no longer a menu action - refactor as required
+ final AlignmentI alignment = getViewport().getAlignment();
+ List<AlignedCodonFrame> mappings = alignment.getCodonFrames();
+ if (mappings == null)
+ {
+ return;
+ }
+ List<SequenceI> cdnaSeqs = new ArrayList<>();
+ for (SequenceI aaSeq : alignment.getSequences())
+ {
+ for (AlignedCodonFrame acf : mappings)
+ {
+ SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
+ if (dnaSeq != null)
+ {
+ /*
+ * There is a cDNA mapping for this protein sequence - add to new
+ * alignment. It will share the same dataset sequence as other mapped
+ * cDNA (no new mappings need to be created).
+ */
+ final Sequence newSeq = new Sequence(dnaSeq);
+ newSeq.setDatasetSequence(dnaSeq);
+ cdnaSeqs.add(newSeq);
+ }
+ }
+ }
+ if (cdnaSeqs.size() == 0)
+ {
+ // show a warning dialog no mapped cDNA
+ return;
+ }
+ AlignmentI cdna = new Alignment(
+ cdnaSeqs.toArray(new SequenceI[cdnaSeqs.size()]));
+ GAlignFrame alignFrame = new AlignFrame(cdna, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ cdna.alignAs(alignment);
+ String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
+ + this.title;
+ Desktop.addInternalFrame(alignFrame, newtitle, AlignFrame.DEFAULT_WIDTH,
+ AlignFrame.DEFAULT_HEIGHT);
+ }
+
+ /**
+ * Set visibility of dna/protein complement view (available when shown in a
+ * split frame).
+ *
+ * @param show
+ */
+ @Override
+ protected void showComplement_actionPerformed(boolean show)
+ {
+ SplitContainerI sf = getSplitViewContainer();
+ if (sf != null)
+ {
+ sf.setComplementVisible(this, show);
+ }
+ }
+
+ /**
+ * Generate the reverse (optionally complemented) of the selected sequences,
+ * and add them to the alignment
+ */
+ @Override
+ protected void showReverse_actionPerformed(boolean complement)
+ {
+ AlignmentI al = null;
+ try
+ {
+ Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
+ al = dna.reverseCdna(complement);
+ viewport.addAlignment(al, "");
+ addHistoryItem(new EditCommand(
+ MessageManager.getString("label.add_sequences"), Action.PASTE,
+ al.getSequencesArray(), 0, al.getWidth(),
+ viewport.getAlignment()));
+ } catch (Exception ex)
+ {
+ System.err.println(ex.getMessage());
+ return;
+ }
+ }
+
+ /**
+ * Try to run a script in the Groovy console, having first ensured that this
+ * AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
+ * be targeted at this alignment.
+ */
+ @Override
+ protected void runGroovy_actionPerformed()
+ {
+ Jalview.setCurrentAlignFrame(this);
+ groovy.ui.Console console = Desktop.getGroovyConsole();
+ if (console != null)
+ {
+ try
+ {
+ console.runScript();
+ } catch (Exception ex)
+ {
+ System.err.println((ex.toString()));
+ JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ MessageManager.getString("label.couldnt_run_groovy_script"),
+ MessageManager.getString("label.groovy_support_failed"),
+ JvOptionPane.ERROR_MESSAGE);
+ }
+ }
+ else
+ {
+ System.err.println("Can't run Groovy script as console not found");
+ }
+ }
+
+ /**
+ * Hides columns containing (or not containing) a specified feature, provided
+ * that would not leave all columns hidden
+ *
+ * @param featureType
+ * @param columnsContaining
+ * @return
+ */
+ public boolean hideFeatureColumns(String featureType,
+ boolean columnsContaining)
+ {
+ boolean notForHiding = avc.markColumnsContainingFeatures(
+ columnsContaining, false, false, featureType);
+ if (notForHiding)
+ {
+ if (avc.markColumnsContainingFeatures(!columnsContaining, false,
+ false, featureType))
+ {
+ getViewport().hideSelectedColumns();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ protected void selectHighlightedColumns_actionPerformed(
+ ActionEvent actionEvent)
+ {
+ // include key modifier check in case user selects from menu
+ avc.markHighlightedColumns(
+ (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0, true,
+ (actionEvent.getModifiers() & (ActionEvent.META_MASK
+ | ActionEvent.CTRL_MASK)) != 0);
+ }
+
+ /**
+ * Rebuilds the Colour menu, including any user-defined colours which have
+ * been loaded either on startup or during the session
+ */
+ public void buildColourMenu()
+ {
+ colourMenu.removeAll();
+
+ colourMenu.add(applyToAllGroups);
+ colourMenu.add(textColour);
+ colourMenu.addSeparator();
+
+ ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
+ viewport.getAlignment(), false);
+
+ colourMenu.add(annotationColour);
+ bg.add(annotationColour);
+ colourMenu.addSeparator();
+ colourMenu.add(conservationMenuItem);
+ colourMenu.add(modifyConservation);
+ colourMenu.add(abovePIDThreshold);
+ colourMenu.add(modifyPID);
+
+ ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
+ ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
+ }
+
+ /**
+ * Open a dialog (if not already open) that allows the user to select and
+ * calculate PCA or Tree analysis
+ */
+ protected void openTreePcaDialog()
+ {
+ if (alignPanel.getCalculationDialog() == null)
+ {
+ new CalculationChooser(AlignFrame.this);
+ }
+ }
+
+ @Override
+ protected void loadVcf_actionPerformed()
+ {
+ JalviewFileChooser chooser = new JalviewFileChooser(
+ Cache.getProperty("LAST_DIRECTORY"));
+ chooser.setFileView(new JalviewFileView());
+ chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
+ chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
+
+ int value = chooser.showOpenDialog(null);
+
+ if (value == JalviewFileChooser.APPROVE_OPTION)
+ {
+ String choice = chooser.getSelectedFile().getPath();
+ Cache.setProperty("LAST_DIRECTORY", choice);
+ SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
+ new VCFLoader(choice).loadVCF(seqs, this);
+ }
+
+ }
+
+ private Rectangle lastFeatureSettingsBounds = null;
+
+ @Override
+ public void setFeatureSettingsGeometry(Rectangle bounds)
+ {
+ lastFeatureSettingsBounds = bounds;
+ }
+
+ @Override
+ public Rectangle getFeatureSettingsGeometry()
+ {
+ return lastFeatureSettingsBounds;
+ }
+}
+
+class PrintThread extends Thread
+{
+ AlignmentPanel ap;
+
+ public PrintThread(AlignmentPanel ap)
+ {
+ this.ap = ap;
+ }
+
+ static PageFormat pf;
+
+ @Override
+ public void run()
+ {
+ PrinterJob printJob = PrinterJob.getPrinterJob();
+
+ if (pf != null)