Applet search by residue index fixed
[jalview.git] / src / jalview / appletgui / Finder.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 \r
20 package jalview.appletgui;\r
21 \r
22 import java.util.*;\r
23 \r
24 import java.awt.*;\r
25 import java.awt.event.*;\r
26 \r
27 import jalview.datamodel.*;\r
28 import jalview.jbappletgui.*;\r
29 \r
30 public class Finder\r
31     extends GFinder\r
32 {\r
33   AlignViewport av;\r
34   AlignmentPanel ap;\r
35   Frame frame;\r
36   SuperGroup searchGroup;\r
37   Vector searchResults;\r
38 \r
39   int seqIndex = 0;\r
40   int resIndex = 0;\r
41   public Finder(final AlignmentPanel ap)\r
42   {\r
43     this.av = ap.av;\r
44     this.ap = ap;\r
45     frame = new Frame();\r
46     frame.add(this);\r
47     jalview.bin.JalviewLite.addFrame(frame, "Find", 340, 120);\r
48     frame.repaint();\r
49     frame.addWindowListener(new WindowAdapter()\r
50     {\r
51       public void windowClosing(WindowEvent evt)\r
52       {\r
53         ap.highlightSearchResults(null);\r
54       }\r
55     });\r
56   }\r
57 \r
58   public void textfield_actionPerformed(ActionEvent e)\r
59   {\r
60     doSearch(false);\r
61   }\r
62 \r
63   public void findNext_actionPerformed(ActionEvent e)\r
64   {\r
65     doSearch(false);\r
66   }\r
67 \r
68   public void findAll_actionPerformed(ActionEvent e)\r
69   {\r
70     resIndex = 0;\r
71     seqIndex = 0;\r
72     doSearch(true);\r
73   }\r
74 \r
75   public void cancel_actionPerformed(ActionEvent e)\r
76   {\r
77     try\r
78     {\r
79       // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
80       ap.highlightSearchResults(null);\r
81       ap.idPanel.highlightSearchResults(null);\r
82       // frame.setClosed(true);\r
83     }\r
84     catch (Exception ex)\r
85     {}\r
86   }\r
87 \r
88   public void createNewGroup_actionPerformed(ActionEvent e)\r
89   {\r
90     Color[] newColors = new Color[24];\r
91     for (int i = 0; i < 24; i++)\r
92     {\r
93       newColors[i] = new Color(60, 160, 115);\r
94     }\r
95 \r
96     jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(\r
97         newColors);\r
98     String searchString = textfield.getText();\r
99 \r
100     searchGroup = new SuperGroup(searchString, ucs, true, true, false);\r
101 \r
102     for (int i = 0; i < searchResults.size(); i += 3)\r
103     {\r
104       // its possible edits may have occurred since search was performed\r
105       // account for this here\r
106 \r
107       SequenceI seq = av.alignment.getSequenceAt(Integer.parseInt(searchResults.\r
108           elementAt(i).toString()));\r
109       int startRes = seq.findIndex(Integer.parseInt(searchResults.elementAt(i +\r
110           1).toString())) - 1;\r
111       int endRes = seq.findIndex(Integer.parseInt(searchResults.elementAt(i + 2).\r
112                                                   toString())) - 1;\r
113 \r
114       SequenceGroup sg = new SequenceGroup(searchString, ucs, true, true, false,\r
115                                            startRes, endRes);\r
116       sg.addSequence(seq, false);\r
117       av.alignment.addGroup(sg);\r
118       searchGroup.addGroup(sg);\r
119 \r
120     }\r
121 \r
122     ap.av.alignment.addSuperGroup(searchGroup);\r
123     ap.highlightSearchResults(null);\r
124   }\r
125 \r
126   void doSearch(boolean findAll)\r
127   {\r
128     createNewGroup.setEnabled(false);\r
129 \r
130     String searchString = textfield.getText().toUpperCase();\r
131 \r
132     com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString);\r
133 \r
134     searchResults = new Vector();\r
135     int[] allResults = null;\r
136 \r
137     Sequence seq;\r
138     String item = null;\r
139     boolean found = false;\r
140 \r
141     ////// is the searchString a residue number?\r
142     try\r
143     {\r
144       int res = Integer.parseInt(searchString);\r
145       found = true;\r
146 \r
147       if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize() < 1)\r
148       {\r
149         seq = (Sequence) av.getAlignment().getSequenceAt(0);\r
150       }\r
151       else\r
152       {\r
153         seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0));\r
154       }\r
155 \r
156       searchResults.addElement(Integer.toString(av.getAlignment().findIndex(seq)));\r
157       searchResults.addElement(String.valueOf(res));\r
158       searchResults.addElement(String.valueOf(res));\r
159 \r
160     }\r
161     catch (NumberFormatException ex)\r
162     {}\r
163     ///////////////////////////////////////////////\r
164 \r
165 \r
166     int end = av.alignment.getHeight();\r
167 \r
168     SequenceGroup selection = av.getSelectionGroup();\r
169     if (selection != null)\r
170     {\r
171       if (selection.getSize() < 1 ||\r
172           (selection.getEndRes() - selection.getStartRes() < 2))\r
173       {\r
174         selection = null;\r
175       }\r
176     }\r
177 \r
178     while (!found && seqIndex < end)\r
179     {\r
180       seq = (Sequence) av.alignment.getSequenceAt(seqIndex);\r
181 \r
182       if (selection != null && !selection.sequences.contains(seq))\r
183       {\r
184         seqIndex++;\r
185         resIndex = 0;\r
186         continue;\r
187       }\r
188 \r
189       item = seq.getSequence().toUpperCase();\r
190 \r
191       if (selection != null && selection.getEndRes() < av.alignment.getWidth())\r
192       {\r
193         item = item.substring(0, selection.getEndRes() + 1);\r
194       }\r
195 \r
196       ///Shall we ignore gaps????\r
197       StringBuffer noGaps = new StringBuffer();\r
198       int insertCount = 0;\r
199       Vector spaces = new Vector();\r
200 \r
201       for (int j = 0; j < item.length(); j++)\r
202       {\r
203 \r
204         if (!jalview.util.Comparison.isGap(item.charAt(j)))\r
205         {\r
206           noGaps.append(item.charAt(j));\r
207           spaces.addElement(new Integer(insertCount));\r
208         }\r
209         else\r
210         {\r
211           insertCount++;\r
212         }\r
213       }\r
214 \r
215       for (int r = resIndex; r < noGaps.length(); r++)\r
216       {\r
217 \r
218         if (regex.searchFrom(noGaps.toString(), r))\r
219         {\r
220           resIndex = regex.matchedFrom();\r
221           if (selection != null &&\r
222               (resIndex + Integer.parseInt(spaces.elementAt(resIndex).toString())) <\r
223               selection.getStartRes())\r
224           {\r
225             continue;\r
226           }\r
227 \r
228           searchResults.addElement(Integer.toString(seqIndex));\r
229           int sres = seq.findPosition(resIndex +\r
230                                       Integer.parseInt(spaces.\r
231               elementAt(resIndex).toString()));\r
232           int eres = seq.findPosition(regex.matchedTo() - 1 +\r
233                                       Integer.parseInt(\r
234                                       spaces.elementAt(regex.matchedTo() - 1).\r
235                                       toString()));\r
236           searchResults.addElement(sres + "");\r
237           searchResults.addElement(eres + "");\r
238 \r
239           if (!findAll)\r
240           {\r
241             // thats enough, break and display the result\r
242             found = true;\r
243             resIndex++;\r
244             break;\r
245           }\r
246 \r
247           r = resIndex;\r
248         }\r
249       }\r
250       if (!found)\r
251       {\r
252         seqIndex++;\r
253         resIndex = 0;\r
254       }\r
255     }\r
256 \r
257     Vector idMatch = new Vector();\r
258     for (int id = 0; id < av.alignment.getHeight(); id++)\r
259     {\r
260       if (regex.search(av.alignment.getSequenceAt(id).getName()))\r
261       {\r
262         idMatch.addElement(av.alignment.getSequenceAt(id));\r
263       }\r
264     }\r
265 \r
266     if (searchResults.size() == 0 && idMatch.size() > 0)\r
267     {\r
268       ap.idPanel.highlightSearchResults(idMatch);\r
269     }\r
270 \r
271     if (searchResults.size() > 0)\r
272     {\r
273       allResults = new int[searchResults.size()];\r
274       for (int i = 0; i < searchResults.size(); i++)\r
275       {\r
276         allResults[i] = Integer.parseInt(searchResults.elementAt(i).toString());\r
277       }\r
278 \r
279       createNewGroup.setEnabled(true);\r
280     }\r
281     else\r
282     {\r
283       resIndex = 0;\r
284       seqIndex = 0;\r
285     }\r
286 \r
287     // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
288     ap.highlightSearchResults(allResults);\r
289 \r
290     if (findAll)\r
291     {\r
292       String message = (searchResults.size() / 3) + " matches found.";\r
293       System.out.println(message);\r
294     }\r
295 \r
296   }\r
297 \r
298 }\r