/*
DownloadPanel.java / Frost
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package frost.fileTransfer.download;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
import javax.swing.tree.TreePath;
import frost.Core;
import frost.MainFrame;
import frost.SettingsClass;
import frost.SettingsUpdater;
import frost.ext.ExecuteDocument;
import frost.fileTransfer.FileTransferManager;
import frost.fileTransfer.FreenetPriority;
import frost.fileTransfer.PersistenceManager;
import frost.fileTransfer.common.FileListFileDetailsDialog;
import frost.gui.AddNewDownloadsDialog;
import frost.messaging.frost.boards.Board;
import frost.messaging.frost.boards.TofTree;
import frost.util.CopyToClipboard;
import frost.util.FileAccess;
import frost.util.gui.JSkinnablePopupMenu;
import frost.util.gui.MiscToolkit;
import frost.util.gui.TextComponentClipboardMenu;
import frost.util.gui.search.TableFindAction;
import frost.util.gui.translation.Language;
import frost.util.gui.translation.LanguageEvent;
import frost.util.gui.translation.LanguageListener;
import frost.util.model.SortedModelTable;
@SuppressWarnings("serial")
public class DownloadPanel extends JPanel implements SettingsUpdater {
private PopupMenuDownload popupMenuDownload = null;
private final Listener listener = new Listener();
private static final Logger logger = Logger.getLogger(DownloadPanel.class.getName());
private DownloadModel model = null;
private Language language = null;
private final JToolBar downloadToolBar = new JToolBar();
private final JButton downloadPasteButton = new JButton(MiscToolkit.loadImageIcon("/data/toolbar/edit-paste.png"));
private final JButton submitDownloadTextfieldButton = new JButton(MiscToolkit
.loadImageIcon("/data/toolbar/document-save-as.png"));
private final JButton downloadActivateButton = new JButton(MiscToolkit
.loadImageIcon("/data/toolbar/media-playback-start.png"));
private final JButton downloadPauseButton = new JButton(MiscToolkit
.loadImageIcon("/data/toolbar/media-playback-pause.png"));
private final JButton downloadPrefixApplyButton = new JButton(MiscToolkit
.loadImageIcon("/data/toolbar/view-refresh.png"));
private final JButton downloadDirSelectButton = new JButton(MiscToolkit
.loadImageIcon("/data/toolbar/folder-open.png"));
private final JButton downloadDirCreateButton = new JButton(MiscToolkit
.loadImageIcon("/data/toolbar/folder-new.png"));
private final JButton downloadDirApplyButton = new JButton(MiscToolkit
.loadImageIcon("/data/toolbar/view-refresh.png"));
private final JMenu downloadDirRecentMenu = new JMenu();
private final JTextField downloadPrefixTextField = new JTextField(30);
private final JTextField downloadDirTextField = new JTextField(30);
private final JTextField downloadTextField = new JTextField(30);
private final JLabel downloadItemCountLabel = new JLabel();
private final JLabel downloadQuickloadLabel = new JLabel();
private final JLabel downloadPrefixLabel = new JLabel();
private final JLabel downloadDirLabel = new JLabel();
private final JCheckBox removeFinishedDownloadsCheckBox = new JCheckBox();
private final JCheckBox showExternalGlobalQueueItems = new JCheckBox();
private Color downloadDirDefaultBackground;
private SortedModelTable<FrostDownloadItem> modelTable;
private boolean initialized = false;
private boolean downloadingActivated = false;
private int downloadItemCount = 0;
public DownloadPanel() {
super();
Core.frostSettings.addUpdater(this);
language = Language.getInstance();
language.addLanguageListener(listener);
}
public DownloadTableFormat getTableFormat() {
return (DownloadTableFormat) modelTable.getTableFormat();
}
/**
* This Document changes all newlines in the text into semicolons. Needed if
* the user pastes multiple download keys, each on a line, into the download
* text field.
*/
protected class HandleMultiLineKeysDocument extends PlainDocument {
@Override
public void insertString(final int offs, String str, final AttributeSet a) throws BadLocationException {
str = str.replace('\n', ';');
str = str.replace('\r', ' ');
super.insertString(offs, str, a);
}
}
public void initialize() {
if (!initialized) {
refreshLanguage();
MiscToolkit.configureButton(downloadPasteButton);
MiscToolkit.configureButton(submitDownloadTextfieldButton);
MiscToolkit.configureButton(downloadPrefixApplyButton);
MiscToolkit.configureButton(downloadDirSelectButton);
MiscToolkit.configureButton(downloadDirCreateButton);
MiscToolkit.configureButton(downloadDirApplyButton);
MiscToolkit.configureButton(downloadActivateButton); // play_rollover
MiscToolkit.configureButton(downloadPauseButton); // pause_rollover
new TextComponentClipboardMenu(downloadTextField, language);
new TextComponentClipboardMenu(downloadPrefixTextField, language);
final TextComponentClipboardMenu tcmenu = new TextComponentClipboardMenu(downloadDirTextField, language);
final JPopupMenu menu = tcmenu.getPopupMenu();
menu.addSeparator();
menu.add(downloadDirRecentMenu);
downloadDirRecentMenu.addMenuListener(listener);
downloadToolBar.setRollover(true);
downloadToolBar.setFloatable(false);
removeFinishedDownloadsCheckBox.setOpaque(false);
showExternalGlobalQueueItems.setOpaque(false);
// Toolbar
downloadToolBar.add(downloadActivateButton);
downloadToolBar.add(downloadPauseButton);
downloadToolBar.add(Box.createRigidArea(new Dimension(8, 0)));
downloadToolBar.add(removeFinishedDownloadsCheckBox);
if (PersistenceManager.isPersistenceEnabled()) {
downloadToolBar.add(Box.createRigidArea(new Dimension(8, 0)));
downloadToolBar.add(showExternalGlobalQueueItems);
}
downloadToolBar.add(Box.createHorizontalGlue());
downloadToolBar.add(downloadItemCountLabel);
final GridBagConstraints gridBagConstraints = new GridBagConstraints();
final JPanel gridBagLayout = new JPanel(new GridBagLayout());
gridBagConstraints.anchor = GridBagConstraints.WEST;
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.insets = new Insets(0, 3, 0, 3);
gridBagConstraints.weightx = 0.0;
gridBagConstraints.weighty = 0.0;
gridBagConstraints.gridwidth = 1;
gridBagConstraints.gridheight = 1;
// Quickload
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.weightx = 0.0;
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagLayout.add(downloadQuickloadLabel, gridBagConstraints);
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagLayout.add(downloadTextField, gridBagConstraints);
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 0;
{
JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0));
p.add(submitDownloadTextfieldButton);
p.add(downloadPasteButton);
gridBagLayout.add(p, gridBagConstraints);
}
// Prefix
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.weightx = 0.0;
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagLayout.add(downloadPrefixLabel, gridBagConstraints);
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagLayout.add(downloadPrefixTextField, gridBagConstraints);
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 1;
{
JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0));
p.add(downloadPrefixApplyButton);
gridBagLayout.add(p, gridBagConstraints);
}
// Download directory
gridBagConstraints.fill = GridBagConstraints.NONE;
gridBagConstraints.weightx = 0.0;
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagLayout.add(downloadDirLabel, gridBagConstraints);
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 2;
gridBagLayout.add(downloadDirTextField, gridBagConstraints);
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 2;
{
JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0));
p.add(downloadDirSelectButton);
p.add(downloadDirCreateButton);
p.add(downloadDirApplyButton);
gridBagLayout.add(p, gridBagConstraints);
}
downloadTextField.setMinimumSize(downloadTextField.getPreferredSize());
downloadPrefixTextField.setMinimumSize(downloadTextField.getPreferredSize());
downloadDirTextField.setMinimumSize(downloadTextField.getPreferredSize());
downloadTextField.setDocument(new HandleMultiLineKeysDocument());
downloadDirTextField.setText(Core.frostSettings.getValue(SettingsClass.DIR_DOWNLOAD));
downloadDirDefaultBackground = downloadDirTextField.getBackground();
updateDownloadDirTextFieldBackground();
// create the main download panel
modelTable = new SortedModelTable<FrostDownloadItem>(model);
new TableFindAction().install(modelTable.getTable());
setLayout(new BorderLayout());
final JPanel panelHeader = new JPanel(new BorderLayout());
panelHeader.add(downloadToolBar, BorderLayout.PAGE_START);
panelHeader.add(gridBagLayout, BorderLayout.CENTER);
add(panelHeader, BorderLayout.NORTH);
add(modelTable.getScrollPane(), BorderLayout.CENTER);
fontChanged();
modelTable.getTable().setDefaultRenderer(Object.class, new CellRenderer());
// listeners
downloadTextField.addActionListener(listener);
downloadPasteButton.addActionListener(listener);
submitDownloadTextfieldButton.addActionListener(listener);
downloadActivateButton.addActionListener(listener);
downloadPauseButton.addActionListener(listener);
modelTable.getScrollPane().addMouseListener(listener);
modelTable.getTable().addKeyListener(listener);
modelTable.getTable().addMouseListener(listener);
removeFinishedDownloadsCheckBox.addItemListener(listener);
showExternalGlobalQueueItems.addItemListener(listener);
downloadPrefixApplyButton.addActionListener(listener);
downloadDirTextField.addKeyListener(listener);
downloadDirTextField.addFocusListener(listener);
downloadDirSelectButton.addActionListener(listener);
downloadDirCreateButton.addActionListener(listener);
downloadDirApplyButton.addActionListener(listener);
Core.frostSettings.addPropertyChangeListener(SettingsClass.FILE_LIST_FONT_NAME, listener);
Core.frostSettings.addPropertyChangeListener(SettingsClass.FILE_LIST_FONT_SIZE, listener);
Core.frostSettings.addPropertyChangeListener(SettingsClass.FILE_LIST_FONT_STYLE, listener);
// Settings
removeFinishedDownloadsCheckBox.setSelected(Core.frostSettings
.getBoolValue(SettingsClass.DOWNLOAD_REMOVE_FINISHED));
showExternalGlobalQueueItems.setSelected(Core.frostSettings
.getBoolValue(SettingsClass.GQ_SHOW_EXTERNAL_ITEMS_DOWNLOAD));
setDownloadingActivated(Core.frostSettings.getBoolValue(SettingsClass.DOWNLOADING_ACTIVATED));
assignHotkeys();
initialized = true;
}
}
private Dimension calculateLabelSize(final String text) {
final JLabel dummyLabel = new JLabel(text);
dummyLabel.doLayout();
return dummyLabel.getPreferredSize();
}
private void refreshLanguage() {
downloadPasteButton.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.pasteKeys"));
submitDownloadTextfieldButton.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.downloadKeys"));
downloadActivateButton.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.activateDownloading"));
downloadPauseButton.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.pauseDownloading"));
removeFinishedDownloadsCheckBox.setText(language.getString("DownloadPane.removeFinishedDownloads"));
showExternalGlobalQueueItems.setText(language.getString("DownloadPane.showExternalGlobalQueueItems"));
downloadTextField.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.addKeys"));
downloadPrefixTextField.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.downloadPrefix"));
downloadDirTextField.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.downloadDir"));
downloadPrefixApplyButton
.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.applyDownloadPrefix"));
downloadDirSelectButton.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.selectDownloadDir"));
downloadDirCreateButton.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.createDownloadDir"));
downloadDirApplyButton.setToolTipText(language.getString("DownloadPane.toolbar.tooltip.applyDownloadDir"));
downloadDirRecentMenu.setText(language.getString("DownloadPane.toolbar.downloadDirMenu.setDownloadDirTo"));
downloadQuickloadLabel.setText(language.getString("DownloadPane.toolbar.label.downloadQuickload") + ": ");
downloadPrefixLabel.setText(language.getString("DownloadPane.toolbar.label.downloadPrefix") + ": ");
downloadDirLabel.setText(language.getString("DownloadPane.toolbar.label.downloadDir") + ": ");
final String waiting = language.getString("DownloadPane.toolbar.waiting");
final Dimension labelSize = calculateLabelSize(waiting + ": 00000");
downloadItemCountLabel.setPreferredSize(labelSize);
downloadItemCountLabel.setMinimumSize(labelSize);
downloadItemCountLabel.setText(waiting + ": " + downloadItemCount);
}
public void setModel(final DownloadModel model) {
this.model = model;
}
private void updateDownloadDirTextFieldBackground() {
final File file = new File(downloadDirTextField.getText());
if (file.isDirectory()) {
downloadDirTextField.setBackground(downloadDirDefaultBackground);
} else {
downloadDirTextField.setBackground(Color.YELLOW);
}
}
private void downloadDirTextField_keyReleased(final KeyEvent e) {
updateDownloadDirTextFieldBackground();
}
private void downloadDirTextField_focusLost(final FocusEvent e) {
updateDownloadDirTextFieldBackground();
}
private final String getDownloadPrefix() {
return downloadPrefixTextField.getText();
}
private final String getDownloadDir() {
final String dir = downloadDirTextField.getText();
if (dir.length() == 0) {
return null;
} else {
return dir;
}
}
private void downloadDirSelectButton_actionPerformed(final ActionEvent e) {
final JFileChooser fc = new JFileChooser(FileAccess.appendSeparator(downloadDirTextField.getText()));
fc.setDialogTitle(language.getString("Options.downloads.filechooser.title"));
fc.setFileHidingEnabled(true);
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fc.setMultiSelectionEnabled(false);
final int returnVal = fc.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
final File file = fc.getSelectedFile();
Core.frostSettings.setValue(SettingsClass.DIR_LAST_USED, file.getParent());
downloadDirTextField.setText(file.getPath());
updateDownloadDirTextFieldBackground();
}
}
private void downloadDirCreateButton_actionPerformed(final ActionEvent e) {
File dir = new File(downloadDirTextField.getText());
try {
dir.mkdirs();
} catch (Exception foo) {
}
updateDownloadDirTextFieldBackground();
}
private void applyDownloadPrefixToSelectedDownloads() {
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
for (final FrostDownloadItem i : selectedItems) {
if (!i.isExternal()) {
i.setFilenamePrefix(getDownloadPrefix());
i.fireValueChanged();
}
}
}
private void applyDownloadDirToSelectedDownloads() {
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
for (final FrostDownloadItem i : selectedItems) {
if (!i.isExternal()) {
i.setDownloadDir(getDownloadDir());
i.fireValueChanged();
}
}
}
private void downloadDirApplyButton_actionPerformed(final ActionEvent e) {
applyDownloadDirToSelectedDownloads();
}
private void downloadPrefixApplyButton_actionPerformed(final ActionEvent e) {
applyDownloadPrefixToSelectedDownloads();
}
/**
* downloadTextField Action Listener (Download/Quickload) The textfield can
* contain 1 key to download or multiple keys separated by ';'.
*/
private void downloadTextField_actionPerformed(final ActionEvent e) {
String keylist = downloadTextField.getText();
if (keylist != null && keylist.length() != 0) {
openAddNewDownloadsDialog(keylist);
}
}
/**
* Get keyTyped for downloadTable
*/
private void downloadTable_keyPressed(final KeyEvent e) {
final char key = e.getKeyChar();
if (key == KeyEvent.VK_DELETE && !modelTable.getTable().isEditing()) {
removeSelectedDownloads();
}
}
private void removeSelectedDownloads() {
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
final List<String> externalRequestsToRemove = new LinkedList<String>();
final List<FrostDownloadItem> requestsToRemove = new LinkedList<FrostDownloadItem>();
for (final FrostDownloadItem frostDownloadItem : selectedItems) {
requestsToRemove.add(frostDownloadItem);
if (frostDownloadItem.isExternal()) {
externalRequestsToRemove.add(frostDownloadItem.getGqIdentifier());
}
}
model.removeItems(requestsToRemove);
modelTable.getTable().clearSelection();
if (FileTransferManager.inst().getPersistenceManager() != null && externalRequestsToRemove.size() > 0) {
new Thread() {
@Override
public void run() {
FileTransferManager.inst().getPersistenceManager().removeRequests(externalRequestsToRemove);
}
}.start();
}
}
public boolean isDownloadingActivated() {
return downloadingActivated;
}
public void setDownloadingActivated(final boolean b) {
downloadingActivated = b;
downloadActivateButton.setEnabled(!downloadingActivated);
downloadPauseButton.setEnabled(downloadingActivated);
}
public void setDownloadItemCount(final int newDownloadItemCount) {
downloadItemCount = newDownloadItemCount;
final String s = new StringBuilder().append(language.getString("DownloadPane.toolbar.waiting")).append(": ")
.append(downloadItemCount).toString();
downloadItemCountLabel.setText(s);
}
private PopupMenuDownload getPopupMenuDownload() {
if (popupMenuDownload == null) {
popupMenuDownload = new PopupMenuDownload();
language.addLanguageListener(popupMenuDownload);
}
return popupMenuDownload;
}
private void showDownloadTablePopupMenu(final MouseEvent e) {
// select row where rightclick occurred if row under mouse is NOT
// selected
final Point p = e.getPoint();
final int y = modelTable.getTable().rowAtPoint(p);
if (y < 0) {
return;
}
if (!modelTable.getTable().getSelectionModel().isSelectedIndex(y)) {
modelTable.getTable().getSelectionModel().setSelectionInterval(y, y);
}
getPopupMenuDownload().show(e.getComponent(), e.getX(), e.getY());
}
private void fontChanged() {
final String fontName = Core.frostSettings.getValue(SettingsClass.FILE_LIST_FONT_NAME);
final int fontStyle = Core.frostSettings.getIntValue(SettingsClass.FILE_LIST_FONT_STYLE);
final int fontSize = Core.frostSettings.getIntValue(SettingsClass.FILE_LIST_FONT_SIZE);
Font font = new Font(fontName, fontStyle, fontSize);
if (!font.getFamily().equals(fontName)) {
logger.severe("The selected font was not found in your system\n"
+ "That selection will be changed to \"SansSerif\".");
Core.frostSettings.setValue(SettingsClass.FILE_LIST_FONT_NAME, "SansSerif");
font = new Font("SansSerif", fontStyle, fontSize);
}
modelTable.setFont(font);
}
private void downloadPasteButtonPressed(final ActionEvent e) {
Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
if (transferable == null) {
return;
}
// try to get data from clipboard
String clipboardText;
try {
if (!transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return;
}
clipboardText = (String) transferable.getTransferData(DataFlavor.stringFlavor);
} catch (Exception stfu) {
return;
}
if (clipboardText != null && clipboardText.length() != 0) {
openAddNewDownloadsDialog(clipboardText);
}
}
private void openAddNewDownloadsDialog(final String keylist) {
// parse plaintext to get key list
List<FrostDownloadItem> frostDownloadItemList = DownloadManager.parseKeys(keylist);
if (frostDownloadItemList.size() == 0) {
return;
}
// add default download dir and prefix
for (final FrostDownloadItem frostDownloadItem : frostDownloadItemList) {
final String downloadDir = this.downloadDirTextField.getText();
if (downloadDir != null && downloadDir.length() != 0) {
frostDownloadItem.setDownloadDir(downloadDir);
}
final String filenamePrefix = this.downloadPrefixTextField.getText();
if (filenamePrefix != null && filenamePrefix.length() != 0) {
frostDownloadItem.setFilenamePrefix(this.downloadPrefixTextField.getText());
}
}
// open dialog - blocking
new AddNewDownloadsDialog(MainFrame.getInstance()).startDialog(frostDownloadItemList);
}
private void downloadActivateButtonPressed(final ActionEvent e) {
setDownloadingActivated(true);
}
private void downloadPauseButtonPressed(final ActionEvent e) {
setDownloadingActivated(false);
}
private void openFile(FrostDownloadItem dlItem) {
if (dlItem == null) {
return;
}
final File targetFile = new File(dlItem.getDownloadFilename());
if (!targetFile.isFile()) {
logger.info("Executing: File not found: " + targetFile.getAbsolutePath());
return;
}
logger.info("Executing: " + targetFile.getAbsolutePath());
try {
ExecuteDocument.openDocument(targetFile);
} catch (final Throwable t) {
JOptionPane.showMessageDialog(this, "Could not open the file: " + targetFile.getAbsolutePath() + "\n"
+ t.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
/*
* (non-Javadoc)
*
* @see frost.SettingsUpdater#updateSettings()
*/
public void updateSettings() {
Core.frostSettings.setValue(SettingsClass.DOWNLOADING_ACTIVATED, isDownloadingActivated());
}
public void changeItemPriorites(final List<FrostDownloadItem> items, final FreenetPriority newPrio) {
if (items == null || items.size() == 0 || FileTransferManager.inst().getPersistenceManager() == null) {
return;
}
for (final FrostDownloadItem di : items) {
String gqid = null;
di.setPriority(newPrio);
if (di.getState() == FrostDownloadItem.STATE_PROGRESS) {
gqid = di.getGqIdentifier();
}
if (gqid != null) {
FileTransferManager.inst().getPersistenceManager().getFcpTools().changeRequestPriority(gqid, newPrio);
}
}
}
private void assignHotkeys() {
// assign keys 1-6 - set priority of selected items
final Action setPriorityAction = new AbstractAction() {
public void actionPerformed(final ActionEvent event) {
final FreenetPriority prio = FreenetPriority.getPriority(new Integer(event.getActionCommand()).intValue());
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
changeItemPriorites(selectedItems, prio);
}
};
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0),
"SETPRIO");
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_2, 0),
"SETPRIO");
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_3, 0),
"SETPRIO");
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_4, 0),
"SETPRIO");
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_5, 0),
"SETPRIO");
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_6, 0),
"SETPRIO");
getActionMap().put("SETPRIO", setPriorityAction);
// Enter
final Action setOpenFileAction = new AbstractAction() {
public void actionPerformed(final ActionEvent event) {
openFile(modelTable.getSelectedItem());
}
};
getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),"OpenFile");
getActionMap().put("OpenFile", setOpenFileAction);
}
/**
* Renderer draws background of DONE items in green.
*/
private class CellRenderer extends DefaultTableCellRenderer {
private final Color col_green = new Color(0x00, 0x80, 0x00);
public CellRenderer() {
super();
}
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value,
final boolean isSelected, final boolean hasFocus, final int row, final int column) {
super.getTableCellRendererComponent(table, value, isSelected, /* hasFocus */
false, row, column);
final FrostDownloadItem item = (FrostDownloadItem) model.getItemAt(row);
// set background of DONE downloads green
if (item.getState() == FrostDownloadItem.STATE_DONE) {
setBackground(col_green);
} else {
setBackground(modelTable.getTable().getBackground());
}
return this;
}
}
private class PopupMenuDownload extends JSkinnablePopupMenu implements ActionListener, LanguageListener {
private final JMenuItem detailsItem = new JMenuItem();
private final JMenuItem copyKeysAndNamesItem = new JMenuItem();
private final JMenuItem copyExtendedInfoItem = new JMenuItem();
private final JMenuItem disableAllDownloadsItem = new JMenuItem();
private final JMenuItem disableSelectedDownloadsItem = new JMenuItem();
private final JMenuItem enableAllDownloadsItem = new JMenuItem();
private final JMenuItem enableSelectedDownloadsItem = new JMenuItem();
private final JMenuItem invertEnabledAllItem = new JMenuItem();
private final JMenuItem invertEnabledSelectedItem = new JMenuItem();
private final JMenuItem removeSelectedDownloadsItem = new JMenuItem();
private final JMenuItem restartSelectedDownloadsItem = new JMenuItem();
private final JMenuItem startSelectedDownloadsNow = new JMenuItem();
private final JMenuItem useThisDownloadDirItem = new JMenuItem();
private final JMenuItem jumpToAssociatedMessage = new JMenuItem();
private JMenu changePriorityMenu = null;
private JMenuItem removeFromGqItem = null;
private JMenuItem retrieveDirectExternalDownloads = null;
public PopupMenuDownload() {
super();
initialize();
}
private void initialize() {
if (PersistenceManager.isPersistenceEnabled()) {
changePriorityMenu = new JMenu();
for(final FreenetPriority priority : FreenetPriority.values()) {
JMenuItem priorityMenuItem = new JMenuItem();
priorityMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(final ActionEvent actionEvent) {
changeItemPriorites(modelTable.getSelectedItems(), priority);
}
});
changePriorityMenu.add(priorityMenuItem);
}
removeFromGqItem = new JMenuItem();
removeFromGqItem.addActionListener(this);
retrieveDirectExternalDownloads = new JMenuItem();
retrieveDirectExternalDownloads.addActionListener(this);
}
refreshLanguage();
// TODO: implement cancel of downloads
copyKeysAndNamesItem.addActionListener(this);
copyExtendedInfoItem.addActionListener(this);
restartSelectedDownloadsItem.addActionListener(this);
removeSelectedDownloadsItem.addActionListener(this);
enableAllDownloadsItem.addActionListener(this);
disableAllDownloadsItem.addActionListener(this);
enableSelectedDownloadsItem.addActionListener(this);
disableSelectedDownloadsItem.addActionListener(this);
invertEnabledAllItem.addActionListener(this);
invertEnabledSelectedItem.addActionListener(this);
detailsItem.addActionListener(this);
startSelectedDownloadsNow.addActionListener(this);
useThisDownloadDirItem.addActionListener(this);
jumpToAssociatedMessage.addActionListener(this);
}
private void refreshLanguage() {
detailsItem.setText(language.getString("Common.details"));
copyKeysAndNamesItem.setText(language.getString("Common.copyToClipBoard.copyKeysWithFilenames"));
copyExtendedInfoItem.setText(language.getString("Common.copyToClipBoard.copyExtendedInfo"));
restartSelectedDownloadsItem.setText(language
.getString("DownloadPane.fileTable.popupmenu.restartSelectedDownloads"));
removeSelectedDownloadsItem.setText(language
.getString("DownloadPane.fileTable.popupmenu.remove.removeSelectedDownloads"));
enableAllDownloadsItem.setText(language
.getString("DownloadPane.fileTable.popupmenu.enableDownloads.enableAllDownloads"));
disableAllDownloadsItem.setText(language
.getString("DownloadPane.fileTable.popupmenu.enableDownloads.disableAllDownloads"));
enableSelectedDownloadsItem.setText(language
.getString("DownloadPane.fileTable.popupmenu.enableDownloads.enableSelectedDownloads"));
disableSelectedDownloadsItem.setText(language
.getString("DownloadPane.fileTable.popupmenu.enableDownloads.disableSelectedDownloads"));
invertEnabledAllItem.setText(language
.getString("DownloadPane.fileTable.popupmenu.enableDownloads.invertEnabledStateForAllDownloads"));
invertEnabledSelectedItem
.setText(language
.getString("DownloadPane.fileTable.popupmenu.enableDownloads.invertEnabledStateForSelectedDownloads"));
startSelectedDownloadsNow.setText(language
.getString("DownloadPane.fileTable.popupmenu.startSelectedDownloadsNow"));
useThisDownloadDirItem.setText(language.getString("DownloadPane.fileTable.popupmenu.useThisDownloadDir"));
jumpToAssociatedMessage.setText(language
.getString("DownloadPane.fileTable.popupmenu.jumpToAssociatedMessage"));
if (PersistenceManager.isPersistenceEnabled()) {
changePriorityMenu.setText(language.getString("Common.priority.changePriority"));
for(int itemNum = 0; itemNum < changePriorityMenu.getItemCount() ; itemNum++) {
changePriorityMenu.getItem(itemNum).setText(FreenetPriority.getName(itemNum));
}
removeFromGqItem.setText(language.getString("DownloadPane.fileTable.popupmenu.removeFromGlobalQueue"));
retrieveDirectExternalDownloads.setText(language
.getString("DownloadPane.fileTable.popupmenu.retrieveDirectExternalDownloads"));
}
}
public void actionPerformed(final ActionEvent e) {
if (e.getSource() == copyKeysAndNamesItem) {
CopyToClipboard.copyKeysAndFilenames(modelTable.getSelectedItems().toArray());
} else if (e.getSource() == copyExtendedInfoItem) {
CopyToClipboard.copyExtendedInfo(modelTable.getSelectedItems().toArray());
} else if (e.getSource() == restartSelectedDownloadsItem) {
restartSelectedDownloads();
} else if (e.getSource() == useThisDownloadDirItem) {
useThisDownloadDirectory();
} else if (e.getSource() == jumpToAssociatedMessage) {
jumpToAssociatedMessage();
} else if (e.getSource() == removeSelectedDownloadsItem) {
removeSelectedDownloads();
} else if (e.getSource() == enableAllDownloadsItem) {
enableAllDownloads();
} else if (e.getSource() == disableAllDownloadsItem) {
disableAllDownloads();
} else if (e.getSource() == enableSelectedDownloadsItem) {
enableSelectedDownloads();
} else if (e.getSource() == disableSelectedDownloadsItem) {
disableSelectedDownloads();
} else if (e.getSource() == invertEnabledAllItem) {
invertEnabledAll();
} else if (e.getSource() == invertEnabledSelectedItem) {
invertEnabledSelected();
} else if (e.getSource() == detailsItem) {
showDetails();
} else if (e.getSource() == removeFromGqItem) {
removeSelectedUploadsFromGlobalQueue();
} else if (e.getSource() == retrieveDirectExternalDownloads) {
retrieveDirectExternalDownloads();
} else if (e.getSource() == startSelectedDownloadsNow) {
startSelectedDownloadsNow();
}
}
private void removeSelectedUploadsFromGlobalQueue() {
if (FileTransferManager.inst().getPersistenceManager() == null) {
return;
}
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
final List<String> requestsToRemove = new ArrayList<String>();
final List<FrostDownloadItem> itemsToUpdate = new ArrayList<FrostDownloadItem>();
for (final FrostDownloadItem item : selectedItems) {
if (FileTransferManager.inst().getPersistenceManager().isItemInGlobalQueue(item)) {
requestsToRemove.add(item.getGqIdentifier());
itemsToUpdate.add(item);
item.setInternalRemoveExpected(true);
}
}
FileTransferManager.inst().getPersistenceManager().removeRequests(requestsToRemove);
// after remove, update state of removed items
for (final FrostDownloadItem item : itemsToUpdate) {
item.setState(FrostDownloadItem.STATE_WAITING);
item.setEnabled(Boolean.FALSE);
item.setPriority(FreenetPriority.PAUSE);
item.fireValueChanged();
}
}
private void retrieveDirectExternalDownloads() {
if (FileTransferManager.inst().getPersistenceManager() == null) {
return;
}
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
for (final FrostDownloadItem item : selectedItems) {
if (item.isExternal() && item.isDirect() && item.getState() == FrostDownloadItem.STATE_DONE) {
final long expectedFileSize = item.getFileSize(); // set
// from
// global
// queue
FileTransferManager.inst().getPersistenceManager().maybeEnqueueDirectGet(item, expectedFileSize);
}
}
}
private void startSelectedDownloadsNow() {
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
final List<FrostDownloadItem> itemsToStart = new LinkedList<FrostDownloadItem>();
for (final FrostDownloadItem i : selectedItems) {
if (i.isExternal()) {
continue;
}
if (i.getState() != FrostDownloadItem.STATE_WAITING) {
continue;
}
if (i.getKey() == null) {
continue;
}
itemsToStart.add(i);
}
for (final FrostDownloadItem dlItem : itemsToStart) {
dlItem.setEnabled(true);
FileTransferManager.inst().getDownloadManager().startDownload(dlItem);
}
}
private void showDetails() {
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
if (selectedItems.size() != 1) {
return;
}
if (!selectedItems.get(0).isSharedFile()) {
return;
}
new FileListFileDetailsDialog(MainFrame.getInstance()).startDialog(selectedItems.get(0).getFileListFileObject());
}
private void invertEnabledSelected() {
model.setItemsEnabled(null, modelTable.getSelectedItems());
}
private void invertEnabledAll() {
model.setAllItemsEnabled(null);
}
private void disableSelectedDownloads() {
model.setItemsEnabled(Boolean.FALSE, modelTable.getSelectedItems());
}
private void enableSelectedDownloads() {
model.setItemsEnabled(Boolean.TRUE, modelTable.getSelectedItems());
}
private void disableAllDownloads() {
model.setAllItemsEnabled(Boolean.FALSE);
}
private void enableAllDownloads() {
model.setAllItemsEnabled(Boolean.TRUE);
}
private void restartSelectedDownloads() {
model.restartItems(modelTable.getSelectedItems());
}
private void useThisDownloadDirectory() {
if (modelTable.getSelectedItems().size() > 0) {
downloadDirTextField.setText(modelTable.getSelectedItems().get(0).getDownloadDir());
}
}
private void jumpToAssociatedMessage() {
if (modelTable.getSelectedItems().size() > 0) {
final FrostDownloadItem item = modelTable.getSelectedItems().get(0);
final String boardName = item.getAssociatedBoardName();
final String messageId = item.getAssociatedMessageId();
if (boardName != null && messageId != null) {
final Board board = MainFrame.getInstance().getFrostMessageTab().getTofTreeModel().getBoardByName(
boardName);
final TofTree t = MainFrame.getInstance().getFrostMessageTab().getTofTree();
if (board != null && t != null) {
t.clearSelection();
MainFrame.getInstance().getFrostMessageTab().forceSelectMessageId(messageId);
t.setSelectionPath(new TreePath(board.getPath()));
MainFrame.getInstance().selectTabbedPaneTab("MainFrame.tabbedPane.news");
}
}
}
}
public void languageChanged(final LanguageEvent event) {
refreshLanguage();
}
@Override
public void show(final Component invoker, final int x, final int y) {
removeAll();
final List<FrostDownloadItem> selectedItems = modelTable.getSelectedItems();
if (selectedItems.size() == 0) {
return;
}
add(copyKeysAndNamesItem);
add(copyExtendedInfoItem);
addSeparator();
add(startSelectedDownloadsNow);
add(restartSelectedDownloadsItem);
addSeparator();
if (PersistenceManager.isPersistenceEnabled()) {
add(changePriorityMenu);
addSeparator();
}
final JMenu enabledSubMenu = new JMenu(language
.getString("DownloadPane.fileTable.popupmenu.enableDownloads")
+ "...");
enabledSubMenu.add(enableSelectedDownloadsItem);
enabledSubMenu.add(disableSelectedDownloadsItem);
enabledSubMenu.add(invertEnabledSelectedItem);
enabledSubMenu.addSeparator();
enabledSubMenu.add(enableAllDownloadsItem);
enabledSubMenu.add(disableAllDownloadsItem);
enabledSubMenu.add(invertEnabledAllItem);
add(enabledSubMenu);
// we only find external items if persistence is enabled
if (PersistenceManager.isPersistenceEnabled()) {
for (final FrostDownloadItem item : selectedItems) {
if (item.isExternal() && item.isDirect() && item.getState() == FrostDownloadItem.STATE_DONE) {
add(retrieveDirectExternalDownloads);
break;
}
}
}
add(removeSelectedDownloadsItem);
if (FileTransferManager.inst().getPersistenceManager() != null && selectedItems != null) {
// add only if there are removable items selected
for (final FrostDownloadItem item : selectedItems) {
if (FileTransferManager.inst().getPersistenceManager().isItemInGlobalQueue(item)) {
add(removeFromGqItem);
break;
}
}
}
if (selectedItems.size() == 1) {
final FrostDownloadItem item = selectedItems.get(0);
if (item.isSharedFile()) {
addSeparator();
add(detailsItem);
}
addSeparator();
add(useThisDownloadDirItem);
if (item.getAssociatedMessageId() != null) {
addSeparator();
add(jumpToAssociatedMessage);
}
}
super.show(invoker, x, y);
}
}
private class Listener extends MouseAdapter implements LanguageListener, ActionListener, KeyListener,
MouseListener, PropertyChangeListener, ItemListener, FocusListener, MenuListener {
public Listener() {
super();
}
public void languageChanged(final LanguageEvent event) {
refreshLanguage();
}
public void actionPerformed(final ActionEvent e) {
if (e.getSource() == downloadDirSelectButton) {
downloadDirSelectButton_actionPerformed(e);
} else if (e.getSource() == downloadDirCreateButton) {
downloadDirCreateButton_actionPerformed(e);
} else if (e.getSource() == downloadPrefixApplyButton) {
downloadPrefixApplyButton_actionPerformed(e);
} else if (e.getSource() == downloadDirApplyButton) {
downloadDirApplyButton_actionPerformed(e);
} else if (e.getSource() == submitDownloadTextfieldButton) {
downloadTextField_actionPerformed(e);
} else if (e.getSource() == downloadTextField) {
downloadTextField_actionPerformed(e);
} else if (e.getSource() == downloadPasteButton) {
downloadPasteButtonPressed(e);
} else if (e.getSource() == downloadActivateButton) {
downloadActivateButtonPressed(e);
} else if (e.getSource() == downloadPauseButton) {
downloadPauseButtonPressed(e);
} else {
for (int i = 0; i < downloadDirRecentMenu.getItemCount(); i++) {
final JMenuItem item = downloadDirRecentMenu.getItem(i);
if (e.getSource() == item) {
downloadDirTextField.setText(item.getText());
}
}
}
}
public void keyPressed(final KeyEvent e) {
if (e.getSource() == modelTable.getTable()) {
downloadTable_keyPressed(e);
}
}
public void keyReleased(final KeyEvent e) {
if (e.getSource() == downloadDirTextField) {
downloadDirTextField_keyReleased(e);
}
}
public void keyTyped(final KeyEvent e) {
}
public void focusGained(final FocusEvent e) {
}
public void focusLost(final FocusEvent e) {
if (e.getSource() == downloadDirTextField) {
downloadDirTextField_focusLost(e);
}
}
@Override
public void mousePressed(final MouseEvent e) {
if (e.getClickCount() == 2) {
if (e.getSource() == modelTable.getTable()) {
// Start file from download table. Is this a good idea?
openFile(modelTable.getSelectedItem());
}
} else if (e.isPopupTrigger()) {
if ((e.getSource() == modelTable.getTable()) || (e.getSource() == modelTable.getScrollPane())) {
showDownloadTablePopupMenu(e);
}
}
}
@Override
public void mouseReleased(final MouseEvent e) {
if ((e.getClickCount() == 1) && (e.isPopupTrigger())) {
if ((e.getSource() == modelTable.getTable()) || (e.getSource() == modelTable.getScrollPane())) {
showDownloadTablePopupMenu(e);
}
}
}
public void propertyChange(final PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(SettingsClass.FILE_LIST_FONT_NAME)) {
fontChanged();
}
if (evt.getPropertyName().equals(SettingsClass.FILE_LIST_FONT_SIZE)) {
fontChanged();
}
if (evt.getPropertyName().equals(SettingsClass.FILE_LIST_FONT_STYLE)) {
fontChanged();
}
}
public void itemStateChanged(final ItemEvent e) {
if (removeFinishedDownloadsCheckBox.isSelected()) {
Core.frostSettings.setValue(SettingsClass.DOWNLOAD_REMOVE_FINISHED, true);
model.removeFinishedDownloads();
} else {
Core.frostSettings.setValue(SettingsClass.DOWNLOAD_REMOVE_FINISHED, false);
}
if (showExternalGlobalQueueItems.isSelected()) {
Core.frostSettings.setValue(SettingsClass.GQ_SHOW_EXTERNAL_ITEMS_DOWNLOAD, true);
} else {
Core.frostSettings.setValue(SettingsClass.GQ_SHOW_EXTERNAL_ITEMS_DOWNLOAD, false);
model.removeExternalDownloads();
}
}
public void menuCanceled(MenuEvent e) {
}
public void menuDeselected(MenuEvent e) {
}
public void menuSelected(MenuEvent e) {
if (e.getSource() == downloadDirRecentMenu) {
JMenuItem item;
downloadDirRecentMenu.removeAll();
item = new JMenuItem(Core.frostSettings.getValue(SettingsClass.DIR_DOWNLOAD));
downloadDirRecentMenu.add(item);
item.addActionListener(this);
final LinkedList<String> dirs = FileTransferManager.inst().getDownloadManager().getRecentDownloadDirs();
if( dirs.size() > 0 ) {
downloadDirRecentMenu.addSeparator();
final ListIterator<String> iter = dirs.listIterator(dirs.size());
while (iter.hasPrevious()) {
final String dir = (String) iter.previous();
item = new JMenuItem(dir);
downloadDirRecentMenu.add(item);
item.addActionListener(this);
}
}
}
}
}
}