Add dbrefs before zero length features
[jalview.git] / src / jalview / gui / IdPanel.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 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 package jalview.gui;\r
20 \r
21 import java.awt.*;\r
22 import java.awt.event.*;\r
23 import javax.swing.*;\r
24 \r
25 import jalview.datamodel.*;\r
26 \r
27 /**\r
28  * DOCUMENT ME!\r
29  *\r
30  * @author $author$\r
31  * @version $Revision$\r
32  */\r
33 public class IdPanel\r
34     extends JPanel implements MouseListener,\r
35     MouseMotionListener, MouseWheelListener\r
36 {\r
37   protected IdCanvas idCanvas;\r
38   protected AlignViewport av;\r
39   protected AlignmentPanel alignPanel;\r
40   ScrollThread scrollThread = null;\r
41   int offy;\r
42   int width;\r
43   int lastid = -1;\r
44   boolean mouseDragging = false;\r
45 \r
46   /**\r
47    * Creates a new IdPanel object.\r
48    *\r
49    * @param av DOCUMENT ME!\r
50    * @param parent DOCUMENT ME!\r
51    */\r
52   public IdPanel(AlignViewport av, AlignmentPanel parent)\r
53   {\r
54     this.av = av;\r
55     alignPanel = parent;\r
56     idCanvas = new IdCanvas(av);\r
57     setLayout(new BorderLayout());\r
58     add(idCanvas, BorderLayout.CENTER);\r
59     addMouseListener(this);\r
60     addMouseMotionListener(this);\r
61     addMouseWheelListener(this);\r
62     ToolTipManager.sharedInstance().registerComponent(this);\r
63   }\r
64 \r
65   /**\r
66    * DOCUMENT ME!\r
67    *\r
68    * @param e DOCUMENT ME!\r
69    */\r
70   public void mouseMoved(MouseEvent e)\r
71   {\r
72     int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));\r
73     if (seq > -1 && seq < av.alignment.getHeight())\r
74     {\r
75       SequenceI sequence = av.alignment.getSequenceAt(seq);\r
76       StringBuffer tip = new StringBuffer("<html>");\r
77       tip.append(sequence.getDisplayId(true));\r
78       if (sequence.getDescription() != null)\r
79       {\r
80         tip.append("<table width=250 border=0><tr><td><i>");\r
81         tip.append(sequence.getDescription());\r
82 \r
83         DBRefEntry[] dbrefs = sequence.getDatasetSequence().getDBRef();\r
84         if (dbrefs != null)\r
85         {\r
86           tip.append("<i>");\r
87           for (int i = 0; i < dbrefs.length; i++)\r
88           {\r
89             tip.append("<br>");\r
90             tip.append(dbrefs[i].getSource() + " "\r
91                        + dbrefs[i].getAccessionId());\r
92           }\r
93           tip.append("</i>");\r
94         }\r
95 \r
96         //ADD NON POSITIONAL SEQUENCE INFO\r
97         SequenceFeature[] features = sequence.getDatasetSequence().\r
98             getSequenceFeatures();\r
99         if (features != null)\r
100         {\r
101           for (int i = 0; i < features.length; i++)\r
102           {\r
103             if (features[i].begin == 0 && features[i].end == 0)\r
104             {\r
105               tip.append("<br>" + features[i].featureGroup\r
106                          + " " + features[i].getType() + " " +\r
107                          features[i].description);\r
108             }\r
109           }\r
110         }\r
111         tip.append("</i></td></tr></table>");\r
112       }\r
113 \r
114 \r
115       tip.append("</html>");\r
116       setToolTipText(tip.toString());\r
117     }\r
118   }\r
119 \r
120   /**\r
121    * DOCUMENT ME!\r
122    *\r
123    * @param e DOCUMENT ME!\r
124    */\r
125   public void mouseDragged(MouseEvent e)\r
126   {\r
127     mouseDragging = true;\r
128 \r
129     int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));\r
130 \r
131     if (seq < lastid)\r
132     {\r
133       selectSeqs(lastid - 1, seq);\r
134     }\r
135     else if (seq > lastid)\r
136     {\r
137       selectSeqs(lastid + 1, seq);\r
138     }\r
139 \r
140     lastid = seq;\r
141     alignPanel.paintAlignment(true);\r
142   }\r
143 \r
144   public void mouseWheelMoved(MouseWheelEvent e)\r
145   {\r
146     e.consume();\r
147       if (e.getWheelRotation() > 0)\r
148       {\r
149         alignPanel.scrollUp(false);\r
150       }\r
151       else\r
152       {\r
153         alignPanel.scrollUp(true);\r
154       }\r
155   }\r
156 \r
157   /**\r
158    * DOCUMENT ME!\r
159    *\r
160    * @param e DOCUMENT ME!\r
161    */\r
162   public void mouseClicked(MouseEvent e)\r
163   {\r
164     if (e.getClickCount() < 2)\r
165     {\r
166       return;\r
167     }\r
168 \r
169     java.util.Vector links = Preferences.sequenceURLLinks;\r
170     if (links == null || links.size() < 1)\r
171     {\r
172       return;\r
173     }\r
174 \r
175     int seq = alignPanel.seqPanel.findSeq(e);\r
176 \r
177     //DEFAULT LINK IS FIRST IN THE LINK LIST\r
178 \r
179     String id = av.getAlignment().getSequenceAt(seq).getName();\r
180     if (id.indexOf("|") > -1)\r
181     {\r
182       id = id.substring(id.lastIndexOf("|") + 1);\r
183     }\r
184 \r
185     String url = links.elementAt(0).toString();\r
186     url = url.substring(url.indexOf("|") + 1);\r
187 \r
188     int index = url.indexOf("$SEQUENCE_ID$");\r
189     url = url.substring(0, index) + id + url.substring(index + 13);\r
190 \r
191     try\r
192     {\r
193       jalview.util.BrowserLauncher.openURL(url);\r
194     }\r
195     catch (Exception ex)\r
196     {\r
197       JOptionPane.showInternalMessageDialog(Desktop.desktop,\r
198                                             "Unixers: Couldn't find default web browser."\r
199                                             +\r
200           "\nAdd the full path to your browser in Preferences.",\r
201                                             "Web browser not found",\r
202                                             JOptionPane.WARNING_MESSAGE);\r
203       ex.printStackTrace();\r
204     }\r
205   }\r
206 \r
207   /**\r
208    * DOCUMENT ME!\r
209    *\r
210    * @param e DOCUMENT ME!\r
211    */\r
212   public void mouseEntered(MouseEvent e)\r
213   {\r
214     if (scrollThread != null)\r
215     {\r
216       scrollThread.running = false;\r
217     }\r
218   }\r
219 \r
220   /**\r
221    * DOCUMENT ME!\r
222    *\r
223    * @param e DOCUMENT ME!\r
224    */\r
225   public void mouseExited(MouseEvent e)\r
226   {\r
227     if (av.getWrapAlignment())\r
228     {\r
229       return;\r
230     }\r
231 \r
232     if (mouseDragging && (e.getY() < 0) && (av.getStartSeq() > 0))\r
233     {\r
234       scrollThread = new ScrollThread(true);\r
235     }\r
236 \r
237     if (mouseDragging && (e.getY() >= getHeight()) &&\r
238         (av.alignment.getHeight() > av.getEndSeq()))\r
239     {\r
240       scrollThread = new ScrollThread(false);\r
241     }\r
242   }\r
243 \r
244   /**\r
245    * DOCUMENT ME!\r
246    *\r
247    * @param e DOCUMENT ME!\r
248    */\r
249   public void mousePressed(MouseEvent e)\r
250   {\r
251     if (e.getClickCount() == 2)\r
252     {\r
253       return;\r
254     }\r
255 \r
256     int seq = alignPanel.seqPanel.findSeq(e);\r
257 \r
258     if (javax.swing.SwingUtilities.isRightMouseButton(e))\r
259     {\r
260       jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(alignPanel,\r
261           (Sequence) av.getAlignment().getSequenceAt(seq),\r
262           Preferences.sequenceURLLinks);\r
263       pop.show(this, e.getX(), e.getY());\r
264 \r
265       return;\r
266     }\r
267 \r
268     if ( (av.getSelectionGroup() == null) ||\r
269         ( (!e.isControlDown() && !e.isShiftDown()) && av.getSelectionGroup() != null))\r
270     {\r
271       av.setSelectionGroup(new SequenceGroup());\r
272       av.getSelectionGroup().setStartRes(0);\r
273       av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);\r
274     }\r
275 \r
276     if (e.isShiftDown() && (lastid != -1))\r
277     {\r
278       selectSeqs(lastid, seq);\r
279     }\r
280     else\r
281     {\r
282       selectSeq(seq);\r
283     }\r
284 \r
285     alignPanel.paintAlignment(true);\r
286   }\r
287 \r
288   /**\r
289    * DOCUMENT ME!\r
290    *\r
291    * @param seq DOCUMENT ME!\r
292    */\r
293   void selectSeq(int seq)\r
294   {\r
295     lastid = seq;\r
296 \r
297     SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);\r
298     av.getSelectionGroup().addOrRemove(pickedSeq, true);\r
299   }\r
300 \r
301   /**\r
302    * DOCUMENT ME!\r
303    *\r
304    * @param start DOCUMENT ME!\r
305    * @param end DOCUMENT ME!\r
306    */\r
307   void selectSeqs(int start, int end)\r
308   {\r
309     if (av.getSelectionGroup() == null)\r
310     {\r
311       return;\r
312     }\r
313 \r
314     if (end >= av.getAlignment().getHeight())\r
315     {\r
316       end = av.getAlignment().getHeight() - 1;\r
317     }\r
318 \r
319     lastid = start;\r
320 \r
321     if (end < start)\r
322     {\r
323       int tmp = start;\r
324       start = end;\r
325       end = tmp;\r
326       lastid = end;\r
327     }\r
328 \r
329     for (int i = start; i <= end; i++)\r
330     {\r
331       av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i),\r
332                                          true);\r
333     }\r
334   }\r
335 \r
336   /**\r
337    * DOCUMENT ME!\r
338    *\r
339    * @param e DOCUMENT ME!\r
340    */\r
341   public void mouseReleased(MouseEvent e)\r
342   {\r
343     if (scrollThread != null)\r
344     {\r
345       scrollThread.running = false;\r
346     }\r
347 \r
348     mouseDragging = false;\r
349     PaintRefresher.Refresh(this, av.getSequenceSetId());\r
350   }\r
351 \r
352   /**\r
353    * DOCUMENT ME!\r
354    *\r
355    * @param found DOCUMENT ME!\r
356    */\r
357   public void highlightSearchResults(java.util.Vector found)\r
358   {\r
359     idCanvas.setHighlighted(found);\r
360 \r
361     if (found == null)\r
362     {\r
363       return;\r
364     }\r
365 \r
366     int index = av.alignment.findIndex( (SequenceI) found.get(0));\r
367 \r
368     // do we need to scroll the panel?\r
369     if ( (av.getStartSeq() > index) || (av.getEndSeq() < index))\r
370     {\r
371       alignPanel.setScrollValues(av.getStartRes(), index);\r
372     }\r
373   }\r
374 \r
375   // this class allows scrolling off the bottom of the visible alignment\r
376   class ScrollThread\r
377       extends Thread\r
378   {\r
379     boolean running = false;\r
380     boolean up = true;\r
381 \r
382     public ScrollThread(boolean up)\r
383     {\r
384       this.up = up;\r
385       start();\r
386     }\r
387 \r
388     public void stopScrolling()\r
389     {\r
390       running = false;\r
391     }\r
392 \r
393     public void run()\r
394     {\r
395       running = true;\r
396 \r
397       while (running)\r
398       {\r
399         if (alignPanel.scrollUp(up))\r
400         {\r
401           // scroll was ok, so add new sequence to selection\r
402           int seq = av.getStartSeq();\r
403 \r
404           if (!up)\r
405           {\r
406             seq = av.getEndSeq();\r
407           }\r
408 \r
409           if (seq < lastid)\r
410           {\r
411             selectSeqs(lastid - 1, seq);\r
412           }\r
413           else if (seq > lastid)\r
414           {\r
415             selectSeqs(lastid + 1, seq);\r
416           }\r
417 \r
418           lastid = seq;\r
419         }\r
420         else\r
421         {\r
422           running = false;\r
423         }\r
424 \r
425         alignPanel.paintAlignment(false);\r
426 \r
427         try\r
428         {\r
429           Thread.sleep(100);\r
430         }\r
431         catch (Exception ex)\r
432         {\r
433         }\r
434       }\r
435     }\r
436   }\r
437 }\r