/* * Jalview - A Sequence Alignment Editor and Viewer * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package jalview.gui; import jalview.datamodel.*; import jalview.jbgui.*; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; /** * DOCUMENT ME! * * @author $author$ * @version $Revision$ */ public class Finder extends GFinder { AlignViewport av; AlignmentPanel ap; JInternalFrame frame; SuperGroup searchGroup; Vector searchResults; int seqIndex = 0; int resIndex = 0; /** * Creates a new Finder object. * * @param av DOCUMENT ME! * @param ap DOCUMENT ME! * @param f DOCUMENT ME! */ public Finder(AlignViewport av, AlignmentPanel ap, JInternalFrame f) { this.av = av; this.ap = ap; frame = f; // all a big pain, but we need to wait until the frame is visible before the textfield can // obtain the focus///////////////////////// frame.addInternalFrameListener(new InternalFrameAdapter() { public void internalFrameOpened(InternalFrameEvent evt) { SwingUtilities.invokeLater(new Runnable() { public void run() { textfield.requestFocus(); } }); } /** * DOCUMENT ME! * * @param evt DOCUMENT ME! */ public void internalFrameClosing(InternalFrameEvent evt) { cancel_actionPerformed(null); } }); } /** * DOCUMENT ME! * * @param e DOCUMENT ME! */ public void findNext_actionPerformed(ActionEvent e) { doSearch(false); } /** * DOCUMENT ME! * * @param e DOCUMENT ME! */ public void findAll_actionPerformed(ActionEvent e) { resIndex = 0; seqIndex = 0; doSearch(true); } /** * DOCUMENT ME! * * @param e DOCUMENT ME! */ public void cancel_actionPerformed(ActionEvent e) { try { // if allResults is null, this effectively switches displaySearch flag in seqCanvas ap.highlightSearchResults(null); ap.idPanel.highlightSearchResults(null); // frame.setClosed(true); } catch (Exception ex) { } } /** * DOCUMENT ME! * * @param e DOCUMENT ME! */ public void createNewGroup_actionPerformed(ActionEvent e) { Color[] newColors = new Color[24]; for (int i = 0; i < 24; i++) { newColors[i] = new Color(60, 160, 115); } jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(newColors); String searchString = textfield.getText(); searchGroup = new SuperGroup(searchString, ucs, true, true, false); for (int i = 0; i < searchResults.size(); i += 3) { // its possible edits may have occurred since search was performed // account for this here SequenceI seq = av.alignment.getSequenceAt(Integer.parseInt( searchResults.elementAt(i).toString())); int startRes = seq.findIndex(Integer.parseInt( searchResults.elementAt(i + 1).toString())) - 1; int endRes = seq.findIndex(Integer.parseInt( searchResults.elementAt(i + 2).toString())) - 1; SequenceGroup sg = new SequenceGroup(searchString, ucs, true, true, false, startRes, endRes); sg.addSequence(seq, false); av.alignment.addGroup(sg); searchGroup.addGroup(sg); } ap.av.alignment.addSuperGroup(searchGroup); ap.highlightSearchResults(null); } /** * DOCUMENT ME! * * @param findAll DOCUMENT ME! */ void doSearch(boolean findAll) { createNewGroup.setEnabled(false); String searchString = textfield.getText().toUpperCase().trim(); com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString); searchResults = new Vector(); int[] allResults = null; Sequence seq; String item = null; boolean found = false; ////// is the searchString a residue number? try { int res = Integer.parseInt(searchString); found = true; if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize() < 1) { seq = (Sequence) av.getAlignment().getSequenceAt(0); } else { seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0)); } searchResults.add(Integer.toString(av.getAlignment().findIndex(seq))); searchResults.add(res+""); searchResults.add(res+""); } catch (NumberFormatException ex) { } /////////////////////////////////////////////// Color[] newColors = new Color[24]; for (int i = 0; i < 24; i++) { newColors[i] = new Color(60, 160, 115); } jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(newColors); searchGroup = new SuperGroup(searchString, ucs, true, true, false); int end = av.alignment.getHeight(); SequenceGroup selection = av.getSelectionGroup(); if (selection != null) { if ((selection.getSize() < 1) || ((selection.getEndRes() - selection.getStartRes()) < 2)) { selection = null; } } while (!found && (seqIndex < end)) { seq = (Sequence) av.alignment.getSequenceAt(seqIndex); if ((selection != null) && !selection.sequences.contains(seq)) { seqIndex++; resIndex = 0; continue; } item = seq.getSequence().toUpperCase(); if ((selection != null) && (selection.getEndRes() < av.alignment.getWidth())) { item = item.substring(0, selection.getEndRes() + 1); } ///Shall we ignore gaps???? StringBuffer noGapsSB = new StringBuffer(); int insertCount = 0; Vector spaces = new Vector(); for (int j = 0; j < item.length(); j++) { if (!jalview.util.Comparison.isGap(item.charAt(j))) { noGapsSB.append(item.charAt(j)); spaces.add(new Integer(insertCount)); } else { insertCount++; } } String noGaps = noGapsSB.toString(); for (int r = resIndex; r < noGaps.length(); r++) { if (regex.searchFrom(noGaps, r)) { resIndex = regex.matchedFrom(); if ((selection != null) && ((resIndex + Integer.parseInt(spaces.get(resIndex).toString())) < selection.getStartRes())) { continue; } searchResults.add(Integer.toString(seqIndex)); int sres = seq.findPosition(resIndex + Integer.parseInt(spaces.elementAt(resIndex) .toString())); int eres = seq.findPosition(regex.matchedTo() - 1 + Integer.parseInt(spaces.elementAt(regex.matchedTo() - 1).toString())); searchResults.addElement(sres + ""); searchResults.addElement(eres + ""); if (!findAll) { // thats enough, break and display the result found = true; resIndex++; break; } r = resIndex; } else { break; } } if (!found) { seqIndex++; resIndex = 0; } } Vector idMatch = new Vector(); for (int id = 0; id < av.alignment.getHeight(); id++) { if (regex.search(av.alignment.getSequenceAt(id).getName())) { idMatch.add(av.alignment.getSequenceAt(id)); } } if ((searchResults.size() == 0) && (idMatch.size() > 0)) { ap.idPanel.highlightSearchResults(idMatch); } if (searchResults.size() > 0) { allResults = new int[searchResults.size()]; for (int i = 0; i < searchResults.size(); i++) { allResults[i] = Integer.parseInt(searchResults.get(i).toString()); } createNewGroup.setEnabled(true); } else { JOptionPane.showInternalMessageDialog(this, "Finished searching", null, JOptionPane.INFORMATION_MESSAGE); resIndex = 0; seqIndex = 0; } // if allResults is null, this effectively switches displaySearch flag in seqCanvas ap.highlightSearchResults(allResults); if (findAll) { String message = (searchResults.size() / 3) + " matches found."; JOptionPane.showInternalMessageDialog(this, message, null, JOptionPane.INFORMATION_MESSAGE); } } }