package com.limegroup.gnutella.gui; import com.limegroup.gnutella.gui.themes.ThemeFileHandler; import com.limegroup.gnutella.licenses.License; import com.limegroup.gnutella.licenses.LicenseFactory; import com.limegroup.gnutella.licenses.VerificationListener; import com.limegroup.gnutella.URN; import com.limegroup.gnutella.xml.LimeXMLDocument; import org.apache.commons.httpclient.URI; import javax.swing.Icon; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.JComponent; import javax.swing.JTextArea; import javax.swing.JButton; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import javax.swing.UIManager; import java.awt.Font; import java.awt.Dimension; import java.awt.Insets; import java.awt.GridBagLayout; import java.awt.GridBagConstraints; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * A dialog displaying license information. */ public abstract class LicenseWindow extends JDialog implements VerificationListener { /** The URN that the license is expected to match. */ protected final URN URN; /** The LimeXMLDocument with information about the file this license matches. */ protected final LimeXMLDocument DOCUMENT; /** The License itself. */ protected final License LICENSE; /** The panel where the ongoing status of the license verification is shown */ protected final JPanel DETAILS; /** A listener who wants to receive notification about the license being verified */ protected final VerificationListener LISTENER; /** The value to insert in the key to lookup message bundle info. */ protected final String KEY_VALUE; public static LicenseWindow create(License l, URN u, LimeXMLDocument d, VerificationListener v) { String name = l.getLicenseName(); if(LicenseFactory.CC_NAME.equals(name)) return new CCWindow(l, u, d, v); else if(LicenseFactory.WEED_NAME.equals(name)) return new WeedWindow(l, u, d, v); else return new UnknownWindow(l, u, d, v); } /** * Constructs a new LicenseWindow. * @param license the License being displayed * @param urn the URN the license is validating against * @param listener a VerificationListener this license can forward * licenseVerified events to. */ private LicenseWindow(License license, URN urn, LimeXMLDocument document, VerificationListener listener, String keyValue) { super(GUIMediator.getAppFrame()); URN = urn; LICENSE = license; DETAILS = new JPanel(new GridBagLayout()); LISTENER = listener; KEY_VALUE = keyValue; DOCUMENT = document; setModal(false); setResizable(false); setTitle(getTitleString()); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); JComponent pane = (JComponent)getContentPane(); GUIUtils.addHideAction(pane); pane.setPreferredSize(new Dimension(400, 230)); DETAILS.setPreferredSize(new Dimension(400, 210)); getContentPane().setLayout(new GridBagLayout()); constructDialog(getContentPane()); validate(); if(GUIMediator.isAppVisible()) setLocationRelativeTo(GUIMediator.getAppFrame()); else setLocation(GUIMediator.getScreenCenterPoint(this)); } /** * Notification that a license has been verified. * * Rebuilds the details panel to match the new status. */ public void licenseVerified(License license) { if(license == LICENSE) { SwingUtilities.invokeLater(new Runnable() { public void run() { buildDetails(); } }); } if(LISTENER != null) LISTENER.licenseVerified(license); } protected void createVerifying() { GridBagConstraints c = new GridBagConstraints(); // TODO: Add a pretty animation. JTextArea text = newTextArea(getLocatingString()); c.anchor = GridBagConstraints.CENTER; c.fill = GridBagConstraints.BOTH; c.weightx = 1; c.weighty = 1; DETAILS.add(text, c); } protected void createNotVerified() { GridBagConstraints c = new GridBagConstraints(); JTextArea text = newTextArea(getNotVerifiedString()); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; c.weightx = 1; c.weighty = 1; c.anchor = GridBagConstraints.NORTHWEST; DETAILS.add(text, c); JButton button = new JButton(getVerifyString()); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { LICENSE.verify(LicenseWindow.this); buildDetails(); } }); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.NONE; c.weightx = 0; c.weighty = 0; c.anchor = GridBagConstraints.SOUTHWEST; DETAILS.add(button, c); } protected void createNotValid() { GridBagConstraints c = new GridBagConstraints(); URI licenseURI = LICENSE.getLicenseURI(); JComponent comp; comp = new JLabel(getWarningIcon()); c.anchor = GridBagConstraints.NORTH; c.insets = new Insets(0, 0, 0, 5); DETAILS.add(comp, c); String invalidText = getInvalidString(); if(licenseURI != null && allowRetryLink()) invalidText += " " + getRetryString(); comp = newTextArea(invalidText); c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.BOTH; c.weightx = 1; c.weighty = 1; c.insets = new Insets(7, 0, 0, 0); DETAILS.add(comp, c); c.gridwidth = 1; c.gridheight = 2; c.weightx = 0; c.weighty = 0; DETAILS.add(javax.swing.Box.createGlue(), c); JButton button = new JButton(getVerifyString()); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { LICENSE.verify(LicenseWindow.this); buildDetails(); } }); button.setVisible(licenseURI != null && allowVerifyLookup()); c.gridwidth = GridBagConstraints.RELATIVE; c.gridheight = 2; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.CENTER; c.insets = new Insets(0, 0, 0, 100); DETAILS.add(button, c); if(LICENSE.getLicenseDeed(URN) == null || !allowClaimedDeedLink()) { comp = new JLabel(); comp.setVisible(false); } else { comp = new URLLabel(LICENSE.getLicenseDeed(URN), getClaimedDeedString()); } c.gridwidth = GridBagConstraints.REMAINDER; c.gridheight = 1; c.anchor = GridBagConstraints.WEST; c.fill = GridBagConstraints.BOTH; c.weightx = 0; c.weighty = 0; c.insets = new Insets(0, 0, 3, 0); DETAILS.add(comp, c); if(licenseURI == null || !allowVerificationLink()) { comp = new JLabel(); comp.setVisible(false); } else { comp = new URLLabel(licenseURI, getVerificationString()); } c.insets = new Insets(0, 0, 3, 0); DETAILS.add(comp, c); } protected void createValid() { GridBagConstraints c = new GridBagConstraints(); JComponent label = new JLabel(getDetailsString()); Font f = label.getFont(); label.setFont(new Font(f.getName(), Font.BOLD, f.getSize())); c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = GridBagConstraints.REMAINDER; c.anchor = GridBagConstraints.NORTHWEST; DETAILS.add(label, c); JTextArea text = newTextArea(LICENSE.getLicenseDescription(URN)); c.gridwidth = GridBagConstraints.RELATIVE; c.gridheight = 2; c.weighty = 1; c.weightx = .7; c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.BOTH; DETAILS.add(text, c); if(LICENSE.getLicenseDeed(URN) != null) { label = new URLLabel(LICENSE.getLicenseDeed(URN), getDeedString()); } else { label = new JLabel(); label.setVisible(false); } c.gridwidth = GridBagConstraints.REMAINDER; c.gridheight = 1; c.weighty = 0; c.weightx = .3; c.anchor = GridBagConstraints.NORTHWEST; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(0, 0, 3, 0); DETAILS.add(label, c); label = new URLLabel(LICENSE.getLicenseURI(), getVerificationString()); DETAILS.add(label, c); } /** * Builds the details panel. * * This will show either a message that * 1) The license is currently being located. * 2) The license is not yet verified, asking the user to verify. * 3) The license could not be validated (with guess-work links) * 4) The license is valid (with the details, and links) */ protected void buildDetails() { DETAILS.removeAll(); if(LICENSE.isVerifying()) createVerifying(); else if(!LICENSE.isVerified()) createNotVerified(); else if(!LICENSE.isValid(URN)) createNotValid(); else // LICENSE.isValid() createValid(); validate(); repaint(); } /** Creates the top of the window. */ protected void createTopOfWindow(Container parent) { GridBagConstraints c = new GridBagConstraints(); JLabel img = new URLLabel(getLargeLicenseURLString(), getLargeLicenseIcon()); c.insets = new Insets(4, 4, 2, 0); parent.add(img, c); JComponent line = new Line(ThemeFileHandler.TABLE_BACKGROUND_COLOR.getValue()); c.insets = new Insets(0, 2, 0, 2); c.gridwidth = GridBagConstraints.RELATIVE; c.fill = GridBagConstraints.VERTICAL; parent.add(line, c); JTextArea text = newTextArea(LICENSE.getLicense()); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(4, 0, 2, 4); parent.add(text, c); } /** * Constructs the dialog itself. */ protected void constructDialog(Container parent) { // Add the // [ img ] | [ license ] createTopOfWindow(parent); GridBagConstraints c = new GridBagConstraints(); // Add a ----------- // line below img & license JComponent line = new Line(ThemeFileHandler.TABLE_BACKGROUND_COLOR.getValue()); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(0, 0, 2, 0); parent.add(line, c); // Create the details panel. buildDetails(); // Add the details panel. c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(4, 4, 0, 4); c.weighty = 1; c.weightx = 1; parent.add(DETAILS, c); // Add a ------------ // line below the details. line = new Line(ThemeFileHandler.TABLE_BACKGROUND_COLOR.getValue()); c.gridwidth = GridBagConstraints.REMAINDER; c.gridheight = GridBagConstraints.RELATIVE; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(2, 0, 2, 0); c.ipady = 0; c.weighty = 0; c.weightx = 0; parent.add(line, c); // Add an OK button out of the window. JButton button = new JButton(GUIMediator.getStringResource("GENERAL_OK_BUTTON_LABEL")); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { LicenseWindow.this.dispose(); LicenseWindow.this.setVisible(false); } }); c.gridheight = GridBagConstraints.REMAINDER; c.gridwidth = GridBagConstraints.REMAINDER; c.insets = new Insets(0, 0, 4, 4); c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.EAST; parent.add(button, c); pack(); } /** * Builds a new JTextArea with the appropriate values set. */ private JTextArea newTextArea(String msg) { JTextArea text = new JTextArea(); text.setLineWrap(true); text.setWrapStyleWord(true); text.setEditable(false); text.setFont(UIManager.getFont("Table.font")); JLabel label = new JLabel(); text.setForeground(label.getForeground()); text.setBackground(label.getBackground()); text.setText(msg); return text; } protected String getTitleString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_TITLE"); } protected String getLocatingString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_LOCATING"); } protected String getNotVerifiedString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_UNVERIFIED"); } protected String getVerifyString() { return GUIMediator.getStringResource("LICENSE_VERIFY"); } protected Icon getWarningIcon() { return GUIMediator.getThemeImage("warning"); } protected String getInvalidString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_INVALID"); } protected String getRetryString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_RETRY"); } protected String getClaimedDeedString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_CLAIMED_DEED"); } protected String getVerificationString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_VERIFICATION"); } protected String getDetailsString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_DETAILS"); } protected String getDeedString() { return GUIMediator.getStringResource("LICENSE_" + KEY_VALUE + "_DEED"); } protected Icon getLargeLicenseIcon() { return GUIMediator.getThemeImage(KEY_VALUE.toLowerCase() + "_window"); } protected boolean allowRetryLink() { return true; } protected boolean allowVerificationLink() { return true; } protected boolean allowClaimedDeedLink() { return true; } protected boolean allowVerifyLookup() { return true; } protected abstract String getLargeLicenseURLString(); /** * Special stuff for a CC license. */ private static class CCWindow extends LicenseWindow { CCWindow(License l, URN u, LimeXMLDocument d, VerificationListener v) { super(l, u, d, v, "CC"); } protected String getLargeLicenseURLString() { return "http://www.creativecommons.org"; } } /** * Special stuff for a Weed license. */ private static class WeedWindow extends LicenseWindow { WeedWindow(License l, URN u, LimeXMLDocument d, VerificationListener v) { super(l, u, d, v, "WEED"); } protected String getLargeLicenseURLString() { return "http://www.weedshare.com"; } /** Overriden to only show the img, not a license text box. */ protected void createTopOfWindow(Container parent) { GridBagConstraints c = new GridBagConstraints(); JLabel img = new URLLabel(getLargeLicenseURLString(), getLargeLicenseIcon()); c.insets = new Insets(4, 4, 2, 4); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; parent.add(img, c); } } /** * Special stuff for an unknown license. */ private static class UnknownWindow extends LicenseWindow { UnknownWindow(License l, URN u, LimeXMLDocument d, VerificationListener v) { super(l, u, d, v, "UNKNOWN"); } protected String getLargeLicenseURLString() { return "http://www.limewire.com"; } protected Icon getLargeLicenseIcon() { return GUIMediator.getThemeImage("logo"); } /** Overriden to only show the img, not a license text box. */ protected void createTopOfWindow(Container parent) { GridBagConstraints c = new GridBagConstraints(); JLabel img = new URLLabel(getLargeLicenseURLString(), getLargeLicenseIcon()); c.insets = new Insets(4, 4, 2, 4); c.gridwidth = GridBagConstraints.REMAINDER; c.fill = GridBagConstraints.BOTH; parent.add(img, c); } /** Always shows not valid. */ protected void buildDetails() { DETAILS.removeAll(); createNotValid(); validate(); repaint(); } /** Can't handle unknown licenses. */ protected boolean allowRetryLink() { return false; } /** Can't handle unknown licenses. */ protected boolean allowVerificationLink() { return false; } /** Can't handle unknown licenses. */ protected boolean allowClaimedDeedLink() { return false; } /** Can't handle unknown licenses. */ protected boolean allowVerifyLookup() { return false; } } }