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