/*
* Jalview - A Sequence Alignment Editor and Viewer
* Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package jalview.gui;
import jalview.datamodel.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision$
*/
public class IdPanel extends JPanel implements MouseListener,
MouseMotionListener
{
protected IdCanvas idCanvas;
protected AlignViewport av;
protected AlignmentPanel alignPanel;
ScrollThread scrollThread = null;
int offy;
int width;
int lastid = -1;
boolean mouseDragging = false;
/**
* Creates a new IdPanel object.
*
* @param av DOCUMENT ME!
* @param parent DOCUMENT ME!
*/
public IdPanel(AlignViewport av, AlignmentPanel parent)
{
this.av = av;
alignPanel = parent;
idCanvas = new IdCanvas(av);
setLayout(new BorderLayout());
add(idCanvas, BorderLayout.CENTER);
addMouseListener(this);
addMouseMotionListener(this);
ToolTipManager.sharedInstance().registerComponent(this);
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseMoved(MouseEvent e)
{
int y = e.getY();
if (av.getWrapAlignment())
{
y = getWrappedY(y);
}
final int seq = av.getIndex(y);
if(seq!=-1)
{
SequenceI sequence = av.alignment.getSequenceAt(seq);
StringBuffer tip = new StringBuffer("");
tip.append(sequence.getDisplayId(true));
if (av.alignment.getSequenceAt(seq).getDescription() != null)
{
tip.append("
");
tip.append(av.alignment.getSequenceAt(seq).getDescription());
//ADD NON POSITIONAL SEQUENCE INFO
SequenceFeature [] features = sequence.getDatasetSequence().getSequenceFeatures();
if(features!=null)
{
for(int i=0; i"+features[i].featureGroup
+" "+ features[i].getType()+" "+features[i].description);
}
}
}
tip.append(" |
");
}
DBRefEntry[] dbrefs = sequence.getDatasetSequence().getDBRef();
if (dbrefs != null)
{
tip.append("");
for (int i = 0; i < dbrefs.length; i++)
{
tip.append("
");
tip.append(dbrefs[i].getSource() + " "
+ dbrefs[i].getAccessionId());
}
tip.append("");
}
tip.append("");
setToolTipText(tip.toString());
}
}
int getWrappedY(int y)
{
int hgap = av.charHeight;
if (av.scaleAboveWrapped)
hgap += av.charHeight;
return y - hgap;
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseDragged(MouseEvent e)
{
mouseDragging = true;
int y = e.getY();
if (av.getWrapAlignment())
{
y = getWrappedY(y);
}
int seq = av.getIndex(y);
if (seq < 0)
{
return;
}
if (seq < lastid)
{
selectSeqs(lastid - 1, seq);
}
else if (seq > lastid)
{
selectSeqs(lastid + 1, seq);
}
lastid = seq;
alignPanel.repaint();
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() < 2)
return;
java.util.Vector links = Preferences.sequenceURLLinks;
if (links == null || links.size() < 1)
return;
int y = e.getY();
if (av.getWrapAlignment())
{
y = getWrappedY(y);
}
//DEFAULT LINK IS FIRST IN THE LINK LIST
int seq = av.getIndex(y);
if(seq==-1)
return;
String id = av.getAlignment().getSequenceAt(seq).getName();
if (id.indexOf("|") > -1)
id = id.substring(id.lastIndexOf("|") + 1);
String url = links.elementAt(0).toString();
url = url.substring(url.indexOf("|")+1);
int index = url.indexOf("$SEQUENCE_ID$");
url = url.substring(0, index)+ id + url.substring(index+13);
try
{
jalview.util.BrowserLauncher.openURL(url);
}
catch (Exception ex)
{
JOptionPane.showInternalMessageDialog(Desktop.desktop,
"Unixers: Couldn't find default web browser."
+"\nAdd the full path to your browser in Preferences.",
"Web browser not found", JOptionPane.WARNING_MESSAGE );
ex.printStackTrace();
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseEntered(MouseEvent e)
{
if (scrollThread != null)
{
scrollThread.running = false;
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseExited(MouseEvent e)
{
if (av.getWrapAlignment())
{
return;
}
if (mouseDragging && (e.getY() < 0) && (av.getStartSeq() > 0))
{
scrollThread = new ScrollThread(true);
}
if (mouseDragging && (e.getY() >= getHeight()) &&
(av.alignment.getHeight() > av.getEndSeq()))
{
scrollThread = new ScrollThread(false);
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mousePressed(MouseEvent e)
{
if (e.getClickCount() == 2)
{
return;
}
int y = e.getY();
if (av.getWrapAlignment())
{
y = getWrappedY(y);
}
int seq = av.getIndex(y);
if (seq == -1)
{
return;
}
if (javax.swing.SwingUtilities.isRightMouseButton(e))
{
jalview.gui.PopupMenu pop = new jalview.gui.PopupMenu(alignPanel,
(Sequence) av.getAlignment().getSequenceAt(seq),
Preferences.sequenceURLLinks);
pop.show(this, e.getX(), y);
return;
}
/* if (!e.isControlDown() && !e.isShiftDown() &&
(av.alignment.findGroup(av.alignment.getSequenceAt(seq)) != null))
{
System.out.println("no modifiers");
SequenceGroup selection = new SequenceGroup();
SequenceGroup sg = av.alignment.findGroup(av.alignment.getSequenceAt(
seq));
selection.setStartRes(0);
selection.setEndRes(av.alignment.getWidth() - 1);
for (int i = 0; i < sg.getSize(); i++)
{
selection.addSequence(sg.getSequenceAt(i), true);
}
av.setSelectionGroup(selection);
return;
}*/
if ((av.getSelectionGroup() == null) ||
((!e.isControlDown() && !e.isShiftDown()) && av.getSelectionGroup() != null))
{
av.setSelectionGroup(new SequenceGroup());
av.getSelectionGroup().setStartRes(0);
av.getSelectionGroup().setEndRes(av.alignment.getWidth() - 1);
}
if (e.isShiftDown() && (lastid != -1))
{
selectSeqs(lastid, seq);
}
else
{
selectSeq(seq);
}
alignPanel.repaint();
}
/**
* DOCUMENT ME!
*
* @param seq DOCUMENT ME!
*/
void selectSeq(int seq)
{
lastid = seq;
SequenceI pickedSeq = av.getAlignment().getSequenceAt(seq);
av.getSelectionGroup().addOrRemove(pickedSeq, true);
}
/**
* DOCUMENT ME!
*
* @param start DOCUMENT ME!
* @param end DOCUMENT ME!
*/
void selectSeqs(int start, int end)
{
if(av.getSelectionGroup()==null)
return;
lastid = start;
if (end < start)
{
int tmp = start;
start = end;
end = tmp;
lastid = end;
}
for (int i = start; i <= end; i++)
{
av.getSelectionGroup().addSequence(av.getAlignment().getSequenceAt(i),
true);
}
}
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseReleased(MouseEvent e)
{
if (scrollThread != null)
{
scrollThread.running = false;
}
mouseDragging = false;
PaintRefresher.Refresh(av.alignment);
}
/**
* DOCUMENT ME!
*
* @param found DOCUMENT ME!
*/
public void highlightSearchResults(java.util.Vector found)
{
idCanvas.setHighlighted(found);
if (found == null)
{
return;
}
int index = av.alignment.findIndex((SequenceI) found.get(0));
// do we need to scroll the panel?
if ((av.getStartSeq() > index) || (av.getEndSeq() < index))
{
alignPanel.setScrollValues(av.getStartRes(), index);
}
}
// this class allows scrolling off the bottom of the visible alignment
class ScrollThread extends Thread
{
boolean running = false;
boolean up = true;
public ScrollThread(boolean up)
{
this.up = up;
start();
}
public void stopScrolling()
{
running = false;
}
public void run()
{
running = true;
while (running)
{
if (alignPanel.scrollUp(up))
{
// scroll was ok, so add new sequence to selection
int seq = av.getStartSeq();
if (!up)
{
seq = av.getEndSeq();
}
if (seq < lastid)
{
selectSeqs(lastid - 1, seq);
}
else if (seq > lastid)
{
selectSeqs(lastid + 1, seq);
}
lastid = seq;
}
else
{
running = false;
}
alignPanel.repaint();
try
{
Thread.sleep(100);
}
catch (Exception ex)
{
}
}
}
}
}