1 package SnowMailClient.view.MessagesPreview; 2 3 import java.awt.Color ; 4 import java.awt.EventQueue ; 5 import SnowMailClient.SnowMailClientApp; 6 import SnowMailClient.model.*; 7 import SnowMailClient.model.accounts.*; 8 import SnowMailClient.MailEngine.*; 9 import SnowMailClient.utils.storage.*; 10 import SnowMailClient.utils.*; 11 import snow.utils.gui.*; 12 import snow.concurrent.*; 13 14 import snow.sortabletable.*; 15 import SnowMailClient.Language.Language; 16 17 import java.util.*; 18 import java.util.concurrent.*; 19 import java.text.*; 20 import java.awt.BorderLayout ; 21 import java.awt.event.*; 22 import javax.swing.*; 23 import javax.swing.event.*; 24 import javax.swing.table.*; 25 import java.beans.PropertyVetoException ; 26 27 34 public final class PreviewDialog extends JDialog implements ListSelectionListener 35 { 36 final private JTable table = new JTable(); 37 private final PreviewModel previewModel; 38 private SortableTableModel stm; 39 private boolean hasBeenClosed = false; 40 private final JLabel statusLabel = new JLabel(); 41 private final JButton deleteBT = new JButton(Language.translate("Delete selected"),Icons.CrossIcon.shared10); 42 private final JButton deleteSpamBT = new JButton(Language.translate("Delete and add to blacklist"), Icons.CrossIcon.shared10); 44 private final JButton downloadBT = new JButton(Language.translate("Download selected"), 46 SnowMailClientApp.loadImageIcon("pics/receivemail.PNG")); 47 48 private final JCheckBox leaveACopyOnTheServerButton = new JCheckBox(Language.translate("Leave a copy on the server")); 49 50 private final int fontSize = UIManager.getFont("Label.font").getSize(); 51 private final JProgressBar messagesProgress = new JProgressBar(); 52 53 private JSplitPane mainSplit; 54 private final JTextPane previewPane = new JTextPane(); 55 56 final private SnowBackgroundPanel backgroundPanel = new SnowBackgroundPanel(new BorderLayout (0,0)); 57 58 60 public PreviewDialog(JDialog ref, PreviewModel previewModel, boolean modal) 61 { 62 super(ref, Language.translate("Preview (advanced options are available in the context menu)"), modal); 63 this.previewModel = previewModel; 64 init(); 65 } 66 67 69 public PreviewDialog(JFrame ref, PreviewModel previewModel, boolean modal) 70 { 71 super(ref, Language.translate("Preview"), modal); 72 this.previewModel = previewModel; 73 init(); 74 } 75 76 private void init() 77 { 78 this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); 80 this.setContentPane(backgroundPanel); 82 83 84 stm = new SortableTableModel(previewModel, 5, false); table.setModel( stm ); 88 stm.installGUI(table); 89 90 91 mainSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, 92 new JScrollPane(table), 93 new JScrollPane(this.previewPane)); 94 this.getContentPane().add(mainSplit, BorderLayout.CENTER); 95 mainSplit.setOneTouchExpandable(true); 96 previewPane.setEditable(false); 97 98 AdvancedSearchPanel asp = new AdvancedSearchPanel("Filter: ", null, stm, false); 101 102 this.getContentPane().add(asp, BorderLayout.NORTH); 104 asp.add(messagesProgress); 105 asp.add(statusLabel); 106 messagesProgress.setVisible(true); 107 messagesProgress.setIndeterminate(true); 108 109 110 111 table.setDefaultRenderer(Object .class, new PreviewCellRenderer(previewModel, stm)); 112 116 JPanel controlPanelMain = new JPanel(); 119 controlPanelMain.setLayout(new BoxLayout(controlPanelMain, BoxLayout.Y_AXIS)); 120 121 this.getContentPane().add(controlPanelMain, BorderLayout.SOUTH); 122 123 JPanel controlPanel = new JPanel(); 124 controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS)); 125 controlPanel.setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 126 controlPanelMain.add(controlPanel); 127 128 controlPanel.add(leaveACopyOnTheServerButton); 129 leaveACopyOnTheServerButton.setToolTipText(Language.translate("Don't concern deletion.")); 130 131 controlPanel.add(Box.createHorizontalStrut(10)); 132 133 GUIUtils.setSmallDimensions(deleteBT); 134 deleteBT.addActionListener(new ActionListener() 135 { 136 public void actionPerformed(ActionEvent e) 137 { 138 deleteSelectedMails(false); 139 } 140 }); 141 142 143 GUIUtils.setSmallDimensions(deleteSpamBT); 145 deleteSpamBT.addActionListener(new ActionListener() 146 { 147 public void actionPerformed(ActionEvent e) 148 { 149 deleteSelectedMails(true); 150 } 151 }); 152 153 controlPanel.add(downloadBT); 154 155 controlPanel.add(Box.createHorizontalGlue()); 156 controlPanel.add(Box.createHorizontalStrut(30)); 157 158 GUIUtils.setSmallDimensions(downloadBT); 159 downloadBT.addActionListener(new ActionListener() 160 { 161 public void actionPerformed(ActionEvent e) 162 { 163 Thread t = new Thread () 164 { 165 public void run() 166 { 167 downloadSelectedMails(); 168 } 169 }; 170 t.start(); 171 } 172 }); 173 174 JButton closeBT = new JButton( Language.translate("Close"), Icons.CrossIcon.shared10 ); 175 GUIUtils.setSmallDimensions(closeBT); 176 controlPanel.add(closeBT); 177 closeBT.setBackground(Color.orange); 178 closeBT.addActionListener(new ActionListener() 179 { 180 public void actionPerformed(ActionEvent e) 181 { 182 closeDialogIfPossible() ; 184 } 186 }); 187 188 this.addWindowListener(new WindowAdapter() 189 { 190 @Override public void windowClosing(WindowEvent we) 191 { 192 closeDialogIfPossible(); 193 } 194 @Override public void windowClosed(WindowEvent we) 195 { 196 } 198 }); 199 200 201 table.addMouseListener(new MouseAdapter() 202 { 203 @Override public void mousePressed(MouseEvent me) 204 { 205 if(me.isPopupTrigger()) 206 { 207 displayTablePopup(me); 208 } 209 } 210 211 @Override public void mouseReleased(MouseEvent me) 212 { 213 if(me.isPopupTrigger()) 214 { 215 displayTablePopup(me); 216 } 217 } 218 219 }); 220 221 table.getSelectionModel().addListSelectionListener(this); 222 mainSplit.setDividerLocation(0.8); 223 mainSplit.setDividerLocation(400); 224 225 } 227 228 private boolean getMailsBeingDownloaded() 229 { 230 for(int i=0; i<this.previewModel.getRowCount(); i++) 231 { 232 PreviewHeader ph0 = this.previewModel.getMessageHeaderAt(i); 233 if(ph0.state==PreviewHeader.State.DownloadingMessage) 234 { 235 return true; 236 } 237 } 238 return false; 239 } 240 241 boolean acceptedClose = false; 242 private void closeDialogIfPossible() 243 { 244 if(acceptedClose) return; 245 246 248 Vector<PreviewHeader> downloading = this.previewModel.getMailsBeingDownloaded(); 249 if(downloading.size()>0) 250 { 251 int rep = JOptionPane.showConfirmDialog(this, 253 Language.translate("Some mails are still downloading.\nClosing this dialog will cancel the downloads.\nDo you want to close the dialog ?"), 254 Language.translate("Confirm Closing"), JOptionPane.OK_CANCEL_OPTION); 255 if(rep==JOptionPane.OK_OPTION) 256 { 257 acceptedClose = true; 258 this.stopDownload( downloading ); 259 260 if(this.isVisible()) 261 { 262 SnowMailClientApp.getInstance().getProperties().saveComponentSizeInINIFile( 263 this, "MailPreviewDialog"); 264 setVisible(false); 265 } 266 dispose(); 267 } 268 else 269 { 270 if(!this.isVisible()) 272 { 273 this.setVisible(true); 274 if(this.getWidth()<100 || this.getHeight()<100) 275 { 276 this.setSize(500,400); 277 } 278 } 279 } 280 } 281 else 282 { 283 acceptedClose = true; 284 if(this.isVisible()) 285 { 286 SnowMailClientApp.getInstance().getProperties().saveComponentSizeInINIFile( 287 this, "MailPreviewDialog"); 288 setVisible(false); 289 } 290 dispose(); 291 } 292 } 293 294 private void displayTablePopup(MouseEvent me) 295 { 296 JPopupMenu popup = new JPopupMenu("Preview table popup"); 297 int[] viewSel = table.getSelectedRows(); 298 if(viewSel.length==0) return; 299 300 int posMod0 = this.stm.getIndexInUnsortedFromTablePos(viewSel[0]); 301 PreviewHeader ph0 = this.previewModel.getMessageHeaderAt(posMod0); 302 PreviewHeader.State uniformState = ph0.state; 303 final Vector<PreviewHeader> selected = new Vector<PreviewHeader>(); 304 for(int i=0;i<viewSel.length;i++) 305 { 306 int posMod = this.stm.getIndexInUnsortedFromTablePos(viewSel[i]); 307 PreviewHeader ph = this.previewModel.getMessageHeaderAt(posMod); 308 if(uniformState != ph.state) 309 { 310 popup.add(Language.translate("States of selected messages are not uniform")); 311 popup.show(table,me.getX(),me.getY()); 312 return; 313 } 314 selected.addElement(ph); 315 } 316 317 if( uniformState!=PreviewHeader.State.MessageDownloaded 318 && uniformState!=PreviewHeader.State.DownloadingMessage) 319 { 320 JMenuItem download = new JMenuItem(Language.translate("Download"), SnowMailClientApp.loadImageIcon("pics/receivemail.PNG")); 322 popup.add(download); 323 download.addActionListener(new ActionListener() 324 { 325 public void actionPerformed(ActionEvent ae) 326 { 327 download(selected, false); 328 } 329 }); 330 331 JMenuItem downloadK = new JMenuItem(Language.translate("Download and keep on server"), SnowMailClientApp.loadImageIcon("pics/receivemail.PNG")); 332 popup.add(downloadK); 333 downloadK.addActionListener(new ActionListener() 334 { 335 public void actionPerformed(ActionEvent ae) 336 { 337 download(selected, true); 338 } 339 }); 340 } 341 342 if(uniformState==PreviewHeader.State.DownloadingMessage) 343 { 344 JMenuItem stop = new JMenuItem(Language.translate("Stop download"), new Icons.StopIcon(10,10,true)); 346 popup.add(stop); 347 stop.addActionListener(new ActionListener() 348 { 349 public void actionPerformed(ActionEvent ae) 350 { 351 stopDownload(selected); 352 } 353 }); 354 } 355 356 if(selected.size()==1) 357 { 358 JMenuItem viewBeg = new JMenuItem(Language.translate("Preview")); 359 popup.add(viewBeg); 360 viewBeg.addActionListener(new ActionListener() 361 { 362 public void actionPerformed(ActionEvent ae) 363 { 364 preview(selected.get(0)); 365 } 366 }); 367 } 368 369 if(uniformState!=PreviewHeader.State.DownloadingMessage) 370 { 371 JMenuItem del = new JMenuItem(Language.translate("Delete"), Icons.CrossIcon.shared10); 372 popup.addSeparator(); 373 popup.add(del); 374 del.addActionListener(new ActionListener() 375 { 376 public void actionPerformed(ActionEvent ae) 377 { 378 deleteMessages(selected, false, true); 379 } 380 }); 381 382 JMenuItem del2 = new JMenuItem(Language.translate("Delete and Blacklist"), SnowMailClientApp.loadImageIcon("pics/addtospam.PNG")); 383 popup.add(del2); 384 del2.addActionListener(new ActionListener() 385 { 386 public void actionPerformed(ActionEvent ae) 387 { 388 deleteMessages(selected, true, true); 389 } 390 }); 391 } 392 393 popup.show(table, me.getX(), me.getY()); 394 } 395 396 private void stopDownload(final Vector<PreviewHeader> headers) 397 { 398 for(PreviewHeader ph : headers) 399 { 400 final MailAccount account = ph.getAccount(); 402 InterruptableTask it = ph.downloadTask; 403 if(it!=null) 404 { 405 System.out.println("Request stop"); 407 it.requestStop(); 408 ph.downloadTask = null; 409 } 410 } 411 } 412 413 415 private void preview(final PreviewHeader ph) 416 { 417 InterruptableTask<Object > prevTask = new InterruptableTask<Object >() 418 { 419 public void run() 420 { 421 try 422 { 423 SecurePopConnection spop = ph.getAccount().getCheckedPopConnection(); 424 String top = spop.getMessageTop(ph.getUIDL(), 50); 425 new MessagePreview(PreviewDialog.this, ph, top); 427 } 428 catch(Exception ex) 429 { 430 } 431 } 432 }; 433 434 ph.getAccount().messagesDownloadExecutor.execute(prevTask); 435 437 } 438 439 private void deleteMessages(final List<PreviewHeader> headers, final boolean addToBlackListAndSPAM, boolean forceDelete) 440 { 441 for(final PreviewHeader ph : headers) 442 { 443 ph.state = PreviewHeader.State.Deleting; 444 ph.forceDelete = forceDelete; 445 446 InterruptableTask<Object > delTask = new InterruptableTask<Object >() 447 { 448 public void run() 449 { 450 try 451 { 452 SecurePopConnection spop = ph.getAccount().getCheckedPopConnection(); 453 spop.deleteMessage(ph.getUIDL()); 454 ph.state = PreviewHeader.State.Deleted; 455 EventQueue.invokeLater(new Runnable () 456 { public void run() 457 { 458 previewModel.removeMessageHeader(ph); 459 if(addToBlackListAndSPAM) 460 { 461 String from = ph.getEntryValue("from", "<NO FROM FIELD>"); 462 Address fad = new Address(from); 463 SnowMailClientApp.getInstance().getSpamBook().incrementMailsReceivedFrom_AddIfNotFound(fad); 464 } 465 } 466 }); 467 } 468 catch(Exception ex) 469 { 470 ph.state = PreviewHeader.State.DownloadError; 471 ph.error = ex; 472 table.repaint(); 473 } 474 } 475 }; 476 477 ph.getAccount().messagesDownloadExecutor.execute(delTask); 478 480 481 } 482 } 483 484 485 private void download(final Vector<PreviewHeader> headers, final boolean forceKeep) 486 { 487 for(final PreviewHeader ph : headers) 488 { 489 ph.state = PreviewHeader.State.DownloadingMessage; 490 ph.alreadyDownloadedSize = 0; 491 ph.error = null; 492 ph.forceKeep = forceKeep; 493 494 InterruptableTask<Object > downloadTask = new InterruptableTask<Object >() 495 { 496 public void run() 497 { 498 try 499 { 500 table.repaint(); 501 Counter counter = new Counter() 502 { 503 public void increment(int count) 504 { 505 super.increment(count); 506 ph.alreadyDownloadedSize = counterValue; 507 table.repaint(); 508 } 509 }; 510 String message = ph.getAccount().getCheckedPopConnection().getMessage(ph.getUIDL(), interrupter, counter); 511 addMessage(message, ph); 512 ph.state = PreviewHeader.State.MessageDownloaded; 513 } 514 catch(ManualInterruptedException e) 515 { 516 ph.state = PreviewHeader.State.DownloadInterrupted; 517 ph.error = e; 518 } 519 catch(Exception e) 520 { 521 ph.state = PreviewHeader.State.DownloadError; 522 ph.error = e; 523 } 524 finally 525 { 526 table.repaint(); 527 } 528 } 529 }; 530 531 ph.getAccount().messagesDownloadExecutor.execute(downloadTask); 532 ph.downloadTask = downloadTask; 533 534 } 535 } 536 537 public void setMaximalMessageNumber(final int max) 538 { 539 EventQueue.invokeLater(new Runnable () { public void run() 540 { 541 messagesProgress.setVisible(true); 542 messagesProgress.setIndeterminate(false); 543 messagesProgress.setMaximum(max); 544 }}); 545 } 546 547 public void setMessageProgress(final int n) 548 { 549 EventQueue.invokeLater(new Runnable () { public void run() 550 { 551 messagesProgress.setValue(n); 552 }}); 553 } 554 555 public void _incrementMessageProgress(final int n) 557 { 558 EventQueue.invokeLater(new Runnable () { public void run() 559 { 560 messagesProgress.setValue( messagesProgress.getValue()+n ); 561 messagesProgress.setString(""+messagesProgress.getValue()); 562 }}); 563 } 564 565 public void setMessageProgressInvisible() 566 { 567 EventQueue.invokeLater(new Runnable () { public void run() 568 { 569 messagesProgress.setVisible(false); 570 }}); 571 } 572 573 575 public void valueChanged(ListSelectionEvent e) 576 { 577 deleteBT.setEnabled(table.getSelectedRows().length>0); 578 this.downloadBT.setEnabled(table.getSelectedRows().length>0); 579 this.deleteSpamBT.setEnabled(table.getSelectedRows().length>0); 580 581 if(table.getSelectedRows().length==1) 582 { 583 int posMod0 = this.stm.getIndexInUnsortedFromTablePos(table.getSelectedRow()); 584 PreviewHeader ph0 = this.previewModel.getMessageHeaderAt(posMod0); 585 586 StringBuffer sb = new StringBuffer (); 587 588 if(ph0.state == PreviewHeader.State.DownloadError) 589 { 590 sb.append(Language.translate("Error")+":"+ph0.error.getMessage()); 591 sb.append("\r\n\r\n"+Language.translate("Message Header")+":\r\n"); 592 } 593 594 sb.append(ph0.toString()); 595 596 this.previewPane.setText(sb.toString()); 597 this.previewPane.setCaretPosition(0); 598 } 599 else 600 { 601 this.previewPane.setText(""); 602 } 603 604 } 605 606 public PreviewModel getPreviewModel() { return previewModel; } 607 608 public void setStatusLabelText(final String stlt) 609 { 610 EventQueue.invokeLater(new Runnable () { public void run() 611 { 612 statusLabel.setText(stlt); 613 }}); 614 } 615 616 618 private void addMessage(final String messTxt, final PreviewHeader header) throws Exception 619 { 620 final MailMessage mess = new MailMessage(); 621 mess.parse(messTxt); 622 mess.setHasBeenReceived(true); 623 624 try 625 { 626 double p = SnowMailClientApp.getInstance().getWordStatistic().calculateSpamProbability(mess).getProbability(); 627 mess.setSPAMProbability(p); 628 } 629 catch(Exception es) 630 { 631 es.printStackTrace(); 632 } 633 634 mess.setEditable(false); 635 mess.selectedInView = false; 636 637 638 EventQueue.invokeLater(new Runnable () 639 { 640 public void run() 641 { 642 try 643 { 644 SnowMailClientApp.getInstance().getFoldersModel() 645 .getInboxFolder() 646 .getMailFolder().addMessage(mess); 647 } 648 catch(Exception e) 649 { 650 e.printStackTrace(); 652 } 653 } 654 }); 655 656 if(header.forceDelete || (!this.leaveACopyOnTheServerButton.isSelected() 657 && !header.forceKeep)) 658 { 659 System.out.println("Delete message "+header.getUIDL()); 660 header.getAccount().getCheckedPopConnection().deleteMessage(header.getUIDL()); 661 } 662 663 EventQueue.invokeLater(new Runnable () 664 { 665 public void run() 666 { 667 previewModel.removeMessageHeader(header); 668 } 669 }); 670 671 } 673 674 private void downloadSelectedMails() 675 { 676 EventQueue.invokeLater(new Runnable () { public void run() 677 { 678 stm.storeTableSelection(); 680 681 Vector<PreviewHeader> h = previewModel.getAllMailsNotAlreadyDownloaded_(true); 682 System.out.println("Download "+h.size()+" headers"); 683 download( h, false ); 684 }}); 685 686 } 687 688 private void deleteSelectedMails(boolean markAsSpam) 689 { 690 Vector<PreviewHeader> selected = new Vector<PreviewHeader>(); 691 int[] sel = table.getSelectedRows(); 692 for(int i=0; i<sel.length; i++) 693 { 694 int pos = stm.getIndexInUnsortedFromTablePos(sel[i]); 695 PreviewHeader h = previewModel.getMessageHeaderAt(pos); 696 selected.add(h); 697 } 698 699 deleteMessages(selected, markAsSpam, true); 700 701 702 } 703 704 705 } | Popular Tags |