Multiple Views
[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           if (end >= av.getAlignment().getHeight())\r
296           {\r
297             end = av.getAlignment().getHeight() - 1;\r
298           }\r
299 \r
300         lastid = start;\r
301 \r
302         if (end < start)\r
303         {\r
304             int tmp = start;\r
305             start = end;\r
306             end = tmp;\r
307             lastid = end;\r
308         }\r
309 \r
310         for (int i = start; i <= end; i++)\r
311         {\r
312           av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i),\r
313                 true);\r
314         }\r
315     }\r
316 \r
317     /**\r
318      * DOCUMENT ME!\r
319      *\r
320      * @param e DOCUMENT ME!\r
321      */\r
322     public void mouseReleased(MouseEvent e)\r
323     {\r
324         if (scrollThread != null)\r
325         {\r
326             scrollThread.running = false;\r
327         }\r
328 \r
329         mouseDragging = false;\r
330         PaintRefresher.Refresh(this, av.getSequenceSetId());\r
331     }\r
332 \r
333     /**\r
334      * DOCUMENT ME!\r
335      *\r
336      * @param found DOCUMENT ME!\r
337      */\r
338     public void highlightSearchResults(java.util.Vector found)\r
339     {\r
340         idCanvas.setHighlighted(found);\r
341 \r
342         if (found == null)\r
343         {\r
344             return;\r
345         }\r
346 \r
347         int index = av.alignment.findIndex((SequenceI) found.get(0));\r
348 \r
349         // do we need to scroll the panel?\r
350         if ((av.getStartSeq() > index) || (av.getEndSeq() < index))\r
351         {\r
352             alignPanel.setScrollValues(av.getStartRes(), index);\r
353         }\r
354     }\r
355 \r
356     // this class allows scrolling off the bottom of the visible alignment\r
357     class ScrollThread extends Thread\r
358     {\r
359         boolean running = false;\r
360         boolean up = true;\r
361 \r
362         public ScrollThread(boolean up)\r
363         {\r
364             this.up = up;\r
365             start();\r
366         }\r
367 \r
368         public void stopScrolling()\r
369         {\r
370             running = false;\r
371         }\r
372 \r
373         public void run()\r
374         {\r
375             running = true;\r
376 \r
377             while (running)\r
378             {\r
379                 if (alignPanel.scrollUp(up))\r
380                 {\r
381                     // scroll was ok, so add new sequence to selection\r
382                     int seq = av.getStartSeq();\r
383 \r
384                     if (!up)\r
385                     {\r
386                         seq = av.getEndSeq();\r
387                     }\r
388 \r
389                     if (seq < lastid)\r
390                     {\r
391                         selectSeqs(lastid - 1, seq);\r
392                     }\r
393                     else if (seq > lastid)\r
394                     {\r
395                         selectSeqs(lastid + 1, seq);\r
396                     }\r
397 \r
398                     lastid = seq;\r
399                 }\r
400                 else\r
401                 {\r
402                     running = false;\r
403                 }\r
404 \r
405                 alignPanel.repaint();\r
406 \r
407                 try\r
408                 {\r
409                     Thread.sleep(100);\r
410                 }\r
411                 catch (Exception ex)\r
412                 {\r
413                 }\r
414             }\r
415         }\r
416     }\r
417 }\r