package gui; import javax.swing.BoxLayout; import javax.swing.JEditorPane; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JSplitPane; import javax.swing.ToolTipManager; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import javax.swing.border.TitledBorder; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeWillExpandListener; import communication.Connection; import communication.Download; import util.GuiOperations; import util.PrefObj; import util.SortTreeModel; import util.TreeStringComparatorDate; import util.TreeStringComparatorName; import util.UserPreferences; import api.Item; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Set; import java.util.prefs.Preferences; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; public class ItemPanel extends JPanel implements TreeSelectionListener { private static final long serialVersionUID = -6845029704959817538L; private JTree tree; private JSplitPane splitPane; private JPanel rightPanel; private JEditorPane infoPane; private JTreeDownload downloadTree; private DefaultMutableTreeNode waitNode; private DefaultMutableTreeNode rootNode; private DefaultMutableTreeNode loadNode; private String waitNodeTxt = "Connect your account"; private String rootNodeTxt = "Your files"; private String loadNodeTxt = "Loading..."; private DefaultTreeModel waitTreeModel; private SortTreeModel treeModel; private Preferences prefs = null; private Connection conn; private MainScreen ms; private Boolean treeLoaded = false; private Boolean stopOperation = false; private Boolean sortedByName = true; private Boolean playWithLineStyle = false; private String lineStyle = "Horizontal"; protected JPopupMenu itemMenu; protected JMenuItem autoDownloadEveryMenuItem; protected JMenuItem addToAutomaticDownloadMenuItem; protected JMenuItem pauseOrResumeDownloadMenuItem; protected JMenuItem cancelDownloadMenuItem; protected JMenuItem removeDownloadMenuItem; protected JMenuItem pauseAllMenuItem; protected JMenuItem resumeAllMenuItem; protected JMenuItem cancelAllMenuItem; protected JMenuItem cleanDownloadedMenuItem; protected JMenuItem sortByNameMenuItem; protected JMenuItem sortByDateMenuItem; protected JMenuItem expandMenuItem; protected JMenuItem collapseMenuItem; public static List<String> prefsAutoDLFolder; @SuppressWarnings( "unchecked" ) public ItemPanel( MainScreen mainScreen ) throws Exception { super( new GridLayout( 1, 0 ) ); ms = mainScreen; itemMenu = new JPopupMenu(); autoDownloadEveryMenuItem = new JMenuItem( "Automatically download everything" ); autoDownloadEveryMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { ListIterator<String> prefIterator = prefsAutoDLFolder.listIterator(); while ( prefIterator.hasNext() ) { String id = prefIterator.next(); if ( id == null ) continue; DefaultMutableTreeNode node = getItemInTree( id ); if ( node != null && node instanceof FolderNode ) ( (FolderNode) node ).setAutoDLVar( false ); } try { prefsAutoDLFolder = new ArrayList<String>( 1 ); PrefObj.putObject( prefs, "AUTODL_FOLDERS", prefsAutoDLFolder ); } catch ( Exception e1 ) { e1.printStackTrace(); } tree.repaint(); } } ); addToAutomaticDownloadMenuItem = new JMenuItem( "Add to automatic download" ); addToAutomaticDownloadMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { Object node = tree.getLastSelectedPathComponent(); if ( node instanceof FolderNode ) ( (FolderNode) node ).setAutoDL( !( (FolderNode) node ).isAutoDL() ); tree.repaint(); } } ); pauseOrResumeDownloadMenuItem = new JMenuItem( "Pause/resume selected" ); pauseOrResumeDownloadMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { Object node = tree.getLastSelectedPathComponent(); if ( node instanceof LeafNode ) { GuiOperations.pauseOrResumeSelectedItem( ms, ( (LeafNode) node ).getItem() ); } } } ); cancelDownloadMenuItem = new JMenuItem( "Cancel selected" ); cancelDownloadMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { Object node = tree.getLastSelectedPathComponent(); if ( node instanceof LeafNode ) { GuiOperations.cancelSelectedItem( ms, ( (LeafNode) node ).getItem() ); } } } ); removeDownloadMenuItem = new JMenuItem( "Remove selected" ); removeDownloadMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { GuiOperations.removeSelectedItem( getItemPanel() ); } } ); pauseAllMenuItem = new JMenuItem( "Pause all" ); pauseAllMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { GuiOperations.pauseAll( ms, true ); } } ); resumeAllMenuItem = new JMenuItem( "Resume all" ); resumeAllMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { GuiOperations.pauseAll( ms, false ); } } ); cancelAllMenuItem = new JMenuItem( "Cancel all" ); cancelAllMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { GuiOperations.cancelAll( getItemPanel() ); } } ); cleanDownloadedMenuItem = new JMenuItem( "Clean downloaded/canceled files" ); cleanDownloadedMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { GuiOperations.cleanDownloadedItems( getItemPanel() ); } } ); sortByNameMenuItem = new JMenuItem( "Sort by name" ); sortByNameMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { GuiOperations.changeSortOrder( ms, "name" ); } } ); sortByDateMenuItem = new JMenuItem( "Sort by date" ); sortByDateMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { GuiOperations.changeSortOrder( ms, "date" ); } } ); expandMenuItem = new JMenuItem( "Expand everything" ); expandMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { expandEverything(); } } ); collapseMenuItem = new JMenuItem( "Collapse everything" ); collapseMenuItem.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { collapseEverything(); } } ); itemMenu.add( autoDownloadEveryMenuItem ); itemMenu.add( addToAutomaticDownloadMenuItem ); itemMenu.addSeparator(); itemMenu.add( pauseOrResumeDownloadMenuItem ); itemMenu.add( cancelDownloadMenuItem ); itemMenu.add( removeDownloadMenuItem ); itemMenu.addSeparator(); itemMenu.add( pauseAllMenuItem ); itemMenu.add( resumeAllMenuItem ); itemMenu.add( cancelAllMenuItem ); itemMenu.addSeparator(); itemMenu.add( sortByNameMenuItem ); itemMenu.add( sortByDateMenuItem ); itemMenu.addSeparator(); itemMenu.add( expandMenuItem ); itemMenu.add( collapseMenuItem ); itemMenu.addSeparator(); itemMenu.add( cleanDownloadedMenuItem ); // Create a tree waitNode = new DefaultMutableTreeNode( waitNodeTxt ); rootNode = new DefaultMutableTreeNode( rootNodeTxt ); loadNode = new DefaultMutableTreeNode( loadNodeTxt ); waitTreeModel = new DefaultTreeModel( waitNode ); tree = new JTree( waitTreeModel ); tree.setEditable( false ); tree.getSelectionModel().setSelectionMode( TreeSelectionModel.SINGLE_TREE_SELECTION ); // Enable tool tips ToolTipManager.sharedInstance().registerComponent( tree ); tree.setRowHeight( 0 ); tree.setCellRenderer( new NodeRenderer() ); tree.setUI( new AnimatedTreeUI() ); // Listen for when the selection changes. tree.addTreeSelectionListener( this ); MouseListener ml = new MouseAdapter() { @Override public void mouseReleased( MouseEvent e ) { int selRow = tree.getClosestRowForLocation( e.getX(), e.getY() ); if ( selRow > 0 ) { if ( e.getClickCount() == 1 ) { pauseOrResumeDownloadMenuItem.setEnabled( true ); cancelDownloadMenuItem.setEnabled( true ); removeDownloadMenuItem.setEnabled( true ); } else if ( e.getClickCount() == 2 ) { // System.out.println( "2 clic " + e.getButton() + " : " // + selRow + " " // + selPath.toString() ); } } else { pauseOrResumeDownloadMenuItem.setEnabled( false ); cancelDownloadMenuItem.setEnabled( false ); removeDownloadMenuItem.setEnabled( false ); } TreePath selTmp = tree.getPathForRow( selRow ); tree.setSelectionPath( selTmp ); Object obj = selTmp.getLastPathComponent(); if ( obj instanceof FolderNode ) { if ( ( (FolderNode) obj ).isAutoDL() ) addToAutomaticDownloadMenuItem.setText( "Remove from automatic download" ); else addToAutomaticDownloadMenuItem.setText( "Add to automatic download" ); } addToAutomaticDownloadMenuItem.setVisible( obj instanceof FolderNode ); // Hide first separator if necessary for ( int i = 0; i < itemMenu.getComponentCount() - 1; i++ ) { if ( itemMenu.getComponent( i ) instanceof JSeparator ) { ( (JSeparator) itemMenu.getComponent( i ) ).setVisible( obj instanceof FolderNode ); break; } } if ( e.getButton() == MouseEvent.BUTTON3 ) itemMenu.show( e.getComponent(), e.getX(), e.getY() ); } }; tree.addMouseListener( ml ); tree.addTreeWillExpandListener( new TreeWillExpandListener() { @Override public void treeWillExpand( TreeExpansionEvent event ) throws ExpandVetoException { } @Override public void treeWillCollapse( TreeExpansionEvent event ) throws ExpandVetoException { TreePath path = event.getPath(); DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); if ( node.equals( (DefaultMutableTreeNode) treeModel.getRoot() ) ) throw new ExpandVetoException( event ); } } ); if ( playWithLineStyle ) { System.out.println( "line style = " + lineStyle ); tree.putClientProperty( "JTree.lineStyle", lineStyle ); } // Create the scroll pane and add the tree to it. JScrollPane treeView = new JScrollPane( tree ); treeView.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentListener() { @Override public void adjustmentValueChanged( AdjustmentEvent e ) { tree.repaint(); } } ); rightPanel = new JPanel(); rightPanel.setLayout( new BoxLayout( rightPanel, BoxLayout.PAGE_AXIS ) ); // Create the HTML viewing pane infoPane = new JEditorPane(); infoPane.setEditable( false ); JScrollPane infoView = new JScrollPane( infoPane ); infoView.setPreferredSize( new Dimension( 0, 0 ) ); downloadTree = new JTreeDownload( ms ); JScrollPane downView = new JScrollPane( downloadTree ); downView.getHorizontalScrollBar().addAdjustmentListener( new AdjustmentListener() { @Override public void adjustmentValueChanged( AdjustmentEvent e ) { downloadTree.repaint(); } } ); downView.setPreferredSize( new Dimension( 0, 0 ) ); downView.setBorder( new TitledBorder( "Downloads" ) ); rightPanel.add( infoView ); rightPanel.add( downView ); // Add the scroll panes to a split pane splitPane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT ); splitPane.setLeftComponent( treeView ); splitPane.setRightComponent( rightPanel ); splitPane.setDividerLocation( UserPreferences.PREFS.getInt( "FRAME_DIV_POS", Math.round( ms.getWidth() / 2 ) ) ); splitPane.setPreferredSize( new Dimension( 500, 300 ) ); // Add the split pane to this panel add( splitPane ); if ( prefs == null && UserPreferences.PREFS != null ) prefs = UserPreferences.PREFS; try { prefsAutoDLFolder = (List<String>) PrefObj.getObject( prefs, "AUTODL_FOLDERS" ); } catch ( Exception e ) { prefsAutoDLFolder = new ArrayList<String>( 1 ); PrefObj.putObject( prefs, "AUTODL_FOLDERS", prefsAutoDLFolder ); } } /** Required by TreeSelectionListener interface. */ public void valueChanged( TreeSelectionEvent e ) { updateInfo(); } private void updateInfo() { DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if ( node == null ) return; Object obj = node.getUserObject(); if ( obj instanceof Item ) { if ( node instanceof LeafNode ) infoPane.setText( ( (LeafNode) node ).getInfos() ); else if ( node instanceof FolderNode ) infoPane.setText( ( (FolderNode) node ).getInfos() ); } } public void initTree() { switch ( UserPreferences.PREF_BEHAVIOR_SORT_BY ) { case UserPreferences.OPTION_SORT_BY_DATE: treeModel = new SortTreeModel( rootNode, new TreeStringComparatorDate() ); sortedByName = false; sortByNameMenuItem.setEnabled( true ); sortByDateMenuItem.setEnabled( false ); break; default: treeModel = new SortTreeModel( rootNode, new TreeStringComparatorName() ); sortedByName = true; sortByNameMenuItem.setEnabled( false ); sortByDateMenuItem.setEnabled( true ); break; } treeModel.addTreeModelListener( new MyTreeModelListener() ); waitTreeModel.setRoot( waitNode ); tree.setModel( waitTreeModel ); tree.setEditable( false ); treeLoaded = false; infoPane.setText( "" ); } public void populateTree( Connection connection ) { this.stopOperation = false; conn = connection; if ( !treeLoaded ) waitTreeModel.setRoot( loadNode ); try { List<Item> rootItems = conn.getRootItems(); fillTree( rootItems ); reorderTree( rootItems ); if ( !treeLoaded ) { tree.setModel( treeModel ); tree.expandRow( 0 ); } // The list of all the items from the API V2 doesn't return the // shared items... if ( UserPreferences.PREF_LOAD_SHARED ) fillSharedTree(); else removeSharedTree(); treeLoaded = true; } catch ( Exception e ) { System.out.println( e.toString() ); } } private void fillTree( List<Item> rootItems ) { ListIterator<Item> i = rootItems.listIterator(); DefaultMutableTreeNode itemNode = null; while ( i.hasNext() ) { Item currentItem = i.next(); if ( currentItem.isDir() ) itemNode = new FolderNode( currentItem ); else itemNode = new LeafNode( currentItem ); // If it doesn't exist DefaultMutableTreeNode searchNode = null; if ( ( searchNode = getItemInTree( currentItem ) ) == null ) { // If the item is shared and we don't want to add shared items if ( ( isParentShared( currentItem, rootItems ) || currentItem.isShared() ) && !UserPreferences.PREF_LOAD_SHARED ) { currentItem.setShared( true ); continue; } // Check if the item is a child for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).breadthFirstEnumeration(); e .hasMoreElements() && searchNode == null; ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object nodeInfo = curNode.getUserObject(); if ( nodeInfo instanceof Item ) { Item itTmp = (Item) nodeInfo; // If it's a child if ( itTmp.getId().equals( currentItem.getParentId() ) ) { if ( itTmp.isShared() ) currentItem.setShared( true ); searchNode = curNode; treeModel.insertNodeInto( itemNode, searchNode ); } } } // If it's not a child or we didn't find the parent in the // nodes, we put it in the root if ( searchNode == null ) { treeModel.insertNodeInto( itemNode, (DefaultMutableTreeNode) treeModel.getRoot() ); } // System.out.println( "Add: " + currentItem.getName() + " id:" // + currentItem.getId() ); } } } private void reorderTree( List<Item> rootItems ) { // We must stock the nodes in a map. If we change the tree, the // enumeration could be messed up HashMap<DefaultMutableTreeNode, DefaultMutableTreeNode> nodeMap = new HashMap<DefaultMutableTreeNode, DefaultMutableTreeNode>(); // Reorder the nodes, the lone children should be on the root, // so we just check the root children for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).children(); e.hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object nodeInfo = curNode.getUserObject(); if ( nodeInfo instanceof Item ) { Item itTmp = (Item) nodeInfo; // System.out.println(itTmp.getName()); // If the current root-child node should not be on the root // we look for its parent node if ( !itTmp.getParentId().equals( "0" ) ) { DefaultMutableTreeNode searchNode = null; for ( @SuppressWarnings( "rawtypes" ) Enumeration ePar = ( (DefaultMutableTreeNode) treeModel.getRoot() ) .breadthFirstEnumeration(); ePar.hasMoreElements() && searchNode == null; ) { DefaultMutableTreeNode curParNode = (DefaultMutableTreeNode) ePar.nextElement(); Object nodeParInfo = curParNode.getUserObject(); if ( nodeParInfo instanceof Item ) { Item itParTmp = (Item) nodeParInfo; if ( itParTmp.getId().equals( itTmp.getParentId() ) ) { searchNode = curParNode; nodeMap.put( curNode, searchNode ); break; } } } } } } // Reorder Set<DefaultMutableTreeNode> keys = nodeMap.keySet(); Iterator<DefaultMutableTreeNode> it = keys.iterator(); while ( it.hasNext() ) { DefaultMutableTreeNode key = it.next(); if ( nodeMap.get( key ) != null ) { // Set shared if it belongs to a shared directory if ( ( (Item) nodeMap.get( key ).getUserObject() ).isShared() ) ( (Item) key.getUserObject() ).setShared( true ); treeModel.removeNodeFromParent( key ); treeModel.insertNodeInto( key, nodeMap.get( key ) ); } } // If the tree is loaded, we should clean items deleted on the server if ( treeLoaded ) { // Same as before, we stock nodes to delete in a list List<DefaultMutableTreeNode> delList = new ArrayList<DefaultMutableTreeNode>( 1 ); for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).depthFirstEnumeration(); e .hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object curNodeItem = curNode.getUserObject(); if ( curNodeItem instanceof Item ) { Item curItem = (Item) curNodeItem; // We don't check shared Items, which are loaded in // fillSharedTree separately if ( curItem.isShared() ) continue; else if ( !isItemInList( curItem, rootItems ) ) { // System.out.println("Del : " + curItem.getName()); delList.add( curNode ); } } } ListIterator<DefaultMutableTreeNode> itDel = delList.listIterator(); while ( itDel.hasNext() ) { DefaultMutableTreeNode delNode = itDel.next(); treeModel.removeNodeFromParent( delNode ); } } } private void fillSharedTree() { for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).children(); e.hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object nodeInfo = curNode.getUserObject(); if ( nodeInfo instanceof Item ) { Item itTmp = (Item) nodeInfo; if ( itTmp.getName().contains( "shared" ) ) { addChildren( curNode ); break; } } } } private void removeSharedTree() { for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).children(); e.hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object nodeInfo = curNode.getUserObject(); if ( nodeInfo instanceof Item ) { Item itTmp = (Item) nodeInfo; if ( itTmp.getName().contains( "shared" ) ) { treeModel.removeNodeFromParent( curNode ); break; } } } } private void addChildren( DefaultMutableTreeNode node ) { if ( stopOperation ) return; List<Item> li = null; try { li = ( (Item) node.getUserObject() ).listChildren(); } catch ( Exception e ) { li = null; System.out.println( e.toString() ); } if ( li != null ) { // First, we should clean deleted items List<DefaultMutableTreeNode> delList = new ArrayList<DefaultMutableTreeNode>( 1 ); for ( @SuppressWarnings( "rawtypes" ) Enumeration e = node.children(); e.hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object curNodeItem = curNode.getUserObject(); if ( curNodeItem instanceof Item ) { Item curItem = (Item) curNodeItem; if ( !isItemInList( curItem, li ) ) delList.add( curNode ); } } ListIterator<DefaultMutableTreeNode> itDel = delList.listIterator(); while ( itDel.hasNext() ) { DefaultMutableTreeNode delNode = itDel.next(); treeModel.removeNodeFromParent( delNode ); } ListIterator<Item> i = li.listIterator(); DefaultMutableTreeNode childNode = null; while ( i.hasNext() ) { Item childItem = i.next(); // They're all shared here, so we flag them shared childItem.setShared( true ); if ( ( childNode = getItemInTree( childItem ) ) == null ) { if ( childItem.isDir() ) childNode = new FolderNode( childItem ); else childNode = new LeafNode( childItem ); treeModel.insertNodeInto( childNode, node ); // System.out.println( "Add: " + childItem.getName() + // " id:" + childItem.getId() ); // System.out.println( "Parent: " + // ((Item)node.getUserObject()).getName() + " id:" + // ((Item)node.getUserObject()).getId() ); if ( childItem.isDir() ) addChildren( childNode ); } else if ( childItem.isDir() ) { addChildren( childNode ); } } } else { List<DefaultMutableTreeNode> delList = new ArrayList<DefaultMutableTreeNode>( 1 ); for ( @SuppressWarnings( "rawtypes" ) Enumeration e = node.children(); e.hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); delList.add( curNode ); } ListIterator<DefaultMutableTreeNode> itDel = delList.listIterator(); while ( itDel.hasNext() ) { DefaultMutableTreeNode delNode = itDel.next(); treeModel.removeNodeFromParent( delNode ); } } } private Boolean isItemInList( Item item, List<Item> list ) { ListIterator<Item> itList = list.listIterator(); while ( itList.hasNext() ) { Item curItem = itList.next(); if ( curItem.getId().equals( item.getId() ) ) return true; } return false; } private Boolean isParentShared( Item item, List<Item> list ) { ListIterator<Item> itList = list.listIterator(); while ( itList.hasNext() ) { Item curItem = itList.next(); if ( curItem.getId().equals( item.getParentId() ) && curItem.isShared() ) return true; } return false; } public DefaultMutableTreeNode getItemInTree( Item item ) { for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).breadthFirstEnumeration(); e .hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object nodeInfo = curNode.getUserObject(); if ( nodeInfo instanceof Item ) { Item itTmp = (Item) nodeInfo; if ( itTmp.getId().equals( item.getId() ) ) { return curNode; } } } return null; } public DefaultMutableTreeNode getItemInTree( String id ) { for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).breadthFirstEnumeration(); e .hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object nodeInfo = curNode.getUserObject(); if ( nodeInfo instanceof Item ) { Item itTmp = (Item) nodeInfo; if ( itTmp.getId().equals( id ) ) { return curNode; } } } return null; } private DefaultMutableTreeNode getItemInTree( Item item, SortTreeModel treeMod ) { for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeMod.getRoot() ).breadthFirstEnumeration(); e .hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object nodeInfo = curNode.getUserObject(); if ( nodeInfo instanceof Item ) { Item itTmp = (Item) nodeInfo; if ( itTmp.getId().equals( item.getId() ) ) { return curNode; } } } return null; } public void stopOp() { this.stopOperation = true; } public ItemPanel getItemPanel() { return this; } public List<Item> getItems() { List<Item> list = new ArrayList<Item>( 1 ); for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).depthFirstEnumeration(); e .hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); if ( curNode instanceof LeafNode ) { if ( UserPreferences.PREF_BEHAVIOR_DOWNLOAD_EVERYTHING ) list.add( ( (LeafNode) curNode ).getItem() ); else { TreeNode[] nodePath = curNode.getPath(); for ( int i = 0; i < nodePath.length; i++ ) { if ( nodePath[ i ] instanceof FolderNode && ( (FolderNode) nodePath[ i ] ).isAutoDL() ) { list.add( ( (LeafNode) curNode ).getItem() ); break; } } } } } if ( list.isEmpty() ) return null; else return list; } public List<LeafNode> getLeaves() { List<LeafNode> list = new ArrayList<LeafNode>( 1 ); for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).depthFirstEnumeration(); e .hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); if ( curNode instanceof LeafNode ) { list.add( (LeafNode) curNode ); } } if ( list.isEmpty() ) return null; else return list; } public void sortByName() { sortBy( "name" ); } public void sortByDate() { sortBy( "date" ); } public void sortBy( String order ) { DefaultMutableTreeNode tmpNode = null; DefaultMutableTreeNode curNodeCopy = null; SortTreeModel treeModelTmp = null; DefaultMutableTreeNode rootTmp = new DefaultMutableTreeNode( rootNodeTxt ); if ( order.equals( "name" ) ) { treeModelTmp = new SortTreeModel( rootTmp, new TreeStringComparatorName() ); sortedByName = true; } else { treeModelTmp = new SortTreeModel( rootTmp, new TreeStringComparatorDate() ); sortedByName = false; } sortByNameMenuItem.setEnabled( !sortedByName ); sortByDateMenuItem.setEnabled( sortedByName ); for ( @SuppressWarnings( "rawtypes" ) Enumeration e = ( (DefaultMutableTreeNode) treeModel.getRoot() ).breadthFirstEnumeration(); e .hasMoreElements(); ) { DefaultMutableTreeNode curNode = (DefaultMutableTreeNode) e.nextElement(); Object obj = curNode.getUserObject(); if ( obj instanceof Item ) { Item currentItem = (Item) obj; if ( currentItem.isDir() ) curNodeCopy = new FolderNode( currentItem ); else curNodeCopy = new LeafNode( currentItem, ( (LeafNode) curNode ).getDownPerc(), ( (LeafNode) curNode ).getStatus() ); Object objPar = ( (DefaultMutableTreeNode) curNode.getParent() ).getUserObject(); if ( objPar instanceof Item ) { if ( ( tmpNode = getItemInTree( (Item) objPar, treeModelTmp ) ) != null ) { treeModelTmp.insertNodeInto( curNodeCopy, tmpNode ); } } else { treeModelTmp.insertNodeInto( curNodeCopy, rootTmp ); } } } rootNode = rootTmp; treeModel = treeModelTmp; tree.setModel( treeModel ); } public Boolean isSortedByName() { return sortedByName; } public Boolean isSortedByDate() { return !sortedByName; } public void setDownPerc( Item item, float down ) { LeafNode leaf = (LeafNode) getItemInTree( item ); leaf = (LeafNode) getItemInTree( item ); leaf.setDownPerc( down ); tree.repaint(); } public void focus( DefaultMutableTreeNode node ) { if ( node == null ) return; if ( node.isLeaf() && node != (DefaultMutableTreeNode) treeModel.getRoot() ) { TreePath pathNode = new TreePath( node.getPath() ); node = (DefaultMutableTreeNode) node.getParent(); TreePath path = new TreePath( node.getPath() ); tree.expandPath( path ); tree.setSelectionPath( pathNode ); tree.scrollPathToVisible( pathNode ); } } public int getDivPos() { return splitPane.getDividerLocation(); } public synchronized void updateDownload( Download dl ) { downloadTree.updateDownload( dl ); } public JTree getTree() { return tree; } public void checkFiles() { List<LeafNode> leaves = getLeaves(); if ( leaves != null ) { ListIterator<LeafNode> it = leaves.listIterator(); while ( it.hasNext() ) { LeafNode node = it.next(); // Check finished files String filePath = UserPreferences.PREF_DOWNLOAD_TARGET; String dirs = node.getPathDir().getDirs(); if ( dirs != null ) filePath += File.separator + dirs; filePath += File.separator + node.getItem().getName(); File f = new File( filePath ); if ( f.exists() && f.length() == node.getItem().getSize() ) { node.setDownPerc( 1.0f ); node.setStatus( "Completed" ); continue; } // Check part files int i = 0; long dlSize = 0L; while ( true ) { File fPart = new File( filePath + ".pio" + i ); if ( !fPart.exists() ) break; else dlSize += fPart.length(); i++; } if ( i > 0 ) { node.setDownPerc( (float) dlSize / (float) node.getItem().getSize() ); node.setStatus( GuiOperations.getReadableSize( dlSize ) + " / " + GuiOperations.getReadableSize( node.getItem().getSize() ) ); } } } repaint(); } public void expandEverything() { for ( int i = 0; i < tree.getRowCount(); i++ ) { tree.expandRow( i ); } } public void collapseEverything() { for ( int i = tree.getRowCount() - 1; i >= 0; i-- ) { tree.collapseRow( i ); } } @Override public synchronized void repaint() { if ( tree != null ) tree.repaint(); if ( downloadTree != null ) downloadTree.repaint(); if ( infoPane != null ) { updateInfo(); infoPane.repaint(); } super.repaint(); } }