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