/*
* Lilith - a log event viewer.
* Copyright (C) 2007-2017 Joern Huxhorn
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
package de.huxhorn.lilith.swing;
import de.huxhorn.lilith.swing.linklistener.OpenUrlLinkListener;
import de.huxhorn.sulky.swing.KeyStrokes;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.context.AWTFontResolver;
import org.xhtmlrenderer.extend.FontResolver;
import org.xhtmlrenderer.extend.TextRenderer;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.simple.FSScrollPane;
import org.xhtmlrenderer.simple.XHTMLPanel;
import org.xhtmlrenderer.simple.extend.XhtmlNamespaceHandler;
import org.xhtmlrenderer.swing.LinkListener;
import org.xhtmlrenderer.swing.SelectionHighlighter;
public class CheckForUpdateDialog
extends JDialog
{
private static final long serialVersionUID = 7361745831253216248L;
private XHTMLPanel helpPane;
private JLabel messageLabel;
private XhtmlNamespaceHandler xhtmlNamespaceHandler;
private String docRoot;
private ApplicationPreferences applicationPreferences;
private JCheckBox checkForUpdateCheckbox;
private static final int INSET = 10;
public CheckForUpdateDialog(MainFrame mainFrame)
{
super(mainFrame);
this.applicationPreferences = mainFrame.getApplicationPreferences();
setTitle("Check for Update…");
setModal(false);
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
helpPane = new XHTMLPanel();
final Logger logger = LoggerFactory.getLogger(CheckForUpdateDialog.class);
{
SharedContext sharedContext = helpPane.getSharedContext();
TextRenderer textRenderer = sharedContext.getTextRenderer();
textRenderer.setSmoothingThreshold(RendererConstants.SMOOTHING_THRESHOLD);
FontResolver fontResolver = sharedContext.getFontResolver();
if(fontResolver instanceof AWTFontResolver && RendererConstants.MENSCH_FONT != null)
{
AWTFontResolver awtFontResolver = (AWTFontResolver) fontResolver;
awtFontResolver.setFontMapping(RendererConstants.MONOSPACED_FAMILY, RendererConstants.MENSCH_FONT);
if(logger.isInfoEnabled()) logger.info("Installed '{}' font.", RendererConstants.MONOSPACED_FAMILY);
}
}
{
LinkListener originalLinkListener = null;
List mouseTrackingList = helpPane.getMouseTrackingListeners();
if(mouseTrackingList != null)
{
for(Object o : mouseTrackingList)
{
if(logger.isDebugEnabled()) logger.debug("Before MTL {}", o);
if(o instanceof LinkListener)
{
helpPane.removeMouseTrackingListener((LinkListener) o);
originalLinkListener = (LinkListener) o;
}
}
}
helpPane.addMouseTrackingListener(new OpenUrlLinkListener(mainFrame, originalLinkListener));
}
SelectionHighlighter helpPaneCaret = new SelectionHighlighter();
helpPaneCaret.install(helpPane);
SelectionHighlighter.CopyAction copyAction = new SelectionHighlighter.CopyAction();
copyAction.install(helpPaneCaret);
checkForUpdateCheckbox = new JCheckBox("Check for updates on startup.");
checkForUpdateCheckbox.setSelected(applicationPreferences.isCheckingForUpdate());
checkForUpdateCheckbox.addItemListener(new CheckboxListener());
checkForUpdateCheckbox.setMnemonic(KeyEvent.VK_U);
FSScrollPane helpScrollPane = new FSScrollPane(helpPane);
helpScrollPane.setPreferredSize(new Dimension(600, 300));
JPanel content = new JPanel(new GridBagLayout());
setLayout(new GridLayout(1, 1));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets.top = INSET;
gbc.insets.bottom = 0;
gbc.insets.left = INSET;
gbc.insets.right = INSET;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_START;
messageLabel = new JLabel();
Font labelFont = messageLabel.getFont();
labelFont = labelFont.deriveFont(1.5f * labelFont.getSize2D());
messageLabel.setFont(labelFont);
content.add(messageLabel, gbc);
gbc.gridy = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
content.add(helpScrollPane, gbc);
gbc.gridy = 2;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.LINE_START;
content.add(checkForUpdateCheckbox, gbc);
gbc.insets.top = INSET;
gbc.insets.bottom = INSET;
gbc.insets.left = INSET;
gbc.insets.right = INSET;
gbc.anchor = GridBagConstraints.LINE_END;
gbc.gridy = 3;
OkAction okAction = new OkAction();
content.add(new JButton(okAction), gbc);
KeyStrokes.registerCommand(content, okAction, "OK_ACTION");
KeyStrokes.registerCommand(content, new CancelAction(), "CANCEL_ACTION");
add(content);
URL docRootUrl = CheckForUpdateDialog.class.getResource("/help");
if(docRootUrl != null)
{
docRoot = docRootUrl.toString() + "/";
}
if(logger.isDebugEnabled()) logger.debug("Changes docroot: {}", docRoot);
xhtmlNamespaceHandler = new XhtmlNamespaceHandler();
}
public void setMessage(String message)
{
if(message == null)
{
messageLabel.setText("Your version is up to date.");
messageLabel.setIcon(null);
}
else
{
messageLabel.setText(message);
messageLabel.setIcon(Icons.UPDATE_AVAILABLE_32_ICON);
}
}
public void setChanges(String changes)
{
if(changes == null)
{
changes = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE html\n" +
"\tPUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n" +
"\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" +
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n" +
"<head>\n" +
"\t<title>Couldn't load changes file!</title>\n" +
"\t<link href=\"help.css\" rel=\"stylesheet\" type=\"text/css\"/>\n" +
"</head>\n" +
"<body>\n" +
"<p>Couldn't load changes file!</p>\n" +
"</body>\n" +
"</html>";
}
helpPane.setDocumentFromString(changes, docRoot, xhtmlNamespaceHandler);
}
public void setCheckingForUpdate(boolean checkingForUpdate)
{
checkForUpdateCheckbox.setSelected(checkingForUpdate);
}
private class OkAction
extends AbstractAction
{
private static final long serialVersionUID = -7050362653241782872L;
OkAction()
{
super("Ok");
KeyStroke accelerator = LilithKeyStrokes.getKeyStroke(LilithKeyStrokes.ENTER);
putValue(Action.ACCELERATOR_KEY, accelerator);
putValue(Action.MNEMONIC_KEY, KeyEvent.VK_O);
}
public void actionPerformed(ActionEvent e)
{
setVisible(false);
// workaround for http://sourceforge.net/apps/trac/lilith/ticket/72 below
Container parentContainer = getParent();
if(parentContainer != null)
{
parentContainer.requestFocus();
}
// workaround for http://sourceforge.net/apps/trac/lilith/ticket/72 above
}
}
private class CancelAction
extends AbstractAction
{
private static final long serialVersionUID = -7356773009949031885L;
CancelAction()
{
super("Cancel");
KeyStroke accelerator = LilithKeyStrokes.getKeyStroke(LilithKeyStrokes.ESCAPE);
putValue(Action.ACCELERATOR_KEY, accelerator);
putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C);
}
public void actionPerformed(ActionEvent e)
{
setVisible(false);
}
}
private class CheckboxListener
implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
Object source = e.getItemSelectable();
if(source == checkForUpdateCheckbox)
{
applicationPreferences.setCheckingForUpdate(checkForUpdateCheckbox.isSelected());
}
}
}
}