/* * Created on Oct 11, 2007 */ package net.sf.thingamablog.gui.app; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.text.DateFormat; import java.util.Date; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import net.atlanticbb.tantlinger.i18n.I18n; import net.atlanticbb.tantlinger.ui.UIUtils; import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager; import net.sf.thingamablog.blog.PingProgress; import net.sf.thingamablog.blog.PingService; import net.sf.thingamablog.blog.PublishProgress; import net.sf.thingamablog.transport.MailTransportProgress; /** * @author Bob Tantlinger * */ public class LogPanel extends JPanel implements PublishProgress, PingProgress, MailTransportProgress { /** * */ private static final long serialVersionUID = 1L; private static final I18n i18n = I18n.getInstance("net.sf.thingamablog.gui.app"); //$NON-NLS-1$ private JProgressBar progressBar; private JButton abortButton; private JLabel label; private boolean aborted; private JEditorPane output; private DefaultStyledDocument doc; private boolean hasPublishFailed, pingFailed, mailCheckFailed; private DateFormat df = DateFormat.getDateTimeInstance(); private JPopupMenu popupMenu = new JPopupMenu(); private ImageIcon errIcon = UIUtils.getIcon(UIUtils.X32, "failed.png"); //$NON-NLS-1$ private ImageIcon connIcon = UIUtils.getIcon(UIUtils.X32, "transfer.png"); //$NON-NLS-1$ private ImageIcon pingIcon = UIUtils.getIcon(UIUtils.X32, "ping.png"); //$NON-NLS-1$ private ImageIcon fileIcon = UIUtils.getIcon(UIUtils.X32, "html.png"); //$NON-NLS-1$ private ImageIcon completeIcon = UIUtils.getIcon(UIUtils.X32, "complete.png"); //$NON-NLS-1$ private Color labelForeground; public LogPanel() { progressBar = new JProgressBar(); progressBar.setValue(0); progressBar.setStringPainted(true); progressBar.setPreferredSize(new Dimension(10, 10)); label = new JLabel(); labelForeground = label.getForeground(); label.setPreferredSize(new Dimension(400, 36)); doc = new DefaultStyledDocument(); output = new JEditorPane("text/rtf", "") //$NON-NLS-1$ //$NON-NLS-2$ { /** * */ private static final long serialVersionUID = 1L; public boolean getScrollableTracksViewportWidth() { return false;//don't want wordwrap } }; output.setEditable(false); output.setDocument(doc); JScrollPane outputScroller = new JScrollPane(output); outputScroller.getViewport().setBackground(output.getBackground()); outputScroller.setPreferredSize(new Dimension(20, 20)); abortButton = new JButton(UIUtils.getIcon(UIUtils.X16, "cancel.png")); //$NON-NLS-1$ abortButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(!aborted) { aborted = true; updateLabelText(UIUtils.getIcon(UIUtils.X32, "err_feed.png"), i18n.str("task_canceled"), false); //$NON-NLS-1$ updateProgressBar(0, 0); append(i18n.str("task_canceled"), Color.ORANGE); } //dispose(); } }); abortButton.setEnabled(false); abortButton.setPreferredSize(new Dimension(20, 20)); GridBagConstraints gridBagConstraints11 = new GridBagConstraints(); gridBagConstraints11.fill = GridBagConstraints.BOTH; gridBagConstraints11.gridy = 2; gridBagConstraints11.weightx = 1.0; gridBagConstraints11.weighty = 1.0; gridBagConstraints11.gridwidth = 2; gridBagConstraints11.insets = new Insets(4, 0, 0, 0); gridBagConstraints11.gridx = 0; GridBagConstraints gridBagConstraints2 = new GridBagConstraints(); gridBagConstraints2.gridx = 1; gridBagConstraints2.anchor = GridBagConstraints.WEST; gridBagConstraints2.insets = new Insets(0, 5, 0, 0); gridBagConstraints2.gridy = 1; GridBagConstraints gridBagConstraints1 = new GridBagConstraints(); gridBagConstraints1.gridx = 0; gridBagConstraints1.fill = GridBagConstraints.BOTH; gridBagConstraints1.anchor = GridBagConstraints.WEST; gridBagConstraints1.weightx = 1.0; gridBagConstraints1.insets = new Insets(0, 0, 0, 0); gridBagConstraints1.gridy = 1; GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.anchor = GridBagConstraints.WEST; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new Insets(0, 0, 4, 0); gridBagConstraints.gridy = 0; this.setLayout(new GridBagLayout()); this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); this.add(label, gridBagConstraints); this.add(progressBar, gridBagConstraints1); this.add(abortButton, gridBagConstraints2); this.add(outputScroller, gridBagConstraints11); TextEditPopupManager.getInstance().registerJTextComponent(output); popupMenu.add(TextEditPopupManager.getInstance().getAction(TextEditPopupManager.COPY)); popupMenu.add(TextEditPopupManager.getInstance().getAction(TextEditPopupManager.SELECT_ALL)); output.addMouseListener(new PopupHandler()); reset(); } public void reset() { hasPublishFailed = false; pingFailed = false; mailCheckFailed = false; aborted = false; updateLabelText(UIUtils.getIcon(UIUtils.X32, "cogs.png"), i18n.str("tasks_"), false); //$NON-NLS-1$ updateProgressBar(0, 0); updateAbortButton(i18n.str("cancel"), false); //$NON-NLS-1$ } public void clearLog() { output.setText(""); } public void logMessage(String msg) { append(msg, Color.black); } /* (non-Javadoc) * @see net.sf.thingamablog.blog.PublishProgress#publishStarted(long) */ public void publishStarted(final long totalBytesToPublish) { updateLabelText(connIcon, i18n.str("connecting_to_server"), false); //$NON-NLS-1$ append("\n" + i18n.str("publishing") + " @ " + df.format(new Date()), Color.blue); append("=====================================", Color.blue); //$NON-NLS-1$ updateProgressBar(0, (int)totalBytesToPublish); //append(i18n.str("publish_complete") + "\n", Color.blue); } /* (non-Javadoc) * @see net.sf.thingamablog.blog.PublishProgress#filePublishStarted(java.io.File) */ public void filePublishStarted(File f, String pubPath) { //label.setText(f.getName()); updateLabelText(fileIcon, f.getName(), false); append(i18n.str("publishing") + ": " + f.getName() + " -> " + pubPath, Color.blue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //abortButton.setEnabled(true); //abortButton.setText(i18n.str("cancel")); //$NON-NLS-1$ updateAbortButton(i18n.str("cancel"), true); //$NON-NLS-1$ } /* (non-Javadoc) * @see net.sf.thingamablog.blog.PublishProgress#filePublishCompleted(java.io.File) */ public void filePublishCompleted(File f, String pubPath) { } /* (non-Javadoc) * @see net.sf.thingamablog.blog.PublishProgress#publishCompleted() */ public void publishCompleted() { append(i18n.str("publish_complete") + "\n", Color.blue); //$NON-NLS-1$ //$NON-NLS-2$ //label.setText("Publish complete"); //$NON-NLS-1$ updateLabelText(completeIcon, i18n.str("publish_complete"), false); //$NON-NLS-1$ //progressBar.setValue(progressBar.getMaximum()); updateProgressValue(progressBar.getMaximum()); //abortButton.setText(i18n.str("close")); //$NON-NLS-1$ updateAbortButton(i18n.str("cancel"), false); //$NON-NLS-1$ } public void publishFailed(String reason) { //label.setForeground(Color.red); //label.setText(reason); updateLabelText(errIcon, i18n.str("publish_failed"), true); //$NON-NLS-1$ //abortButton.setText(i18n.str("close")); //$NON-NLS-1$ //abortButton.setEnabled(true); append(reason, Color.red); updateAbortButton(i18n.str("cancel"), false); //$NON-NLS-1$ //progressBar.setValue(0); updateProgressValue(0); hasPublishFailed = true; } public boolean isDisplayingFailedMessage() { return hasPublishFailed || this.pingFailed || this.mailCheckFailed; } /* (non-Javadoc) * @see net.sf.thingamablog.transport.TransportProgress#bytesTransferred(long) */ public void bytesTransferred(final long bytes) { updateProgressValue((int)bytes, true); } /* (non-Javadoc) * @see net.sf.thingamablog.transport.TransportProgress#isAborted() */ public boolean isAborted() { return aborted; } public void pingSessionStarted(final int totalServices) { append("\n" + i18n.str("pinging") + " @ " + df.format(new Date()), Color.blue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ append("=====================================", Color.blue); //$NON-NLS-1$ updateAbortButton(i18n.str("cancel"), true); //$NON-NLS-1$ updateProgressBar(0, totalServices); } public void pingStarted(PingService ps) { //label.setText(ps.getServiceName()); updateLabelText(pingIcon, ps.getServiceName(), false); //abortButton.setEnabled(true); //abortButton.setText(i18n.str("cancel")); //$NON-NLS-1$ updateAbortButton(i18n.str("cancel"), true); //$NON-NLS-1$ append(i18n.str("pinging") + ": " + ps.getServiceName() + "...", Color.blue); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } public void pingFinished(PingService ps, boolean success, String message) { //progressBar.setValue(progressBar.getValue() + 1); //updateAbortButton(i18n.str("cancel"), false); updateProgressValue(progressBar.getValue() + 1); if(!success) { append(i18n.str("ping_failed") + ": " + ps.getServiceName(), Color.red); //$NON-NLS-1$ //$NON-NLS-2$ append(message, Color.red); } else append(message, new Color(15, 195, 15)); } public void pingSessionCompleted() { updateLabelText(completeIcon, i18n.str("publish_complete"), false); //$NON-NLS-1$ updateAbortButton(i18n.str("cancel"), false); //$NON-NLS-1$ append(i18n.str("pinging_complete") + "\n", Color.blue); //$NON-NLS-1$ //$NON-NLS-2$ } public boolean isPingSessionAborted() { return aborted; } private void append(final String str, final Color c) { SwingUtilities.invokeLater(new Runnable() { public void run() { SimpleAttributeSet sas = new SimpleAttributeSet(); sas.addAttribute(StyleConstants.Foreground, c); try { doc.insertString(doc.getLength(), str + '\n', sas); output.setCaretPosition(doc.getLength()); } catch(BadLocationException ex) { ex.printStackTrace(); } } }); } private void updateAbortButton(final String text, final boolean enabled) { SwingUtilities.invokeLater(new Runnable() { public void run() { abortButton.setEnabled(enabled); if(text != null) abortButton.setToolTipText(text); } }); } private void updateLabelText(final Icon ico, final String text, final boolean err) { SwingUtilities.invokeLater(new Runnable() { public void run() { label.setIcon(ico); if(err) label.setForeground(Color.RED); else label.setForeground(labelForeground); label.setText(text); } }); } private void updateProgressValue(int val) { this.updateProgressValue(val, false); } private void updateProgressValue(final int val, final boolean increment) { SwingUtilities.invokeLater(new Runnable() { public void run() { if(increment) progressBar.setValue(val + progressBar.getValue()); else progressBar.setValue(val); } }); } private void updateProgressBar(final int val, final int max) { SwingUtilities.invokeLater(new Runnable() { public void run() { progressBar.setMaximum(max); progressBar.setValue(val); } }); } private class PopupHandler extends MouseAdapter { public void mousePressed(MouseEvent e) { checkForPopupTrigger(e); } public void mouseReleased(MouseEvent e) { checkForPopupTrigger(e); } private void checkForPopupTrigger(MouseEvent e) { if(e.isPopupTrigger()) popupMenu.show(e.getComponent(), e.getX(), e.getY()); } } /* (non-Javadoc) * @see net.sf.thingamablog.transport.MailTransportProgress#emailCheckComplete() */ public void emailCheckComplete() { updateAbortButton(i18n.str("cancel"), false); //$NON-NLS-1$ updateLabelText(completeIcon, i18n.str("email_check_complete"), false); //$NON-NLS-1$ append(i18n.str("email_check_complete"), Color.blue); //$NON-NLS-1$ } /* (non-Javadoc) * @see net.sf.thingamablog.transport.MailTransportProgress#emailCheckStarted() */ public void emailCheckStarted(String serverName) { updateAbortButton(i18n.str("cancel"), true); //$NON-NLS-1$ updateLabelText(connIcon, i18n.str("checking_email"), false); //$NON-NLS-1$ append("\n" + i18n.str("checking_email") + ": " + serverName + " @ " + df.format(new Date()), Color.blue); //$NON-NLS-2$ append("=====================================", Color.blue); //$NON-NLS-1$ //append(i18n.str("publish_complete") + "\n", Color.blue); //hasPublishFailed = false; // aborted = false;//TODO hmm } /* (non-Javadoc) * @see net.sf.thingamablog.transport.MailTransportProgress#importingMailMessage(java.lang.String) */ public void messageChecked(String subject, boolean isImportable) { if(isImportable) append("* " + subject, new Color(15, 195, 15)); //$NON-NLS-1$ else append(subject, Color.gray); updateProgressValue(1, true); } /* (non-Javadoc) * @see net.sf.thingamablog.transport.MailTransportProgress#mailCheckFailed(java.lang.String) */ public void mailCheckFailed(String message) { append(message, Color.red); updateProgressValue(0); } /* (non-Javadoc) * @see net.sf.thingamablog.transport.MailTransportProgress#numberOfMessagesToCheck(int) */ public void numberOfMessagesToCheck(final int num) { SwingUtilities.invokeLater(new Runnable() { public void run() { label.setForeground(Color.black); progressBar.setValue(0); progressBar.setMaximum(num); } }); } }