after merge
[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 \r
29 public class Finder extends Panel\r
30 {\r
31   AlignViewport av;\r
32   AlignmentPanel ap;\r
33   Frame frame;\r
34   SuperGroup searchGroup;\r
35   Vector searchResults;\r
36 \r
37   int seqIndex = 0;\r
38   int resIndex = 0;\r
39   public Finder(final AlignmentPanel ap)\r
40   {\r
41     try\r
42     {\r
43       jbInit();\r
44     }\r
45     catch (Exception e)\r
46     {\r
47       e.printStackTrace();\r
48     }\r
49 \r
50     this.av = ap.av;\r
51     this.ap = ap;\r
52     frame = new Frame();\r
53     frame.add(this);\r
54     jalview.bin.JalviewLite.addFrame(frame, "Find", 340, 120);\r
55     frame.repaint();\r
56     frame.addWindowListener(new WindowAdapter()\r
57     {\r
58       public void windowClosing(WindowEvent evt)\r
59       {\r
60         ap.highlightSearchResults(null);\r
61       }\r
62     });\r
63   }\r
64 \r
65   public void textfield_actionPerformed(ActionEvent e)\r
66   {\r
67     doSearch(false);\r
68   }\r
69 \r
70   public void findNext_actionPerformed(ActionEvent e)\r
71   {\r
72     doSearch(false);\r
73   }\r
74 \r
75   public void findAll_actionPerformed(ActionEvent e)\r
76   {\r
77     resIndex = 0;\r
78     seqIndex = 0;\r
79     doSearch(true);\r
80   }\r
81 \r
82   public void cancel_actionPerformed(ActionEvent e)\r
83   {\r
84     try\r
85     {\r
86       // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
87       ap.highlightSearchResults(null);\r
88       ap.idPanel.highlightSearchResults(null);\r
89       // frame.setClosed(true);\r
90     }\r
91     catch (Exception ex)\r
92     {}\r
93   }\r
94 \r
95   public void createNewGroup_actionPerformed(ActionEvent e)\r
96   {\r
97     Color[] newColors = new Color[24];\r
98     for (int i = 0; i < 24; i++)\r
99     {\r
100       newColors[i] = new Color(60, 160, 115);\r
101     }\r
102 \r
103     jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(\r
104         newColors);\r
105     String searchString = textfield.getText();\r
106 \r
107     searchGroup = new SuperGroup(searchString, ucs, true, true, false);\r
108 \r
109     for (int i = 0; i < searchResults.size(); i += 3)\r
110     {\r
111       // its possible edits may have occurred since search was performed\r
112       // account for this here\r
113 \r
114       SequenceI seq = av.alignment.getSequenceAt(Integer.parseInt(searchResults.\r
115           elementAt(i).toString()));\r
116       int startRes = seq.findIndex(Integer.parseInt(searchResults.elementAt(i +\r
117           1).toString())) - 1;\r
118       int endRes = seq.findIndex(Integer.parseInt(searchResults.elementAt(i + 2).\r
119                                                   toString())) - 1;\r
120 \r
121       SequenceGroup sg = new SequenceGroup(searchString, ucs, true, true, false,\r
122                                            startRes, endRes);\r
123       sg.addSequence(seq, false);\r
124       av.alignment.addGroup(sg);\r
125       searchGroup.addGroup(sg);\r
126 \r
127     }\r
128 \r
129     ap.av.alignment.addSuperGroup(searchGroup);\r
130     ap.highlightSearchResults(null);\r
131   }\r
132 \r
133   void doSearch(boolean findAll)\r
134   {\r
135     createNewGroup.setEnabled(false);\r
136 \r
137     String searchString = textfield.getText().toUpperCase();\r
138 \r
139     com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString);\r
140 \r
141     searchResults = new Vector();\r
142     int[] allResults = null;\r
143 \r
144     Sequence seq;\r
145     String item = null;\r
146     boolean found = false;\r
147 \r
148     ////// is the searchString a residue number?\r
149     try\r
150     {\r
151       int res = Integer.parseInt(searchString);\r
152       found = true;\r
153 \r
154       if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize() < 1)\r
155       {\r
156         seq = (Sequence) av.getAlignment().getSequenceAt(0);\r
157       }\r
158       else\r
159       {\r
160         seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0));\r
161       }\r
162 \r
163       searchResults.addElement(Integer.toString(av.getAlignment().findIndex(seq)));\r
164       searchResults.addElement(String.valueOf(res));\r
165       searchResults.addElement(String.valueOf(res));\r
166 \r
167     }\r
168     catch (NumberFormatException ex)\r
169     {}\r
170     ///////////////////////////////////////////////\r
171 \r
172 \r
173     int end = av.alignment.getHeight();\r
174 \r
175     SequenceGroup selection = av.getSelectionGroup();\r
176     if (selection != null)\r
177     {\r
178       if (selection.getSize() < 1 ||\r
179           (selection.getEndRes() - selection.getStartRes() < 2))\r
180       {\r
181         selection = null;\r
182       }\r
183     }\r
184 \r
185     while (!found && seqIndex < end)\r
186     {\r
187       seq = (Sequence) av.alignment.getSequenceAt(seqIndex);\r
188 \r
189       if (selection != null && !selection.sequences.contains(seq))\r
190       {\r
191         seqIndex++;\r
192         resIndex = 0;\r
193         continue;\r
194       }\r
195 \r
196       item = seq.getSequence().toUpperCase();\r
197 \r
198       if (selection != null && selection.getEndRes() < av.alignment.getWidth())\r
199       {\r
200         item = item.substring(0, selection.getEndRes() + 1);\r
201       }\r
202 \r
203       ///Shall we ignore gaps????\r
204       StringBuffer noGaps = new StringBuffer();\r
205       int insertCount = 0;\r
206       Vector spaces = new Vector();\r
207 \r
208       for (int j = 0; j < item.length(); j++)\r
209       {\r
210 \r
211         if (!jalview.util.Comparison.isGap(item.charAt(j)))\r
212         {\r
213           noGaps.append(item.charAt(j));\r
214           spaces.addElement(new Integer(insertCount));\r
215         }\r
216         else\r
217         {\r
218           insertCount++;\r
219         }\r
220       }\r
221 \r
222       for (int r = resIndex; r < noGaps.length(); r++)\r
223       {\r
224 \r
225         if (regex.searchFrom(noGaps.toString(), r))\r
226         {\r
227           resIndex = regex.matchedFrom();\r
228           if (selection != null &&\r
229               (resIndex + Integer.parseInt(spaces.elementAt(resIndex).toString())) <\r
230               selection.getStartRes())\r
231           {\r
232             continue;\r
233           }\r
234 \r
235           searchResults.addElement(Integer.toString(seqIndex));\r
236           int sres = seq.findPosition(resIndex +\r
237                                       Integer.parseInt(spaces.\r
238               elementAt(resIndex).toString()));\r
239           int eres = seq.findPosition(regex.matchedTo() - 1 +\r
240                                       Integer.parseInt(\r
241                                       spaces.elementAt(regex.matchedTo() - 1).\r
242                                       toString()));\r
243           searchResults.addElement(sres + "");\r
244           searchResults.addElement(eres + "");\r
245 \r
246           if (!findAll)\r
247           {\r
248             // thats enough, break and display the result\r
249             found = true;\r
250             resIndex++;\r
251             break;\r
252           }\r
253 \r
254           r = resIndex;\r
255         }\r
256         else\r
257           break;\r
258       }\r
259       if (!found)\r
260       {\r
261         seqIndex++;\r
262         resIndex = 0;\r
263       }\r
264     }\r
265 \r
266     Vector idMatch = new Vector();\r
267     for (int id = 0; id < av.alignment.getHeight(); id++)\r
268     {\r
269       if (regex.search(av.alignment.getSequenceAt(id).getName()))\r
270       {\r
271         idMatch.addElement(av.alignment.getSequenceAt(id));\r
272       }\r
273     }\r
274 \r
275     if (searchResults.size() == 0 && idMatch.size() > 0)\r
276     {\r
277       ap.idPanel.highlightSearchResults(idMatch);\r
278     }\r
279 \r
280     if (searchResults.size() > 0)\r
281     {\r
282       allResults = new int[searchResults.size()];\r
283       for (int i = 0; i < searchResults.size(); i++)\r
284       {\r
285         allResults[i] = Integer.parseInt(searchResults.elementAt(i).toString());\r
286       }\r
287 \r
288       createNewGroup.setEnabled(true);\r
289     }\r
290     else\r
291     {\r
292       resIndex = 0;\r
293       seqIndex = 0;\r
294     }\r
295 \r
296     // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
297     ap.highlightSearchResults(allResults);\r
298 \r
299     if (findAll)\r
300     {\r
301       String message = (searchResults.size() / 3) + " matches found.";\r
302       System.out.println(message);\r
303     }\r
304 \r
305   }\r
306 \r
307   Label jLabel1 = new Label();\r
308   protected TextField textfield = new TextField();\r
309   protected Button findAll = new Button();\r
310   protected Button findNext = new Button();\r
311   Panel jPanel1 = new Panel();\r
312   GridLayout gridLayout1 = new GridLayout();\r
313   protected Button createNewGroup = new Button();\r
314 \r
315 \r
316   private void jbInit() throws Exception {\r
317       jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));\r
318       jLabel1.setText("Find");\r
319       jLabel1.setBounds(new Rectangle(3, 30, 34, 15));\r
320       this.setLayout(null);\r
321       textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
322       textfield.setText("");\r
323       textfield.setBounds(new Rectangle(40, 27, 133, 21));\r
324       textfield.addKeyListener(new java.awt.event.KeyAdapter() {\r
325               public void keyTyped(KeyEvent e) {\r
326                   textfield_keyTyped(e);\r
327               }\r
328           });\r
329       textfield.addActionListener(new java.awt.event.ActionListener() {\r
330               public void actionPerformed(ActionEvent e) {\r
331                   textfield_actionPerformed(e);\r
332               }\r
333           });\r
334       findAll.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
335       findAll.setLabel("Find all");\r
336       findAll.addActionListener(new java.awt.event.ActionListener() {\r
337               public void actionPerformed(ActionEvent e) {\r
338                   findAll_actionPerformed(e);\r
339               }\r
340           });\r
341       findNext.setEnabled(false);\r
342       findNext.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
343       findNext.setLabel("Find Next");\r
344       findNext.addActionListener(new java.awt.event.ActionListener() {\r
345               public void actionPerformed(ActionEvent e) {\r
346                   findNext_actionPerformed(e);\r
347               }\r
348           });\r
349       jPanel1.setBounds(new Rectangle(180, 5, 141, 64));\r
350       jPanel1.setLayout(gridLayout1);\r
351       gridLayout1.setHgap(0);\r
352       gridLayout1.setRows(3);\r
353       gridLayout1.setVgap(2);\r
354       createNewGroup.setEnabled(false);\r
355       createNewGroup.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));\r
356       createNewGroup.setLabel("Create new group");\r
357       createNewGroup.addActionListener(new java.awt.event.ActionListener() {\r
358               public void actionPerformed(ActionEvent e) {\r
359                   createNewGroup_actionPerformed(e);\r
360               }\r
361           });\r
362       jPanel1.add(findNext, null);\r
363       jPanel1.add(findAll, null);\r
364       jPanel1.add(createNewGroup, null);\r
365       this.add(textfield, null);\r
366       this.add(jLabel1, null);\r
367       this.add(jPanel1, null);\r
368   }\r
369 \r
370   void textfield_keyTyped(KeyEvent e) {\r
371       findNext.setEnabled(true);\r
372   }\r
373 \r
374 }\r