1 /* 2 * 3 * created: Wed Aug 3 2004 4 * 5 * This file is part of Artemis 6 * 7 * Copyright(C) 2000 Genome Research Limited 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 2 12 * of the License, or(at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 * 23 */ 24 25 package uk.ac.sanger.artemis.editor; 26 27 import java.util.StringTokenizer; 28 import java.util.Vector; 29 import javax.swing.border.*; 30 import javax.swing.event.*; 31 import javax.swing.text.html.*; 32 import javax.swing.text.Document; 33 import javax.swing.*; 34 import java.awt.*; 35 import java.awt.event.*; 36 import java.io.BufferedReader; 37 import java.io.StringReader; 38 import java.io.IOException; 39 import javax.swing.text.BadLocationException; 40 import java.net.URL; 41 42 public class Annotation extends JEditorPane 43 implements HyperlinkListener 44 { 45 /** */ 46 private static final long serialVersionUID = 1L; 47 private int startRange; 48 //private int endRange; 49 /** busy cursor */ 50 private Cursor cbusy = new Cursor(Cursor.WAIT_CURSOR); 51 /** done cursor */ 52 private Cursor cdone = new Cursor(Cursor.DEFAULT_CURSOR); 53 /** desktop pane */ 54 private JDesktopPane desktop = null; 55 /** back option */ 56 private Vector back = new Vector(); 57 /** popup menu */ 58 private JPopupMenu popup; 59 /** known qualifiers */ 60 private Vector qualifier = new Vector(); 61 Annotation(JDesktopPane desktop)62 public Annotation(JDesktopPane desktop) 63 { 64 super(); 65 this.desktop = desktop; 66 67 setEditable(false); 68 setContentType("text/html"); 69 setFont(BigPane.font); 70 addHyperlinkListener(this); 71 } 72 73 Annotation(URL url)74 public Annotation(URL url) throws IOException 75 { 76 super(url); 77 78 setEditable(false); 79 addHyperlinkListener(this); 80 81 // popup 82 addMouseListener(new PopupListener()); 83 popup = new JPopupMenu(); 84 JMenuItem backMenu = new JMenuItem("Back"); 85 popup.add(backMenu); 86 backMenu.addActionListener(new ActionListener() 87 { 88 public void actionPerformed(ActionEvent e) 89 { 90 goBack(); 91 } 92 }); 93 back.add(url); 94 } 95 setAnnotation(String text)96 protected void setAnnotation(String text) 97 { 98 // setText("<html><body>"+text+"</html></body>"); 99 // reportHTML(); 100 // startRange = getDocument().getLength(); 101 String line = null; 102 103 // record qualifiers used 104 try 105 { 106 BufferedReader buffRead = new BufferedReader(new StringReader(text)); 107 while((line = buffRead.readLine()) != null) 108 { 109 int ind = line.indexOf("="); 110 if(ind > -1) 111 qualifier.add(line.substring(0,ind+1).toLowerCase()); 112 } 113 } 114 catch(IOException ioe){} 115 qualifier.add("/similarity="); 116 qualifier.add("/gene="); 117 qualifier.add("/GO_component="); 118 qualifier.add("/product="); 119 qualifier.add("/EC_number="); 120 qualifier.add("/note="); 121 122 text = getDatabaseHTML(text,"SWALL:"); 123 text = getDatabaseHTML(text,"UniProt:"); 124 text = getDatabaseHTML(text,"EMBL:"); 125 setText("<html><body><font size=3>"+text+"</font></html></body>"); 126 startRange = getDocument().getLength(); 127 } 128 129 reportHTML()130 protected void reportHTML() 131 { 132 try 133 { 134 String txt = ((HTMLDocument)getDocument()).getText(0,getDocument().getLength()); 135 System.out.println("TXT:\n"+txt); 136 System.out.println("\nHTML:\n"+getText()+"\n\n"); 137 } 138 catch(BadLocationException ble) 139 { 140 ble.printStackTrace(); 141 } 142 } 143 144 getFeatureText()145 protected String getFeatureText() 146 { 147 String txt = ""; 148 try 149 { 150 txt = ((HTMLDocument)getDocument()).getText(0,getDocument().getLength()).trim(); 151 152 StringBuffer buff = new StringBuffer(); 153 StringTokenizer tok = new StringTokenizer(txt,"/"); 154 int ntok = 0; 155 156 while(tok.hasMoreTokens()) 157 { 158 String tokTxt = "/"+tok.nextToken().trim(); 159 160 int ind = tokTxt.indexOf("="); 161 162 if(ntok != 0 && ind > -1 && qualifier.contains(tokTxt.substring(0,ind+1))) 163 buff.append("\n"+tokTxt); 164 else 165 buff.append(tokTxt); 166 167 ntok++; 168 } 169 170 txt = buff.toString(); 171 } 172 catch(BadLocationException ble) 173 { 174 ble.printStackTrace(); 175 } 176 177 return txt; 178 } 179 180 insert(String s, boolean ortholog)181 protected void insert(String s, boolean ortholog) 182 { 183 s = getDatabaseHTML(s,"SWALL:"); 184 s = getDatabaseHTML(s,"UniProt:"); 185 s = getDatabaseHTML(s,"EMBL:"); 186 s = getGeneDBHTML(s); 187 188 // int ind = s.indexOf("/gene"); 189 190 Document doc = getDocument(); 191 int offset = doc.getLength(); 192 if(ortholog) 193 offset = startRange; 194 195 insert(s,offset); 196 197 setCaretPosition(doc.getLength()); 198 // reportHTML(); 199 } 200 201 insert(String s, int offset)202 protected void insert(String s, int offset) 203 { 204 try 205 { 206 HTMLEditorKit edKit = (HTMLEditorKit)getEditorKit(); 207 // ((HTMLDocument)getDocument()).insertString(offset,"\n",null); 208 edKit.insertHTML((HTMLDocument)getDocument(),offset,"<BR>\n"+s,0,0,HTML.Tag.BR); 209 // HTMLEditorKit.InsertHTMLTextAction("similarity",s,HTML.Tag.BODY,HTML.Tag.P); 210 } 211 catch(BadLocationException ble) 212 { 213 System.out.println("Offset "+offset); 214 ble.printStackTrace(); 215 } 216 catch(Exception exp) 217 { 218 exp.printStackTrace(); 219 } 220 } 221 222 getGeneDBHTML(String s)223 private String getGeneDBHTML(String s) 224 { 225 int ind = s.indexOf("GeneDB"); 226 if(ind>-1) 227 { 228 String startStr = s.substring(0,ind); 229 int ind2 = s.indexOf(";",ind); 230 231 String midStr = s.substring(ind,ind2); 232 String endStr = s.substring(ind2); 233 234 ind2 = midStr.indexOf(":")+1; 235 236 String db = midStr.substring(7,8)+".+"+ 237 midStr.substring(8,ind2-1); 238 String genedb = "http://www.genedb.org/genedb/Search?name="+ 239 midStr.substring(ind2)+ 240 "&organism="+db; 241 242 s = startStr + "<a href=\""+genedb+"\">" + 243 midStr + "</a>" + endStr; 244 } 245 return s; 246 } 247 248 getDatabaseHTML(String s, String db)249 private String getDatabaseHTML(String s, String db) 250 { 251 // int ind = s.indexOf(db); 252 253 // if(ind == -1) 254 // ind = s.indexOf(db.toLowerCase()); 255 256 // if(ind>-1) 257 // { 258 // s = setHyperLinks(s,ind); 259 // String startStr = s.substring(0,ind); 260 // int ind2 = s.indexOf(" ",ind); 261 // int ind3 = s.indexOf(")",ind); 262 // if(ind3>-1 && ind3<ind2) 263 // ind2 = ind3; 264 // ind3 = s.indexOf(";",ind); 265 // if(ind3>-1 && ind3<ind2) 266 // ind2 = ind3; 267 268 // String midStr = s.substring(ind,ind2); 269 // String endStr = s.substring(ind2); 270 271 // String srscmd = "http://srs.sanger.ac.uk/srsbin/cgi-bin/wgetz?-e+" + 272 // "["+midStr+"]"; 273 274 // s = startStr + "<a href=\""+srscmd+"\">" + 275 // midStr + "</a>" + endStr; 276 // } 277 278 int ind = 0; 279 while((ind = s.indexOf(db, ind)) > -1) 280 { 281 s = setHyperLinks(s,ind); 282 ind = s.lastIndexOf("</a>"); 283 } 284 285 db = db.toLowerCase(); 286 ind = 0; 287 while((ind = s.indexOf(db+":", ind)) > -1) 288 { 289 s = setHyperLinks(s,ind); 290 ind = s.lastIndexOf("</a>"); 291 } 292 293 return s; 294 } 295 setHyperLinks(String s, int ind)296 private String setHyperLinks(String s, int ind) 297 { 298 String startStr = s.substring(0,ind); 299 int ind2 = s.indexOf(" ",ind); 300 if(ind2 == -1) 301 ind2 = s.indexOf(";",ind); 302 303 int ind3 = s.indexOf(")",ind); 304 if(ind3>-1 && ind3<ind2) 305 ind2 = ind3; 306 ind3 = s.indexOf(";",ind); 307 if(ind3>-1 && ind3<ind2) 308 ind2 = ind3; 309 ind3 = s.indexOf("\"",ind); 310 if(ind3>-1 && ind3<ind2) 311 ind2 = ind3; 312 313 String midStr = s.substring(ind,ind2); 314 String endStr = s.substring(ind2); 315 String srscmd = DataCollectionPane.srs_url+"/wgetz?-e+["+midStr+"]"; 316 317 // link to uniprot accession 318 if( (ind2 = srscmd.indexOf("UniProt:")) > -1) 319 srscmd = srscmd.substring(0,ind2+7)+"-acc:"+ 320 srscmd.substring(ind2+8); 321 322 if(srscmd.indexOf("ebi.ac.uk") > -1) 323 srscmd = srscmd + "+-vn+2"; 324 325 return startStr + "<a href=\""+srscmd+"\">" + 326 midStr + "</a>" + endStr; 327 } 328 329 /*private void replaceRange(String newStr,int start,int end) 330 { 331 HTMLDocument doc = (HTMLDocument)getDocument(); 332 333 try 334 { 335 doc.remove(start,(end-start)); 336 insert(newStr,start); 337 } 338 catch(BadLocationException ble) 339 { 340 ble.printStackTrace(); 341 } 342 setDocument(doc); 343 }*/ 344 345 346 /** 347 * 348 * Deletes the annotation line that contains an ID. 349 * 350 */ deleteGo(String id, String go_id)351 protected void deleteGo(String id, String go_id) 352 { 353 String txt = getText(); 354 int ind1 = 0; 355 int ind2 = 0; 356 int indID = 0; 357 358 while((ind2 = txt.indexOf("<br>",ind1)) > -1 || 359 (ind2 = txt.indexOf("</body>",ind1)) > -1) 360 { 361 String line = txt.substring(ind1,ind2); 362 363 if( ((indID = line.indexOf(id)) > -1) && 364 (line.indexOf(go_id) > -1) ) 365 break; 366 else 367 ind1 = ind2+1; 368 } 369 370 // ind2 = txt.indexOf("<br>",indID); 371 372 if(ind2 == -1 || ind2 > txt.length()) 373 ind2 = txt.length(); 374 375 if(ind1 == 0) 376 return; 377 378 setText(txt.substring(0,ind1-1)+txt.substring(ind2)); 379 } 380 381 /** 382 * 383 * Deletes the annotation similarity line that contains an ID. 384 * 385 */ delete(String id, boolean ortholog)386 protected void delete(String id, boolean ortholog) 387 { 388 String txt = getText(); 389 390 int ind1 = 0; 391 int ind2 = 0; 392 int indID = 0; 393 String line = null; 394 395 while((ind2 = txt.indexOf("<br>",ind1)) > -1 || 396 (ind2 = txt.indexOf("</body>",ind1)) > -1) 397 { 398 line = txt.substring(ind1,ind2); 399 400 if((line.indexOf("/similarity=") > -1) && 401 ((indID = line.indexOf(id)) > -1) && 402 (line.indexOf("GO:") == -1) ) 403 break; 404 else 405 ind1 = ind2+1; 406 } 407 408 // if ortholog then delete gene and product lines as well 409 if(ortholog) 410 { 411 if(ind1 > -1) 412 ind2 = txt.indexOf("/product=",ind1); 413 else 414 ind2 = txt.indexOf("/product="); 415 416 if(ind2 > -1) 417 ind2 = txt.indexOf("<br>",ind2+4); 418 } 419 420 if(ind2 == -1 || ind2 > txt.length()) 421 ind2 = txt.length(); 422 423 if(ind1 == 0) 424 return; 425 426 setText(txt.substring(0,ind1-1)+txt.substring(ind2)); 427 } 428 429 430 431 /** 432 * 433 * Deletes the annotation note line that contains an ID. 434 * 435 */ deleteNote()436 protected void deleteNote() 437 { 438 String txt = getText(); 439 440 int ind1 = 0; 441 int ind2 = 0; 442 int indID = 0; 443 String line = null; 444 445 while((ind2 = txt.indexOf("<br>",ind1)) > -1 || 446 (ind2 = txt.indexOf("</body>",ind1)) > -1) 447 { 448 line = txt.substring(ind1,ind2); 449 450 if(line.indexOf("/note="Similar to ") > -1) 451 break; 452 else 453 ind1 = ind2+1; 454 } 455 456 if(ind2 == -1 || ind2 > txt.length()) 457 ind2 = txt.length(); 458 459 if(ind1 == 0) 460 return; 461 462 setText(txt.substring(0,ind1-1)+txt.substring(ind2)); 463 } 464 465 setUpSRSFrame(URL url, String search)466 protected void setUpSRSFrame(URL url, String search) 467 throws IOException 468 { 469 if(BigPane.srsFrame == null) 470 { 471 BigPane.setUpSRSFrame((2*desktop.getHeight())/3,desktop); 472 Border loweredbevel = BorderFactory.createLoweredBevelBorder(); 473 Border raisedbevel = BorderFactory.createRaisedBevelBorder(); 474 Border compound = BorderFactory.createCompoundBorder(raisedbevel,loweredbevel); 475 476 JTextField statusField = new JTextField(); 477 statusField.setBorder(compound); 478 statusField.setEditable(false); 479 BigPane.srsFrame.getContentPane().add(statusField, BorderLayout.SOUTH); 480 } 481 482 Annotation edPane = new Annotation(url); 483 JScrollPane jsp = new JScrollPane(edPane); 484 JTabbedPane jtab = (JTabbedPane)BigPane.srsFrame.getContentPane().getComponent(0); 485 jtab.insertTab(search, null,jsp,null,0); 486 BigPane.srsFrame.setVisible(true); 487 } 488 goBack()489 protected void goBack() 490 { 491 if(back.size() < 2) 492 return; 493 494 try 495 { 496 URL url = (URL)back.get(back.size()-2); 497 back.remove(back.size()-1); 498 setPage(url); 499 } 500 catch(IOException ioe) 501 { 502 ioe.printStackTrace(); 503 } 504 } 505 506 /** 507 * 508 * Method to handle hyper link events. 509 * @param event hyper link event 510 * 511 */ hyperlinkUpdate(HyperlinkEvent event)512 public void hyperlinkUpdate(HyperlinkEvent event) 513 { 514 if(event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) 515 { 516 setCursor(cbusy); 517 try 518 { 519 URL url = event.getURL(); 520 521 int ind1 = event.getDescription().indexOf("["); 522 int ind2 = event.getDescription().lastIndexOf("]"); 523 524 String search = ""; 525 if(ind1 > -1 && ind2 > -1) 526 search = event.getDescription().substring(ind1+1,ind2); 527 else 528 { 529 ind1 = event.getDescription().indexOf("=")+1; // genedb 530 if(ind1 > -1) 531 search = event.getDescription().substring(ind1); 532 } 533 534 if(desktop != null) 535 { 536 if(BigPane.srsTabPane.isSelected()) 537 setUpSRSFrame(url,search); 538 539 if(BigPane.srsWin.isSelected()) 540 { 541 int hgt = (2*desktop.getHeight())/3; 542 Annotation edPane = new Annotation(url); 543 JScrollPane jsp = new JScrollPane(edPane); 544 JInternalFrame jif = new JInternalFrame("SRS "+search, 545 true, //resizable 546 true, //closable 547 true, //maximizable 548 true);//iconifiable); 549 JMenuBar menuBar = new JMenuBar(); 550 menuBar.add(new CommonMenu(jif)); 551 jif.setJMenuBar(menuBar); 552 jif.getContentPane().add(jsp); 553 jif.setLocation(0,0); 554 jif.setSize(800,hgt); 555 jif.setVisible(true); 556 desktop.add(jif); 557 } 558 559 if(BigPane.srsBrowser.isSelected()) 560 BrowserControl.displayURL(event.getDescription()); 561 } 562 else 563 { 564 setPage(url); 565 back.add(url); 566 } 567 } 568 catch(IOException ioe) 569 { 570 String msg = event.getDescription(); 571 if(msg.length() > 50) 572 msg = msg.substring(0,50)+"...."; 573 574 JOptionPane.showMessageDialog(this, 575 "Cannot reach URL:\n"+msg, 576 "Cannot Connect", 577 JOptionPane.INFORMATION_MESSAGE); 578 // ioe.printStackTrace(); 579 // ("Can't follow link to " + 580 // event.getURL().toExternalForm() ); 581 } 582 583 setCursor(cdone); 584 } 585 else if(event.getEventType() == HyperlinkEvent.EventType.ENTERED) 586 { 587 try 588 { 589 JTextField statusField = (JTextField)BigPane.srsFrame.getContentPane().getComponent(1); 590 statusField.setText(event.getDescription()); 591 } 592 catch(Exception exp){} 593 594 } 595 else if(event.getEventType() == HyperlinkEvent.EventType.EXITED) 596 { 597 try 598 { 599 JTextField statusField = (JTextField)BigPane.srsFrame.getContentPane().getComponent(1); 600 statusField.setText(""); 601 } 602 catch(Exception exp){} 603 604 } 605 606 } 607 608 /** 609 * 610 * Popup menu listener 611 * 612 */ 613 class PopupListener extends MouseAdapter 614 { mousePressed(MouseEvent e)615 public void mousePressed(MouseEvent e) 616 { 617 maybeShowPopup(e); 618 } 619 mouseReleased(MouseEvent e)620 public void mouseReleased(MouseEvent e) 621 { 622 maybeShowPopup(e); 623 } 624 maybeShowPopup(MouseEvent e)625 private void maybeShowPopup(MouseEvent e) 626 { 627 if(e.isPopupTrigger() && back.size() > 1) 628 popup.show(e.getComponent(), 629 e.getX(), e.getY()); 630 } 631 } 632 633 } 634 635