a04d7bfc9b5a5d0f78c2ac0ac1fc8237482cfdb0
[jalview.git] / src / jalview / appletgui / IdPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19
20 package jalview.appletgui;
21
22 import java.awt.*;
23 import java.awt.event.*;
24
25 import jalview.datamodel.*;
26
27 public class IdPanel
28     extends Panel implements MouseListener, MouseMotionListener
29 {
30
31   protected IdCanvas idCanvas;
32   protected AlignViewport av;
33   protected AlignmentPanel alignPanel;
34   ScrollThread scrollThread = null;
35
36   int offy;
37   int width;
38   int lastid = -1;
39   boolean mouseDragging = false;
40   java.util.Vector links = new java.util.Vector();
41
42   public IdPanel(AlignViewport av, AlignmentPanel parent)
43   {
44     this.av = av;
45     alignPanel = parent;
46     idCanvas = new IdCanvas(av);
47     setLayout(new BorderLayout());
48     add(idCanvas, BorderLayout.CENTER);
49     idCanvas.addMouseListener(this);
50     idCanvas.addMouseMotionListener(this);
51
52     String label, url;
53     if(av.applet!=null)
54     {
55       for (int i = 1; i < 10; i++)
56       {
57         label = av.applet.getParameter("linkLabel_" + i);
58         url = av.applet.getParameter("linkURL_" + i);
59
60         if (label != null && url != null)
61           links.addElement(label + "|" + url);
62
63       }
64     }
65     if (links.size() < 1)
66     {
67       links = new java.util.Vector();
68       links.addElement("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
69     }
70   }
71
72   Tooltip tooltip;
73   public void mouseMoved(MouseEvent e)
74   {
75     int seq = alignPanel.seqPanel.findSeq(e);
76
77     SequenceI sequence = av.getAlignment().getSequenceAt(seq);
78
79     if(sequence.getDescription()==null)
80     {
81       if(tooltip!=null)
82         tooltip.setVisible(false);
83       tooltip = null;
84       return;
85     }
86
87     if (tooltip == null)
88       tooltip = new Tooltip(
89           sequence.getDisplayId(true)
90           + "\n" + sequence.getDescription(), idCanvas);
91     else
92       tooltip.setTip(sequence.getDisplayId(true)
93                      + "\n" + sequence.getDescription());
94
95     tooltip.repaint();
96
97   }
98
99   public void mouseDragged(MouseEvent e)
100   {
101     mouseDragging = true;
102
103     int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));
104
105     if (seq < lastid)
106     {
107       selectSeqs(lastid - 1, seq);
108     }
109     else if (seq > lastid)
110     {
111       selectSeqs(lastid + 1, seq);
112     }
113
114     lastid = seq;
115     alignPanel.repaint();
116   }
117
118   public void mouseClicked(MouseEvent e)
119   {
120     if (e.getClickCount() < 2)
121         return;
122
123
124     //DEFAULT LINK IS FIRST IN THE LINK LIST
125     int seq = alignPanel.seqPanel.findSeq(e);
126     String id = av.getAlignment().getSequenceAt(seq).getName();
127     if (id.indexOf("|") > -1)
128         id = id.substring(id.lastIndexOf("|") + 1);
129
130     String target = links.elementAt(0).toString();
131     target = target.substring(0, target.indexOf("|"));
132     String url = links.elementAt(0).toString();
133     url = url.substring(url.indexOf("|")+1);
134
135     int index = url.indexOf("$SEQUENCE_ID$");
136     url = url.substring(0, index)+ id + url.substring(index+13);
137
138     try
139     {
140
141       alignPanel.alignFrame.showURL(url, target);
142     }
143     catch (Exception ex)
144     {
145       ex.printStackTrace();
146     }
147   }
148
149   public void mouseEntered(MouseEvent e)
150   {
151     if (scrollThread != null)
152     {
153       scrollThread.running = false;
154     }
155   }
156
157   public void mouseExited(MouseEvent e)
158   {
159     if (av.getWrapAlignment())
160     {
161       return;
162     }
163
164     if (mouseDragging && e.getY() < 0 && av.getStartSeq() > 0)
165     {
166       scrollThread = new ScrollThread(true);
167     }
168
169     if (mouseDragging && e.getY() >= getSize().height &&
170         av.alignment.getHeight() > av.getEndSeq())
171     {
172       scrollThread = new ScrollThread(false);
173     }
174   }
175
176   public void mousePressed(MouseEvent e)
177   {
178     if (e.getClickCount() >1 )
179     {
180       return;
181     }
182
183     int y = e.getY();
184     if (av.getWrapAlignment())
185     {
186       y -= 2 * av.charHeight;
187     }
188
189     int seq = alignPanel.seqPanel.findSeq(e);
190
191     if ( (e.getModifiers() & InputEvent.BUTTON3_MASK) ==
192         InputEvent.BUTTON3_MASK)
193     {
194       APopupMenu popup = new APopupMenu(alignPanel, (Sequence) av.getAlignment().getSequenceAt(seq), links);
195       this.add(popup);
196       popup.show(this, e.getX(), e.getY());
197       return;
198     }
199
200
201     if ((av.getSelectionGroup() == null) ||
202             ((!e.isControlDown() && !e.isShiftDown()) && av.getSelectionGroup() != null))
203     {
204       av.setSelectionGroup(new SequenceGroup());
205       av.getSelectionGroup().setStartRes(0);
206       av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);
207     }
208
209
210     if (e.isShiftDown() && lastid != -1)
211     {
212       selectSeqs(lastid, seq);
213     }
214     else
215     {
216       selectSeq(seq);
217     }
218
219     alignPanel.repaint();
220   }
221
222   void selectSeq(int seq)
223   {
224     lastid = seq;
225     SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);
226     av.getSelectionGroup().addOrRemove(pickedSeq, false);
227   }
228
229   void selectSeqs(int start, int end)
230   {
231
232     lastid = start;
233     if (end < start)
234     {
235       int tmp = start;
236       start = end;
237       end = tmp;
238       lastid = end;
239     }
240
241     for (int i = start; i <= end; i++)
242     {
243       av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i), false);
244     }
245
246   }
247
248   public void mouseReleased(MouseEvent e)
249   {
250     if (scrollThread != null)
251     {
252       scrollThread.running = false;
253     }
254
255     if(av.getSelectionGroup()!=null)
256       av.getSelectionGroup().recalcConservation();
257
258     mouseDragging = false;
259     PaintRefresher.Refresh(this, av.alignment);
260   }
261
262   public void highlightSearchResults(java.util.Vector found)
263   {
264     idCanvas.setHighlighted(found);
265
266     if (found == null)
267     {
268       return;
269     }
270
271     int index = av.alignment.findIndex( (SequenceI) found.elementAt(0));
272
273     // do we need to scroll the panel?
274     if (av.getStartSeq() > index || av.getEndSeq() < index)
275     {
276       alignPanel.setScrollValues(av.getStartRes(), index);
277     }
278   }
279
280   // this class allows scrolling off the bottom of the visible alignment
281   class ScrollThread
282       extends Thread
283   {
284     boolean running = false;
285     boolean up = true;
286     public ScrollThread(boolean up)
287     {
288       this.up = up;
289       start();
290     }
291
292     public void stopScrolling()
293     {
294       running = false;
295     }
296
297     public void run()
298     {
299       running = true;
300       while (running)
301       {
302         if (alignPanel.scrollUp(up))
303         {
304           // scroll was ok, so add new sequence to selection
305           int seq = av.getStartSeq();
306           if (!up)
307           {
308             seq = av.getEndSeq();
309           }
310
311           if (seq < lastid)
312           {
313             selectSeqs(lastid - 1, seq);
314           }
315           else if (seq > lastid && seq<av.alignment.getHeight())
316           {
317             selectSeqs(lastid + 1, seq);
318           }
319
320
321           lastid = seq;
322         }
323         else
324         {
325           running = false;
326         }
327
328         alignPanel.repaint();
329         try
330         {
331           Thread.sleep(100);
332         }
333         catch (Exception ex)
334         {}
335       }
336     }
337   }
338
339 }