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