/* * Created on 9 Jul 2007 * Created by Allan Crooks * Copyright (C) 2007 Aelitis, All Rights Reserved. * * 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. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. */ package org.gudy.azureus2.ui.swt; import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.URLEncoder; import java.util.*; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.*; import org.gudy.azureus2.core3.category.Category; import org.gudy.azureus2.core3.category.CategoryManager; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.disk.DiskManagerFileInfo; import org.gudy.azureus2.core3.download.DownloadManager; import org.gudy.azureus2.core3.download.DownloadManagerState; import org.gudy.azureus2.core3.internat.MessageText; import org.gudy.azureus2.core3.logging.LogAlert; import org.gudy.azureus2.core3.logging.Logger; import org.gudy.azureus2.core3.peer.PEPeerManager; import org.gudy.azureus2.core3.peer.PEPeerSource; import org.gudy.azureus2.core3.torrent.TOTorrent; import org.gudy.azureus2.core3.torrent.TOTorrentFactory; import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer; import org.gudy.azureus2.core3.tracker.util.TRTrackerUtils; import org.gudy.azureus2.core3.util.*; import org.gudy.azureus2.plugins.PluginInterface; import org.gudy.azureus2.plugins.download.Download; import org.gudy.azureus2.plugins.ui.UIInputReceiver; import org.gudy.azureus2.plugins.ui.UIInputReceiverListener; import org.gudy.azureus2.plugins.ui.UIPluginView; import org.gudy.azureus2.plugins.ui.tables.TableColumn; import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils; import org.gudy.azureus2.ui.swt.exporttorrent.wizard.ExportTorrentWizard; import org.gudy.azureus2.ui.swt.mainwindow.ClipboardCopy; import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener; import org.gudy.azureus2.ui.swt.maketorrent.*; import org.gudy.azureus2.ui.swt.minibar.DownloadBar; import org.gudy.azureus2.ui.swt.shells.AdvRenameWindow; import org.gudy.azureus2.ui.swt.shells.MessageBoxShell; import org.gudy.azureus2.ui.swt.views.FilesViewMenuUtil; import org.gudy.azureus2.ui.swt.views.ViewUtils; import org.gudy.azureus2.ui.swt.views.tableitems.mytorrents.RankItem; import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils; import com.aelitis.azureus.core.AzureusCore; import com.aelitis.azureus.core.AzureusCoreFactory; import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin; import com.aelitis.azureus.ui.UIFunctions; import com.aelitis.azureus.ui.UIFunctionsManager; import com.aelitis.azureus.ui.UserPrompterResultListener; import com.aelitis.azureus.ui.common.table.TableColumnCore; import com.aelitis.azureus.ui.common.table.TableView; import com.aelitis.azureus.ui.selectedcontent.*; import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT; import com.aelitis.azureus.ui.swt.imageloader.ImageLoader; import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT; import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT; /** * @author Allan Crooks * */ public class TorrentUtil { // selected_dl_types -> 0 (determine that automatically), +1 (downloading), +2 (seeding), +3 (mixed - not used by anything yet) public static void fillTorrentMenu(final Menu menu, final DownloadManager[] dms, final AzureusCore azureus_core, final Composite composite, boolean include_show_details, int selected_dl_types, final TableView tv) { final boolean isSeedingView; switch (selected_dl_types) { case 1: isSeedingView = false; break; case 2: isSeedingView = true; break; case 0: { if (dms.length == 1) { isSeedingView = dms[0].isDownloadComplete(false); break; } } default: // I was going to raise an error, but let's not be too hasty. :) isSeedingView = false; } boolean hasSelection = (dms.length > 0); boolean isTrackerOn = TRTrackerUtils.isTrackerEnabled(); int userMode = COConfigurationManager.getIntParameter("User Mode"); // Enable/Disable Logic boolean bChangeDir = hasSelection; boolean start, stop, changeUrl, barsOpened, forceStart; boolean forceStartEnabled, recheck, manualUpdate, fileMove, fileRescan; changeUrl = barsOpened = manualUpdate = fileMove = fileRescan = true; forceStart = forceStartEnabled = recheck = start = stop = false; boolean canSetSuperSeed = false; boolean superSeedAllYes = true; boolean superSeedAllNo = true; boolean upSpeedDisabled = false; long totalUpSpeed = 0; boolean upSpeedUnlimited = false; long upSpeedSetMax = 0; boolean downSpeedDisabled = false; long totalDownSpeed = 0; boolean downSpeedUnlimited = false; long downSpeedSetMax = 0; boolean allScanSelected = true; boolean allScanNotSelected = true; boolean allStopped = true; if (hasSelection) { for (int i = 0; i < dms.length; i++) { DownloadManager dm = (DownloadManager) dms[i]; try { int maxul = dm.getStats().getUploadRateLimitBytesPerSecond(); if (maxul == 0) { upSpeedUnlimited = true; } else { if (maxul > upSpeedSetMax) { upSpeedSetMax = maxul; } } if (maxul == -1) { maxul = 0; upSpeedDisabled = true; } totalUpSpeed += maxul; int maxdl = dm.getStats().getDownloadRateLimitBytesPerSecond(); if (maxdl == 0) { downSpeedUnlimited = true; } else { if (maxdl > downSpeedSetMax) { downSpeedSetMax = maxdl; } } if (maxdl == -1) { maxdl = 0; downSpeedDisabled = true; } totalDownSpeed += maxdl; } catch (Exception ex) { Debug.printStackTrace(ex); } if (barsOpened && !DownloadBar.getManager().isOpen(dm)) { barsOpened = false; } stop = stop || ManagerUtils.isStopable(dm); start = start || ManagerUtils.isStartable(dm); recheck = recheck || dm.canForceRecheck(); forceStartEnabled = forceStartEnabled || ManagerUtils.isForceStartable(dm); forceStart = forceStart || dm.isForceStart(); boolean stopped = ManagerUtils.isStopped(dm); allStopped &= stopped; fileMove = fileMove && dm.canMoveDataFiles(); if (userMode < 2) { TRTrackerAnnouncer trackerClient = dm.getTrackerClient(); if (trackerClient != null) { boolean update_state = ((SystemTime.getCurrentTime() / 1000 - trackerClient.getLastUpdateTime() >= TRTrackerAnnouncer.REFRESH_MINIMUM_SECS)); manualUpdate = manualUpdate & update_state; } } int state = dm.getState(); bChangeDir &= (state == DownloadManager.STATE_ERROR || state == DownloadManager.STATE_STOPPED || state == DownloadManager.STATE_QUEUED);; /** * Only perform a test on disk if: * 1) We are currently set to allow the "Change Data Directory" option, and * 2) We've only got one item selected - otherwise, we may potentially end up checking massive * amounts of files across multiple torrents before we generate a menu. */ if (bChangeDir && dms.length == 1) { bChangeDir = dm.isDataAlreadyAllocated() && !dm.filesExist( true ); } boolean scan = dm.getDownloadState().getFlag(DownloadManagerState.FLAG_SCAN_INCOMPLETE_PIECES); // include DND files in incomplete stat, since a recheck may // find those files have been completed boolean incomplete = !dm.isDownloadComplete(true); allScanSelected = incomplete && allScanSelected && scan; allScanNotSelected = incomplete && allScanNotSelected && !scan; PEPeerManager pm = dm.getPeerManager(); if (pm != null) { if (pm.canToggleSuperSeedMode()) { canSetSuperSeed = true; } if (pm.isSuperSeedMode()) { superSeedAllYes = false; } else { superSeedAllNo = false; } } else { superSeedAllYes = false; superSeedAllNo = false; } } fileRescan = allScanSelected || allScanNotSelected; } else { // empty right-click barsOpened = false; forceStart = false; forceStartEnabled = false; start = false; stop = false; fileMove = false; fileRescan = false; upSpeedDisabled = true; downSpeedDisabled = true; changeUrl = false; recheck = false; manualUpdate = false; } // === Root Menu === if (bChangeDir) { MenuItem menuItemChangeDir = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(menuItemChangeDir, "MyTorrentsView.menu.changeDirectory"); menuItemChangeDir.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { changeDirSelectedTorrents(dms, composite.getShell()); } }); } // Open Details if (include_show_details) { final MenuItem itemDetails = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemDetails, "MyTorrentsView.menu.showdetails"); menu.setDefaultItem(itemDetails); Utils.setMenuItemImage(itemDetails, "details"); itemDetails.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions(); if (uiFunctions != null) { uiFunctions.openView(UIFunctions.VIEW_DM_DETAILS, dm); } } }); itemDetails.setEnabled(hasSelection); } // Open Bar final MenuItem itemBar = new MenuItem(menu, SWT.CHECK); Messages.setLanguageText(itemBar, "MyTorrentsView.menu.showdownloadbar"); Utils.setMenuItemImage(itemBar, "downloadBar"); itemBar.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { if (DownloadBar.getManager().isOpen(dm)) { DownloadBar.close(dm); } else { DownloadBar.open(dm, menu.getShell()); } } // run }); itemBar.setEnabled(hasSelection); itemBar.setSelection(barsOpened); // --- new MenuItem(menu, SWT.SEPARATOR); // Run Data File final MenuItem itemOpen = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemOpen, "MyTorrentsView.menu.open"); Utils.setMenuItemImage(itemOpen, "run"); itemOpen.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { runDataSources(dms); } }); itemOpen.setEnabled(hasSelection); // Explore (or open containing folder) final boolean use_open_containing_folder = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled"); final MenuItem itemExplore = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemExplore, "MyTorrentsView.menu." + (use_open_containing_folder ? "open_parent_folder" : "explore")); itemExplore.addListener(SWT.Selection, new DMTask(dms, false) { public void run(DownloadManager dm) { ManagerUtils.open(dm, use_open_containing_folder); } }); itemExplore.setEnabled(hasSelection); // === advanced menu === final MenuItem itemAdvanced = new MenuItem(menu, SWT.CASCADE); Messages.setLanguageText(itemAdvanced, "MyTorrentsView.menu.advancedmenu"); //$NON-NLS-1$ itemAdvanced.setEnabled(hasSelection); final Menu menuAdvanced = new Menu(menu.getShell(), SWT.DROP_DOWN); itemAdvanced.setMenu(menuAdvanced); // advanced > Download Speed Menu // long maxDownload = COConfigurationManager.getIntParameter("Max Download Speed KBs", 0) * 1024; long maxUpload = COConfigurationManager.getIntParameter("Max Upload Speed KBs", 0) * 1024; ViewUtils.addSpeedMenu(menu.getShell(), menuAdvanced, true, hasSelection, downSpeedDisabled, downSpeedUnlimited, totalDownSpeed, downSpeedSetMax, maxDownload, upSpeedDisabled, upSpeedUnlimited, totalUpSpeed, upSpeedSetMax, maxUpload, dms.length, new ViewUtils.SpeedAdapter() { public void setDownSpeed(final int speed) { DMTask task = new DMTask(dms) { public void run(DownloadManager dm) { dm.getStats().setDownloadRateLimitBytesPerSecond(speed); } }; task.go(); } public void setUpSpeed(final int speed) { DMTask task = new DMTask(dms) { public void run(DownloadManager dm) { dm.getStats().setUploadRateLimitBytesPerSecond(speed); } }; task.go(); } }); // advanced > Tracker Menu // final Menu menuTracker = new Menu(menu.getShell(), SWT.DROP_DOWN); final MenuItem itemTracker = new MenuItem(menuAdvanced, SWT.CASCADE); Messages.setLanguageText(itemTracker, "MyTorrentsView.menu.tracker"); itemTracker.setMenu(menuTracker); final MenuItem itemChangeTracker = new MenuItem(menuTracker, SWT.PUSH); Messages.setLanguageText(itemChangeTracker, "MyTorrentsView.menu.changeTracker"); //$NON-NLS-1$ Utils.setMenuItemImage(itemChangeTracker, "add_tracker"); itemChangeTracker.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { if ( dms.length > 0 ){ new TrackerChangerWindow(composite.getDisplay(), dms); } } }); itemChangeTracker.setEnabled(changeUrl); final MenuItem itemEditTracker = new MenuItem(menuTracker, SWT.PUSH); Messages.setLanguageText(itemEditTracker, "MyTorrentsView.menu.editTracker"); Utils.setMenuItemImage(itemEditTracker, "edit_trackers"); itemEditTracker.addListener(SWT.Selection, new DMTask(dms) { public void run( final DownloadManager[] dms ) { Map<String,List<DownloadManager>> same_map = new HashMap<String, List<DownloadManager>>(); for ( DownloadManager dm: dms ){ TOTorrent torrent = dm.getTorrent(); if ( torrent == null ){ continue; } List<List<String>> group = TorrentUtils.announceGroupsToList(torrent); String str = ""; for ( List<String> l: group ){ str += "[["; for ( String s:l ){ str += s + ", "; } } List<DownloadManager> dl = same_map.get( str ); if ( dl == null ){ dl = new ArrayList<DownloadManager>(); same_map.put( str, dl ); } dl.add(dm ); } for ( final List<DownloadManager> set: same_map.values()){ TOTorrent torrent = set.get(0).getTorrent(); List<List<String>> group = TorrentUtils.announceGroupsToList(torrent); new MultiTrackerEditor( null, group, new TrackerEditorListener() { public void trackersChanged( String str, String str2, List<List<String>> group ) { for ( DownloadManager dm: set ){ TOTorrent torrent = dm.getTorrent(); TorrentUtils.listToAnnounceGroups(group, torrent); try{ TorrentUtils.writeToFile(torrent); }catch (Throwable e){ Debug.printStackTrace(e); } if ( dm.getTrackerClient() != null){ dm.getTrackerClient().resetTrackerUrl(true); } } } }, true); } } }); itemEditTracker.setEnabled(hasSelection); // edit webseeds final MenuItem itemEditWebSeeds = new MenuItem(menuTracker, SWT.PUSH); Messages.setLanguageText(itemEditWebSeeds, "MyTorrentsView.menu.editWebSeeds"); itemEditWebSeeds.addListener(SWT.Selection, new DMTask(dms) { public void run( final DownloadManager[] dms ) { final TOTorrent torrent = dms[0].getTorrent(); if ( torrent == null ){ return; } List getright = getURLList( torrent, "url-list" ); List webseeds = getURLList( torrent, "httpseeds" ); Map ws = new HashMap(); ws.put( "getright", getright ); ws.put( "webseeds", webseeds ); ws = BDecoder.decodeStrings( ws ); new WebSeedsEditor( null, ws, new WebSeedsEditorListener() { public void webSeedsChanged( String oldName, String newName, Map ws ) { try{ // String -> byte[] ws = BDecoder.decode( BEncoder.encode( ws )); List getright = (List)ws.get( "getright" ); if ( getright == null || getright.size() == 0 ){ torrent.removeAdditionalProperty( "url-list" ); }else{ torrent.setAdditionalListProperty( "url-list", getright ); } List webseeds = (List)ws.get( "webseeds" ); if ( webseeds == null || webseeds.size() == 0 ){ torrent.removeAdditionalProperty( "httpseeds" ); }else{ torrent.setAdditionalListProperty( "httpseeds", webseeds ); } PluginInterface pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByClass(ExternalSeedPlugin.class); if ( pi != null ){ ExternalSeedPlugin ext_seed_plugin = (ExternalSeedPlugin)pi.getPlugin(); ext_seed_plugin.downloadChanged( PluginCoreUtils.wrap( dms[0] )); } }catch (Throwable e){ Debug.printStackTrace( e ); } } }, true ); } protected List getURLList( TOTorrent torrent, String key ) { Object obj = torrent.getAdditionalProperty( key ); if ( obj instanceof byte[] ){ List l = new ArrayList(); l.add(obj); return( l ); }else if ( obj instanceof List ){ return((List)obj); }else{ return( new ArrayList()); } } }); itemEditWebSeeds.setEnabled(dms.length==1); // manual update final MenuItem itemManualUpdate = new MenuItem(menuTracker, SWT.PUSH); Messages.setLanguageText(itemManualUpdate, "GeneralView.label.trackerurlupdate"); //$NON-NLS-1$ //itemManualUpdate.setImage(ImageRepository.getImage("edit_trackers")); itemManualUpdate.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.requestTrackerAnnounce(false); } }); itemManualUpdate.setEnabled(manualUpdate); boolean scrape_enabled = COConfigurationManager.getBooleanParameter("Tracker Client Scrape Enable"); boolean scrape_stopped = COConfigurationManager.getBooleanParameter("Tracker Client Scrape Stopped Enable"); boolean manualScrape = (!scrape_enabled) || ((!scrape_stopped) && allStopped); final MenuItem itemManualScrape = new MenuItem(menuTracker, SWT.PUSH); Messages.setLanguageText(itemManualScrape, "GeneralView.label.trackerscrapeupdate"); //itemManualUpdate.setImage(ImageRepository.getImage("edit_trackers")); itemManualScrape.addListener(SWT.Selection, new DMTask(dms, true, true ) { public void run(DownloadManager dm) { dm.requestTrackerScrape(true); } }); itemManualScrape.setEnabled(manualScrape); // advanced > files final MenuItem itemFiles = new MenuItem(menuAdvanced, SWT.CASCADE); Messages.setLanguageText(itemFiles, "ConfigView.section.files"); final Menu menuFiles = new Menu(composite.getShell(), SWT.DROP_DOWN); itemFiles.setMenu(menuFiles); final MenuItem itemFileMoveData = new MenuItem(menuFiles, SWT.PUSH); Messages.setLanguageText(itemFileMoveData, "MyTorrentsView.menu.movedata"); itemFileMoveData.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { if (dms != null && dms.length > 0) { DirectoryDialog dd = new DirectoryDialog(composite.getShell()); dd.setFilterPath(TorrentOpener.getFilterPathData()); dd.setText(MessageText.getString("MyTorrentsView.menu.movedata.dialog")); String path = dd.open(); if (path != null) { TorrentOpener.setFilterPathData(path); File target = new File(path); for (int i = 0; i < dms.length; i++) { try { dms[i].moveDataFiles(target); } catch (Throwable e) { Logger.log(new LogAlert(dms[i], LogAlert.REPEATABLE, "Download data move operation failed", e)); } } } } } }); itemFileMoveData.setEnabled(fileMove); final MenuItem itemFileMoveTorrent = new MenuItem(menuFiles, SWT.PUSH); Messages.setLanguageText(itemFileMoveTorrent, "MyTorrentsView.menu.movetorrent"); itemFileMoveTorrent.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { if (dms != null && dms.length > 0) { DirectoryDialog dd = new DirectoryDialog(composite.getShell()); String filter_path = TorrentOpener.getFilterPathTorrent(); // If we don't have a decent path, default to the path of the first // torrent. if (filter_path == null || filter_path.trim().length() == 0) { filter_path = new File(dms[0].getTorrentFileName()).getParent(); } dd.setFilterPath(filter_path); dd.setText(MessageText.getString("MyTorrentsView.menu.movedata.dialog")); String path = dd.open(); if (path != null) { File target = new File(path); TorrentOpener.setFilterPathTorrent(target.toString()); for (int i = 0; i < dms.length; i++) { try { dms[i].moveTorrentFile(target); } catch (Throwable e) { Logger.log(new LogAlert(dms[i], LogAlert.REPEATABLE, "Download torrent move operation failed", e)); } } } } } }); itemFileMoveTorrent.setEnabled(fileMove); final MenuItem itemCheckFilesExist = new MenuItem(menuFiles, SWT.PUSH); Messages.setLanguageText(itemCheckFilesExist, "MyTorrentsView.menu.checkfilesexist"); itemCheckFilesExist.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.filesExist( true ); } }); final MenuItem itemFileRescan = new MenuItem(menuFiles, SWT.CHECK); Messages.setLanguageText(itemFileRescan, "MyTorrentsView.menu.rescanfile"); itemFileRescan.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.getDownloadState().setFlag(DownloadManagerState.FLAG_SCAN_INCOMPLETE_PIECES, itemFileRescan.getSelection()); } }); itemFileRescan.setSelection(allScanSelected); itemFileRescan.setEnabled(fileRescan); // clear allocation MenuItem itemFileClearAlloc = new MenuItem(menuFiles, SWT.PUSH); Messages.setLanguageText(itemFileClearAlloc, "MyTorrentsView.menu.clear_alloc_data"); itemFileClearAlloc.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.setDataAlreadyAllocated( false ); } }); itemFileClearAlloc.setEnabled(allStopped); // clear resume MenuItem itemFileClearResume = new MenuItem(menuFiles, SWT.PUSH); Messages.setLanguageText(itemFileClearResume, "MyTorrentsView.menu.clear_resume_data"); itemFileClearResume.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.getDownloadState().clearResumeData(); } }); itemFileClearResume.setEnabled(allStopped); // Advanced - > Rename final MenuItem itemRename = new MenuItem(menuAdvanced, SWT.DROP_DOWN); Messages.setLanguageText(itemRename, "MyTorrentsView.menu.rename"); itemRename.setEnabled(hasSelection); itemRename.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { for (DownloadManager dm : dms) { AdvRenameWindow window = new AdvRenameWindow(); window.open(dm); } } }); // === advanced > export === // ========================= if (userMode > 0) { final MenuItem itemExport = new MenuItem(menuAdvanced, SWT.CASCADE); Messages.setLanguageText(itemExport, "MyTorrentsView.menu.exportmenu"); //$NON-NLS-1$ Utils.setMenuItemImage(itemExport, "export"); itemExport.setEnabled(hasSelection); final Menu menuExport = new Menu(composite.getShell(), SWT.DROP_DOWN); itemExport.setMenu(menuExport); // Advanced > Export > Export XML final MenuItem itemExportXML = new MenuItem(menuExport, SWT.PUSH); Messages.setLanguageText(itemExportXML, "MyTorrentsView.menu.export"); itemExportXML.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { DownloadManager dm = dms[0]; // First only. if (dm != null) new ExportTorrentWizard(itemExportXML.getDisplay(), dm); } }); // Advanced > Export > Export Torrent final MenuItem itemExportTorrent = new MenuItem(menuExport, SWT.PUSH); Messages.setLanguageText(itemExportTorrent, "MyTorrentsView.menu.exporttorrent"); itemExportTorrent.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { // FileDialog for single download // DirectoryDialog for multiple. File[] destinations = new File[dms.length]; if (dms.length == 1) { FileDialog fd = new FileDialog(composite.getShell(), SWT.SAVE); fd.setFileName(dms[0].getTorrentFileName()); String path = fd.open(); if (path == null) {return;} destinations[0] = new File(path); } else { DirectoryDialog dd = new DirectoryDialog(composite.getShell(), SWT.SAVE); String path = dd.open(); if (path == null) {return;} for (int i=0; i<dms.length; i++) { destinations[i] = new File(path, new File(dms[i].getTorrentFileName()).getName()); } } int i=0; try { for (; i<dms.length; i++) { File target = destinations[i]; if (target.exists()) { MessageBox mb = new MessageBox(composite.getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO); mb.setText(MessageText.getString("exportTorrentWizard.process.outputfileexists.title")); mb.setMessage(MessageText.getString("exportTorrentWizard.process.outputfileexists.message") + "\n" + destinations[i].getName()); int result = mb.open(); if (result == SWT.NO) {return;} if (!target.delete()) { throw (new Exception("Failed to delete file")); } } // end deal with clashing torrent // first copy the torrent - DON'T use "writeTorrent" as this amends the // "filename" field in the torrent TorrentUtils.copyToFile(dms[i].getDownloadState().getTorrent(), target); // now remove the non-standard entries TOTorrent dest = TOTorrentFactory.deserialiseFromBEncodedFile(target); dest.removeAdditionalProperties(); dest.serialiseToBEncodedFile(target); } // end for } // end try catch (Throwable e) { Logger.log(new LogAlert(dms[i], LogAlert.UNREPEATABLE, "Torrent export failed", e)); } } // end run() }); // end DMTask // Advanced > Export > WebSeed URL final MenuItem itemWebSeed = new MenuItem(menuExport, SWT.PUSH); Messages.setLanguageText(itemWebSeed, "MyTorrentsView.menu.exporthttpseeds"); itemWebSeed.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { final String NL = "\r\n"; String data = ""; boolean http_enable = COConfigurationManager.getBooleanParameter( "HTTP.Data.Listen.Port.Enable" ); String port; if ( http_enable ){ int p = COConfigurationManager.getIntParameter( "HTTP.Data.Listen.Port" ); int o = COConfigurationManager.getIntParameter( "HTTP.Data.Listen.Port.Override" ); if ( o == 0 ){ port = String.valueOf( p ); }else{ port = String.valueOf( o ); } }else{ data = "You need to enable the HTTP port or modify the URL(s) appropriately" + NL + NL; port = "<port>"; } String ip = COConfigurationManager.getStringParameter( "Tracker IP", "" ); if ( ip.length() == 0 ){ data += "You might need to modify the host address in the URL(s)" + NL + NL; try{ InetAddress ia = AzureusCoreFactory.getSingleton().getInstanceManager().getMyInstance().getExternalAddress(); if ( ia != null ){ ip = IPToHostNameResolver.syncResolve( ia.getHostAddress(), 10000 ); } }catch( Throwable e ){ } if ( ip.length() == 0 ){ ip = "<host>"; } } String base = "http://" + UrlUtils.convertIPV6Host(ip) + ":" + port + "/"; for (int i=0;i<dms.length;i++){ DownloadManager dm = dms[i]; if ( dm == null ){ continue; } TOTorrent torrent = dm.getTorrent(); if ( torrent == null ){ continue; } data += base + "webseed" + NL; try{ data += base + "files/" + URLEncoder.encode( new String( torrent.getHash(), "ISO-8859-1"), "ISO-8859-1" ) + "/" + NL + NL; }catch( Throwable e ){ } } if ( data.length() > 0){ ClipboardCopy.copyToClipBoard( data ); } } }); } // export menu // === advanced > options === // =========================== if (userMode > 0) { final MenuItem itemExportXML = new MenuItem(menuAdvanced, SWT.PUSH); Messages.setLanguageText(itemExportXML, "MainWindow.menu.view.configuration"); itemExportXML.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions(); uiFunctions.openView(UIFunctions.VIEW_DM_MULTI_OPTIONS, dms); } }); } // === advanced > peer sources === // =============================== if (userMode > 0) { final MenuItem itemPeerSource = new MenuItem(menuAdvanced, SWT.CASCADE); Messages.setLanguageText(itemPeerSource, "MyTorrentsView.menu.peersource"); //$NON-NLS-1$ final Menu menuPeerSource = new Menu(composite.getShell(), SWT.DROP_DOWN); itemPeerSource.setMenu(menuPeerSource); for (int i = 0; i < PEPeerSource.PS_SOURCES.length; i++) { final String p = PEPeerSource.PS_SOURCES[i]; String msg_text = "ConfigView.section.connection.peersource." + p; final MenuItem itemPS = new MenuItem(menuPeerSource, SWT.CHECK); itemPS.setData("peerSource", p); Messages.setLanguageText(itemPS, msg_text); //$NON-NLS-1$ itemPS.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.getDownloadState().setPeerSourceEnabled(p, itemPS.getSelection()); } }); itemPS.setSelection(true); boolean bChecked = hasSelection; boolean bEnabled = !hasSelection; if (bChecked) { bEnabled = true; // turn on check if just one dm is not enabled for (int j = 0; j < dms.length; j++) { DownloadManager dm = (DownloadManager) dms[j]; if (!dm.getDownloadState().isPeerSourceEnabled(p)) { bChecked = false; } if (!dm.getDownloadState().isPeerSourcePermitted(p)) { bEnabled = false; } } } itemPS.setSelection(bChecked); itemPS.setEnabled(bEnabled); } } // === advanced > networks === // =========================== if (userMode > 1) { final MenuItem itemNetworks = new MenuItem(menuAdvanced, SWT.CASCADE); Messages.setLanguageText(itemNetworks, "MyTorrentsView.menu.networks"); //$NON-NLS-1$ final Menu menuNetworks = new Menu(composite.getShell(), SWT.DROP_DOWN); itemNetworks.setMenu(menuNetworks); for (int i = 0; i < AENetworkClassifier.AT_NETWORKS.length; i++) { final String nn = AENetworkClassifier.AT_NETWORKS[i]; String msg_text = "ConfigView.section.connection.networks." + nn; final MenuItem itemNetwork = new MenuItem(menuNetworks, SWT.CHECK); itemNetwork.setData("network", nn); Messages.setLanguageText(itemNetwork, msg_text); //$NON-NLS-1$ itemNetwork.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.getDownloadState().setNetworkEnabled(nn, itemNetwork.getSelection()); } }); boolean bChecked = hasSelection; if (bChecked) { // turn on check if just one dm is not enabled for (int j = 0; j < dms.length; j++) { DownloadManager dm = (DownloadManager) dms[j]; if (!dm.getDownloadState().isNetworkEnabled(nn)) { bChecked = false; break; } } } itemNetwork.setSelection(bChecked); } } // superseed if (userMode > 1 && isSeedingView) { final MenuItem itemSuperSeed = new MenuItem(menuAdvanced, SWT.CHECK); Messages.setLanguageText(itemSuperSeed, "ManagerItem.superseeding"); boolean enabled = canSetSuperSeed && (superSeedAllNo || superSeedAllYes); itemSuperSeed.setEnabled(enabled); final boolean selected = superSeedAllNo; if (enabled) { itemSuperSeed.setSelection(selected); itemSuperSeed.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { PEPeerManager pm = dm.getPeerManager(); if (pm != null) { if (pm.isSuperSeedMode() == selected && pm.canToggleSuperSeedMode()) { pm.setSuperSeedMode(!selected); } } } }); } } final MenuItem itemPositionManual = new MenuItem(menuAdvanced, SWT.PUSH); Messages.setLanguageText(itemPositionManual, "MyTorrentsView.menu.reposition.manual"); itemPositionManual.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow( "MyTorrentsView.dialog.setPosition.title", "MyTorrentsView.dialog.setPosition.text"); entryWindow.prompt(new UIInputReceiverListener() { public void UIInputReceiverClosed(UIInputReceiver entryWindow) { if (!entryWindow.hasSubmittedInput()) { return; } String sReturn = entryWindow.getSubmittedInput(); if (sReturn == null) return; int newPosition = -1; try { newPosition = Integer.valueOf(sReturn).intValue(); } catch (NumberFormatException er) { // Ignore } int size = azureus_core.getGlobalManager().downloadManagerCount( isSeedingView); if (newPosition > size) newPosition = size; if (newPosition <= 0) { MessageBox mb = new MessageBox(composite.getShell(), SWT.ICON_ERROR | SWT.OK); mb.setText(MessageText.getString("MyTorrentsView.dialog.NumberError.title")); mb.setMessage(MessageText.getString("MyTorrentsView.dialog.NumberError.text")); mb.open(); return; } moveSelectedTorrentsTo(tv, dms, newPosition); } }); } }); // back to main menu if (userMode > 0 && isTrackerOn) { // Host final MenuItem itemHost = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemHost, "MyTorrentsView.menu.host"); Utils.setMenuItemImage(itemHost, "host"); itemHost.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { hostTorrents(dms, azureus_core, composite); } }); // Publish final MenuItem itemPublish = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemPublish, "MyTorrentsView.menu.publish"); Utils.setMenuItemImage(itemPublish, "publish"); itemPublish.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { publishTorrents(dms, azureus_core, composite); } }); itemHost.setEnabled(hasSelection); itemPublish.setEnabled(hasSelection); } /* Do we really need the Move submenu? There's shortcut keys and toolbar * buttons.. new MenuItem(menu, SWT.SEPARATOR); final MenuItem itemMove = new MenuItem(menu, SWT.CASCADE); Messages.setLanguageText(itemMove, "MyTorrentsView.menu.move"); Utils.setMenuItemImage(itemMove, "move"); itemMove.setEnabled(hasSelection); final Menu menuMove = new Menu(composite.getShell(), SWT.DROP_DOWN); itemMove.setMenu(menuMove); final MenuItem itemMoveTop = new MenuItem(menuMove, SWT.PUSH); Messages.setLanguageText(itemMoveTop, "MyTorrentsView.menu.moveTop"); Utils.setMenuItemImage(itemMoveTop, "top"); itemMoveTop.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { moveSelectedTorrentsTop(); } }); itemMoveTop.setEnabled(moveUp); final MenuItem itemMoveUp = new MenuItem(menuMove, SWT.PUSH); Messages.setLanguageText(itemMoveUp, "MyTorrentsView.menu.moveUp"); Utils.setMenuItemImage(itemMoveUp, "up"); itemMoveUp.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { moveSelectedTorrentsUp(); } }); final MenuItem itemMoveDown = new MenuItem(menuMove, SWT.PUSH); Messages.setLanguageText(itemMoveDown, "MyTorrentsView.menu.moveDown"); Utils.setMenuItemImage(itemMoveDown, "down"); itemMoveDown.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { moveSelectedTorrentsDown(); } }); final MenuItem itemMoveEnd = new MenuItem(menuMove, SWT.PUSH); Messages.setLanguageText(itemMoveEnd, "MyTorrentsView.menu.moveEnd"); Utils.setMenuItemImage(itemMoveEnd, "bottom"); itemMoveEnd.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { moveSelectedTorrentsEnd(); } }); itemMoveEnd.setEnabled(moveDown); */ /* //TODO ensure that all limits combined don't go under the min 5kbs ? //Disable at the end of the list, thus the first item of the array is instanciated last. itemsSpeed[0] = new MenuItem(menuSpeed,SWT.PUSH); Messages.setLanguageText(itemsSpeed[0],"MyTorrentsView.menu.setSpeed.disable"); itemsSpeed[0].setData("maxul", new Integer(-1)); itemsSpeed[0].addListener(SWT.Selection,itemsSpeedListener); */ // Category Menu menuCategory = new Menu(composite.getShell(), SWT.DROP_DOWN); final MenuItem itemCategory = new MenuItem(menu, SWT.CASCADE); Messages.setLanguageText(itemCategory, "MyTorrentsView.menu.setCategory"); //$NON-NLS-1$ //itemCategory.setImage(ImageRepository.getImage("speed")); itemCategory.setMenu(menuCategory); itemCategory.setEnabled(hasSelection); addCategorySubMenu(dms, menuCategory, composite); // --- new MenuItem(menu, SWT.SEPARATOR); // Queue final MenuItem itemQueue = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemQueue, "MyTorrentsView.menu.queue"); //$NON-NLS-1$ Utils.setMenuItemImage(itemQueue, "start"); itemQueue.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { Utils.getOffOfSWTThread(new AERunnable() { public void runSupport() { queueDataSources(dms, true); } }); } }); itemQueue.setEnabled(start); // Force Start if (userMode > 0) { final MenuItem itemForceStart = new MenuItem(menu, SWT.CHECK); Messages.setLanguageText(itemForceStart, "MyTorrentsView.menu.forceStart"); Utils.setMenuItemImage(itemForceStart, "forcestart"); itemForceStart.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { if (ManagerUtils.isForceStartable(dm)) { dm.setForceStart(itemForceStart.getSelection()); } } }); itemForceStart.setSelection(forceStart); itemForceStart.setEnabled(forceStartEnabled); } // Stop final MenuItem itemStop = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemStop, "MyTorrentsView.menu.stop"); //$NON-NLS-1$ Utils.setMenuItemImage(itemStop, "stop"); itemStop.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { Utils.getOffOfSWTThread(new AERunnable() { public void runSupport() { stopDataSources(dms); } }); } }); itemStop.setEnabled(stop); // Force Recheck final MenuItem itemRecheck = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemRecheck, "MyTorrentsView.menu.recheck"); Utils.setMenuItemImage(itemRecheck, "recheck"); itemRecheck.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { if (dm.canForceRecheck()) { dm.forceRecheck(); } } }); itemRecheck.setEnabled(recheck); // Delete final MenuItem itemRemove = new MenuItem(menu, SWT.PUSH); Messages.setLanguageText(itemRemove, "menu.delete.options"); Utils.setMenuItemImage(itemRemove, "delete"); itemRemove.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { removeDownloads(dms, null, true); } }); itemRemove.setEnabled(hasSelection); } private static void addCategorySubMenu(final DownloadManager[] dms, Menu menuCategory, final Composite composite) { MenuItem[] items = menuCategory.getItems(); int i; for (i = 0; i < items.length; i++) { items[i].dispose(); } Category[] categories = CategoryManager.getCategories(); Arrays.sort(categories); // Ensure that there is at least one user category available. boolean allow_category_selection = categories.length > 0; if (allow_category_selection) { boolean user_category_found = false; for (i=0; i<categories.length; i++) { if (categories[i].getType() == Category.TYPE_USER) { user_category_found = true; break; } } // It may be the categories array just contains "uncategorised". allow_category_selection = user_category_found; } if (allow_category_selection) { final Category catUncat = CategoryManager.getCategory(Category.TYPE_UNCATEGORIZED); if (catUncat != null) { final MenuItem itemCategory = new MenuItem(menuCategory, SWT.PUSH); Messages.setLanguageText(itemCategory, catUncat.getName()); itemCategory.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.getDownloadState().setCategory(catUncat); } }); new MenuItem(menuCategory, SWT.SEPARATOR); } for (i = 0; i < categories.length; i++) { final Category category = categories[i]; if (category.getType() == Category.TYPE_USER) { final MenuItem itemCategory = new MenuItem(menuCategory, SWT.PUSH); itemCategory.setText(category.getName()); itemCategory.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager dm) { dm.getDownloadState().setCategory(category); } }); } } new MenuItem(menuCategory, SWT.SEPARATOR); } final MenuItem itemAddCategory = new MenuItem(menuCategory, SWT.PUSH); Messages.setLanguageText(itemAddCategory, "MyTorrentsView.menu.setCategory.add"); itemAddCategory.addListener(SWT.Selection, new DMTask(dms) { public void run(DownloadManager[] dms) { CategoryAdderWindow adderWindow = new CategoryAdderWindow(composite.getDisplay()); Category newCategory = adderWindow.getNewCategory(); if (newCategory != null) assignToCategory(dms, newCategory); } }); } private static void moveSelectedTorrentsTo(TableView tv, DownloadManager[] dms, int iNewPos) { if (dms == null || dms.length == 0) { return; } TableColumnCore sortColumn = tv == null ? null : tv.getSortColumn(); boolean isSortAscending = sortColumn == null ? true : sortColumn.isSortAscending(); for (int i = 0; i < dms.length; i++) { DownloadManager dm = dms[i]; int iOldPos = dm.getPosition(); dm.getGlobalManager().moveTo(dm, iNewPos); if (isSortAscending) { if (iOldPos > iNewPos) iNewPos++; } else { if (iOldPos < iNewPos) iNewPos--; } } if (tv != null) { boolean bForceSort = sortColumn.getName().equals("#"); tv.columnInvalidate("#"); tv.refreshTable(bForceSort); } } private static void changeDirSelectedTorrents(DownloadManager[] dms, Shell shell) { if (dms.length <= 0) return; String sDefPath = COConfigurationManager.getBooleanParameter("Use default data dir") ? COConfigurationManager .getStringParameter("Default save path") : ""; if (sDefPath.length() > 0) { File f = new File(sDefPath); if (!f.exists()) { FileUtil.mkdirs(f); } } DirectoryDialog dDialog = new DirectoryDialog(shell, SWT.SYSTEM_MODAL); dDialog.setFilterPath(sDefPath); dDialog.setMessage(MessageText.getString("MainWindow.dialog.choose.savepath")); String sSavePath = dDialog.open(); if (sSavePath != null) { File fSavePath = new File(sSavePath); for (int i = 0; i < dms.length; i++) { DownloadManager dm = dms[i]; int state = dm.getState(); if (state == DownloadManager.STATE_STOPPED) { if (!dm.filesExist(true)) { state = DownloadManager.STATE_ERROR; } } if (state == DownloadManager.STATE_ERROR) { dm.setTorrentSaveDir(sSavePath); boolean found = dm.filesExist(true); if (!found && dm.getTorrent() != null && !dm.getTorrent().isSimpleTorrent()) { String parentPath = fSavePath.getParent(); if (parentPath != null) { dm.setTorrentSaveDir(parentPath); found = dm.filesExist(true); if (!found) { dm.setTorrentSaveDir(sSavePath); } } } if (found) { dm.stopIt(DownloadManager.STATE_STOPPED, false, false); ManagerUtils.queue(dm, shell); } } } } } /** * Runs a DownloadManager or DiskManagerFileInfo */ public static void runDataSources(Object[] datasources) { for (int i = datasources.length - 1; i >= 0; i--) { if (datasources[i] instanceof DownloadManager) { DownloadManager dm = (DownloadManager) datasources[i]; ManagerUtils.run(dm); } else if (datasources[i] instanceof DiskManagerFileInfo) { DiskManagerFileInfo info = (DiskManagerFileInfo) datasources[i]; Utils.launch(info); } } } public static void hostTorrents(final Object[] download_managers, final AzureusCore azureus_core, final Composite composite) { DMTask task = new DMTask(toDMS(download_managers)) { public void run(DownloadManager dm) { ManagerUtils.host(azureus_core, dm, composite); } }; task.go(); UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions(); if (uiFunctions != null) { uiFunctions.openView(UIFunctions.VIEW_MYTRACKER, null); } } public static void publishTorrents(final Object[] download_managers, final AzureusCore azureus_core, final Composite composite) { DMTask task = new DMTask(toDMS(download_managers)) { public void run(DownloadManager dm) { ManagerUtils.publish(azureus_core, dm, composite); } }; task.go(); UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions(); if (uiFunctions != null) { uiFunctions.openView(UIFunctions.VIEW_MYTRACKER, null); } } public static void removeDataSources(final Object[] datasources) { DownloadManager[] dms = toDMS(datasources); removeDownloads(dms, null); DiskManagerFileInfo[] fileInfos = toDMFI(datasources); if (fileInfos.length > 0) { FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_DELETE, fileInfos); } } public static void stopDataSources(Object[] datasources) { DownloadManager[] dms = toDMS(datasources); for (DownloadManager dm : dms) { ManagerUtils.stop(dm, null); } DiskManagerFileInfo[] fileInfos = toDMFI(datasources); if (fileInfos.length > 0) { FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_SKIPPED, fileInfos); } } public static void queueDataSources(Object[] datasources, boolean startStoppedParents) { DownloadManager[] dms = toDMS(datasources); for (DownloadManager dm : dms) { ManagerUtils.queue(dm, null); } DiskManagerFileInfo[] fileInfos = toDMFI(datasources); if (fileInfos.length > 0) { FilesViewMenuUtil.changePriority(FilesViewMenuUtil.PRIORITY_NORMAL, fileInfos); if (startStoppedParents) { for (DiskManagerFileInfo fileInfo : fileInfos) { if (fileInfo.getDownloadManager().getState() == DownloadManager.STATE_STOPPED) { ManagerUtils.queue(fileInfo.getDownloadManager(), null); } } } } } public static void resumeTorrents(Object[] download_managers) { DMTask task = new DMTask(toDMS(download_managers)) { public void run(DownloadManager dm) { ManagerUtils.start(dm); } }; task.go(); } // Category Stuff public static void assignToCategory(Object[] download_managers, final Category category) { DMTask task = new DMTask(toDMS(download_managers)) { public void run(DownloadManager dm) { dm.getDownloadState().setCategory(category); } }; task.go(); } public static void promptUserForComment(final DownloadManager[] dms) { if (dms.length == 0) {return;} DownloadManager dm = dms[0]; // Create dialog box. String suggested = dm.getDownloadState().getUserComment(); String msg_key_prefix = "MyTorrentsView.menu.edit_comment.enter."; SimpleTextEntryWindow text_entry = new SimpleTextEntryWindow(); text_entry.setTitle(msg_key_prefix + "title"); text_entry.setMessage(msg_key_prefix + "message"); text_entry.setPreenteredText(suggested, false); text_entry.setMultiLine(true); text_entry.prompt(new UIInputReceiverListener() { public void UIInputReceiverClosed(UIInputReceiver text_entry) { if (text_entry.hasSubmittedInput()) { String value = text_entry.getSubmittedInput(); final String value_to_set = (value.length() == 0) ? null : value; DMTask task = new DMTask(dms) { public void run(DownloadManager dm) { dm.getDownloadState().setUserComment(value_to_set); } }; task.go(); } } }); } private static DownloadManager[] toDMS(Object[] objects) { int count = 0; DownloadManager[] result = new DownloadManager[objects.length]; for (Object object : objects) { if (object instanceof DownloadManager) { DownloadManager dm = (DownloadManager) object; result[count++] = dm; } else if (object instanceof SelectedContent) { SelectedContent sc = (SelectedContent) object; if (sc.getFileIndex() == -1 && sc.getDownloadManager() != null) { result[count++] = sc.getDownloadManager(); } } } DownloadManager[] resultTrim = new DownloadManager[count]; System.arraycopy(result, 0, resultTrim, 0, count); return resultTrim; } private static DiskManagerFileInfo[] toDMFI(Object[] objects) { int count = 0; DiskManagerFileInfo[] result = new DiskManagerFileInfo[objects.length]; for (Object object : objects) { if (object instanceof DiskManagerFileInfo) { DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) object; result[count++] = fileInfo; } else if (object instanceof SelectedContent) { SelectedContent sc = (SelectedContent) object; int fileIndex = sc.getFileIndex(); if (fileIndex >= 0 && sc.getDownloadManager() != null) { DownloadManager dm = sc.getDownloadManager(); if (dm != null) { DiskManagerFileInfo[] infos = dm.getDiskManagerFileInfo(); if (fileIndex < infos.length) { result[count++] = infos[fileIndex]; } } } } } DiskManagerFileInfo[] resultTrim = new DiskManagerFileInfo[count]; System.arraycopy(result, 0, resultTrim, 0, count); return resultTrim; } private abstract static class DMTask implements Listener { private DownloadManager[] dms; private boolean ascending; private boolean async; public DMTask(DownloadManager[] dms) { this(dms, true); } public DMTask(DownloadManager[] dms, boolean ascending) { this.dms = dms; this.ascending = ascending; } public DMTask(DownloadManager[] dms, boolean ascending, boolean async ) { this.dms = dms; this.ascending = ascending; this.async = async; } // One of the following methods should be overridden. public void run(DownloadManager dm) { } public void run(DownloadManager[] dm) { } public void handleEvent(Event event) { if ( async ){ new AEThread2( "DMTask:async", true ) { public void run() { go(); } }.start(); }else{ go(); } } public void go() { try { DownloadManager dm = null; for (int i = 0; i < dms.length; i++) { dm = dms[ascending ? i : (dms.length - 1) - i]; if (dm == null) { continue; } this.run(dm); } this.run(dms); } catch (Exception e) { Debug.printStackTrace(e); } } } /** * quick check to see if a file might be a torrent * @param torrentFile * @param deleteFileOnCancel * @param parentShell non-null: display a window if it's not a torrent * @return * * @since 3.0.2.3 */ public static boolean isFileTorrent(File torrentFile, Shell parentShell, String torrentName) { String sFirstChunk = null; try { sFirstChunk = FileUtil.readFileAsString(torrentFile, 16384).toLowerCase(); } catch (IOException e) { Debug.out("warning", e); } if (sFirstChunk == null) { sFirstChunk = ""; } if (!sFirstChunk.startsWith("d")) { if (parentShell != null) { boolean isHTML = sFirstChunk.indexOf("<html") >= 0; final String retry_url = UrlUtils.parseTextForMagnets( torrentName ); String[] buttons; if ( retry_url == null ){ buttons = new String[]{ MessageText.getString("Button.ok") }; }else{ buttons = new String[]{ MessageText.getString( "OpenTorrentWindow.mb.notTorrent.retry" ), MessageText.getString( "Button.cancel" )}; } MessageBoxShell boxShell = new MessageBoxShell( MessageText.getString("OpenTorrentWindow.mb.notTorrent.title"), MessageText.getString("OpenTorrentWindow.mb.notTorrent.text", new String[] { torrentName, isHTML ? "" : MessageText.getString("OpenTorrentWindow.mb.notTorrent.cannot.display") }), buttons , 0 ); if (isHTML) { boxShell.setHtml(sFirstChunk); } boxShell.open( new UserPrompterResultListener() { public void prompterClosed( int result ) { if ( result == 0 && retry_url != null ){ TorrentOpener.openTorrent( retry_url ); } } }); } return false; } return true; } public static Map<String, Boolean> calculateToolbarStates( ISelectedContent[] currentContent, String viewID) { //System.out.println("updateCoreItems(" + currentContent.length + ", " + viewID + " via " + Debug.getCompressedStackTrace()); String[] TBKEYS = new String[] { "download", "play", "stream", "run", "top", "up", "down", "bottom", "start", "stop", "remove" }; Map<String, Boolean> mapNewToolbarStates = new HashMap<String, Boolean>(); String[] itemsNeedingSelection = {}; String[] itemsNeedingRealDMSelection = { "remove", "top", "bottom", "transcode", }; String[] itemsRequiring1DMwithHash = { "details", "comment", "up", "down", }; String[] itemsRequiring1DMSelection = {}; int numSelection = currentContent.length; boolean hasSelection = numSelection > 0; boolean has1Selection = numSelection == 1; for (int i = 0; i < itemsNeedingSelection.length; i++) { String itemID = itemsNeedingSelection[i]; mapNewToolbarStates.put(itemID, hasSelection); } TableView tv = SelectedContentManager.getCurrentlySelectedTableView(); boolean hasRealDM = tv != null; if (!hasRealDM) { MultipleDocumentInterfaceSWT mdi = UIFunctionsManagerSWT.getUIFunctionsSWT().getMDISWT(); if (mdi != null) { MdiEntrySWT entry = mdi.getCurrentEntrySWT(); if (entry != null) { if (entry.getDatasource() instanceof DownloadManager) { hasRealDM = true; } else if ((entry.getIView() instanceof UIPluginView) && (((UIPluginView) entry.getIView()).getDataSource() instanceof DownloadManager)) { hasRealDM = true; } } } } boolean canStart = false; boolean canStop = false; boolean canRemoveFileInfo = false; boolean canRunFileInfo = false; boolean hasDM = false; if (currentContent.length > 0 && hasRealDM) { for (int i = 0; i < currentContent.length; i++) { ISelectedContent content = currentContent[i]; DownloadManager dm = content.getDownloadManager(); int fileIndex = content.getFileIndex(); if (fileIndex == -1) { hasDM = true; if (!canStart && ManagerUtils.isStartable(dm)) { canStart = true; } if (!canStop && ManagerUtils.isStopable(dm)) { canStop = true; } } else { DiskManagerFileInfo[] fileInfos = dm.getDiskManagerFileInfo(); if (fileIndex < fileInfos.length) { DiskManagerFileInfo fileInfo = fileInfos[fileIndex]; if (!canStart && (fileInfo.isSkipped() || ManagerUtils.isStartable(dm))) { canStart = true; } if (!canStop && !fileInfo.isSkipped()) { canStop = true; } if (!canRemoveFileInfo && !fileInfo.isSkipped()) { int storageType = fileInfo.getStorageType(); if (storageType == DiskManagerFileInfo.ST_LINEAR || storageType == DiskManagerFileInfo.ST_COMPACT) { canRemoveFileInfo = true; } } if (!canRunFileInfo && fileInfo.getAccessMode() == DiskManagerFileInfo.READ && fileInfo.getDownloaded() == fileInfo.getLength() && fileInfo.getFile(true).exists()) { canRunFileInfo = true; } } } } boolean canRemove = hasDM || canRemoveFileInfo; mapNewToolbarStates.put("remove", canRemove); } boolean canRun = has1Selection && ((hasDM && !canRunFileInfo) || (!hasDM && canRunFileInfo)); if (canRun) { ISelectedContent content = currentContent[0]; DownloadManager dm = content.getDownloadManager(); if (dm == null) { canRun = false; } else { TOTorrent torrent = dm.getTorrent(); if (torrent == null) { canRun = false; } else if (!dm.getAssumedComplete() && torrent.isSimpleTorrent()) { canRun = false; /* } else if (PlatformTorrentUtils.useEMP(torrent) && PlatformTorrentUtils.embeddedPlayerAvail() && PlayUtils.canProgressiveOrIsComplete(torrent)) { // play button enabled and not UMP.. don't need launch canRun = false; } */ } } } mapNewToolbarStates.put("run", canRun); mapNewToolbarStates.put("start", canStart); mapNewToolbarStates.put("stop", canStop); for (int i = 0; i < itemsNeedingRealDMSelection.length; i++) { String itemID = itemsNeedingRealDMSelection[i]; if (!mapNewToolbarStates.containsKey(itemID)) { mapNewToolbarStates.put(itemID, hasSelection && hasDM && hasRealDM); } } for (int i = 0; i < itemsRequiring1DMSelection.length; i++) { String itemID = itemsRequiring1DMSelection[i]; if (!mapNewToolbarStates.containsKey(itemID)) { mapNewToolbarStates.put(itemID, has1Selection && hasDM); } } for (int i = 0; i < itemsRequiring1DMwithHash.length; i++) { String itemID = itemsRequiring1DMwithHash[i]; if (!mapNewToolbarStates.containsKey(itemID)) { mapNewToolbarStates.put(itemID, hasDM); } } mapNewToolbarStates.put("download", has1Selection && (!(currentContent[0] instanceof ISelectedVuzeFileContent)) && currentContent[0].getDownloadManager() == null && (currentContent[0].getHash() != null || currentContent[0].getDownloadInfo() != null)); if (tv != null) { TableColumn tc = tv.getTableColumn(RankItem.COLUMN_ID); if (tc != null && !tc.isVisible()) { mapNewToolbarStates.put("up", false); mapNewToolbarStates.put("down", false); } } return mapNewToolbarStates; } public static void removeDownloads(DownloadManager[] dms, AERunnable deleteFailed) { removeDownloads(dms, deleteFailed, false); } public static void removeDownloads(final DownloadManager[] dms, final AERunnable deleteFailed, final boolean forcePrompt) { if (dms == null) { return; } // confusing code: // for loop goes through erasing published and low noise torrents until // it reaches a normal one. We then prompt the user, and stop the loop. // When the user finally chooses an option, we act on it. If the user // chose to act on all, we do immediately all and quit. // If the user chose an action just for the one torrent, we do that action, // remove that item from the array (by nulling it), and then call // removeDownloads again so we can prompt again (or erase more published/low noise torrents) for (int i = 0; i < dms.length; i++) { DownloadManager dm = dms[i]; if (dm == null) { continue; } boolean deleteTorrent = COConfigurationManager.getBooleanParameter("def.deletetorrent"); int confirm = COConfigurationManager.getIntParameter("tb.confirm.delete.content"); boolean doPrompt = confirm == 0 | forcePrompt; if (doPrompt) { String title = MessageText.getString("deletedata.title"); String text = MessageText.getString("v3.deleteContent.message", new String[] { dm.getDisplayName() }); String[] buttons; int[] buttonVals; int defaultButtonPos; buttons = new String[] { MessageText.getString("Button.cancel"), MessageText.getString("Button.deleteContent.fromComputer"), MessageText.getString("Button.deleteContent.fromLibrary"), }; buttonVals = new int[] { SWT.CANCEL, 1, 2 }; defaultButtonPos = 2; final MessageBoxShell mb = new MessageBoxShell(title, text, buttons, defaultButtonPos); int numLeft = (dms.length - i); if (numLeft > 1) { mb.setRemember("na", false, MessageText.getString( "v3.deleteContent.applyToAll", new String[] { "" + numLeft })); // never store remember state mb.setRememberOnlyIfButton(-3); } mb.setRelatedObject(dm); mb.setLeftImage("image.trash"); mb.addCheckBox("deletecontent.also.deletetorrent", 2, deleteTorrent); final int index = i; mb.open(new UserPrompterResultListener() { public void prompterClosed(int result) { ImageLoader.getInstance().releaseImage("image.trash"); removeDownloadsPrompterClosed(dms, index, deleteFailed, result, mb.isRemembered(), mb.getCheckBoxEnabled()); } }); return; } else { boolean deleteData = confirm == 1; removeDownloadsPrompterClosed(dms, i, deleteFailed, deleteData ? 1 : 2, true, deleteTorrent); } } } private static void removeDownloadsPrompterClosed(DownloadManager[] dms, int index, AERunnable deleteFailed, int result, boolean doAll, boolean deleteTorrent) { if (result == -1) { // user pressed ESC (as opposed to clicked Cancel), cancel whole // list return; } if (doAll) { if (result == 1 || result == 2) { for (int i = index; i < dms.length; i++) { DownloadManager dm = dms[i]; boolean deleteData = result == 2 ? false : !dm.getDownloadState().getFlag( Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE); ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED, deleteTorrent, deleteData, deleteFailed); } } //else cancel } else { // not remembered if (result == 1 || result == 2) { DownloadManager dm = dms[index]; boolean deleteData = result == 2 ? false : !dm.getDownloadState().getFlag( Download.FLAG_DO_NOT_DELETE_DATA_ON_REMOVE); ManagerUtils.asyncStopDelete(dm, DownloadManager.STATE_STOPPED, deleteTorrent, deleteData, null); } // remove the one we just did and go through loop again dms[index] = null; if (index != dms.length - 1) { removeDownloads(dms, deleteFailed, true); } } } }