LibraryPanel.java

Index Score
xnap.gui
XNap 2

View: Reasons, Metrics, Source Code

These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.

MetricDescription
/* * XNap * * A pure java file sharing client. * * See AUTHORS for copyright information. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package xnap.gui; import xnap.*; import xnap.gui.action.CopyFileAction; import xnap.gui.action.CutFileAction; import xnap.gui.action.PasteFileAction; import xnap.gui.action.OpenFileWithMenu; import xnap.gui.event.*; import xnap.gui.table.*; import xnap.gui.tree.*; import xnap.plugin.*; import xnap.util.*; import xnap.util.event.StateEvent; import xnap.util.event.StateListener; import xnap.util.audio.*; import xnap.io.*; import java.awt.*; import java.awt.event.*; import java.beans.*; import java.util.*; import java.io.*; import java.net.*; import java.text.MessageFormat; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; import javax.swing.table.*; import javax.swing.tree.*; public class LibraryPanel extends AbstractPanel implements PropertyChangeListener, TreeSelectionListener, ListSelectionListener, DirectoryCollector, FileCollector { //--- Constant(s) --- public static final String HISTORY_FILENAME = FileHelper.getHomeDir() + "repository_search_history"; //--- Data field(s) --- private AudioPlayer player = null; private EditableComboBox jcSearch; private JTree jt; private JTable jta; private JFileChooser jfc = null; private LibraryTableModel ltm; private DefaultMutableTreeNode root; private FileTreeModel ftm; private DragFilesSupport dfs; private JSplitPane jspH; private JSplitPane jspV; // preview private JPanel jpPreview; private JScrollPane jspPreview; private JLabel jlStatus; private PlayAction playAction = new PlayAction(); private PlayFileAction playFileAction = new PlayFileAction(); private RefreshAction refreshAction = new RefreshAction(); private StopAction stopAction = new StopAction(); private EnqueueAction enqueueAction = new EnqueueAction(); private PlayFolderAction playFolderAction = new PlayFolderAction(); private EnqueueFolderAction enqueueFolderAction = new EnqueueFolderAction(); private OpenFileAction acOpenFile = new OpenFileAction(this); private ShareFolderAction shareFolderAction = new ShareFolderAction(); private UnshareFolderAction unshareFolderAction = new UnshareFolderAction(); private ReloadTreeAction acReloadTree = new ReloadTreeAction(); private DeleteAction deleteAction = new DeleteAction(); private RenameAction renameAction = new RenameAction(); private CopyFileAction acCopyFile = new CopyFileAction(this); private CutFileAction acCutFile = new CutFileAction(this); private PasteFileAction acPasteFile = new PasteFileAction(this); private File currentDir; private int currentRow; private javax.swing.Timer delayTimer; private DisplayThread displayThread = new DisplayThread(); //--- Constructor(s) --- public LibraryPanel() { initialize(); } //--- Method(s) --- private void initialize() { // search panel Box boxOne = new Box(BoxLayout.X_AXIS); QueryAction acQuery = new QueryAction(); EraseAction acErase = new EraseAction(); JButton jbErase = new JButton(acErase); jbErase.setMargin(new Insets(1, 1, 1, 1)); boxOne.add(jbErase); jcSearch = new EditableComboBox(acQuery, prefs.getSearchHistorySize()); jcSearch.readHistoryFile(new File(HISTORY_FILENAME)); boxOne.add(jcSearch); acErase.setJTextField(jcSearch.getJTextField()); JButton jbQuery = new JButton(acQuery); boxOne.add(jbQuery); JPanel jpTop = new JPanel(new BorderLayout()); jpTop.setBorder(new TitledBorder(XNap.tr("Library Search", 1))); jpTop.add(boxOne, "Center"); /* tree context menu */ JPopupMenu treePopup = new JPopupMenu(); treePopup.add(new JMenuItem(playFolderAction)); treePopup.add(new JMenuItem(enqueueFolderAction)); treePopup.addSeparator(); treePopup.add(new JMenuItem(shareFolderAction)); treePopup.add(new JMenuItem(unshareFolderAction)); treePopup.addSeparator(); treePopup.add(acPasteFile); treePopup.addSeparator(); treePopup.add(new JMenuItem(acReloadTree)); /* tree */ ftm = new FileTreeModel(XNap.tr("Files")); // jt = new JTree(ftm); jt = new DroppableJTree(ftm, this); jt.addTreeSelectionListener(this); jt.setCellRenderer(new FileCellRenderer()); jt.putClientProperty("JTree.lineStyle", "Angled"); MouseListener treePopupListener = new PopupListener(treePopup); jt.addMouseListener(treePopupListener); /* allow multiple selections in tree */ jt.getSelectionModel().setSelectionMode (TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); JScrollPane jspTree = new JScrollPane(); jspTree.setViewportView(jt); /* table context menu */ JPopupMenu popup = new JPopupMenu(); popup.add(new JMenuItem(playAction)); popup.add(new JMenuItem(enqueueAction)); popup.addSeparator(); popup.add(new JMenuItem(acOpenFile)); popup.add(new OpenFileWithMenu(this)); popup.addSeparator(); popup.add(createViewerMenu()); popup.addSeparator(); popup.add(acCopyFile); popup.add(acCutFile); popup.add(acPasteFile); popup.addSeparator(); popup.add(renameAction); popup.add(deleteAction); /* table */ ltm = new LibraryTableModel(); jta = ltm.createJTable(); dfs = new DragFilesSupport(jta, this); jta.getSelectionModel().addListSelectionListener(this); jta.setShowGrid(false); MouseListener popupListener = new PopupListener(popup); jta.addMouseListener(popupListener); jta.addMouseListener(new DoubleClickListener(acOpenFile, jta)); /* set up Emacs keybindings for move actions */ ActionListener al = jta.getActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)); jta.registerKeyboardAction (al,KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK), WHEN_FOCUSED); al = jta.getActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)); jta.registerKeyboardAction (al, KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_MASK), WHEN_FOCUSED); al = jta.getActionForKeyStroke (KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0)); jta.registerKeyboardAction (al, KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK), WHEN_FOCUSED); al = jta.getActionForKeyStroke (KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0)); jta.registerKeyboardAction (al, KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.ALT_MASK), WHEN_FOCUSED); al = jta.getActionForKeyStroke (KeyStroke.getKeyStroke(KeyEvent.VK_HOME, InputEvent.CTRL_MASK)); jta.registerKeyboardAction (al, KeyStroke.getKeyStroke(KeyEvent.VK_LESS, InputEvent.ALT_MASK), WHEN_FOCUSED); al = jta.getActionForKeyStroke (KeyStroke.getKeyStroke(KeyEvent.VK_END, InputEvent.CTRL_MASK)); jta.registerKeyboardAction (al, KeyStroke.getKeyStroke(KeyEvent.VK_LESS, InputEvent.ALT_MASK + InputEvent.SHIFT_MASK), WHEN_FOCUSED); jta.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), acOpenFile); jta.getActionMap().put(acOpenFile, acOpenFile); jta.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0), refreshAction); jta.getActionMap().put(refreshAction, refreshAction); jta.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), deleteAction); jta.getActionMap().put(deleteAction, deleteAction); jta.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), renameAction); jta.getActionMap().put(renameAction, renameAction); jta.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), enqueueAction); jta.getActionMap().put(enqueueAction, enqueueAction); JScrollPane jspTable = new JScrollPane(); jspTable.setViewportView(jta); /* selection delay, which ensures the user really wants the plugin to be activated. */ delayTimer = new javax.swing.Timer(500, new SelectionListener()); delayTimer.setRepeats(false); /* preview pane */ jpPreview = new JPanel(new BorderLayout()); jpPreview.setBackground(Color.gray); jspPreview = new JScrollPane(jpPreview); al = jspPreview.getActionForKeyStroke (KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_DOWN, 0)); jspPreview.registerKeyboardAction (al, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK), WHEN_IN_FOCUSED_WINDOW); al = jspPreview.getActionForKeyStroke (KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, 0)); jspPreview.registerKeyboardAction (al, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK), WHEN_IN_FOCUSED_WINDOW); /* split panels */ jspV = new JSplitPane(JSplitPane.VERTICAL_SPLIT); jspV.add(jspTable, JSplitPane.TOP); jspV.add(jspPreview, JSplitPane.BOTTOM); jspV.setDividerLocation(prefs.getLibraryVerticalDividerLocation()); jspV.setOneTouchExpandable(true); jlStatus = new JLabel(" "); JPanel jpV = new JPanel(new BorderLayout()); jpV.add(jspV, "Center"); jpV.add(jlStatus, "South"); jspH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); jspH.add(jspTree, JSplitPane.LEFT); jspH.add(jpV, JSplitPane.RIGHT); jspH.setDividerLocation(prefs.getLibraryHorizontalDividerLocation()); jspH.setOneTouchExpandable(true); /* content */ setLayout(new BorderLayout()); add(jpTop, BorderLayout.NORTH); add(jspH, BorderLayout.CENTER); // make sure we are set updateAudioPlayer(); // show directories updateTree(); // make sure we are notified when the downloadDir changes prefs.addPropertyChangeListener(this); } /** * Lazy instantiation. */ public JFileChooser getFileChooser() { if (jfc == null) { jfc = new JFileChooser(); MP3FileFilter filter = new MP3FileFilter(); jfc.setFileFilter(filter); } return jfc; } public JMenu getTableMenu() { return ltm.createJMenu(); } public void hasChanged(File directory) { if (currentDir != null) { showDirectory(currentDir); } } /** * This hack sets the focus to jcSearch after the searchpanel has been * activated. This only works for java 1.3 and the JTabbedPane and not for * the IconSplitPane. */ // public void setVisible(boolean visible) // { // super.setVisible(visible); // if (visible) { // SwingUtilities.invokeLater(new Runnable() // { // public void run() // { // // System.out.println("swing invoke runnable"); // jcSearch.grabFocus(); // } // }); // } // } public void purgeHistory() { jcSearch.removeAllItems(); } public void propertyChange(PropertyChangeEvent e) { String p = e.getPropertyName(); if (e.getSource() == prefs) { if (p.equals("incompleteDir")) { ftm.removeChildrenOfSubRoot(XNap.tr("Incomplete Files")); ftm.addChildOfSubRoot(new File(prefs.getIncompleteDir()), XNap.tr("Incomplete Files")); } else if (p.equals("uploadDirs")) { ftm.removeChildrenOfSubRoot(XNap.tr("Shared Files")); String[] dirs = prefs.getUploadDirsArray(); for (int i = 0; i < dirs.length; i++) { ftm.addChildOfSubRoot(new File(dirs[i]), XNap.tr("Shared Files")); } } else if (p.equals("mp3PlayerCmd") || p.equals("mp3PlayerType")) { updateAudioPlayer(); } else if (p.equals("downloadDir") || p.indexOf("DownloadDir") != -1) { ftm.removeChildrenOfSubRoot(XNap.tr("Downloaded Files")); addDownloadDirs(); } } } public void savePrefs() { prefs.setLibraryHorizontalDividerLocation(jspH.getDividerLocation()); prefs.setLibraryVerticalDividerLocation(jspV.getDividerLocation()); jcSearch.setHistorySize(prefs.getSearchHistorySize()); jcSearch.writeHistoryFile(new File(HISTORY_FILENAME)); } private void updateAudioPlayer() { player = AudioSupport.getInstance(prefs.getMP3PlayerType(), prefs.getMP3PlayerCmd()); } /** * Clears the tree and adds a couple of nodes. */ private void updateTree() { ftm.removeSubRoots(); int failed = 0; String[] nodes = prefs.getLibraryTreeNodesArray(); for (int j = 0; j < nodes.length; j++) { if (nodes[j].equals("shares")) { // add shares ftm.addSubRoot(XNap.tr("Shared Files")); String[] dirs = prefs.getUploadDirsArray(); for (int i = 0; i < dirs.length; i++) { ftm.addChildOfSubRoot(new File(dirs[i]), XNap.tr("Shared Files")); } jt.expandRow(jt.getRowCount() - 1); } else if (nodes[j].equals("incompletes")) { // add incomplete dir ftm.addChildOfSubRoot(new File(prefs.getIncompleteDir()), XNap.tr("Incomplete Files")); // ensure that the actual incomplete directory is viewable jt.expandRow(jt.getRowCount() - 1); } else if (nodes[j].equals("downloads")) { addDownloadDirs(); jt.expandRow(jt.getRowCount() - 1); } else if (nodes[j].equals("home")) { ftm.addChildOfSubRoot(new File (System.getProperty("user.home")), XNap.tr("Home Directory")); jt.expandRow(jt.getRowCount() - 1); } else if (nodes[j].equals("root")) { // add system roots File[] roots = File.listRoots(); for (int i = 0; i < roots.length; i++) { ftm.addChildOfSubRoot(roots[i], XNap.tr("Root Directory")); } jt.expandRow(jt.getRowCount() - 1); } else { failed++; } } if (failed == nodes.length) { // always show at least system roots ftm.addSubRoot(XNap.tr("Root Directory")); File[] roots = File.listRoots(); for (int i = 0; i < roots.length; i++) { ftm.addChildOfSubRoot(roots[i], XNap.tr("Root Directory")); } jt.expandRow(jt.getRowCount() - 1); } } /** * Adds the main download directory and all media type download * directories which are set to the tree. */ private void addDownloadDirs() { // add download dir ftm.addChildOfSubRoot(new File(prefs.getDownloadDir()), XNap.tr("Downloaded Files")); for (int i = 0; i < SearchFilter.media.length; i++) { String type = (String)SearchFilter.media[i]; String dir = prefs.getMediaTypeDownloadDir(type); if (i != SearchFilter.MEDIA_ANYTHING && dir.length() > 0) { ftm.addChildOfSubRoot(new File(dir), XNap.tr("Downloaded Files"), " (" + type + ")"); } } } private void showDirectory(File f) { currentDir = f; ltm.clear(); // check if directory is readable by xnap user if (f.canRead()) { ltm.add(f); ltm.resort(); } resetPanel(); } private void showFiles(File[] files) { ltm.clear(); ltm.add(files); ltm.resort(); resetPanel(); } /** * Called when a new directory has been selected. */ public void valueChanged(TreeSelectionEvent e) { Object target = e.getPath().getLastPathComponent(); if (target instanceof File) { File f = (File)target; showDirectory(f); } } /** * Called when the table's selection changes, we check what kind of * file was selected and call the respective viewer plugin if available. */ public void valueChanged(ListSelectionEvent e) { /* user is about to select some files, don't show anything */ if (jta.getSelectedRowCount() > 1) { resetPanel(); return; } int row = jta.getSelectedRow(); if (row != -1) { currentRow = row; delayTimer.restart(); } } public AbstractAction[] getActions() { return (new AbstractAction[] { playFileAction, enqueueAction, playAction, stopAction, null, refreshAction, null, shareFolderAction, unshareFolderAction }); } private void playFile(final File f) { if (player != null) { (new Thread("PlayFile " + f) { public void run() { boolean success; if (f == null) success = player.play(); else success = player.play(f); if (!success) { if (f == null) setStatus(XNap.tr("Could not start player")); else setStatus(XNap.tr("Could not play file", 0, 1) + f); } else if (f != null) setStatus(XNap.tr("Playing", 0, 1) + f); else setStatus(XNap.tr("Starting player")); } } ).start(); } else { setStatus(XNap.tr("Could not launch player")); } } private void enqueueFiles(final LinkedList files) { if (player != null) { (new Thread("EnqueueFiles") { public void run() { int size = files.size(); while (files.size() > 0) { final File f = (File)files.removeFirst(); if (!player.enqueue(f)) setStatus(XNap.tr("Could not enqueue file") + f); } if (size > 0) { setStatus(XNap.tr("Enqueued", 0, 1) + size + XNap.tr("file(s)", 1, 0)); } } } ).start(); } else { setStatus(XNap.tr("Could not launch audio player, please check your preferences")); } } private void doPlay(int[] rows) { if (rows.length == 0) { playFile(null); } else if (rows.length > 0 && player.canPlay(ltm.get(rows[0]))) { playFile(ltm.get(rows[0])); } if (rows.length > 1) { // if more than one file is selected the following files are // enqueued to be played later on LinkedList filestoEnqueue = new LinkedList(); for (int i = 1; i < rows.length; i++) { if (player.canPlay(ltm.get(rows[i]))) { filestoEnqueue.add(ltm.get(rows[i])); } } enqueueFiles(filestoEnqueue); } } public File getDirectory() { TreePath selected = jt.getSelectionPath(); if (selected != null) { Object o = selected.getLastPathComponent(); if (o instanceof File) { return (File)o; } } return null; } public File[] getFiles(boolean showMessage) { int rowC = jta.getSelectedRowCount(); int rows[] = jta.getSelectedRows(); if (showMessage && rowC == 0) { setStatus(XNap.tr("Please select something first")); return null; } File[] files = new File[rowC]; for (int i = 0; i < rowC; i++) { files[i] = ltm.get(rows[i]); } return files; } public File[] getFiles() { return getFiles(true); } /** * displays given file if possible in lower preview frame */ private void displayFile(File f) { if (!f.canRead()) { jspPreview.setViewportView(jpPreview); jlStatus.setText(XNap.tr("Do not have permission to read file")); return; } ViewerPanel panel = GUIPluginManager.getGUIInstance().getViewer(f); if (panel != null) { jlStatus.setText(panel.getStatus()); displayThread.setPanel(panel); } else { resetPanel(); } } public void resetPanel() { jspPreview.setViewportView(jpPreview); updateStatus(); } public int getHorizontalDividerLocation() { return jspH.getDividerLocation(); } public void setHorizontalDividerLocation(int newValue) { if (newValue == -1) { jspH.setDividerLocation(200); } else { jspH.setDividerLocation(newValue); } } public int getVerticalDividerLocation() { return jspV.getDividerLocation(); } public void setVerticalDividerLocation(int newValue) { if (newValue == -1) { jspV.setDividerLocation(200); } else { jspV.setDividerLocation(newValue); } } /** * Updates the status line below the file table. */ public void updateStatus() { StringBuffer sb = new StringBuffer(); File[] files = getFiles(false); if (files.length == 0) { // nothing is selected sb.append(ltm.getRowCount()); sb.append(" files - "); sb.append(Formatter.formatSize(ltm.getTotalSize())); } else if (files.length == 1) { sb.append("1 file - "); sb.append(Formatter.formatNumber(files[0].length()) + " bytes"); } else { long totalSize = 0; for (int i = 0; i < files.length; i++) { totalSize += files[i].length(); } sb.append("selected - "); sb.append(files.length); sb.append(" files - "); sb.append(Formatter.formatSize(totalSize)); } // FIX: we need some kind of padding sb.insert(0, " "); jlStatus.setText(sb.toString()); } private JMenu createViewerMenu() { JMenu jm = new JMenu(XNap.tr("View with Plugin")); jm.setIcon(XNapFrame.getEmptyIcon()); IPlugin[] plugins = PluginManager.getInstance().getPlugins(); for (int i = 0; i < plugins.length; i++) { if (plugins[i] instanceof IViewerPlugin) { jm.add(new ViewerAction((IViewerPlugin)plugins[i], this)); } } return jm; } /* inner classes */ private class ViewerAction extends AbstractAction implements StateListener { private IViewerPlugin plugin; private FileCollector fc; public ViewerAction(IViewerPlugin plugin, FileCollector fc) { this.plugin = plugin; this.fc = fc; putValue(Action.NAME, plugin.getName()); this.setEnabled(plugin.isEnabled()); GUIPluginManager.getInstance().addStateListener(this); } public void actionPerformed(ActionEvent event) { File[] files = fc.getFiles(); if (files != null && files.length > 0) { ViewerPanel vp = plugin.handle(files[0]); jlStatus.setText(vp.getStatus()); displayThread.setPanel(vp); } } public void stateDisabled(StateEvent e) { if (plugin == e.getSource()) { this.setEnabled(false); } } public void stateEnabled(StateEvent e) { if (plugin == e.getSource()) { this.setEnabled(true); } } } /** * Plays a file selected via a FileOpenDialog */ private class PlayFileAction extends AbstractAction { public PlayFileAction() { putValue(Action.NAME, XNap.tr("Play File")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Open a file to play")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("fileopen.png")); putValue(Action.MNEMONIC_KEY, new Integer('O')); } public void actionPerformed(ActionEvent event) { if (getFileChooser().showOpenDialog(LibraryPanel.this) == JFileChooser.APPROVE_OPTION) { playFile(jfc.getSelectedFile()); } } } /** * Plays selected file */ private class PlayAction extends AbstractAction { public PlayAction() { putValue(Action.NAME, XNap.tr("Play")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Plays selected file(s)")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("1rightarrow.png")); putValue(Action.MNEMONIC_KEY, new Integer('P')); } public void actionPerformed(ActionEvent event) { doPlay(jta.getSelectedRows()); } } /** * Stops playing file */ private class StopAction extends AbstractAction { public StopAction() { putValue(Action.NAME, XNap.tr("Stop")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Stop player")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("player_stop.png")); putValue(Action.MNEMONIC_KEY, new Integer('S')); } public void actionPerformed(ActionEvent event) { if (player != null) player.stop(); } } /** * Refresh file and directory listings */ private class RefreshAction extends AbstractAction { public RefreshAction() { putValue(Action.NAME, XNap.tr("Refresh")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Refresh list of files")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("reload.png")); putValue(Action.MNEMONIC_KEY, new Integer('R')); } public void actionPerformed(ActionEvent event) { if (currentDir != null) { showDirectory(currentDir); } } } /** * Refresh file and directory listings */ private class ReloadTreeAction extends AbstractAction { public ReloadTreeAction() { putValue(Action.NAME, XNap.tr("Reload Tree")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Reload Tree")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("reload.png")); } public void actionPerformed(ActionEvent event) { ftm.reload(); } } private class DeleteAction extends AbstractAction { public DeleteAction() { putValue(Action.NAME, XNap.tr("Delete")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Delete selected file(s)")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("editdelete.png")); putValue(Action.MNEMONIC_KEY, new Integer('D')); } public void actionPerformed(ActionEvent event) { File[] files = getFiles(); if (files == null) return; files = Dialogs.showDeleteFilesDialog(LibraryPanel.this, files); if (files != null) { for (int i = 0; i < files.length; i++) { if (!ltm.delete(files[i])) { setStatus(XNap.tr("Could not delete file", 0, 1) + files[i].getName()); } } } } } /** * Enqueues a selected file. */ private class EnqueueAction extends AbstractAction { public EnqueueAction() { putValue(Action.NAME, XNap.tr("Enqueue")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Enqueue selected file")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("queue.png")); putValue(Action.MNEMONIC_KEY, new Integer('Q')); } public void actionPerformed(ActionEvent event) { { LinkedList filestoEnqueue = new LinkedList(); int rowC = jta.getSelectedRowCount(); int[] rows = jta.getSelectedRows(); // collects selected files for (int i = 0; i < rowC; i++) { if (player.canPlay(ltm.get(rows[i]))) { filestoEnqueue.add(ltm.get(rows[i])); } } enqueueFiles(filestoEnqueue); } } } /** * Enqueues selected Folder */ private class EnqueueFolderAction extends AbstractAction { public EnqueueFolderAction() { putValue(Action.NAME, XNap.tr("Enqueue Folder")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Enqueue selected folder")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("queue.png")); putValue(Action.MNEMONIC_KEY, new Integer('F')); } public void actionPerformed(ActionEvent event) { { /* this is a very simple approach to enqueue the files in the specified folder and relies on the shortcomings of our current implementation: When you select a folder in the tree with the right mousebutton the folder is shown in the table, that's why we can just add all files of the table to enqueueFiles */ LinkedList filestoEnqueue = new LinkedList(); for (int i = 0; i < ltm.getRowCount(); i++) { if (player.canPlay(ltm.get(i))) { filestoEnqueue.add(ltm.get(i)); } } enqueueFiles(filestoEnqueue); } } } /** * Plays selected Folder */ private class PlayFolderAction extends AbstractAction { public PlayFolderAction() { putValue(Action.NAME, XNap.tr("Play Folder")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Plays selected folder")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("1rightarrow.png")); putValue(Action.MNEMONIC_KEY, new Integer('L')); } public void actionPerformed(ActionEvent event) { int[] rows = new int[ltm.getRowCount()]; for (int i = 1; i < rows.length; i++) { rows[i] = i; } doPlay(rows); } } private class RenameAction extends AbstractAction { public RenameAction() { putValue(Action.NAME, XNap.tr("Rename")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Rename selected file")); putValue(Action.MNEMONIC_KEY, new Integer('R')); putValue(Action.SMALL_ICON, XNapFrame.getEmptyIcon()); } public void actionPerformed(ActionEvent event) { int i = jta.getSelectedRow(); if (i != -1) { ltm.setCellEditable(i, ltm.NAME); jta.editCellAt(i, ltm.NAME); DefaultCellEditor dce = (DefaultCellEditor)jta.getCellEditor(); JTextField jtf = (JTextField)dce.getComponent(); // jtf.setSelectionStart(0); // jtf.setSelectionEnd(jtf.getText().length()); jtf.grabFocus(); jtf.setCaretPosition(0); ltm.setCellEditable(-1, -1); } } } /** * Share selected Folder */ private class ShareFolderAction extends AbstractAction { public ShareFolderAction() { putValue(Action.NAME, XNap.tr("Share Folder")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Share selected folder")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("connect_established.png")); putValue(Action.MNEMONIC_KEY, new Integer('H')); } public void actionPerformed(ActionEvent event) { Dialogs.showNotification(LibraryPanel.this, "ShareFolder", XNap.tr("Sharing Folder information"), XNap.tr("Please note: Folders are shared recursively, so all subfolders and their content will be shared on the network too.")); TreePath[] selected = jt.getSelectionPaths(); for (int i = 0; i < selected.length; i++) { final Object o = selected[i].getLastPathComponent(); if (o instanceof FileNode) { prefs.appendToUploadDirs(((FileNode)o).getPath()); prefs.write(); } else { setStatus(XNap.tr("Can not share \"") + o + "\""); } } } } /** * unshare selected Folder */ private class UnshareFolderAction extends AbstractAction { public UnshareFolderAction() { putValue(Action.NAME, XNap.tr("Unshare Folder")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Unshare selected folder")); putValue(Action.SMALL_ICON, XNapFrame.getIcon("connect_no.png")); putValue(Action.MNEMONIC_KEY, new Integer('U')); } public void actionPerformed(ActionEvent event) { TreePath[] selected = jt.getSelectionPaths(); for (int i = 0; i < selected.length; i++) { Object o = selected[i].getLastPathComponent(); if (o instanceof FileNode) { prefs.removeFromUploadDirs(((FileNode)o).getPath()); prefs.write(); } else { setStatus(XNap.tr("Can not unshare \"") + o + "\""); } } } } /** * Performs a search. */ private class QueryAction extends AbstractAction { public QueryAction() { putValue(Action.NAME, XNap.tr("Query")); putValue(Action.SHORT_DESCRIPTION, XNap.tr("Perform search")); putValue(Action.MNEMONIC_KEY, new Integer('Q')); } public void actionPerformed(ActionEvent event) { String s = jcSearch.getText().trim(); if (s.length() > 0) { File[] files = Repository.getInstance().search(s); if (files != null && files.length > 0) { jt.clearSelection(); showFiles(files); // having this as well is more consistent and even nicer... Object[] arguments = { new Integer(files.length) }; setStatus(MessageFormat.format (XNap.tr("Found {0} files"), arguments)); } else { setStatus(s + XNap.tr("not found in library", 1, 0)); } jcSearch.addDistinctItemAtTop(s); } else { setStatus(XNap.tr("What are you trying to search for?")); } } } protected class SelectionListener implements ActionListener { public void actionPerformed(ActionEvent event) { int row = jta.getSelectedRow(); if (row == -1 || jta.getSelectedRowCount() != 1) return; if (row == currentRow) { displayFile(ltm.get(row)); } } } private class DisplayThread extends Thread { private ViewerPanel panel; public DisplayThread() { super("LibraryPanelLoader"); start(); } public void setPanel(ViewerPanel newValue) { panel = newValue; this.interrupt(); synchronized(this) { this.notify(); } // seems to have died, start again if (!isAlive()) { start(); } } public void run() { while (true) { while (panel == null) { synchronized (this) { try { this.wait(); } catch (InterruptedException e) { } } } panel.display(); Runnable r = new Runnable() { private ViewerPanel p = panel; public void run() { jspPreview.getHorizontalScrollBar().setValue(0); jspPreview.getVerticalScrollBar().setValue(0); jspPreview.setViewportView(p); jlStatus.setText(p.getStatus()); } }; try { SwingUtilities.invokeAndWait(r); } catch (Exception e) { } panel = null; } } } }

The table below shows all metrics for LibraryPanel.java.

MetricValueDescription