Permalink
Switch branches/tags
Find file
Fetching contributors…
Cannot retrieve contributors at this time
360 lines (301 sloc) 9.38 KB
/*
Copyright 2009 Hauke Rehfeld
This file is part of QuakeInjector.
QuakeInjector 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.
QuakeInjector 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 QuakeInjector. If not, see <http://www.gnu.org/licenses/>.
*/
package de.haukerehfeld.quakeinjector;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.TimeZone;
import javax.swing.ImageIcon;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.Style;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.StyleSheet;
import de.haukerehfeld.quakeinjector.gui.BrowserLauncher;
import de.haukerehfeld.quakeinjector.gui.ScrollablePanel;
/**
* the panel that shows Info about the selected map
*/
class PackageDetailPanel extends JPanel implements ChangeListener,
PackageListSelectionHandler.SelectionListener {
private static final Dimension DEFAULTIMAGESIZE = new Dimension(200, 150);
private static final Dimension NOIMAGESIZE = new Dimension(100, 500);
/**
* Currently selected map
*/
private Package current = null;
private JLabel title;
private JLabel size;
private JLabel date;
private ScrollablePanel content;
private JLabel image;
private boolean imageDisplayed = false;
private JPanel imagePanel;
private JEditorPane description;
private String screenshotRepositoryPath;
/**
* Holds the currently valid screenshot url, for threading reasons
*/
private String supposedImageUrl = null;
/**
* @todo 2009-11-05 19:18 hrehfeld remove, duplicate from packagelistmodel
*/
private ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
public PackageDetailPanel(String screenshotRepositoryPath) {
super(new GridBagLayout());
this.screenshotRepositoryPath = screenshotRepositoryPath;
content = new ScrollablePanel(50, 50) {{
setLayout(new GridBagLayout());
}};
content.setOpaque(false);
//content.setBackground();
title = new JLabel();
title.setHorizontalAlignment(SwingConstants.CENTER);
title.setOpaque(true);
title.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
title.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent arg0) {
if (current != null) {
// TODO: Refactor; get the URL from Configuration
BrowserLauncher.openURL("https://www.quaddicted.com/reviews/" + current.getId() + ".html");
}
}
});
content.add(title, new GridBagConstraints() {{
weightx = 1;
weighty = 0;
fill = BOTH;
anchor = PAGE_START;
ipadx = 5;
ipady = 20;
}});
imagePanel = new JPanel();
imagePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
imagePanel.setOpaque(true);
imagePanel.setBackground(java.awt.Color.DARK_GRAY);
imagePanel.setPreferredSize(DEFAULTIMAGESIZE);
imagePanel.setMinimumSize(DEFAULTIMAGESIZE);
//imagePanel.setSize(DEFAULTIMAGESIZE);
image = new JLabel();
EmptyBorder border = new EmptyBorder(0,0,0,0);
image.setBorder(border);
image.setHorizontalAlignment(SwingConstants.CENTER);
image.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
image.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// TODO: Refactor
BrowserLauncher.openURL(PackageDetailPanel.this.screenshotRepositoryPath + current.getId() + ".jpg");
}
});
imagePanel.add(image);
description = new JEditorPane("text/html", "");
description.setEditable(false);
description.addHyperlinkListener(new HyperlinkListener() {
@Override public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) {
java.net.URL url = e.getURL();
if (url != null) {
BrowserLauncher.openURL(url.toString());
}
else {
System.err.println("Weird hyperlink with null URL: " + e.getDescription());
String link = "https://www.quaddicted.com/reviews/" + e.getDescription();
BrowserLauncher.openURL(link);
}
}
}
});
content.add(description, new GridBagConstraints() {{
gridy = 2;
weightx = 1;
weighty = 0;
fill = BOTH;
anchor = PAGE_START;
}});
{
HTMLEditorKit doc = ((HTMLEditorKit) description.getEditorKit());
StyleSheet styles = doc.getStyleSheet();
Enumeration rules = styles.getStyleNames();
while (rules.hasMoreElements()) {
String name = (String) rules.nextElement();
Style rule = styles.getStyle(name);
//System.out.println(rule.toString());
}
}
//Put the editor pane in a scroll pane.
JScrollPane descriptionScroll = new JScrollPane(content);
descriptionScroll.getViewport().setBackground(javax.swing.UIManager.getColor("TextPane.background"));
descriptionScroll.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants
.VERTICAL_SCROLLBAR_ALWAYS);
add(descriptionScroll, new GridBagConstraints() {{
gridy = 0;
gridwidth = 2;
weightx = 1;
weighty = 1;
fill = BOTH;
anchor = PAGE_START;
}});
int detailHeight = 20;
date = new JLabel();
date.setHorizontalAlignment(SwingConstants.CENTER);
add(date, new GridBagConstraints() {{
gridy = 1;
gridx = 0;
weightx = 1;
weighty = 0;
fill = NONE;
anchor = CENTER;
ipadx = 5;
ipady = 3;
}});
size = new JLabel();
size.setHorizontalAlignment(SwingConstants.CENTER);
add(size, new GridBagConstraints() {{
gridy = 1;
gridx = 1;
weightx = 1;
weighty = 0;
fill = NONE;
anchor = CENTER;
ipadx = 5;
ipady = 3;
}});
}
private void addImage() {
content.add(imagePanel, new GridBagConstraints() {{
gridy = 1;
weightx = 1;
weighty = 1;
fill = NONE;
anchor = CENTER;
}});
imageDisplayed = true;
}
private void removeImage() {
content.remove(imagePanel);
imageDisplayed = false;
}
private void refreshUi() {
title.setText(current.getTitle());
date.setText(toString(current.getDate()));
size.setText(current.getSize() / 1000f + "mb");
if (!imageDisplayed) {
addImage();
}
image.setIcon(null);
supposedImageUrl = screenshotRepositoryPath + current.getId() + "_injector.jpg";
//load image in bg thread
new SwingWorker<ImageIcon,Void>() {
private final String url = supposedImageUrl;
@Override
public ImageIcon doInBackground() {
try {
return new ImageIcon(new URL(url), current.getId());
}
catch (java.net.MalformedURLException e) {
}
return null;
}
@Override
public void done() {
//threading: is the image still valid?
if (isCancelled() || !supposedImageUrl.equals(url)) {
return;
}
ImageIcon icon;
try {
icon = get();
}
catch (java.lang.InterruptedException e) {
icon = null;
}
catch (java.util.concurrent.ExecutionException e) {
icon = null;
}
if (icon == null || (icon.getImageLoadStatus() & java.awt.MediaTracker.COMPLETE) == 0) {
removeImage();
System.err.println("Couldn't load image " + supposedImageUrl);
}
else {
image.setIcon(icon);
imagePanel.setMinimumSize(DEFAULTIMAGESIZE);
}
revalidate();
repaint();
}
}.execute();
description.getEditorKit().createDefaultDocument();
description.setText(current.getDescription()
+ toString(current.getRequirements()) + "<p></p>");
//scroll to top
description.setCaretPosition(0);
revalidate();
repaint();
}
private String toString(Date date) {
DateFormat dfm = new SimpleDateFormat("MMM d, yyyy");
dfm.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
return dfm.format(date);
}
private String toString(List<Requirement> requirements) {
if (requirements.isEmpty()) {
return "";
}
List<String> links = new ArrayList<String>(requirements.size());
for (Requirement r: requirements) {
links.add("<a href=\"" + r.getId() + ".html\">" + r.getId() + "</a>");
}
return "<p>Requires: " + Utils.join(links, ", ") + ".</p>";
}
@Override
public void selectionChanged(Package map) {
this.current = map;
refreshUi();
}
@Override
public void stateChanged(ChangeEvent e) {
System.out.println("StateChanged()");
refreshUi();
}
}