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