updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
[jalview.git] / src / jalview / appletgui / Finder.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19
20 package jalview.appletgui;
21
22 import java.util.*;
23
24 import java.awt.*;
25 import java.awt.event.*;
26
27 import jalview.datamodel.*;
28 import java.awt.Rectangle;
29
30 public class Finder extends Panel implements ActionListener
31 {
32   AlignViewport av;
33   AlignmentPanel ap;
34   Frame frame;
35
36   SearchResults searchResults;
37
38   int seqIndex = 0;
39   int resIndex = 0;
40   public Finder(final AlignmentPanel ap)
41   {
42     try
43     {
44       jbInit();
45     }
46     catch (Exception e)
47     {
48       e.printStackTrace();
49     }
50
51     this.av = ap.av;
52     this.ap = ap;
53     frame = new Frame();
54     frame.add(this);
55     jalview.bin.JalviewLite.addFrame(frame, "Find", 340, 120);
56     frame.repaint();
57     frame.addWindowListener(new WindowAdapter()
58     {
59       public void windowClosing(WindowEvent evt)
60       {
61         ap.highlightSearchResults(null);
62       }
63     });
64   }
65
66   public void actionPerformed(ActionEvent evt)
67   {
68     if (evt.getSource() == textfield)
69       doSearch(false);
70
71     else if (evt.getSource() == findNext)
72       doSearch(false);
73
74     else if (evt.getSource() == findAll)
75     {
76       resIndex = 0;
77       seqIndex = 0;
78       doSearch(true);
79     }
80     else if(evt.getSource() == createNewGroup)
81       createNewGroup_actionPerformed();
82   }
83
84
85   public void createNewGroup_actionPerformed()
86   {
87
88     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, null);
89     Dialog dialog = new Dialog(ap.alignFrame, "Enter New Feature Name", true);
90     dialog.add(cap);
91
92     cap.setText(textfield.getText());
93
94     dialog.setBounds( frame.getLocation().x+frame.getSize().width+5,
95                       frame.getLocation().y+20,300,100);
96     dialog.show();
97
98
99     String featureName = cap.getText().trim();
100     if(featureName.length()<1)
101       return;
102
103
104     for (int i = 0; i < searchResults.getSize(); i ++ )
105     {
106         SequenceI seq = searchResults.getResultSequence(i);
107
108         SequenceFeature sf = new SequenceFeature(featureName,
109             null, null,
110             searchResults.getResultStart(i),
111            searchResults.getResultEnd(i), "Search Results");
112
113         ap.seqPanel.seqCanvas.getFeatureRenderer().addNewFeature(
114             featureName, new Color(60,160,115));
115         seq.addSequenceFeature(sf);
116     }
117
118     ap.seqPanel.seqCanvas.getFeatureRenderer().findAllFeatures();
119     ap.alignFrame.sequenceFeatures.setState(true);
120     av.showSequenceFeatures(true);
121     ap.highlightSearchResults(null);
122   }
123
124   void doSearch(boolean findAll)
125   {
126     createNewGroup.setEnabled(false);
127
128     String searchString = textfield.getText();
129     if(!caseSensitive.getState())
130       searchString = searchString.toUpperCase();
131
132     com.stevesoft.pat.Regex regex = new com.stevesoft.pat.Regex(searchString);
133
134     searchResults = new SearchResults();
135
136     Sequence seq;
137     String item = null;
138     boolean found = false;
139
140     ////// is the searchString a residue number?
141     try
142     {
143       int res = Integer.parseInt(searchString);
144       found = true;
145
146       if (av.getSelectionGroup() == null || av.getSelectionGroup().getSize(false) < 1)
147       {
148         seq = (Sequence) av.getAlignment().getSequenceAt(0);
149       }
150       else
151       {
152         seq = (Sequence) (av.getSelectionGroup().getSequenceAt(0));
153       }
154
155
156       searchResults.addResult(seq, res, res);
157
158     }
159     catch (NumberFormatException ex)
160     {}
161     ///////////////////////////////////////////////
162
163
164     int end = av.alignment.getHeight();
165
166     SequenceGroup selection = av.getSelectionGroup();
167     if (selection != null)
168     {
169       if (selection.getSize(false) < 1 ||
170           (selection.getEndRes() - selection.getStartRes() < 2))
171       {
172         selection = null;
173       }
174     }
175
176     while (!found && seqIndex < end)
177     {
178
179       seq = (Sequence) av.alignment.getSequenceAt(seqIndex);
180
181       if (selection != null && !selection.getSequences(false).contains(seq))
182       {
183         seqIndex++;
184         resIndex = 0;
185         continue;
186       }
187
188       item = seq.getSequence();
189       if(!caseSensitive.getState())
190         item = item.toUpperCase();
191
192       if (selection != null && selection.getEndRes() < av.alignment.getWidth())
193       {
194         item = item.substring(0, selection.getEndRes() + 1);
195       }
196
197       ///Shall we ignore gaps????
198       StringBuffer noGapsSB = new StringBuffer();
199       int insertCount = 0;
200       Vector spaces = new Vector();
201
202       for (int j = 0; j < item.length(); j++)
203       {
204
205         if (!jalview.util.Comparison.isGap(item.charAt(j)))
206         {
207           noGapsSB.append(item.charAt(j));
208           spaces.addElement(new Integer(insertCount));
209         }
210         else
211         {
212           insertCount++;
213         }
214       }
215
216       String noGaps = noGapsSB.toString();
217
218       for (int r = resIndex; r < noGaps.length(); r++)
219       {
220
221         if (regex.searchFrom(noGaps, r))
222         {
223           resIndex = regex.matchedFrom();
224           if (selection != null &&
225               (resIndex + Integer.parseInt(spaces.elementAt(resIndex).toString())) <
226               selection.getStartRes())
227           {
228             continue;
229           }
230
231
232           int sres = seq.findPosition(resIndex +
233                                       Integer.parseInt(spaces.
234               elementAt(resIndex).toString()));
235           int eres = seq.findPosition(regex.matchedTo() - 1 +
236                                       Integer.parseInt(
237                                       spaces.elementAt(regex.matchedTo() - 1).
238                                       toString()));
239
240           searchResults.addResult(seq, sres, eres);
241
242           if (!findAll)
243           {
244             // thats enough, break and display the result
245             found = true;
246             resIndex++;
247             break;
248           }
249
250           r = resIndex;
251         }
252         else
253           break;
254       }
255       if (!found)
256       {
257         seqIndex++;
258         resIndex = 0;
259       }
260     }
261
262     Vector idMatch = new Vector();
263     for (int id = 0; id < av.alignment.getHeight(); id++)
264     {
265       if (regex.search(av.alignment.getSequenceAt(id).getName()))
266       {
267         idMatch.addElement(av.alignment.getSequenceAt(id));
268       }
269     }
270
271     if (searchResults.getSize() == 0 && idMatch.size() > 0)
272     {
273       ap.idPanel.highlightSearchResults(idMatch);
274     }
275
276     if (searchResults.getSize() > 0)
277     {
278       createNewGroup.setEnabled(true);
279     }
280     else
281     {
282       searchResults = null;
283       resIndex = 0;
284       seqIndex = 0;
285     }
286
287     // if allResults is null, this effectively switches displaySearch flag in seqCanvas
288     ap.highlightSearchResults(searchResults);
289
290     if (findAll)
291     {
292       String message = (searchResults==null?0 : searchResults.getSize()) + " matches found.";
293       ap.alignFrame.statusBar.setText("Search results: "+searchString+" : "+message);
294     }
295
296   }
297
298   Label jLabel1 = new Label();
299   protected TextField textfield = new TextField();
300   protected Button findAll = new Button();
301   protected Button findNext = new Button();
302   Panel jPanel1 = new Panel();
303   GridLayout gridLayout1 = new GridLayout();
304   protected Button createNewGroup = new Button();
305   Checkbox caseSensitive = new Checkbox();
306
307   private void jbInit() throws Exception {
308       jLabel1.setFont(new java.awt.Font("Verdana", 0, 12));
309       jLabel1.setText("Find");
310       jLabel1.setBounds(new Rectangle(3, 30, 34, 15));
311       this.setLayout(null);
312       textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
313       textfield.setText("");
314       textfield.setBounds(new Rectangle(40, 27, 133, 21));
315       textfield.addKeyListener(new java.awt.event.KeyAdapter() {
316               public void keyTyped(KeyEvent e) {
317                   textfield_keyTyped(e);
318               }
319           });
320       textfield.addActionListener(this);
321       findAll.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
322       findAll.setLabel("Find all");
323       findAll.addActionListener(this);
324       findNext.setEnabled(false);
325       findNext.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
326       findNext.setLabel("Find Next");
327       findNext.addActionListener(this);
328       jPanel1.setBounds(new Rectangle(180, 5, 141, 64));
329       jPanel1.setLayout(gridLayout1);
330       gridLayout1.setHgap(0);
331       gridLayout1.setRows(3);
332       gridLayout1.setVgap(2);
333       createNewGroup.setEnabled(false);
334       createNewGroup.setFont(new java.awt.Font("Verdana", Font.PLAIN, 10));
335       createNewGroup.setLabel("New Feature");
336       createNewGroup.addActionListener(this);
337     caseSensitive.setLabel("Match Case");
338     caseSensitive.setBounds(new Rectangle(40, 49, 126, 23));
339     jPanel1.add(findNext, null);
340       jPanel1.add(findAll, null);
341       jPanel1.add(createNewGroup, null);
342     this.add(caseSensitive);
343     this.add(textfield, null);
344       this.add(jLabel1, null);
345       this.add(jPanel1, null);
346   }
347
348   void textfield_keyTyped(KeyEvent e) {
349       findNext.setEnabled(true);
350   }
351
352 }