e6fb5e6c16d35e8bc9439cf1f6fe69ba0407c58b
[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 jalview.jbappletgui.GFinder;\r
23 import jalview.datamodel.*;\r
24 import java.awt.event.*;\r
25 import java.util.*;\r
26 import java.awt.*;\r
27 \r
28 public class Finder extends GFinder\r
29 {\r
30   AlignViewport av;\r
31   AlignmentPanel ap;\r
32   Frame frame;\r
33   SuperGroup searchGroup;\r
34   Vector searchResults;\r
35 \r
36   int seqIndex = 0;\r
37   int resIndex = 0;\r
38   public Finder(final AlignmentPanel ap)\r
39   {\r
40     this.av = ap.av;\r
41     this.ap = ap;\r
42     frame = new Frame();\r
43     frame.add(this);\r
44     jalview.bin.JalviewLite.addFrame(frame, "Find", 340,120);\r
45     frame.repaint();\r
46     frame.addWindowListener(new WindowAdapter()\r
47         {public void windowClosing(WindowEvent evt)\r
48               { ap.highlightSearchResults( null ); }\r
49         });\r
50   }\r
51 \r
52   public void textfield_actionPerformed(ActionEvent e)\r
53   {\r
54     doSearch(false);\r
55   }\r
56 \r
57   public void findNext_actionPerformed(ActionEvent e)\r
58   {\r
59     doSearch(false);\r
60   }\r
61 \r
62   public void findAll_actionPerformed(ActionEvent e)\r
63   {\r
64     resIndex=0;\r
65     seqIndex=0;\r
66     doSearch(true);\r
67   }\r
68 \r
69   public void cancel_actionPerformed(ActionEvent e)\r
70   {\r
71     try{\r
72       // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
73       ap.highlightSearchResults( null );\r
74       ap.idPanel.highlightSearchResults( null );\r
75      // frame.setClosed(true);\r
76     }catch(Exception ex){ }\r
77   }\r
78 \r
79 \r
80   public void createNewGroup_actionPerformed(ActionEvent e)\r
81   {\r
82    Color [] newColors = new Color[24];\r
83    for(int i=0; i<24; i++)\r
84      newColors[i] = new Color(60,160,115);\r
85 \r
86    jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(newColors);\r
87    String searchString = textfield.getText();\r
88 \r
89    searchGroup = new SuperGroup(searchString, ucs , true, true, false);\r
90 \r
91 \r
92     for(int i=0; i<searchResults.size(); i+=3)\r
93     {\r
94       // its possible edits may have occurred since search was performed\r
95       // account for this here\r
96 \r
97       SequenceI seq = av.alignment.getSequenceAt( Integer.parseInt(searchResults.elementAt(i).toString()) );\r
98       int startRes = seq.findIndex( Integer.parseInt(searchResults.elementAt(i+1).toString()) )-1;\r
99       int endRes = seq.findIndex(   Integer.parseInt(searchResults.elementAt(i+2).toString()) )-1;\r
100 \r
101       SequenceGroup sg = new SequenceGroup(searchString, ucs, true, true, false, startRes , endRes  );\r
102       sg.addSequence(seq);\r
103       av.alignment.addGroup(sg);\r
104       searchGroup.addGroup( sg );\r
105 \r
106     }\r
107 \r
108     ap.av.alignment.addSuperGroup(searchGroup);\r
109     ap.highlightSearchResults( null );\r
110   }\r
111 \r
112 \r
113   void doSearch(boolean findAll)\r
114   {\r
115     createNewGroup.setEnabled(false);\r
116 \r
117     String searchString = textfield.getText().toUpperCase();\r
118 \r
119     com.stevesoft.pat.Regex regex = new  com.stevesoft.pat.Regex(searchString);\r
120 \r
121     searchResults = new Vector();\r
122     int [] allResults = null;\r
123 \r
124     Sequence seq;\r
125     String item=null;\r
126     boolean found = false;\r
127 \r
128     ////// is the searchString a residue number?\r
129     try{\r
130       int res = Integer.parseInt(searchString);\r
131       found = true;\r
132 \r
133       if(av.getSelectionGroup().getSize()>0)\r
134         seq = (Sequence)(av.getSelectionGroup().getSequenceAt(0));\r
135       else\r
136         seq = (Sequence)av.getAlignment().getSequenceAt(0);\r
137 \r
138       searchResults.addElement( Integer.toString( av.getAlignment().findIndex(seq) ) );\r
139       searchResults.addElement( Integer.toString( seq.findIndex(res)-1 ) );\r
140       searchResults.addElement( Integer.toString( seq.findIndex(res)-1 ) );\r
141 \r
142     }catch(NumberFormatException ex){}\r
143     ///////////////////////////////////////////////\r
144 \r
145 \r
146     int end = av.alignment.getHeight();\r
147 \r
148     SequenceGroup selection = av.getSelectionGroup();\r
149     if(selection!=null)\r
150      if(selection.getSize()<1 || (selection.getEndRes()-selection.getStartRes()<2))\r
151       selection = null;\r
152 \r
153     while( !found && seqIndex<end)\r
154     {\r
155       seq = (Sequence)av.alignment.getSequenceAt(seqIndex);\r
156 \r
157 \r
158       if(selection!=null && !selection.sequences.contains(seq))\r
159       {\r
160         seqIndex++;\r
161         resIndex=0;\r
162         continue;\r
163       }\r
164 \r
165       item = seq.getSequence().toUpperCase();\r
166 \r
167       if(selection!=null && selection.getEndRes()<av.alignment.getWidth())\r
168           item = item.substring(0, selection.getEndRes()+1);\r
169 \r
170       ///Shall we ignore gaps????\r
171       StringBuffer noGaps = new StringBuffer();\r
172       int insertCount=0;\r
173       Vector spaces = new Vector();\r
174 \r
175       for (int j=0; j < item.length(); j++)\r
176       {\r
177 \r
178         if(!jalview.util.Comparison.isGap(item.charAt(j)))\r
179          {\r
180            noGaps.append(item.charAt(j));\r
181            spaces.addElement(new Integer(insertCount));\r
182          }\r
183         else\r
184            insertCount++;\r
185       }\r
186 \r
187 \r
188 \r
189       for(int r = resIndex; r<noGaps.length(); r++)\r
190       {\r
191 \r
192        if( regex.searchFrom( noGaps.toString(), r ) )\r
193        {\r
194          resIndex = regex.matchedFrom();\r
195          if(selection!=null && ( resIndex+ Integer.parseInt(spaces.elementAt(resIndex).toString()) )<selection.getStartRes())\r
196            continue;\r
197 \r
198          searchResults.addElement( Integer.toString( seqIndex) );\r
199          int sres = seq.findPosition( resIndex+ Integer.parseInt(spaces.elementAt(resIndex).toString()) );\r
200          int eres = seq.findPosition( regex.matchedTo()-1 + Integer.parseInt(spaces.elementAt(regex.matchedTo()-1).toString()) );\r
201           searchResults.addElement( sres+"" );\r
202           searchResults.addElement( eres+"" );\r
203 \r
204 \r
205          if(!findAll)\r
206          {\r
207            // thats enough, break and display the result\r
208            found = true;\r
209            resIndex++;\r
210            break;\r
211          }\r
212 \r
213          r=resIndex;\r
214        }\r
215       }\r
216       if(!found)\r
217       {\r
218         seqIndex++;\r
219         resIndex = 0;\r
220       }\r
221     }\r
222 \r
223 \r
224     Vector idMatch = new Vector();\r
225     for(int id = 0; id<av.alignment.getHeight(); id++)\r
226     {\r
227       if(   regex.search( av.alignment.getSequenceAt(id).getName() ) )\r
228         idMatch.addElement( av.alignment.getSequenceAt(id) );\r
229     }\r
230 \r
231     if(searchResults.size()==0 && idMatch.size()>0)\r
232       ap.idPanel.highlightSearchResults( idMatch );\r
233 \r
234 \r
235     if(searchResults.size()>0)\r
236     {\r
237       allResults = new int[searchResults.size()];\r
238       for(int i=0; i<searchResults.size(); i++)\r
239         allResults[i] = Integer.parseInt(searchResults.elementAt(i).toString());\r
240 \r
241       createNewGroup.setEnabled(true);\r
242     }\r
243     else\r
244     {\r
245       resIndex=0;\r
246       seqIndex=0;\r
247     }\r
248 \r
249     // if allResults is null, this effectively switches displaySearch flag in seqCanvas\r
250     ap.highlightSearchResults( allResults );\r
251 \r
252     if (findAll)\r
253     {\r
254       String message =  (searchResults.size()/3) + " matches found.";\r
255       System.out.println(message);\r
256     }\r
257 \r
258   }\r
259 \r
260 }\r