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