1 /*
2  * Created on Jul 13, 2006 6:15:55 PM
3  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16  */
17 package com.aelitis.azureus.ui.swt.shells.main;
18 
19 import java.io.File;
20 import java.net.URL;
21 import java.text.SimpleDateFormat;
22 import java.util.Date;
23 import java.util.HashMap;
24 import java.util.Locale;
25 import java.util.Map;
26 
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.events.PaintEvent;
29 import org.eclipse.swt.events.PaintListener;
30 import org.eclipse.swt.graphics.Point;
31 import org.eclipse.swt.program.Program;
32 import org.eclipse.swt.widgets.*;
33 import org.gudy.azureus2.core3.config.COConfigurationManager;
34 import org.gudy.azureus2.core3.config.ParameterListener;
35 import org.gudy.azureus2.core3.config.impl.ConfigurationDefaults;
36 import org.gudy.azureus2.core3.download.DownloadManager;
37 import org.gudy.azureus2.core3.global.GlobalManager;
38 import org.gudy.azureus2.core3.global.GlobalManagerEvent;
39 import org.gudy.azureus2.core3.history.DownloadHistoryManager;
40 import org.gudy.azureus2.core3.internat.MessageText;
41 import org.gudy.azureus2.core3.logging.LogEvent;
42 import org.gudy.azureus2.core3.logging.LogIDs;
43 import org.gudy.azureus2.core3.logging.Logger;
44 import org.gudy.azureus2.core3.torrent.TOTorrent;
45 import org.gudy.azureus2.core3.torrent.impl.TorrentOpenOptions;
46 import org.gudy.azureus2.core3.util.*;
47 import org.gudy.azureus2.plugins.PluginManager;
48 import org.gudy.azureus2.plugins.download.DownloadStub;
49 import org.gudy.azureus2.plugins.ui.UIInputReceiver;
50 import org.gudy.azureus2.plugins.ui.UIInputReceiverListener;
51 import org.gudy.azureus2.plugins.ui.UIInstance;
52 import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager;
53 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer;
54 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
55 import org.gudy.azureus2.ui.swt.FileDownloadWindow;
56 import org.gudy.azureus2.ui.swt.SimpleTextEntryWindow;
57 import org.gudy.azureus2.ui.swt.Utils;
58 import org.gudy.azureus2.ui.swt.mainwindow.*;
59 import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar;
60 import org.gudy.azureus2.ui.swt.minibar.MiniBarManager;
61 import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
62 import org.gudy.azureus2.ui.swt.plugins.UISWTView;
63 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
64 import org.gudy.azureus2.ui.swt.pluginsimpl.*;
65 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell;
66 import org.gudy.azureus2.ui.swt.shells.MessageSlideShell;
67 import org.gudy.azureus2.ui.swt.update.FullUpdateWindow;
68 
69 import com.aelitis.azureus.core.AzureusCore;
70 import com.aelitis.azureus.core.AzureusCoreFactory;
71 import com.aelitis.azureus.core.cnetwork.ContentNetwork;
72 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
73 import com.aelitis.azureus.ui.*;
74 import com.aelitis.azureus.ui.common.table.TableView;
75 import com.aelitis.azureus.ui.common.updater.UIUpdater;
76 import com.aelitis.azureus.ui.mdi.MdiEntry;
77 import com.aelitis.azureus.ui.mdi.MdiEntryOpenListener;
78 import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
79 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
80 import com.aelitis.azureus.ui.skin.SkinConstants;
81 import com.aelitis.azureus.ui.swt.Initializer;
82 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
83 import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
84 import com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry;
85 import com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT;
86 import com.aelitis.azureus.ui.swt.mdi.TabbedMDI;
87 import com.aelitis.azureus.ui.swt.mdi.TabbedMdiInterface;
88 import com.aelitis.azureus.ui.swt.plugininstall.SimplePluginInstaller;
89 import com.aelitis.azureus.ui.swt.search.SearchHandler;
90 import com.aelitis.azureus.ui.swt.shells.BrowserWindow;
91 import com.aelitis.azureus.ui.swt.shells.RemotePairingWindow;
92 import com.aelitis.azureus.ui.swt.shells.opentorrent.OpenTorrentOptionsWindow;
93 import com.aelitis.azureus.ui.swt.shells.opentorrent.OpenTorrentWindow;
94 import com.aelitis.azureus.ui.swt.skin.*;
95 import com.aelitis.azureus.ui.swt.skin.SWTSkinButtonUtility.ButtonListenerAdapter;
96 import com.aelitis.azureus.ui.swt.uiupdater.UIUpdaterSWT;
97 import com.aelitis.azureus.ui.swt.utils.ColorCache;
98 import com.aelitis.azureus.ui.swt.utils.TagUIUtilsV3;
99 import com.aelitis.azureus.ui.swt.views.skin.*;
100 import com.aelitis.azureus.ui.swt.views.skin.SkinnedDialog.SkinnedDialogClosedListener;
101 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBar;
102 import com.aelitis.azureus.ui.swt.views.skin.sidebar.SideBarEntrySWT;
103 import com.aelitis.azureus.util.ConstantsVuze;
104 import com.aelitis.azureus.util.ContentNetworkUtils;
105 import com.aelitis.azureus.util.UrlFilter;
106 
107 /**
108  * @author TuxPaper
109  * @created Jul 13, 2006
110  *
111  */
112 public class UIFunctionsImpl
113 	implements UIFunctionsSWT
114 {
115 	private final static String MSG_ALREADY_EXISTS = "OpenTorrentWindow.mb.alreadyExists";
116 
117 	private final static String MSG_ALREADY_EXISTS_NAME = MSG_ALREADY_EXISTS
118 			+ ".default.name";
119 
120 	private final static LogIDs LOGID = LogIDs.GUI;
121 
122 	private final com.aelitis.azureus.ui.swt.shells.main.MainWindow mainWindow;
123 
124 	/**
125 	 * Stores the current <code>SWTSkin</code> so it can be used by {@link #createMenu(Shell)}
126 	 */
127 	private SWTSkin skin = null;
128 
129 	protected boolean isTorrentMenuVisible;
130 
131 	/**
132 	 * @param window
133 	 */
UIFunctionsImpl( com.aelitis.azureus.ui.swt.shells.main.MainWindow window)134 	public UIFunctionsImpl(
135 			com.aelitis.azureus.ui.swt.shells.main.MainWindow window) {
136 		this.mainWindow = window;
137 
138 		COConfigurationManager.addAndFireParameterListener(
139 				"show_torrents_menu", new ParameterListener() {
140 					public void parameterChanged(String parameterName) {
141 						isTorrentMenuVisible = COConfigurationManager.getBooleanParameter("show_torrents_menu");
142 					}
143 				});
144 	}
145 
146 	public int
getUIType()147 	getUIType()
148 	{
149 		return( PluginManager.UI_SWT );
150 	}
151 
152 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#addPluginView(java.lang.String, org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener)
addPluginView(final String viewID, final UISWTViewEventListener l)153 	public void addPluginView(final String viewID, final UISWTViewEventListener l) {
154 		try {
155 
156 			Utils.execSWTThread(new AERunnable() {
157 				public void runSupport() {
158 					PluginsMenuHelper.getInstance().addPluginView(viewID, l);
159 				}
160 			});
161 
162 		} catch (Exception e) {
163 			Logger.log(new LogEvent(LOGID, "addPluginView", e));
164 		}
165 
166 	}
167 
168 	// @see com.aelitis.azureus.ui.UIFunctions#bringToFront()
bringToFront()169 	public void bringToFront() {
170 		bringToFront(true);
171 	}
172 
173 	// @see com.aelitis.azureus.ui.UIFunctions#bringToFront(boolean)
bringToFront(final boolean tryTricks)174 	public void bringToFront(final boolean tryTricks) {
175 
176 		String debug = COConfigurationManager.getStringParameter( "adv.setting.ui.debug.window.show", "" );
177 
178 		if ( debug.equals( "1" )){
179 			Debug.out( "UIF::bringToFront" );
180 		}
181 
182 		Utils.execSWTThread(new AERunnable() {
183 			public void runSupport() {
184 				try {
185 					// this will force active and set !minimized after PW test
186 					mainWindow.setVisible(true, tryTricks);
187 
188 				} catch (Exception e) {
189 					Logger.log(new LogEvent(LOGID, "bringToFront", e));
190 				}
191 
192 			}
193 		});
194 	}
195 
196 	public int
getVisibilityState()197 	getVisibilityState()
198 	{
199 		final Shell shell = getMainShell();
200 
201 		if ( shell == null ){
202 
203 			return( VS_MINIMIZED_TO_TRAY );		// not sure about this
204 
205 		}else{
206 
207 			final int[] result = { VS_MINIMIZED_TO_TRAY };
208 
209 			final AESemaphore sem = new AESemaphore( "getVisibilityState" );
210 
211 			if (
212 				Utils.execSWTThread(
213 					new AERunnable()
214 					{
215 						public void
216 						runSupport()
217 						{
218 							try{
219 								if ( !shell.isVisible()){
220 
221 									result[0] = VS_MINIMIZED_TO_TRAY;
222 
223 								}else if ( shell.getMinimized()){
224 
225 									result[0] = VS_MINIMIZED;
226 
227 								}else{
228 
229 									result[0] = VS_ACTIVE;
230 								}
231 							}finally{
232 
233 								sem.release();
234 							}
235 						}
236 					})){
237 
238 				sem.reserve( 30*1000 );	// shouldn't block as if this is SWT thread code will run immediately, otherwise SWT thread shoudl be quick
239 			}
240 
241 			return( result[0] );
242 		}
243 	}
244 
245 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closeDownloadBars()
closeDownloadBars()246 	public void closeDownloadBars() {
247 		try {
248 			Utils.execSWTThreadLater(0, new AERunnable() {
249 				public void runSupport() {
250 					MiniBarManager.getManager().closeAll();
251 				}
252 			});
253 
254 		} catch (Exception e) {
255 			Logger.log(new LogEvent(LOGID, "closeDownloadBars", e));
256 		}
257 
258 	}
259 
260 	/* (non-Javadoc)
261 	 * @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closePluginView(org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore)
262 	 */
closePluginView(UISWTViewCore view)263 	public void closePluginView(UISWTViewCore view) {
264 		try {
265 			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
266 			if (mdi == null) {
267 				return;
268 			}
269 			String id;
270 			if (view instanceof UISWTViewImpl) {
271 				id = ((UISWTViewImpl)view).getViewID();
272 			} else {
273 				id = view.getClass().getName();
274 				int i = id.lastIndexOf('.');
275 				if (i > 0) {
276 					id = id.substring(i + 1);
277 				}
278 			}
279 			mdi.closeEntry(id);
280 
281 		} catch (Exception e) {
282 			Logger.log(new LogEvent(LOGID, "closePluginView", e));
283 		}
284 
285 	}
286 
287 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closePluginViews(java.lang.String)
closePluginViews(String sViewID)288 	public void closePluginViews(String sViewID) {
289 		try {
290 			MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
291 			if (mdi == null) {
292 				return;
293 			}
294 			mdi.closeEntry(sViewID);
295 
296 		} catch (Exception e) {
297 			Logger.log(new LogEvent(LOGID, "closePluginViews", e));
298 		}
299 
300 	}
301 
302 	// @see com.aelitis.azureus.ui.UIFunctions#dispose(boolean, boolean)
dispose(boolean for_restart, boolean close_already_in_progress)303 	public boolean dispose(boolean for_restart, boolean close_already_in_progress) {
304 		try {
305 			return mainWindow.dispose(for_restart, close_already_in_progress);
306 		} catch (Exception e) {
307 			Logger.log(new LogEvent(LOGID, "Disposing MainWindow", e));
308 		}
309 		return false;
310 	}
311 
312 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getMainShell()
getMainShell()313 	public Shell getMainShell() {
314 		return mainWindow == null ? null : mainWindow.getShell();
315 	}
316 
317 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getPluginViews()
getPluginViews()318 	public UISWTView[] getPluginViews() {
319 		try {
320 			return new UISWTView[0];
321 		} catch (Exception e) {
322 			Logger.log(new LogEvent(LOGID, "getPluginViews", e));
323 		}
324 
325 		return new UISWTView[0];
326 	}
327 
328 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getSWTPluginInstanceImpl()
getSWTPluginInstanceImpl()329 	public UISWTInstanceImpl getSWTPluginInstanceImpl() {
330 		try {
331 			return mainWindow.getUISWTInstanceImpl();
332 		} catch (Exception e) {
333 			Logger.log(new LogEvent(LOGID, "getSWTPluginInstanceImpl", e));
334 		}
335 
336 		return null;
337 	}
338 
339 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openPluginView(java.lang.String, java.lang.String, org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener, java.lang.Object, boolean)
openPluginView(String sParentID, String sViewID, UISWTViewEventListener l, Object dataSource, boolean bSetFocus)340 	public void openPluginView(String sParentID, String sViewID,
341 			UISWTViewEventListener l, Object dataSource, boolean bSetFocus) {
342 		try {
343 			MultipleDocumentInterfaceSWT mdi = getMDISWT();
344 
345 			if (mdi != null) {
346 
347 				String sidebarParentID = null;
348 
349 				if (UISWTInstance.VIEW_MYTORRENTS.equals(sParentID)) {
350 					sidebarParentID = SideBar.SIDEBAR_HEADER_TRANSFERS;
351 				} else if (UISWTInstance.VIEW_MAIN.equals(sParentID)) {
352 					sidebarParentID = MultipleDocumentInterface.SIDEBAR_HEADER_PLUGINS;
353 				} else {
354 					System.err.println("Can't find parent " + sParentID + " for " + sViewID);
355 				}
356 
357 				MdiEntry entry = mdi.createEntryFromEventListener(sidebarParentID, l, sViewID,
358 						true, dataSource, null);
359 				if (bSetFocus) {
360 					mdi.showEntryByID(sViewID);
361 				} else if (entry instanceof BaseMdiEntry) {
362 					// Some plugins (CVS Updater) want their view's composite initialized
363 					// on OpenPluginView, otherwise they won't do logic users expect
364 					// (like check for new snapshots).  So, enforce loading entry.
365 					((BaseMdiEntry) entry).build();
366 				}
367 			}
368 		} catch (Exception e) {
369 			Logger.log(new LogEvent(LOGID, "openPluginView", e));
370 		}
371 
372 	}
373 
374 	// @see com.aelitis.azureus.ui.UIFunctions#refreshIconBar()
refreshIconBar()375 	public void refreshIconBar() {
376 		try {
377 			SkinView[] tbSkinViews = SkinViewManager.getMultiByClass(ToolBarView.class);
378 			if (tbSkinViews != null) {
379 				for (SkinView skinview : tbSkinViews) {
380 					if (skinview instanceof ToolBarView) {
381 						ToolBarView tb = (ToolBarView) skinview;
382   					if (tb.isVisible()) {
383   						tb.refreshCoreToolBarItems();
384   					}
385 					}
386 				}
387 			}
388 
389 		} catch (Exception e) {
390 			Logger.log(new LogEvent(LOGID, "refreshIconBar", e));
391 		}
392 
393 	}
394 
395 	// @see com.aelitis.azureus.ui.UIFunctions#refreshLanguage()
refreshLanguage()396 	public void refreshLanguage() {
397 		try {
398 			mainWindow.setSelectedLanguageItem();
399 
400 		} catch (Exception e) {
401 			Logger.log(new LogEvent(LOGID, "refreshLanguage", e));
402 		}
403 
404 	}
405 
406 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#removePluginView(java.lang.String)
removePluginView(String viewID)407 	public void removePluginView(String viewID) {
408 		try {
409 
410 			PluginsMenuHelper.getInstance().removePluginViews(viewID);
411 
412 		} catch (Exception e) {
413 			Logger.log(new LogEvent(LOGID, "removePluginView", e));
414 		}
415 
416 	}
417 
418 	// @see com.aelitis.azureus.ui.UIFunctions#setStatusText(java.lang.String)
setStatusText(final String string)419 	public void setStatusText(final String string) {
420 		Utils.execSWTThreadLater(0, new AERunnable() {
421 			public void runSupport() {
422 				IMainStatusBar sb = getMainStatusBar();
423 				if ( sb != null ){
424 					sb.setStatusText(string);
425 				}
426 			}
427 		});
428 	}
429 
430 	// @see com.aelitis.azureus.ui.UIFunctions#setStatusText(int, java.lang.String, com.aelitis.azureus.ui.UIStatusTextClickListener)
setStatusText(final int statustype, final String string, final UIStatusTextClickListener l)431 	public void setStatusText(final int statustype, final String string,
432 			final UIStatusTextClickListener l) {
433 		Utils.execSWTThreadLater(0, new AERunnable() {
434 			public void runSupport() {
435 				IMainStatusBar sb = getMainStatusBar();
436 				if ( sb != null ){
437 					sb.setStatusText(statustype, string, l);
438 				}
439 			}
440 		});
441 	}
442 
443 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#getMainStatusBar()
getMainStatusBar()444 	public IMainStatusBar getMainStatusBar() {
445 		if (mainWindow == null) {
446 			return null;
447 		}
448 		return mainWindow.getMainStatusBar();
449 	}
450 
451 	// BurnPlugin uses this for VIEW_CONFIG
452 	// RCM uses VIEW_MYTORRENTS and VIEW_CONFIG and VIEW_DM_DETAILS
453 	@Deprecated
openView(final int viewID, final Object data)454 	public void openView(final int viewID, final Object data) {
455 		MultipleDocumentInterface mdi = getMDI();
456 		if (viewID == VIEW_CONFIG) {
457 			mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_CONFIG, data);
458 		} else if (viewID == VIEW_DM_DETAILS) {
459 			mdi.showEntryByID(
460 					MultipleDocumentInterface.SIDEBAR_SECTION_TORRENT_DETAILS, data);
461 		} else if (viewID == VIEW_MYTORRENTS) {
462 			mdi.showEntryByID(MultipleDocumentInterface.SIDEBAR_SECTION_LIBRARY,
463 					data);
464 		} else {
465 			System.err.println(
466 					"DEPRECATED -- Use getMDI().showEntryByID(" + viewID + "..)");
467 		}
468 	}
469 
getUISWTInstance()470 	public UISWTInstance getUISWTInstance() {
471 		UISWTInstanceImpl impl = mainWindow.getUISWTInstanceImpl();
472 		if (impl == null) {
473 			Debug.out("No uiswtinstanceimpl");
474 		}
475 		return impl;
476 	}
477 
478 	// @see com.aelitis.azureus.ui.UIFunctions#viewURL(java.lang.String, java.lang.String, java.lang.String)
viewURL(String url, String target, String sourceRef)479 	public void viewURL(String url, String target, String sourceRef) {
480 		viewURL(url, target, 0, 0, true, false);
481 	}
482 
viewURL(final String url, final String target, final int w, final int h, final boolean allowResize, final boolean isModal)483 	public boolean viewURL(final String url, final String target, final int w,
484 			final int h, final boolean allowResize, final boolean isModal) {
485 
486 		 mainWindow.getShell().getDisplay().syncExec(new AERunnable() {
487 			public void runSupport() {
488 				String realURL = url;
489 				ContentNetwork cn = ContentNetworkUtils.getContentNetworkFromTarget(target);
490 				if ( !realURL.startsWith( "http" )
491 					&& !realURL.startsWith("#")) {
492 					if ("_blank".equals(target)) {
493 						realURL = cn.getExternalSiteRelativeURL(realURL, false );
494 					} else {
495 						realURL = cn.getSiteRelativeURL(realURL, false );
496 					}
497 				}
498 				if (target == null) {
499 					if (UrlFilter.getInstance().urlCanRPC(realURL)) {
500 						realURL = cn.appendURLSuffix(realURL, false, true);
501 					}
502 					BrowserWindow window = new BrowserWindow( mainWindow.getShell(), realURL,
503 							w, h, allowResize, isModal);
504 					window.waitUntilClosed();
505 				} else {
506 					showURL(realURL, target);
507 				}
508 			}
509 		});
510 		return true;
511 	}
512 
viewURL(final String url, final String target, final double w, final double h, final boolean allowResize, final boolean isModal)513 	public boolean viewURL(final String url, final String target, final double w,
514 			final double h, final boolean allowResize, final boolean isModal) {
515 
516 		 mainWindow.getShell().getDisplay().syncExec(new AERunnable() {
517 			public void runSupport() {
518 				String realURL = url;
519 				ContentNetwork cn = ContentNetworkUtils.getContentNetworkFromTarget(target);
520 				if ( !realURL.startsWith( "http" )){
521 					if ("_blank".equals(target)) {
522 						realURL = cn.getExternalSiteRelativeURL(realURL, false );
523 					} else {
524 						realURL = cn.getSiteRelativeURL(realURL, false );
525 					}
526 				}
527 				if (target == null) {
528 					if (UrlFilter.getInstance().urlCanRPC(realURL)) {
529 						realURL = cn.appendURLSuffix(realURL, false, true);
530 					}
531 					BrowserWindow window = new BrowserWindow( mainWindow.getShell(), realURL,
532 							w, h, allowResize, isModal);
533 					window.waitUntilClosed();
534 				} else {
535 					showURL(realURL, target);
536 				}
537 			}
538 		});
539 		return true;
540 	}
541 
542 	/**
543 	 * @param url
544 	 * @param target
545 	 */
546 
showURL(final String url, String target)547 	private void showURL(final String url, String target) {
548 
549 		if ("_blank".equalsIgnoreCase(target)) {
550 			Utils.launch(url);
551 			return;
552 		}
553 
554 		if (target.startsWith("tab-")) {
555 			target = target.substring(4);
556 		}
557 
558 		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
559 
560 		if (MultipleDocumentInterface.SIDEBAR_SECTION_PLUS.equals(target)) {
561 			SBC_PlusFTUX.setSourceRef(url.substring(1));
562 			mdi.showEntryByID(target);
563 			return;
564 		}
565 
566 		// Note; We don't setSourceRef on ContentNetwork here like we do
567 		// everywhere else because the source ref should already be set
568 		// by the caller
569 		if (mdi == null || !mdi.showEntryByID(target)) {
570 			Utils.launch(url);
571 			return;
572 		}
573 
574 		MdiEntry entry = mdi.getEntry(target);
575 		entry.addListener(new MdiEntryOpenListener() {
576 
577 			public void mdiEntryOpen(MdiEntry entry) {
578 				entry.removeListener(this);
579 
580 				mainWindow.setVisible( true, true );
581 
582 				if (!(entry instanceof SideBarEntrySWT)) {
583 					return;
584 				}
585 				SideBarEntrySWT entrySWT = (SideBarEntrySWT) entry;
586 
587 				SWTSkinObjectBrowser soBrowser = SWTSkinUtils.findBrowserSO(entrySWT.getSkinObject());
588 
589 				if (soBrowser != null) {
590 					//((SWTSkinObjectBrowser) skinObject).getBrowser().setVisible(false);
591 					if (url == null || url.length() == 0) {
592 						soBrowser.restart();
593 					} else {
594 						String fullURL = url;
595 						if (UrlFilter.getInstance().urlCanRPC(url)) {
596 							// 4010 Tux: This shouldn't be.. either determine ContentNetwork from
597 							//           url or target, or do something..
598 							fullURL = ConstantsVuze.getDefaultContentNetwork().appendURLSuffix(
599 									url, false, true);
600 						}
601 
602 						soBrowser.setURL(fullURL);
603 					}
604 				}
605 			}
606 		});
607 	}
608 
609 	// @see com.aelitis.azureus.ui.UIFunctions#promptUser(java.lang.String, java.lang.String, java.lang.String[], int, java.lang.String, java.lang.String, boolean, int)
promptUser(String title, String text, String[] buttons, int defaultOption, String rememberID, String rememberText, boolean rememberByDefault, int autoCloseInMS, UserPrompterResultListener l)610 	public void promptUser(String title, String text, String[] buttons,
611 			int defaultOption, String rememberID, String rememberText,
612 			boolean rememberByDefault, int autoCloseInMS, UserPrompterResultListener l) {
613 		MessageBoxShell.open(getMainShell(), title, text, buttons,
614 				defaultOption, rememberID, rememberText, rememberByDefault,
615 				autoCloseInMS, l);
616 	}
617 
618 	// @see com.aelitis.azureus.ui.UIFunctions#getUserPrompter(java.lang.String, java.lang.String, java.lang.String[], int)
getUserPrompter(String title, String text, String[] buttons, int defaultOption)619 	public UIFunctionsUserPrompter getUserPrompter(String title, String text,
620 			String[] buttons, int defaultOption) {
621 
622 		MessageBoxShell mb = new MessageBoxShell(title, text, buttons,
623 				defaultOption);
624 		return mb;
625 	}
626 
isGlobalTransferBarShown()627 	public boolean isGlobalTransferBarShown() {
628 		if (!AzureusCoreFactory.isCoreRunning()) {
629 			return false;
630 		}
631 		return AllTransfersBar.getManager().isOpen(
632 				AzureusCoreFactory.getSingleton().getGlobalManager());
633 	}
634 
showGlobalTransferBar()635 	public void showGlobalTransferBar() {
636 		AllTransfersBar.open(getMainShell());
637 	}
638 
closeGlobalTransferBar()639 	public void closeGlobalTransferBar() {
640 		AllTransfersBar.closeAllTransfersBar();
641 	}
642 
refreshTorrentMenu()643 	public void refreshTorrentMenu() {
644 		if (!isTorrentMenuVisible) {
645 			return;
646 		}
647 		try {
648 			Utils.execSWTThread(new AERunnable() {
649 				public void runSupport() {
650 					final MenuItem torrentItem = MenuFactory.findMenuItem(
651 							mainWindow.getMainMenu().getMenu(IMenuConstants.MENU_ID_MENU_BAR),
652 							MenuFactory.MENU_ID_TORRENT, false);
653 
654 					if (null != torrentItem) {
655 
656 						DownloadManager[] dms = SelectedContentManager.getDMSFromSelectedContent();
657 
658 						final DownloadManager[] dm_final = dms;
659 						final boolean detailed_view_final = false;
660 						if (null == dm_final) {
661 							torrentItem.setEnabled(false);
662 						} else {
663 							TableView<?> tv = SelectedContentManager.getCurrentlySelectedTableView();
664 
665 							torrentItem.getMenu().setData("TableView", tv);
666 							torrentItem.getMenu().setData("downloads", dm_final);
667 							torrentItem.getMenu().setData("is_detailed_view",
668 									Boolean.valueOf(detailed_view_final));
669 							torrentItem.setEnabled(true);
670 						}
671 					}
672 				}
673 			});
674 
675 		} catch (Exception e) {
676 			Logger.log(new LogEvent(LOGID, "refreshTorrentMenu", e));
677 		}
678 	}
679 
createMainMenu(Shell shell)680 	public IMainMenu createMainMenu(Shell shell) {
681 		IMainMenu menu;
682 		boolean uiClassic = COConfigurationManager.getStringParameter("ui").equals("az2");
683 		if (uiClassic) {
684 			menu = new org.gudy.azureus2.ui.swt.mainwindow.MainMenu(shell);
685 		} else {
686 			menu = new MainMenu(skin, shell);
687 		}
688 		return menu;
689 	}
690 
getSkin()691 	public SWTSkin getSkin() {
692 		return skin;
693 	}
694 
setSkin(SWTSkin skin)695 	public void setSkin(SWTSkin skin) {
696 		this.skin = skin;
697 	}
698 
getMainWindow()699 	public IMainWindow getMainWindow() {
700 		return mainWindow;
701 	}
702 
703 	// @see com.aelitis.azureus.ui.UIFunctions#getUIUpdater()
getUIUpdater()704 	public UIUpdater getUIUpdater() {
705 		return UIUpdaterSWT.getInstance();
706 	}
707 
708 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#closeAllDetails()
closeAllDetails()709 	public void closeAllDetails() {
710 		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
711 		if (mdi == null) {
712 			return;
713 		}
714 		MdiEntry[] sideBarEntries = mdi.getEntries();
715 		for (int i = 0; i < sideBarEntries.length; i++) {
716 			MdiEntry entry = sideBarEntries[i];
717 			String id = entry.getId();
718 			if (id != null && id.startsWith("DMDetails_")) {
719 				mdi.closeEntry(id);
720 			}
721 		}
722 
723 	}
724 
725 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#hasDetailViews()
hasDetailViews()726 	public boolean hasDetailViews() {
727 		MultipleDocumentInterface mdi = UIFunctionsManager.getUIFunctions().getMDI();
728 		if (mdi == null) {
729 			return false;
730 		}
731 
732 		MdiEntry[] sideBarEntries = mdi.getEntries();
733 		for (int i = 0; i < sideBarEntries.length; i++) {
734 			MdiEntry entry = sideBarEntries[i];
735 			String id = entry.getId();
736 			if (id != null && id.startsWith("DMDetails_")) {
737 				return true;
738 			}
739 		}
740 
741 		return false;
742 	}
743 
744 	public void
performAction( int action_id, Object args, final actionListener listener )745 	performAction(
746 		int 					action_id,
747 		Object 					args,
748 		final actionListener 	listener )
749 	{
750 		if ( action_id == ACTION_FULL_UPDATE ){
751 
752 			FullUpdateWindow.handleUpdate((String)args, listener );
753 
754 		}else if ( action_id == ACTION_UPDATE_RESTART_REQUEST ){
755 
756 			String MSG_PREFIX = "UpdateMonitor.messagebox.";
757 
758 			String title = MessageText.getString(MSG_PREFIX + "restart.title" );
759 
760 			String text = MessageText.getString(MSG_PREFIX + "restart.text" );
761 
762 			bringToFront();
763 
764 			boolean no_timeout = args instanceof Boolean && ((Boolean)args).booleanValue();
765 
766 			int timeout = 180000;
767 
768 			if ( no_timeout || !PluginInitializer.getDefaultInterface().getPluginManager().isSilentRestartEnabled()){
769 
770 				timeout = -1;
771 			}
772 
773 			MessageBoxShell messageBoxShell = new MessageBoxShell(title, text,
774 					new String[] {
775 				MessageText.getString("UpdateWindow.restart"),
776 				MessageText.getString("UpdateWindow.restartLater")
777 			}, 0);
778 			messageBoxShell.setAutoCloseInMS(timeout);
779 			messageBoxShell.setParent(getMainShell());
780 			messageBoxShell.setOneInstanceOf(MSG_PREFIX);
781 			messageBoxShell.open( new UserPrompterResultListener() {
782 				public void prompterClosed(int result) {
783 					listener.actionComplete(result == 0);
784 				}
785 			});
786 		}else{
787 
788 			Debug.out( "Unknown action " + action_id );
789 		}
790 	}
791 
792 	// @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#showCoreWaitDlg()
showCoreWaitDlg()793 	public Shell showCoreWaitDlg() {
794 		final SkinnedDialog closeDialog = new SkinnedDialog(
795 				"skin3_dlg_coreloading", "coreloading.body", SWT.TITLE | SWT.BORDER
796 				| SWT.APPLICATION_MODAL);
797 
798 		closeDialog.setTitle(MessageText.getString("dlg.corewait.title"));
799 		SWTSkin skin = closeDialog.getSkin();
800 		SWTSkinObjectButton soButton = (SWTSkinObjectButton) skin.getSkinObject("close");
801 
802 		final SWTSkinObjectText soWaitTask = (SWTSkinObjectText) skin.getSkinObject("task");
803 
804 		final SWTSkinObject soWaitProgress = skin.getSkinObject("progress");
805 		if (soWaitProgress != null) {
806 			soWaitProgress.getControl().addPaintListener(new PaintListener() {
807 				public void paintControl(PaintEvent e) {
808 					Control c = (Control) e.widget;
809 					Point size = c.getSize();
810 					e.gc.setBackground(ColorCache.getColor(e.display, "#23a7df"));
811 					Object data = soWaitProgress.getData("progress");
812 					if (data instanceof Long) {
813 						int waitProgress = ((Long) data).intValue();
814 						int breakX = size.x * waitProgress / 100;
815 						e.gc.fillRectangle(0, 0, breakX, size.y);
816 						e.gc.setBackground(ColorCache.getColor(e.display, "#cccccc"));
817 						e.gc.fillRectangle(breakX, 0, size.x - breakX, size.y);
818 					}
819 				}
820 			});
821 		}
822 
823 		if (!AzureusCoreFactory.isCoreRunning()) {
824 			final Initializer initializer = Initializer.getLastInitializer();
825 			if (initializer != null) {
826 				initializer.addListener(new InitializerListener() {
827 					public void reportPercent(final int percent) {
828 						Utils.execSWTThread(new AERunnable() {
829 							public void runSupport() {
830 								if (soWaitProgress != null && !soWaitProgress.isDisposed()) {
831 									soWaitProgress.setData("progress", new Long(percent));
832 									soWaitProgress.getControl().redraw();
833 									soWaitProgress.getControl().update();
834 								}
835 							}
836 						});
837 						if (percent > 100) {
838 							initializer.removeListener(this);
839 						}
840 					}
841 
842 					public void reportCurrentTask(String currentTask) {
843 						if (soWaitTask != null && !soWaitTask.isDisposed()) {
844 							soWaitTask.setText(currentTask);
845 						}
846 					}
847 				});
848 			}
849 		}
850 
851 		if (soButton != null) {
852 			soButton.addSelectionListener(new ButtonListenerAdapter() {
853 				public void pressed(SWTSkinButtonUtility buttonUtility,
854 						SWTSkinObject skinObject, int stateMask) {
855 					closeDialog.close();
856 				}
857 			});
858 		}
859 
860 		closeDialog.addCloseListener(new SkinnedDialogClosedListener() {
861 			public void skinDialogClosed(SkinnedDialog dialog) {
862 			}
863 		});
864 
865 		closeDialog.open();
866 		return closeDialog.getShell();
867 	}
868 
869 	/**
870 	 * @param searchText
871 	 */
872 	//TODO : Tux Move to utils? Could you also add a "mode" or something that would be added to the url
873 	// eg: &subscribe_mode=true
doSearch(final String sSearchText)874 	public void doSearch(final String sSearchText) {
875 		Utils.execSWTThread(new AERunnable() {
876 			public void runSupport() {
877 				doSearch(sSearchText, false);
878 			}
879 		});
880 	}
881 
882 	public void
doSearch( String sSearchText, boolean toSubscribe)883 	doSearch(
884 		String sSearchText,
885 		boolean toSubscribe)
886 	{
887 		if (sSearchText.length() == 0) {
888 			return;
889 		}
890 
891 		if ( checkForSpecialSearchTerm( sSearchText )){
892 
893 			return;
894 		}
895 
896 		SearchHandler.handleSearch( sSearchText, toSubscribe );
897 	}
898 
899 	private static boolean
checkForSpecialSearchTerm( String str )900 	checkForSpecialSearchTerm(
901 		String		str )
902 	{
903 		str = str.trim();
904 
905 		String hit = UrlUtils.parseTextForURL( str, true, true );
906 
907 		if ( hit == null ){
908 
909 			try{
910 				File f = new File( str );
911 
912 				if ( f.isFile()){
913 
914 					String name = f.getName().toLowerCase();
915 
916 					if ( name.endsWith( ".torrent" ) || name.endsWith( ".vuze" )){
917 
918 						UIFunctionsSWT uif = UIFunctionsManagerSWT.getUIFunctionsSWT();
919 
920 						if ( uif != null ){
921 
922 			    			uif.openTorrentOpenOptions(
923 			    				null, null, new String[] { f.getAbsolutePath() },
924 			    				false, false);
925 
926 			    			return( true );
927 						}
928 					}
929 				}
930 			}catch( Throwable e ){
931 			}
932 
933 			return( false );
934 		}
935 
936 		try{
937 				// if it is just a trivial URL (no path/query) then most unlikely to refer to
938 				// a torrent file so just launch the URL
939 
940 			URL hit_url = new URL( hit );
941 
942 			URL url;
943 
944 			if ( hit_url.getProtocol().equals( "tor" )){
945 
946 				url = new URL( hit.substring( 4 ));
947 
948 			}else{
949 
950 				url = hit_url;
951 			}
952 
953 			String path = url.getPath();
954 
955 			if (( path.length() == 0 || path.equals( "/" )) && url.getQuery() == null ){
956 
957 				Utils.launch( hit_url.toExternalForm());
958 
959 				return( true );
960 			}
961 		}catch( Throwable e ){
962 		}
963 
964 		UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
965 
966 		new FileDownloadWindow( uiFunctions.getMainShell(), hit, null, null, true );
967 
968 		return( true );
969 	}
970 
971 
promptForSearch()972 	public void promptForSearch() {
973 		SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow("Button.search", "search.dialog.text");
974 		entryWindow.prompt(new UIInputReceiverListener() {
975 			public void UIInputReceiverClosed(UIInputReceiver receiver) {
976 				if (receiver.hasSubmittedInput()) {
977 					doSearch(receiver.getSubmittedInput());
978 				}
979 			}
980 		});
981 	}
982 
getMDI()983 	public MultipleDocumentInterface getMDI() {
984 		return (MultipleDocumentInterface) SkinViewManager.getByViewID(SkinConstants.VIEWID_MDI);
985 	}
986 
getMDISWT()987 	public MultipleDocumentInterfaceSWT getMDISWT() {
988 		return (MultipleDocumentInterfaceSWT) SkinViewManager.getByViewID(SkinConstants.VIEWID_MDI);
989 	}
990 
991 	/**
992 	 *
993 	 * @param keyPrefix
994 	 * @param details may not get displayed
995 	 * @param textParams
996 	 */
showErrorMessage(final String keyPrefix, final String details, final String[] textParams)997 	public void showErrorMessage(final String keyPrefix,
998 			final String details, final String[] textParams) {
999 		Utils.execSWTThread(new AERunnable() {
1000 			public void runSupport() {
1001 				Shell mainShell = getMainShell();
1002 				if (mainShell.getDisplay().getActiveShell() != null
1003 						|| mainShell.isFocusControl()) {
1004 					new MessageSlideShell(Display.getCurrent(), SWT.ICON_ERROR,
1005 							keyPrefix, details, textParams, -1);
1006 				} else {
1007 					MessageBoxShell mb = new MessageBoxShell(SWT.OK, keyPrefix,
1008 							textParams);
1009 					mb.open(null);
1010 				}
1011 			}
1012 		});
1013 	}
1014 
forceNotify(final int iconID, final String title, final String text, final String details, final Object[] relatedObjects, final int timeoutSecs)1015 	public void forceNotify(final int iconID, final String title, final String text,
1016 			final String details, final Object[] relatedObjects, final int timeoutSecs) {
1017 
1018 		Utils.execSWTThread(new AERunnable() {
1019 			public void runSupport() {
1020 				int swtIconID = SWT.ICON_INFORMATION;
1021 				switch (iconID) {
1022 					case STATUSICON_WARNING:
1023 						swtIconID = SWT.ICON_WARNING;
1024 						break;
1025 
1026 					case STATUSICON_ERROR:
1027 						swtIconID = SWT.ICON_ERROR;
1028 						break;
1029 				}
1030 
1031 				new MessageSlideShell(SWTThread.getInstance().getDisplay(), swtIconID,
1032 						title, text, details, relatedObjects, timeoutSecs);
1033 
1034 			}
1035 		});
1036 	}
1037 
1038 	public void
installPlugin( String plugin_id, String resource_prefix, actionListener listener )1039 	installPlugin(
1040 		String 				plugin_id,
1041 		String				resource_prefix,
1042 		actionListener		listener )
1043 	{
1044 		new SimplePluginInstaller( plugin_id, resource_prefix, listener );
1045 	}
1046 
getToolBarManager()1047 	public UIToolBarManager getToolBarManager() {
1048 		return UIToolBarManagerImpl.getInstance();
1049 	}
1050 
1051 	public void
runOnUIThread( final int ui_type, final Runnable runnable )1052 	runOnUIThread(
1053 		final int			ui_type,
1054 		final Runnable		runnable )
1055 	{
1056 		if ( ui_type == UIInstance.UIT_SWT ){
1057 
1058 			Utils.execSWTThread( runnable );
1059 
1060 		}else{
1061 
1062 			runnable.run();
1063 		}
1064 	}
1065 
1066 	public boolean
isProgramInstalled( String extension, String name )1067 	isProgramInstalled(
1068 		String extension,
1069 		String name )
1070 	{
1071 		if ( !extension.startsWith( "." )){
1072 
1073 			extension = "." + extension;
1074 		}
1075 
1076 		Program program = Program.findProgram( extension );
1077 
1078 		return( program == null ? false:(program.getName().toLowerCase(Locale.US).indexOf( name.toLowerCase(Locale.US)) != -1));
1079 	}
1080 
1081 	public void
openRemotePairingWindow()1082 	openRemotePairingWindow()
1083 	{
1084 		RemotePairingWindow.open();
1085 	}
1086 
1087 	public void
playOrStreamDataSource( Object ds, String referal, boolean launch_already_checked, boolean complete_only )1088 	playOrStreamDataSource(
1089 		Object 		ds,
1090 		String 		referal,
1091 		boolean 	launch_already_checked,
1092 		boolean 	complete_only )
1093 	{
1094 		TorrentListViewsUtils.playOrStreamDataSource( ds, referal, launch_already_checked, complete_only );
1095 	}
1096 
1097 	public void
setHideAll( boolean hidden )1098 	setHideAll(
1099 		boolean hidden )
1100 	{
1101 		mainWindow.setHideAll( hidden );
1102 	}
1103 
1104 	public boolean
addTorrentWithOptions( boolean force, TorrentOpenOptions torrentOptions)1105 	addTorrentWithOptions(
1106 		boolean 			force,
1107 		TorrentOpenOptions 	torrentOptions)
1108 	{
1109 		Map<String, Object> add_options = new HashMap<String, Object>();
1110 
1111 		add_options.put( UIFunctions.OTO_FORCE_OPEN, force );
1112 
1113 		return( addTorrentWithOptions( torrentOptions, add_options ));
1114 	}
1115 
1116 	public boolean
addTorrentWithOptions( final TorrentOpenOptions torrentOptions, Map<String, Object> addOptions )1117 	addTorrentWithOptions(
1118 		final TorrentOpenOptions 	torrentOptions,
1119 		Map<String, Object> 		addOptions )
1120 	{
1121 		Boolean is_silent = (Boolean)addOptions.get( UIFunctions.OTO_SILENT );
1122 
1123 		if ( is_silent == null ){
1124 
1125 			is_silent = UIFunctions.OTO_SILENT_DEFAULT;
1126 		}
1127 
1128 		if (AzureusCoreFactory.isCoreRunning()){
1129 
1130 			AzureusCore core = AzureusCoreFactory.getSingleton();
1131 
1132 			GlobalManager gm = core.getGlobalManager();
1133 
1134 				// Check if torrent already exists in gm, and add if not
1135 
1136 			TOTorrent torrent = torrentOptions.getTorrent();
1137 
1138 			DownloadManager existingDownload = gm.getDownloadManager( torrent );
1139 
1140 			if ( existingDownload != null ){
1141 
1142 				if ( !is_silent ){
1143 
1144 					final String fExistingName = existingDownload.getDisplayName();
1145 					final DownloadManager fExistingDownload = existingDownload;
1146 
1147 					fExistingDownload.fireGlobalManagerEvent(GlobalManagerEvent.ET_REQUEST_ATTENTION);
1148 
1149 					Utils.execSWTThread(new AERunnable() {
1150 						public void runSupport() {
1151 							boolean can_merge = TorrentUtils.canMergeAnnounceURLs(
1152 									torrentOptions.getTorrent(), fExistingDownload.getTorrent());
1153 
1154 							long	existed_for = SystemTime.getCurrentTime() - fExistingDownload.getCreationTime();
1155 
1156 							Shell mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
1157 
1158 							if ((Display.getDefault().getActiveShell() == null
1159 									|| !mainShell.isVisible() || mainShell.getMinimized())
1160 									&& (!can_merge)) {
1161 
1162 
1163 									// seems we're getting some double additions (linux user reported but could be a general issue) so
1164 									// don't warn if the matching download has been added recently
1165 
1166 								if ( existed_for > 15*1000 ){
1167 
1168 									new MessageSlideShell(Display.getCurrent(), SWT.ICON_INFORMATION,
1169 											MSG_ALREADY_EXISTS, null, new String[] {
1170 												":" + torrentOptions.sOriginatingLocation, // : prefix is deliberate to disable click on ref in message as might be an unwanted action
1171 												fExistingName,
1172 												MessageText.getString(MSG_ALREADY_EXISTS_NAME),
1173 											}, new Object[] {
1174 												fExistingDownload
1175 											}, -1);
1176 								}
1177 							} else {
1178 
1179 								if (can_merge) {
1180 
1181 									String text = MessageText.getString(MSG_ALREADY_EXISTS
1182 											+ ".text", new String[] {
1183 										":" + torrentOptions.sOriginatingLocation,
1184 										fExistingName,
1185 										MessageText.getString(MSG_ALREADY_EXISTS_NAME),
1186 									});
1187 
1188 									text += "\n\n"
1189 											+ MessageText.getString("openTorrentWindow.mb.alreadyExists.merge");
1190 
1191 									MessageBoxShell mb = new MessageBoxShell(SWT.YES | SWT.NO,
1192 											MessageText.getString(MSG_ALREADY_EXISTS + ".title"), text);
1193 
1194 									mb.open(new UserPrompterResultListener() {
1195 										public void prompterClosed(int result) {
1196 											if (result == SWT.YES) {
1197 
1198 												TorrentUtils.mergeAnnounceURLs(
1199 														torrentOptions.getTorrent(),
1200 														fExistingDownload.getTorrent());
1201 											}
1202 										}
1203 									});
1204 								} else {
1205 
1206 									if ( existed_for > 15*1000 ){
1207 
1208 										MessageBoxShell mb = new MessageBoxShell(SWT.OK,
1209 												MSG_ALREADY_EXISTS, new String[] {
1210 													":" + torrentOptions.sOriginatingLocation,
1211 													fExistingName,
1212 													MessageText.getString(MSG_ALREADY_EXISTS_NAME),
1213 												});
1214 										mb.open(null);
1215 									}
1216 								}
1217 							}
1218 						}
1219 					});
1220 				}
1221 
1222 				if ( torrentOptions.bDeleteFileOnCancel ){
1223 
1224 					File torrentFile = new File(torrentOptions.sFileName);
1225 
1226 					torrentFile.delete();
1227 				}
1228 
1229 				return( true );
1230 
1231 			}else{
1232 
1233 				try{
1234 					final DownloadStub archived = core.getPluginManager().getDefaultPluginInterface().getDownloadManager().lookupDownloadStub( torrent.getHash());
1235 
1236 					if ( archived != null ){
1237 
1238 						if ( is_silent ){
1239 
1240 								// restore it for them
1241 
1242 							archived.destubbify();
1243 
1244 							if ( torrentOptions.bDeleteFileOnCancel ){
1245 
1246 								File torrentFile = new File(torrentOptions.sFileName);
1247 
1248 								torrentFile.delete();
1249 							}
1250 
1251 							return( true );
1252 
1253 						}else{
1254 
1255 							Utils.execSWTThread(new AERunnable() {
1256 								public void runSupport() {
1257 
1258 									Shell mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
1259 
1260 									String existingName = archived.getName();
1261 
1262 									if (	Display.getDefault().getActiveShell() == null ||
1263 											!mainShell.isVisible() ||
1264 											mainShell.getMinimized()){
1265 
1266 										new MessageSlideShell(
1267 												Display.getCurrent(),
1268 												SWT.ICON_INFORMATION,
1269 												"OpenTorrentWindow.mb.inArchive", null,
1270 												new String[] {
1271 													existingName
1272 												},
1273 												new Object[0],
1274 												-1 );
1275 
1276 									}else{
1277 
1278 										MessageBoxShell mb =
1279 												new MessageBoxShell(
1280 													SWT.OK,
1281 													"OpenTorrentWindow.mb.inArchive",
1282 													new String[] {
1283 														existingName
1284 													});
1285 
1286 										mb.open(null);
1287 									}
1288 								}
1289 							});
1290 
1291 							return( true );
1292 						}
1293 
1294 					}
1295 				}catch( Throwable e ){
1296 					Debug.out( e );
1297 				}
1298 
1299 				if ( !is_silent ){
1300 
1301 					try{
1302 						DownloadHistoryManager dlm = (DownloadHistoryManager)core.getGlobalManager().getDownloadHistoryManager();
1303 
1304 						final long[] existing = dlm.getDates( torrentOptions.getTorrent().getHash());
1305 
1306 						if ( existing != null ){
1307 
1308 							long	redownloaded = existing[3];
1309 
1310 							if ( SystemTime.getCurrentTime() - redownloaded > 60*10*1000 ){
1311 
1312 								Utils.execSWTThread(new AERunnable() {
1313 									public void runSupport() {
1314 										Shell mainShell = UIFunctionsManagerSWT.getUIFunctionsSWT().getMainShell();
1315 
1316 										if ( mainShell != null && !mainShell.isDisposed()){
1317 
1318 											new MessageSlideShell(
1319 												mainShell.getDisplay(), SWT.ICON_INFORMATION,
1320 												"OpenTorrentWindow.mb.inHistory", null,
1321 												new String[] {
1322 														torrentOptions.getTorrentName(),
1323 														new SimpleDateFormat().format( new Date( existing[0] ))
1324 												},
1325 												new Object[] {
1326 
1327 												}, -1);
1328 										}
1329 									}
1330 								});
1331 							}
1332 						}
1333 					}catch( Throwable e ){
1334 
1335 						Debug.out( e );
1336 					}
1337 				}
1338 			}
1339 		}
1340 
1341 		Boolean force = (Boolean)addOptions.get( UIFunctions.OTO_FORCE_OPEN );
1342 
1343 		if ( force == null ){
1344 
1345 			force = UIFunctions.OTO_FORCE_OPEN_DEFAULT;
1346 		}
1347 
1348 		if ( !force ){
1349 
1350 			TOTorrent torrent = torrentOptions.getTorrent();
1351 
1352 			boolean is_featured = torrent != null && PlatformTorrentUtils.isFeaturedContent( torrent );
1353 
1354 			String showAgainMode = COConfigurationManager.getStringParameter(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS);
1355 
1356 			if ( 	is_featured ||
1357 					is_silent ||
1358 					(	showAgainMode != null && ((showAgainMode.equals(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_NEVER)) || (showAgainMode.equals(ConfigurationDefaults.CFG_TORRENTADD_OPENOPTIONS_MANY)
1359 							&& torrentOptions.getFiles() != null && torrentOptions.getFiles().length == 1)))){
1360 
1361 					// we're about to silently add the download - ensure that it is going to be saved somewhere vaguely sensible
1362 					// as the current save location is simply taken from the 'default download' config which can be blank (for example)
1363 
1364 				boolean	looks_good = false;
1365 
1366 				String save_loc = torrentOptions.getParentDir().trim();
1367 
1368 				if ( save_loc.length() == 0 ){
1369 
1370 						// blank :(
1371 
1372 				}else if ( save_loc.startsWith( "." )){
1373 
1374 						// relative to who knows where
1375 				}else{
1376 
1377 					File f = new File( save_loc );
1378 
1379 					if ( !f.exists()){
1380 
1381 						f.mkdirs();
1382 					}
1383 
1384 					if ( f.isDirectory() && FileUtil.canWriteToDirectory( f )){
1385 
1386 						if ( !f.equals(AETemporaryFileHandler.getTempDirectory())){
1387 
1388 							looks_good = true;
1389 						}
1390 					}
1391 				}
1392 
1393 				if ( looks_good ){
1394 
1395 					TorrentManagerImpl t_man = TorrentManagerImpl.getSingleton();
1396 
1397 					t_man.optionsAdded( torrentOptions );
1398 
1399 					t_man.optionsAccepted( torrentOptions );
1400 
1401 					boolean ok = TorrentOpener.addTorrent(torrentOptions);
1402 
1403 					t_man.optionsRemoved( torrentOptions );
1404 
1405 					return( ok );
1406 				}
1407 
1408 				torrentOptions.setParentDir( "" );
1409 
1410 				if ( is_silent ){
1411 
1412 					return( false );
1413 
1414 				}else{
1415 
1416 					MessageBoxShell mb =
1417 						new MessageBoxShell(
1418 							SWT.OK | SWT.ICON_ERROR,
1419 							"OpenTorrentWindow.mb.invaliddefsave",
1420 							new String[]{ save_loc });
1421 
1422 					mb.open(
1423 						new UserPrompterResultListener()
1424 						{
1425 							public void
1426 							prompterClosed(
1427 								int result)
1428 							{
1429 								OpenTorrentOptionsWindow.addTorrent( torrentOptions );
1430 							}
1431 						});
1432 				}
1433 
1434 				return( true );
1435 			}
1436 		}
1437 
1438 		if ( is_silent ){
1439 
1440 			return( false );
1441 
1442 		}else{
1443 
1444 			OpenTorrentOptionsWindow.addTorrent( torrentOptions );
1445 
1446 			return( true );
1447 		}
1448 	}
1449 
1450 	/* (non-Javadoc)
1451 	 * @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openTorrentOpenOptions(org.eclipse.swt.widgets.Shell, java.lang.String, java.lang.String[], boolean, boolean, boolean)
1452 	 */
openTorrentOpenOptions(Shell shell, String sPathOfFilesToOpen, String[] sFilesToOpen, boolean defaultToStopped, boolean forceOpen)1453 	public void openTorrentOpenOptions(Shell shell, String sPathOfFilesToOpen,
1454 			String[] sFilesToOpen, boolean defaultToStopped, boolean forceOpen) {
1455 
1456 		TorrentOpenOptions torrentOptions = new TorrentOpenOptions();
1457 		if (defaultToStopped) {
1458 			torrentOptions.setStartMode( TorrentOpenOptions.STARTMODE_STOPPED );
1459 		}
1460 		if (sFilesToOpen == null) {
1461 			new OpenTorrentWindow(shell);
1462 		} else {
1463 			// with no listener, Downloader will open options window if user configured
1464 			TorrentOpener.openTorrentsFromStrings(torrentOptions, shell,
1465 					sPathOfFilesToOpen, sFilesToOpen, null, null, forceOpen);
1466 		}
1467 	}
1468 
1469 	public void
openTorrentOpenOptions( Shell shell, String sPathOfFilesToOpen, String[] sFilesToOpen, Map<String,Object> options )1470 	openTorrentOpenOptions(
1471 		Shell 					shell,
1472 		String 					sPathOfFilesToOpen,
1473 		String[] 				sFilesToOpen,
1474 		Map<String,Object>		options )
1475 	{
1476 		Boolean _defaultToStopped 	= (Boolean)options.get( UIFunctions.OTO_DEFAULT_TO_STOPPED );
1477 		boolean	defaultToStopped	= _defaultToStopped!=null?_defaultToStopped:UIFunctions.OTO_DEFAULT_TO_STOPPED_DEFAULT;
1478 
1479 		Boolean _hideErrors		 	= (Boolean)options.get( UIFunctions.OTO_HIDE_ERRORS );
1480 		boolean	hideErrors			= _hideErrors!=null?_hideErrors:UIFunctions.OTO_HIDE_ERRORS_DEFAULT;
1481 
1482 		TorrentOpenOptions torrentOptions = new TorrentOpenOptions();
1483 		if (defaultToStopped) {
1484 			torrentOptions.setStartMode( TorrentOpenOptions.STARTMODE_STOPPED );
1485 		}
1486 		torrentOptions.setHideErrors( hideErrors );
1487 
1488 		if (sFilesToOpen == null) {
1489 			new OpenTorrentWindow(shell);
1490 		} else {
1491 			// with no listener, Downloader will open options window if user configured
1492 
1493 			Boolean _forceOpen 	= (Boolean)options.get( UIFunctions.OTO_FORCE_OPEN );
1494 			boolean	forceOpen	= _forceOpen!=null?_forceOpen:UIFunctions.OTO_FORCE_OPEN_DEFAULT;
1495 
1496 			TorrentOpener.openTorrentsFromStrings(
1497 					torrentOptions, shell,
1498 					sPathOfFilesToOpen, sFilesToOpen, null, null, forceOpen );
1499 		}
1500 	}
1501 
1502 	/* (non-Javadoc)
1503 	 * @see com.aelitis.azureus.ui.swt.UIFunctionsSWT#openTorrentWindow()
1504 	 */
openTorrentWindow()1505 	public void openTorrentWindow() {
1506 		new OpenTorrentWindow(Utils.findAnyShell());
1507 	}
1508 
1509 	// @see com.aelitis.azureus.ui.UIFunctions#showCreateTagDialog()
showCreateTagDialog(TagReturner tagReturner)1510 	public void showCreateTagDialog(TagReturner tagReturner) {
1511 		TagUIUtilsV3.showCreateTagDialog(tagReturner);
1512 	}
1513 
createTabbedMDI(Composite parent, String id)1514 	public TabbedMdiInterface createTabbedMDI(Composite parent, String id) {
1515 		return new TabbedMDI(parent, id);
1516 	}
1517 
adjustPXForDPI(int px)1518 	public int adjustPXForDPI(int px) {
1519 		return( Utils.adjustPXForDPI( px ));
1520 	}
1521 }
1522