updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
[jalview.git] / src / jalview / gui / 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 package jalview.gui;
20
21 import jalview.datamodel.*;
22
23 import java.awt.*;
24 import java.awt.event.*;
25
26 import javax.swing.*;
27
28
29 /**
30  * DOCUMENT ME!
31  *
32  * @author $author$
33  * @version $Revision$
34  */
35 public class IdPanel extends JPanel implements MouseListener,
36     MouseMotionListener
37 {
38     protected IdCanvas idCanvas;
39     protected AlignViewport av;
40     protected AlignmentPanel alignPanel;
41     ScrollThread scrollThread = null;
42     int offy;
43     int width;
44     int lastid = -1;
45     boolean mouseDragging = false;
46
47     /**
48      * Creates a new IdPanel object.
49      *
50      * @param av DOCUMENT ME!
51      * @param parent DOCUMENT ME!
52      */
53     public IdPanel(AlignViewport av, AlignmentPanel parent)
54     {
55         this.av = av;
56         alignPanel = parent;
57         idCanvas = new IdCanvas(av);
58         setLayout(new BorderLayout());
59         add(idCanvas, BorderLayout.CENTER);
60         addMouseListener(this);
61         addMouseMotionListener(this);
62         ToolTipManager.sharedInstance().registerComponent(this);
63     }
64
65     /**
66      * DOCUMENT ME!
67      *
68      * @param e DOCUMENT ME!
69      */
70     public void mouseMoved(MouseEvent e)
71     {
72       int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));
73       if(seq>-1 && seq<av.alignment.getHeight())
74       {
75         SequenceI sequence = av.alignment.getSequenceAt(seq);
76         StringBuffer tip = new StringBuffer("<html>");
77         tip.append(sequence.getDisplayId(true));
78         if (av.alignment.getSequenceAt(seq).getDescription() != null)
79         {
80           tip.append("<table width=250 border=0><tr><td><i>");
81           tip.append(av.alignment.getSequenceAt(seq).getDescription());
82
83           //ADD NON POSITIONAL SEQUENCE INFO
84           SequenceFeature [] features = sequence.getDatasetSequence().getSequenceFeatures();
85           if(features!=null)
86           {
87             for(int i=0; i<features.length; i++)
88             {
89               if(features[i].begin == 0 && features[i].end ==0)
90               {
91                 tip.append("<br>"+features[i].featureGroup
92                           +" "+ features[i].getType()+" "+features[i].description);
93               }
94             }
95           }
96           tip.append("</i></td></tr></table>");
97         }
98
99         DBRefEntry[] dbrefs = sequence.getDatasetSequence().getDBRef();
100         if (dbrefs != null)
101         {
102           tip.append("<i>");
103           for (int i = 0; i < dbrefs.length; i++)
104           {
105             tip.append("<br>");
106             tip.append(dbrefs[i].getSource() + " "
107                        + dbrefs[i].getAccessionId());
108           }
109           tip.append("</i>");
110         }
111
112         tip.append("</html>");
113         setToolTipText(tip.toString());
114       }
115     }
116
117
118     /**
119      * DOCUMENT ME!
120      *
121      * @param e DOCUMENT ME!
122      */
123     public void mouseDragged(MouseEvent e)
124     {
125         mouseDragging = true;
126
127         int seq = Math.max(0, alignPanel.seqPanel.findSeq(e));
128
129         if (seq < lastid)
130         {
131             selectSeqs(lastid - 1, seq);
132         }
133         else if (seq > lastid)
134         {
135             selectSeqs(lastid + 1, seq);
136         }
137
138         lastid = seq;
139         alignPanel.repaint();
140     }
141
142
143     /**
144      * DOCUMENT ME!
145      *
146      * @param e DOCUMENT ME!
147      */
148     public void mouseClicked(MouseEvent e)
149     {
150       if (e.getClickCount() < 2)
151         return;
152
153       java.util.Vector links = Preferences.sequenceURLLinks;
154       if (links == null || links.size() < 1)
155         return;
156
157       int seq = alignPanel.seqPanel.findSeq(e);
158
159       //DEFAULT LINK IS FIRST IN THE LINK LIST
160
161       String id = av.getAlignment().getSequenceAt(seq).getName();
162       if (id.indexOf("|") > -1)
163         id = id.substring(id.lastIndexOf("|") + 1);
164
165
166       String url = links.elementAt(0).toString();
167       url = url.substring(url.indexOf("|")+1);
168
169       int index = url.indexOf("$SEQUENCE_ID$");
170       url = url.substring(0, index)+ id + url.substring(index+13);
171
172       try
173       {
174         jalview.util.BrowserLauncher.openURL(url);
175       }
176       catch (Exception ex)
177       {
178        JOptionPane.showInternalMessageDialog(Desktop.desktop,
179            "Unixers: Couldn't find default web browser."
180           +"\nAdd the full path to your browser in Preferences.",
181           "Web browser not found", JOptionPane.WARNING_MESSAGE );
182         ex.printStackTrace();
183       }
184     }
185
186     /**
187      * DOCUMENT ME!
188      *
189      * @param e DOCUMENT ME!
190      */
191     public void mouseEntered(MouseEvent e)
192     {
193         if (scrollThread != null)
194         {
195             scrollThread.running = false;
196         }
197     }
198
199     /**
200      * DOCUMENT ME!
201      *
202      * @param e DOCUMENT ME!
203      */
204     public void mouseExited(MouseEvent e)
205     {
206         if (av.getWrapAlignment())
207         {
208             return;
209         }
210
211         if (mouseDragging && (e.getY() < 0) && (av.getStartSeq() > 0))
212         {
213             scrollThread = new ScrollThread(true);
214         }
215
216         if (mouseDragging && (e.getY() >= getHeight()) &&
217                 (av.alignment.getHeight() > av.getEndSeq()))
218         {
219             scrollThread = new ScrollThread(false);
220         }
221     }
222
223     /**
224      * DOCUMENT ME!
225      *
226      * @param e DOCUMENT ME!
227      */
228     public void mousePressed(MouseEvent e)
229     {
230         if (e.getClickCount() == 2)
231         {
232             return;
233         }
234
235         int seq = alignPanel.seqPanel.findSeq(e);
236
237
238         if (javax.swing.SwingUtilities.isRightMouseButton(e))
239         {
240             jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(alignPanel,
241                     (Sequence) av.getAlignment().getSequenceAt(seq),
242                     Preferences.sequenceURLLinks);
243             pop.show(this, e.getX(), e.getY());
244
245             return;
246         }
247
248
249
250         if ((av.getSelectionGroup() == null) ||
251                 ((!e.isControlDown() && !e.isShiftDown()) && av.getSelectionGroup() != null))
252         {
253           av.setSelectionGroup(new SequenceGroup());
254           av.getSelectionGroup().setStartRes(0);
255           av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);
256         }
257
258
259         if (e.isShiftDown() && (lastid != -1))
260         {
261             selectSeqs(lastid, seq);
262         }
263         else
264         {
265             selectSeq(seq);
266         }
267
268         alignPanel.repaint();
269     }
270
271     /**
272      * DOCUMENT ME!
273      *
274      * @param seq DOCUMENT ME!
275      */
276     void selectSeq(int seq)
277     {
278         lastid = seq;
279
280         SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);
281         av.getSelectionGroup().addOrRemove(pickedSeq, true);
282     }
283
284     /**
285      * DOCUMENT ME!
286      *
287      * @param start DOCUMENT ME!
288      * @param end DOCUMENT ME!
289      */
290     void selectSeqs(int start, int end)
291     {
292       if(av.getSelectionGroup()==null)
293             return;
294
295         lastid = start;
296
297         if (end < start)
298         {
299             int tmp = start;
300             start = end;
301             end = tmp;
302             lastid = end;
303         }
304
305         for (int i = start; i <= end; i++)
306         {
307           av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i),
308                 true);
309         }
310     }
311
312     /**
313      * DOCUMENT ME!
314      *
315      * @param e DOCUMENT ME!
316      */
317     public void mouseReleased(MouseEvent e)
318     {
319         if (scrollThread != null)
320         {
321             scrollThread.running = false;
322         }
323
324         mouseDragging = false;
325         PaintRefresher.Refresh(av.alignment);
326     }
327
328     /**
329      * DOCUMENT ME!
330      *
331      * @param found DOCUMENT ME!
332      */
333     public void highlightSearchResults(java.util.Vector found)
334     {
335         idCanvas.setHighlighted(found);
336
337         if (found == null)
338         {
339             return;
340         }
341
342         int index = av.alignment.findIndex((SequenceI) found.get(0));
343
344         // do we need to scroll the panel?
345         if ((av.getStartSeq() > index) || (av.getEndSeq() < index))
346         {
347             alignPanel.setScrollValues(av.getStartRes(), index);
348         }
349     }
350
351     // this class allows scrolling off the bottom of the visible alignment
352     class ScrollThread extends Thread
353     {
354         boolean running = false;
355         boolean up = true;
356
357         public ScrollThread(boolean up)
358         {
359             this.up = up;
360             start();
361         }
362
363         public void stopScrolling()
364         {
365             running = false;
366         }
367
368         public void run()
369         {
370             running = true;
371
372             while (running)
373             {
374                 if (alignPanel.scrollUp(up))
375                 {
376                     // scroll was ok, so add new sequence to selection
377                     int seq = av.getStartSeq();
378
379                     if (!up)
380                     {
381                         seq = av.getEndSeq();
382                     }
383
384                     if (seq < lastid)
385                     {
386                         selectSeqs(lastid - 1, seq);
387                     }
388                     else if (seq > lastid)
389                     {
390                         selectSeqs(lastid + 1, seq);
391                     }
392
393                     lastid = seq;
394                 }
395                 else
396                 {
397                     running = false;
398                 }
399
400                 alignPanel.repaint();
401
402                 try
403                 {
404                     Thread.sleep(100);
405                 }
406                 catch (Exception ex)
407                 {
408                 }
409             }
410         }
411     }
412 }