/** * Copyright (C) Azureus Software, Inc, 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. * */ package com.aelitis.azureus.ui.swt.shells.opentorrent; import java.io.*; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.*; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.config.StringIterator; import org.gudy.azureus2.core3.config.StringList; import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults; import org.gudy.azureus2.core3.internat.MessageText; import org.gudy.azureus2.core3.torrent.impl.TorrentOpenOptions; import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloader; import org.gudy.azureus2.core3.torrentdownloader.TorrentDownloaderCallBackInterface; import org.gudy.azureus2.core3.util.*; import org.gudy.azureus2.ui.swt.*; import org.gudy.azureus2.ui.swt.mainwindow.Colors; import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener; import com.aelitis.azureus.core.AzureusCore; import com.aelitis.azureus.core.AzureusCoreFactory; import com.aelitis.azureus.ui.UIFunctions; import com.aelitis.azureus.ui.UIFunctionsManager; import com.aelitis.azureus.ui.common.updater.UIUpdatable; import com.aelitis.azureus.ui.swt.shells.main.UIFunctionsImpl; import com.aelitis.azureus.ui.swt.skin.*; import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT; import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog; import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog.SkinnedDialogClosedListener; import com.aelitis.azureus.ui.swt.views.skin.StandardButtonsArea; public class OpenTorrentWindow implements TorrentDownloaderCallBackInterface, UIUpdatable { protected static String CONFIG_REFERRER_DEFAULT = "openUrl.referrer.default"; private Shell shellForChildren; private Shell parent; private SkinnedDialog dlg; private StandardButtonsArea buttonsArea; private Button btnPasteOpen; private SWTSkinObjectTextbox soTextArea; private SWTSkinObject soReferArea; private Combo referrer_combo; private String last_referrer; private StringList referrers; //private TorrentOpenOptions torrentOptions; private SWTSkinObjectCheckbox soShowAdvanced; public OpenTorrentWindow(Shell parent) { this.parent = parent; Utils.execSWTThread(new AERunnable() { public void runSupport() { swt_createWindow(); } }); } private void swt_createWindow() { dlg = new SkinnedDialog("skin3_dlg_opentorrent", "shell", SWT.RESIZE | SWT.DIALOG_TRIM); shellForChildren = dlg.getShell(); SWTSkin skin = dlg.getSkin(); SWTSkinObject soTopBar = skin.getSkinObject("add-buttons"); if (soTopBar instanceof SWTSkinObjectContainer) { swt_addButtons(((SWTSkinObjectContainer) soTopBar).getComposite()); } soTextArea = (SWTSkinObjectTextbox) skin.getSkinObject("text-area"); Text tb = ((Text) soTextArea.getControl()); tb.setFocus(); tb.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { int userMode = COConfigurationManager.getIntParameter("User Mode"); if (userMode > 0) { if (soReferArea != null) { String text = ((Text) e.widget).getText(); boolean hasURL = UrlUtils.parseTextForURL(text, false, true) != null; soReferArea.setVisible(hasURL); } } } }); SWTSkinObject so; so = skin.getSkinObject("show-advanced"); if (so instanceof SWTSkinObjectCheckbox) { soShowAdvanced = (SWTSkinObjectCheckbox) so; soShowAdvanced.setChecked(COConfigurationManager.getBooleanParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS)); } soReferArea = skin.getSkinObject("refer-area"); last_referrer = COConfigurationManager.getStringParameter( CONFIG_REFERRER_DEFAULT, ""); so = skin.getSkinObject("refer-combo"); if (so instanceof SWTSkinObjectContainer) { referrer_combo = new Combo(((SWTSkinObjectContainer) so).getComposite(), SWT.BORDER); referrer_combo.setLayoutData(Utils.getFilledFormData()); referrers = COConfigurationManager.getStringListParameter("url_open_referrers"); StringIterator iter = referrers.iterator(); while (iter.hasNext()) { referrer_combo.add(iter.next()); } if (last_referrer != null) { referrer_combo.setText(last_referrer); } } SWTSkinObject soButtonArea = skin.getSkinObject("button-area"); if (soButtonArea instanceof SWTSkinObjectContainer) { buttonsArea = new StandardButtonsArea() { protected void clicked(int intValue) { String referrer = null; if (referrer_combo != null) { referrer = referrer_combo.getText().trim(); } if (dlg != null) { dlg.close(); } if (intValue == SWT.OK && soTextArea != null && soTextArea.getText().length()>0) { openTorrent(soTextArea.getText(), referrer); } } }; buttonsArea.setButtonIDs(new String[] { MessageText.getString("Button.ok"), MessageText.getString("Button.cancel") }); buttonsArea.setButtonVals(new Integer[] { SWT.OK, SWT.CANCEL }); buttonsArea.swt_createButtons(((SWTSkinObjectContainer) soButtonArea).getComposite()); } UIUpdaterSWT.getInstance().addUpdater(this); /* * The bring-to-front logic for torrent addition is controlled by other parts of the code so we don't * want the dlg to override this behaviour (main example here is torrents passed from, say, a browser, * and the user has disabled the 'show vuze on external torrent add' feature) */ dlg.open("otw",false); dlg.addCloseListener(new SkinnedDialogClosedListener() { public void skinDialogClosed(SkinnedDialog dialog) { dispose(); } }); } protected void openTorrent(String text, String newReferrer) { if (newReferrer != null && newReferrer.length() > 0) { if (!referrers.contains(newReferrer)) { referrers.add(newReferrer); COConfigurationManager.setParameter("url_open_referrers", referrers); COConfigurationManager.save(); } COConfigurationManager.setParameter(CONFIG_REFERRER_DEFAULT, newReferrer); COConfigurationManager.save(); } final String[] splitters = { "\r\n", "\n", "\r", "\t" }; String lines[] = null; for (int i = 0; i < splitters.length; i++) { if (text.indexOf(splitters[i]) >= 0) { lines = text.split(splitters[i]); break; } } if (lines == null) { lines = new String[] { text }; } TorrentOpener.openTorrentsFromStrings(new TorrentOpenOptions(), parent, null, lines, newReferrer, this, false); } protected void dispose() { UIUpdaterSWT.getInstance().removeUpdater(this); } private void swt_addButtons(Composite parent) { Composite cButtons = new Composite(parent, SWT.NONE); RowLayout rLayout = new RowLayout(SWT.HORIZONTAL); rLayout.marginBottom = 0; rLayout.marginLeft = 0; rLayout.marginRight = 0; rLayout.marginTop = 0; cButtons.setLayout(rLayout); cButtons.setLayoutData(Utils.getFilledFormData()); // Buttons for tableTorrents Button browseTorrent = new Button(cButtons, SWT.PUSH); Messages.setLanguageText(browseTorrent, "OpenTorrentWindow.addFiles"); browseTorrent.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { FileDialog fDialog = new FileDialog(shellForChildren, SWT.OPEN | SWT.MULTI); fDialog.setFilterExtensions(new String[] { "*.torrent", "*.tor", Constants.FILE_WILDCARD }); fDialog.setFilterNames(new String[] { "*.torrent", "*.tor", Constants.FILE_WILDCARD }); fDialog.setFilterPath(TorrentOpener.getFilterPathTorrent()); fDialog.setText(MessageText.getString("MainWindow.dialog.choose.file")); String fileName = TorrentOpener.setFilterPathTorrent(fDialog.open()); if (fileName != null) { addTorrentsToWindow(fDialog.getFilterPath(), fDialog.getFileNames()); } } }); Button browseFolder = new Button(cButtons, SWT.PUSH); Messages.setLanguageText(browseFolder, "OpenTorrentWindow.addFiles.Folder"); browseFolder.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { DirectoryDialog fDialog = new DirectoryDialog(shellForChildren, SWT.NULL); fDialog.setFilterPath(TorrentOpener.getFilterPathTorrent()); fDialog.setMessage(MessageText.getString("MainWindow.dialog.choose.folder")); String path = TorrentOpener.setFilterPathTorrent(fDialog.open()); if (path != null) { addTorrentsToWindow(path, null); } } }); btnPasteOpen = new Button(cButtons, SWT.PUSH); Messages.setLanguageText(btnPasteOpen, "OpenTorrentWindow.addFiles.Clipboard"); btnPasteOpen.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { Clipboard clipboard = new Clipboard(shellForChildren.getDisplay()); String sClipText = (String) clipboard.getContents(TextTransfer.getInstance()); if (sClipText != null) { addTorrentsFromTextList(sClipText.trim(), false); } } }); btnPasteOpen.setVisible(false); } private String ensureTrailingSeparator(String sPath) { if (sPath == null || sPath.length() == 0 || sPath.endsWith(File.separator)) return sPath; return sPath + File.separator; } private int addTorrentsToWindow(String sTorrentFilePath, String[] sTorrentFilenames) { String text = soTextArea.getText(); sTorrentFilePath = ensureTrailingSeparator(sTorrentFilePath); // Process Directory if (sTorrentFilePath != null && sTorrentFilenames == null) { File dir = new File(sTorrentFilePath); if (!dir.isDirectory()) return 0; final File[] files = dir.listFiles(new FileFilter() { public boolean accept(File arg0) { if (FileUtil.getCanonicalFileName(arg0.getName()).endsWith(".torrent")) return true; if (FileUtil.getCanonicalFileName(arg0.getName()).endsWith(".tor")) return true; return false; } }); if (files.length == 0) return 0; sTorrentFilenames = new String[files.length]; for (int i = 0; i < files.length; i++) sTorrentFilenames[i] = files[i].getName(); } int numAdded = 0; if ( sTorrentFilenames != null ){ for (int i = 0; i < sTorrentFilenames.length; i++) { if (sTorrentFilenames[i] == null || sTorrentFilenames[i].length() == 0) continue; // Process File String sFileName = ((sTorrentFilePath == null) ? "" : sTorrentFilePath) + sTorrentFilenames[i]; File file = new File(sFileName); try { if (UrlUtils.isURL(sFileName) || (file.exists() && TorrentUtils.isTorrentFile(sFileName))) { if (text.length() > 0) { text += "\n"; } text += sFileName; numAdded++; } } catch (FileNotFoundException e) { } catch (IOException e) { } } if (numAdded > 0) { soTextArea.setText(text); } } return numAdded; } /** * Add Torrent(s) to Window using a text list of files/urls/torrents * * @param sClipText Text to parse * @param bVerifyOnly Only check if there's potential torrents in the text, * do not try to add the torrents. * * @return Number of torrents added or found. When bVerifyOnly, this number * may not be exact. */ private int addTorrentsFromTextList(String sClipText, boolean bVerifyOnly) { String[] lines = null; int iNumFound = 0; // # of consecutive non torrent lines int iNoTorrentLines = 0; // no use checking the whole clipboard (which may be megabytes) final int MAX_CONSECUTIVE_NONTORRENT_LINES = 100; final String[] splitters = { "\r\n", "\n", "\r", "\t" }; for (int i = 0; i < splitters.length; i++) if (sClipText.indexOf(splitters[i]) >= 0) { lines = sClipText.split(splitters[i]); break; } if (lines == null) lines = new String[] { sClipText }; // Check if URL, 20 byte hash, Dir, or file for (int i = 0; i < lines.length; i++) { String line = lines[i].trim(); if (line.startsWith("\"") && line.endsWith("\"")) { if (line.length() < 3) { line = ""; } else { line = line.substring(1, line.length() - 2); } } boolean ok; if (line.length()==0) { ok = false; } else if (UrlUtils.isURL(line)) { ok = true; } else { File file = new File(line); if (!file.exists()) { ok = false; } else if (file.isDirectory()) { if (bVerifyOnly) { // XXX Could do a file count here, but the number found is not // expected to be an exact number anyway, since we aren't // event verifying if they are torrents. ok = true; } else { iNumFound += addTorrentsToWindow(lines[i], null); ok = false; } } else { ok = true; } } if (!ok) { iNoTorrentLines++; lines[i] = null; if (iNoTorrentLines > MAX_CONSECUTIVE_NONTORRENT_LINES) break; } else { iNumFound++; iNoTorrentLines = 0; } } if (bVerifyOnly) { return iNumFound; } return addTorrentsToWindow(null, lines); } public static void main(String[] args) { AzureusCore core = AzureusCoreFactory.create(); core.start(); UIConfigDefaultsSWT.initialize(); // try { // SWTThread.createInstance(null); // } catch (SWTThreadAlreadyInstanciatedException e) { // e.printStackTrace(); // } Display display = Display.getDefault(); Colors.getInstance(); COConfigurationManager.setParameter("User Mode", 2); UIFunctionsImpl uiFunctions = new UIFunctionsImpl(null); UIFunctionsManager.setUIFunctions(uiFunctions); // invoke(null, core.getGlobalManager()); OpenTorrentWindow window = new OpenTorrentWindow(null); while (!window.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } core.stop(); } private boolean isDisposed() { if (dlg == null) { return false; } return dlg.isDisposed(); } public void TorrentDownloaderEvent(int state, TorrentDownloader inf) { // This method is run even if the window is closed. // The default is to delete file on cancel // We set this flag to false if we detected the file was not a torrent if (!inf.getDeleteFileOnCancel() && (state == TorrentDownloader.STATE_CANCELLED || state == TorrentDownloader.STATE_ERROR || state == TorrentDownloader.STATE_DUPLICATE || state == TorrentDownloader.STATE_FINISHED)) { File file = inf.getFile(); // we already know it isn't a torrent.. we are just using the call // to popup the message TorrentUtil.isFileTorrent(file, inf.getURL()); if (file.exists()) { file.delete(); } return; } if (state == TorrentDownloader.STATE_INIT) { } else if (state == TorrentDownloader.STATE_FINISHED) { File file = inf.getFile(); TorrentOpenOptions torrentOptions = new TorrentOpenOptions(); if (!TorrentOpener.mergeFileIntoTorrentInfo(file.getAbsolutePath(), inf.getURL(), torrentOptions)) { if (file.exists()) file.delete(); } else { UIFunctions uif = UIFunctionsManager.getUIFunctions(); boolean b = uif.addTorrentWithOptions(false, torrentOptions); if (!b && file.exists()) { file.delete(); } } } else if (state == TorrentDownloader.STATE_CANCELLED || state == TorrentDownloader.STATE_ERROR || state == TorrentDownloader.STATE_DUPLICATE) { } else if (state == TorrentDownloader.STATE_DOWNLOADING) { int count = inf.getLastReadCount(); int numRead = inf.getTotalRead(); if (!inf.getDeleteFileOnCancel() && numRead >= 16384) { inf.cancel(); } else if (numRead == count && count > 0) { final byte[] bytes = inf.getLastReadBytes(); if (bytes[0] != 'd') { inf.setDeleteFileOnCancel(false); } } } else { return; } } public void updateUI() { boolean bTorrentInClipboard = false; Clipboard clipboard = new Clipboard(Display.getDefault()); String sClipText = (String) clipboard.getContents(TextTransfer.getInstance()); if (sClipText != null) bTorrentInClipboard = addTorrentsFromTextList(sClipText, true) > 0; if (btnPasteOpen != null && !btnPasteOpen.isDisposed() && btnPasteOpen.isVisible() != bTorrentInClipboard) { btnPasteOpen.setVisible(bTorrentInClipboard); if (bTorrentInClipboard) { btnPasteOpen.setToolTipText(sClipText); } } clipboard.dispose(); } public String getUpdateUIName() { return null; } }