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