e211e3e52a2004feb95c463df5de9c06e04d9236
[jalview.git] / src / jalview / gui / Finder.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
3  * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
4  * 
5  * This file is part of Jalview.
6  * 
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 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.gui;
19
20 import java.util.*;
21
22 import java.awt.*;
23 import java.awt.event.*;
24 import javax.swing.*;
25
26 import jalview.datamodel.*;
27 import jalview.jbgui.*;
28
29 /**
30  * DOCUMENT ME!
31  * 
32  * @author $author$
33  * @version $Revision$
34  */
35 public class Finder extends GFinder
36 {
37   AlignViewport av;
38
39   AlignmentPanel ap;
40
41   JInternalFrame frame;
42
43   int seqIndex = 0;
44
45   int resIndex = -1;
46
47   SearchResults searchResults;
48
49   /**
50    * Creates a new Finder object.
51    * 
52    * @param av
53    *          DOCUMENT ME!
54    * @param ap
55    *          DOCUMENT ME!
56    * @param f
57    *          DOCUMENT ME!
58    */
59   public Finder()
60   {
61     frame = new JInternalFrame();
62     frame.setContentPane(this);
63     frame.setLayer(JLayeredPane.PALETTE_LAYER);
64     Desktop.addInternalFrame(frame, "Find", 340, 110);
65
66     textfield.requestFocus();
67   }
68
69   /**
70    * DOCUMENT ME!
71    * 
72    * @param e
73    *          DOCUMENT ME!
74    */
75   public void findNext_actionPerformed(ActionEvent e)
76   {
77     if (getFocusedViewport())
78     {
79       doSearch(false);
80     }
81   }
82
83   /**
84    * DOCUMENT ME!
85    * 
86    * @param e
87    *          DOCUMENT ME!
88    */
89   public void findAll_actionPerformed(ActionEvent e)
90   {
91     if (getFocusedViewport())
92     {
93       resIndex = -1;
94       seqIndex = 0;
95       doSearch(true);
96     }
97   }
98
99   /**
100    * gets the topmost alignment window and sets av and ap accordingly
101    * 
102    * @return false if no alignment window was found
103    */
104   boolean getFocusedViewport()
105   {
106     // now checks further down the window stack to fix bug
107     // https://mantis.lifesci.dundee.ac.uk/view.php?id=36008
108     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
109     for (int f = 0; f < frames.length; f++)
110     {
111       JInternalFrame frame = frames[f];
112       if (frame != null && frame instanceof AlignFrame)
113       {
114         av = ((AlignFrame) frame).viewport;
115         ap = ((AlignFrame) frame).alignPanel;
116         return true;
117       }
118     }
119     return false;
120   }
121
122   /**
123    * DOCUMENT ME!
124    * 
125    * @param e
126    *          DOCUMENT ME!
127    */
128   public void createNewGroup_actionPerformed(ActionEvent e)
129   {
130     SequenceI[] seqs = new SequenceI[searchResults.getSize()];
131     SequenceFeature[] features = new SequenceFeature[searchResults
132             .getSize()];
133
134     for (int i = 0; i < searchResults.getSize(); i++)
135     {
136       seqs[i] = searchResults.getResultSequence(i).getDatasetSequence();
137
138       features[i] = new SequenceFeature(textfield.getText().trim(),
139               "Search Results", null, searchResults.getResultStart(i),
140               searchResults.getResultEnd(i), "Search Results");
141     }
142
143     if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
144             features, true, ap))
145     {
146       ap.alignFrame.showSeqFeatures.setSelected(true);
147       av.setShowSequenceFeatures(true);
148       ap.highlightSearchResults(null);
149     }
150   }
151
152   /**
153    * incrementally search the alignment
154    * 
155    * @param findAll
156    *          true means find all results and raise a dialog box
157    */
158   void doSearch(boolean findAll)
159   {
160     createNewGroup.setEnabled(false);
161
162     String searchString = textfield.getText().trim();
163
164     if (searchString.length() < 1)
165     {
166       return;
167     }
168     // TODO: extend finder to match descriptions, features and annotation, and
169     // other stuff
170     // TODO: add switches to control what is searched - sequences, IDS,
171     // descriptions, features
172     jalview.analysis.Finder finder = new jalview.analysis.Finder(
173             av.alignment, av.getSelectionGroup(), seqIndex, resIndex);
174     finder.setCaseSensitive(caseSensitive.isSelected());
175     finder.setFindAll(findAll);
176
177     finder.find(searchString); // returns true if anything was actually found
178
179     seqIndex = finder.getSeqIndex();
180     resIndex = finder.getResIndex();
181
182     searchResults = finder.getSearchResults(); // find(regex,
183     // caseSensitive.isSelected(), )
184     Vector idMatch = finder.getIdMatch();
185     boolean haveResults = false;
186     // set or reset the GUI
187     if ((idMatch.size() > 0))
188     {
189       haveResults = true;
190       ap.idPanel.highlightSearchResults(idMatch);
191     }
192     else
193     {
194       ap.idPanel.highlightSearchResults(null);
195     }
196
197     if (searchResults.getSize() > 0)
198     {
199       haveResults = true;
200       createNewGroup.setEnabled(true);
201     }
202     else
203     {
204       searchResults = null;
205     }
206
207     // if allResults is null, this effectively switches displaySearch flag in
208     // seqCanvas
209     ap.highlightSearchResults(searchResults);
210     // TODO: add enablers for 'SelectSequences' or 'SelectColumns' or
211     // 'SelectRegion' selection
212     if (!haveResults)
213     {
214       JOptionPane.showInternalMessageDialog(this, "Finished searching",
215               null, JOptionPane.INFORMATION_MESSAGE);
216       resIndex = -1;
217       seqIndex = 0;
218     }
219
220     if (findAll)
221     {
222       String message = (idMatch.size() > 0) ? "" + idMatch.size() + " IDs"
223               : "";
224       if (idMatch.size() > 0 && searchResults.getSize() > 0)
225       {
226         message += " and ";
227       }
228       message += searchResults.getSize() + " subsequence matches found.";
229       JOptionPane.showInternalMessageDialog(this, message, null,
230               JOptionPane.INFORMATION_MESSAGE);
231       resIndex = -1;
232       seqIndex = 0;
233     }
234
235   }
236 }