1 /**
2  * Created on Jul 3, 2008
3  *
4  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  */
20 
21 package com.aelitis.azureus.ui.swt.views.skin;
22 
23 import java.util.Locale;
24 import java.util.Map;
25 
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.graphics.Image;
28 import org.eclipse.swt.layout.GridLayout;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Text;
31 import org.gudy.azureus2.core3.config.COConfigurationManager;
32 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
33 import org.gudy.azureus2.core3.download.DownloadManager;
34 import org.gudy.azureus2.core3.torrent.TOTorrent;
35 import org.gudy.azureus2.core3.torrent.TOTorrentFile;
36 import org.gudy.azureus2.core3.util.AERunnable;
37 import org.gudy.azureus2.core3.util.Debug;
38 import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener;
39 import org.gudy.azureus2.plugins.ui.tables.TableManager;
40 import org.gudy.azureus2.plugins.ui.tables.TableRow;
41 import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener;
42 import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem;
43 import org.gudy.azureus2.ui.swt.TorrentUtil;
44 import org.gudy.azureus2.ui.swt.Utils;
45 import org.gudy.azureus2.ui.swt.debug.ObfusticateImage;
46 import org.gudy.azureus2.ui.swt.plugins.UISWTInstance;
47 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent;
48 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
49 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewImpl;
50 import org.gudy.azureus2.ui.swt.views.MyTorrentsSuperView;
51 import org.gudy.azureus2.ui.swt.views.MyTorrentsView;
52 import org.gudy.azureus2.ui.swt.views.table.TableRowSWT;
53 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT;
54 import org.gudy.azureus2.ui.swt.views.table.utils.TableColumnCreator;
55 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils;
56 
57 import com.aelitis.azureus.core.AzureusCore;
58 import com.aelitis.azureus.core.AzureusCoreFactory;
59 import com.aelitis.azureus.core.AzureusCoreRunningListener;
60 import com.aelitis.azureus.core.torrent.PlatformTorrentUtils;
61 import com.aelitis.azureus.ui.UIFunctionsManager;
62 import com.aelitis.azureus.ui.common.ToolBarItem;
63 import com.aelitis.azureus.ui.common.table.TableColumnCore;
64 import com.aelitis.azureus.ui.common.table.TableRowCore;
65 import com.aelitis.azureus.ui.common.table.TableSelectionAdapter;
66 import com.aelitis.azureus.ui.common.table.impl.TableColumnManager;
67 import com.aelitis.azureus.ui.common.updater.UIUpdatable;
68 import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface;
69 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent;
70 import com.aelitis.azureus.ui.selectedcontent.ISelectedVuzeFileContent;
71 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager;
72 import com.aelitis.azureus.ui.swt.columns.utils.TableColumnCreatorV3;
73 import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
74 import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
75 import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectTextbox;
76 import com.aelitis.azureus.util.DLReferals;
77 import com.aelitis.azureus.util.DataSourceUtils;
78 import com.aelitis.azureus.util.PlayUtils;
79 
80 /**
81  * Classic My Torrents view wrapped in a SkinView
82  *
83  * @author TuxPaper
84  * @created Jul 3, 2008
85  *
86  */
87 public class SBC_LibraryTableView
88 	extends SkinView
89 	implements UIUpdatable, ObfusticateImage, UIPluginViewToolBarListener
90 {
91 	private final static String ID = "SBC_LibraryTableView";
92 
93 	private Composite viewComposite;
94 
95 	private TableViewSWT<?> tv;
96 
97 	protected int torrentFilterMode = SBC_LibraryView.TORRENTS_ALL;
98 
99 	private SWTSkinObject soParent;
100 
101 	private MyTorrentsView torrentView;
102 
103 	private UISWTViewEventListener swtViewListener;
104 
105 	private UISWTViewImpl view;
106 
skinObjectInitialShow(SWTSkinObject skinObject, Object params)107 	public Object skinObjectInitialShow(SWTSkinObject skinObject, Object params) {
108 		soParent = skinObject.getParent();
109 
110   	AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
111 			public void azureusCoreRunning(final AzureusCore core) {
112 				Utils.execSWTThread(new AERunnable() {
113 					public void runSupport() {
114 						if (soParent == null || soParent.isDisposed()) {
115 							return;
116 						}
117 						initShow(core);
118 					}
119 				});
120 			}
121   	});
122 
123 		return null;
124 	}
125 
initShow(AzureusCore core)126 	public void initShow(AzureusCore core) {
127 		Object data = soParent.getControl().getData("TorrentFilterMode");
128 		if (data instanceof Long) {
129 			torrentFilterMode = (int) ((Long) data).longValue();
130 		}
131 
132 		data = soParent.getControl().getData("DataSource");
133 
134 		boolean useBigTable = useBigTable();
135 
136 		SWTSkinObjectTextbox soFilter = (SWTSkinObjectTextbox) skin.getSkinObject(
137 				"library-filter", soParent.getParent());
138 		Text txtFilter = soFilter == null ? null : soFilter.getTextControl();
139 
140 		SWTSkinObjectContainer soCats = (SWTSkinObjectContainer) skin.getSkinObject(
141 				"library-categories", soParent.getParent());
142 		Composite cCats = soCats == null ? null : soCats.getComposite();
143 
144 		// columns not needed for small mode, all torrents
145 		TableColumnCore[] columns = useBigTable
146 				|| torrentFilterMode != SBC_LibraryView.TORRENTS_ALL ? getColumns()
147 				: null;
148 
149 		if (null != columns) {
150 			TableColumnManager tcManager = TableColumnManager.getInstance();
151 			tcManager.addColumns(columns);
152 		}
153 
154 		if (useBigTable) {
155 			if (torrentFilterMode == SBC_LibraryView.TORRENTS_COMPLETE
156 					|| torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE
157 					|| torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
158 
159 				swtViewListener = torrentView = new MyTorrentsView_Big(core, torrentFilterMode,
160 						columns, txtFilter, cCats);
161 
162 			} else {
163 				swtViewListener = torrentView = new MyTorrentsView_Big(core, torrentFilterMode,
164 						columns, txtFilter, cCats);
165 			}
166 
167 		} else {
168 			String tableID = SB_Transfers.getTableIdFromFilterMode(
169 					torrentFilterMode, false);
170 			if (torrentFilterMode == SBC_LibraryView.TORRENTS_COMPLETE) {
171 				swtViewListener = torrentView = new MyTorrentsView(core, tableID, true, columns, txtFilter,
172 						cCats,true);
173 
174 			} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE) {
175 				swtViewListener = torrentView = new MyTorrentsView(core, tableID, false, columns, txtFilter,
176 						cCats,true);
177 
178 			} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
179 				swtViewListener = torrentView = new MyTorrentsView(core, tableID, true, columns, txtFilter,
180 						cCats, true) {
181 					public boolean isOurDownloadManager(DownloadManager dm) {
182 						if (PlatformTorrentUtils.getHasBeenOpened(dm)) {
183 							return false;
184 						}
185 						return super.isOurDownloadManager(dm);
186 					}
187 				};
188 			} else {
189 				swtViewListener = new MyTorrentsSuperView(txtFilter, cCats) {
190 					public void initializeDone() {
191 						MyTorrentsView seedingview = getSeedingview();
192 						if (seedingview != null) {
193 							seedingview.overrideDefaultSelected(new TableSelectionAdapter() {
194 								public void defaultSelected(TableRowCore[] rows, int stateMask) {
195 									doDefaultClick(rows, stateMask, false);
196 								}
197 							});
198 							MyTorrentsView torrentview = getTorrentview();
199 							if (torrentview != null) {
200 								torrentview.overrideDefaultSelected(new TableSelectionAdapter() {
201 									public void defaultSelected(TableRowCore[] rows, int stateMask) {
202 										doDefaultClick(rows, stateMask, false);
203 									}
204 								});
205 							}
206 						}
207 					}
208 				};
209 			}
210 
211 			if (torrentView != null) {
212 				torrentView.overrideDefaultSelected(new TableSelectionAdapter() {
213 					public void defaultSelected(TableRowCore[] rows, int stateMask) {
214 						doDefaultClick(rows, stateMask, false);
215 					}
216 				});
217 			}
218 		}
219 
220 		if (torrentView != null) {
221 			tv = torrentView.getTableView();
222 			if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
223 				torrentView.setRebuildListOnFocusGain(true);
224 			}
225 		}
226 
227 		try {
228 			view = new UISWTViewImpl(ID + torrentFilterMode, UISWTInstance.VIEW_MAIN, false);
229 			view.setDatasource(data);
230 			view.setEventListener(swtViewListener, true);
231 		} catch (Exception e) {
232 			Debug.out(e);
233 		}
234 
235 		SWTSkinObjectContainer soContents = new SWTSkinObjectContainer(skin,
236 				skin.getSkinProperties(), getUpdateUIName(), "", soMain);
237 
238 		skin.layout();
239 
240 		viewComposite = soContents.getComposite();
241 		viewComposite.setLayoutData(Utils.getFilledFormData());
242 		GridLayout gridLayout = new GridLayout();
243 		gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginHeight = gridLayout.marginWidth = 0;
244 		viewComposite.setLayout(gridLayout);
245 
246 		view.initialize(viewComposite);
247 
248 
249 		SWTSkinObject soSizeSlider = skin.getSkinObject("table-size-slider", soParent.getParent());
250 		if (soSizeSlider instanceof SWTSkinObjectContainer) {
251 			SWTSkinObjectContainer so = (SWTSkinObjectContainer) soSizeSlider;
252 			if (tv != null && !tv.enableSizeSlider(so.getComposite(), 16, 100)) {
253 				so.setVisible(false);
254 			}
255 		}
256 
257 
258 		if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL
259 				&& tv != null) {
260 			tv.addRefreshListener(new TableRowRefreshListener() {
261 				public void rowRefresh(TableRow row) {
262 					TableRowSWT rowCore = (TableRowSWT)row;
263 					Object ds = rowCore.getDataSource(true);
264 					if (!(ds instanceof DownloadManager)) {
265 						return;
266 					}
267 					DownloadManager dm = (DownloadManager) ds;
268 					boolean changed = false;
269 					boolean assumedComplete = dm.getAssumedComplete();
270 					if (!assumedComplete) {
271 						changed |= rowCore.setAlpha(160);
272 					} else if (!PlatformTorrentUtils.getHasBeenOpened(dm)) {
273 						changed |= rowCore.setAlpha(255);
274 					} else {
275 						changed |= rowCore.setAlpha(255);
276 					}
277 				}
278 			});
279 		}
280 
281 		viewComposite.getParent().layout(true);
282 	}
283 
284 	public static void
doDefaultClick( final TableRowCore[] rows, final int stateMask, final boolean neverPlay)285 	doDefaultClick(
286 		final TableRowCore[] 	rows,
287 		final int 				stateMask,
288 		final boolean 			neverPlay)
289 	{
290 		if ( rows == null || rows.length != 1 ){
291 			return;
292 		}
293 
294 		final Object ds = rows[0].getDataSource(true);
295 
296 		boolean webInBrowser = COConfigurationManager.getBooleanParameter( "Library.LaunchWebsiteInBrowser" );
297 
298 		if ( webInBrowser ){
299 
300 			DiskManagerFileInfo fileInfo = DataSourceUtils.getFileInfo(ds);
301 
302 			if ( fileInfo != null ){
303 
304 				if ( ManagerUtils.browseWebsite( fileInfo )){
305 
306 					return;
307 				}
308 			}else{
309 
310 				DownloadManager dm = DataSourceUtils.getDM( ds);
311 
312 				if ( dm != null ){
313 
314 					if ( ManagerUtils.browseWebsite( dm )){
315 
316 						return;
317 					}
318 				}
319 			}
320 		}
321 
322 		String mode = COConfigurationManager.getStringParameter("list.dm.dblclick");
323 
324 		if (mode.equals("1")) {
325 
326 				// show detailed view
327 
328 			if ( UIFunctionsManager.getUIFunctions().getMDI().showEntryByID( MultipleDocumentInterface.SIDEBAR_SECTION_TORRENT_DETAILS, ds)){
329 
330 				return;
331 			}
332 		}else if (mode.equals("2")) {
333 
334 				// Show in explorer
335 
336 			boolean openMode = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled");
337 			DiskManagerFileInfo file = DataSourceUtils.getFileInfo(ds);
338 			if (file != null) {
339 				ManagerUtils.open(file, openMode);
340 				return;
341 			}
342 			DownloadManager dm = DataSourceUtils.getDM(ds);
343 			if (dm != null) {
344 				ManagerUtils.open(dm, openMode);
345 				return;
346 			}
347 		}else if (mode.equals("3") || mode.equals("4")){
348 
349 			// Launch
350 			DiskManagerFileInfo file = DataSourceUtils.getFileInfo(ds);
351 			if (file != null) {
352 				if (	mode.equals("4") &&
353 						file.getDownloaded() == file.getLength() &&
354 						Utils.isQuickViewSupported( file )){
355 
356 					Utils.setQuickViewActive( file, true );
357 				}else{
358 					TorrentUtil.runDataSources(new Object[]{ file });
359 				}
360 				return;
361 			}
362 			DownloadManager dm = DataSourceUtils.getDM(ds);
363 			if (dm != null) {
364 				TorrentUtil.runDataSources(new Object[]{ dm });
365 				return;
366 			}
367 		}else if (mode.equals("5")) {
368 			DiskManagerFileInfo fileInfo = DataSourceUtils.getFileInfo(ds);
369 			if ( fileInfo != null ){
370 				ManagerUtils.browse( fileInfo );
371 				return;
372 			}
373 			DownloadManager dm = DataSourceUtils.getDM(ds);
374 			if (dm != null) {
375 				ManagerUtils.browse( dm );
376 				return;
377 			}
378 		}
379 
380 		if (neverPlay) {
381 			return;
382 		}
383 
384 			// fallback
385 
386 		if (PlayUtils.canPlayDS(ds, -1,true) || (stateMask & SWT.CONTROL) != 0) {
387 			TorrentListViewsUtils.playOrStreamDataSource(ds,
388 					DLReferals.DL_REFERAL_DBLCLICK, false, true );
389 			return;
390 		}
391 
392 		if (PlayUtils.canStreamDS(ds, -1,true)) {
393 			TorrentListViewsUtils.playOrStreamDataSource(ds,
394 					DLReferals.DL_REFERAL_DBLCLICK, true, false );
395 			return;
396 		}
397 
398 		DownloadManager dm = DataSourceUtils.getDM(ds);
399 		DiskManagerFileInfo file = DataSourceUtils.getFileInfo(ds);
400 		TOTorrent torrent = DataSourceUtils.getTorrent(ds);
401 		if (torrent == null && file != null) {
402 			DownloadManager dmFile = file.getDownloadManager();
403 			if (dmFile != null) {
404 				torrent = dmFile.getTorrent();
405 			}
406 		}
407 		if (file != null && file.getDownloaded() == file.getLength()) {
408 			TorrentUtil.runDataSources(new Object[] { file });
409 		} else if (dm != null) {
410 			TorrentUtil.runDataSources(new Object[] { dm });
411 		}
412 	}
413 
414 	// @see com.aelitis.azureus.ui.swt.utils.UIUpdatable#getUpdateUIName()
getUpdateUIName()415 	public String getUpdateUIName() {
416 		return ID;
417 	}
418 
419 	// @see com.aelitis.azureus.ui.swt.utils.UIUpdatable#updateUI()
updateUI()420 	public void updateUI() {
421 		if (viewComposite == null || viewComposite.isDisposed()
422 				|| !viewComposite.isVisible() || view == null) {
423 			return;
424 		}
425 		view.triggerEvent(UISWTViewEvent.TYPE_REFRESH, null);
426 	}
427 
428 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectShown(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
skinObjectShown(SWTSkinObject skinObject, Object params)429 	public Object skinObjectShown(SWTSkinObject skinObject, Object params) {
430 		super.skinObjectShown(skinObject, params);
431 
432 		if (view != null) {
433 			view.triggerEvent(UISWTViewEvent.TYPE_FOCUSGAINED, null);
434 		}
435 
436 		Utils.execSWTThreadLater(0, new AERunnable() {
437 
438 			public void runSupport() {
439 				updateUI();
440 			}
441 		});
442 
443 		return null;
444 	}
445 
446 	// @see com.aelitis.azureus.ui.swt.views.skin.SkinView#skinObjectHidden(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
skinObjectHidden(SWTSkinObject skinObject, Object params)447 	public Object skinObjectHidden(SWTSkinObject skinObject, Object params) {
448 		if (view != null) {
449 			view.triggerEvent(UISWTViewEvent.TYPE_FOCUSLOST, null);
450 		}
451 
452 		return super.skinObjectHidden(skinObject, params);
453 	}
454 
455 	/* (non-Javadoc)
456 	 * @see org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener#refreshToolBarItems(java.util.Map)
457 	 */
refreshToolBarItems(Map<String, Long> list)458 	public void refreshToolBarItems(Map<String, Long> list) {
459 		if (!isVisible()) {
460 			return;
461 		}
462 		if (view != null) {
463 			view.refreshToolBarItems(list);
464 		}
465 		if (tv == null) {
466 			return;
467 		}
468 		ISelectedContent[] currentContent = SelectedContentManager.getCurrentlySelectedContent();
469 		boolean has1Selection = currentContent.length == 1;
470 		list.put(
471 				"play",
472 				has1Selection
473 						&& (!(currentContent[0] instanceof ISelectedVuzeFileContent))
474 						&& PlayUtils.canPlayDS(currentContent[0],
475 								currentContent[0].getFileIndex(),false)
476 						? UIToolBarItem.STATE_ENABLED : 0);
477 		list.put(
478 				"stream",
479 				has1Selection
480 						&& (!(currentContent[0] instanceof ISelectedVuzeFileContent))
481 						&& PlayUtils.canStreamDS(currentContent[0],
482 								currentContent[0].getFileIndex(),false)
483 						? UIToolBarItem.STATE_ENABLED : 0);
484 	}
485 
toolBarItemActivated(ToolBarItem item, long activationType, Object datasource)486 	public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) {
487 		// currently stream and play are handled by ToolbarView..
488 		if (isVisible() && view != null) {
489 			return view.toolBarItemActivated(item, activationType, datasource);
490 		}
491 		return false;
492 	}
493 
494 	/**
495 	 * Return either MODE_SMALLTABLE or MODE_BIGTABLE
496 	 * Subclasses may override
497 	 * @return
498 	 */
getTableMode()499 	protected int getTableMode() {
500 		return SBC_LibraryView.MODE_SMALLTABLE;
501 	}
502 
503 	/**
504 	 * Returns whether the big version of the tables should be used
505 	 * Subclasses may override
506 	 * @return
507 	 */
useBigTable()508 	protected boolean useBigTable() {
509 		return false;
510 	}
511 
512 	/**
513 	 * Returns the appropriate set of columns for the completed or incomplete torrents views
514 	 * Subclasses may override to return different sets of columns
515 	 * @return
516 	 */
getColumns()517 	protected TableColumnCore[] getColumns() {
518 		if (torrentFilterMode == SBC_LibraryView.TORRENTS_COMPLETE) {
519 			return TableColumnCreator.createCompleteDM(TableManager.TABLE_MYTORRENTS_COMPLETE);
520 		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_INCOMPLETE) {
521 			return TableColumnCreator.createIncompleteDM(TableManager.TABLE_MYTORRENTS_INCOMPLETE);
522 		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_UNOPENED) {
523 			return TableColumnCreatorV3.createUnopenedDM(
524 					TableManager.TABLE_MYTORRENTS_UNOPENED, false);
525 		} else if (torrentFilterMode == SBC_LibraryView.TORRENTS_ALL) {
526 			return TableColumnCreator.createCompleteDM(TableManager.TABLE_MYTORRENTS_ALL_BIG);
527 		}
528 
529 		return null;
530 	}
531 
532 	// @see com.aelitis.azureus.ui.swt.skin.SWTSkinObjectAdapter#skinObjectDestroyed(com.aelitis.azureus.ui.swt.skin.SWTSkinObject, java.lang.Object)
skinObjectDestroyed(SWTSkinObject skinObject, Object params)533 	public Object skinObjectDestroyed(SWTSkinObject skinObject, Object params) {
534 		if (view != null) {
535   		view.triggerEvent(UISWTViewEvent.TYPE_DESTROY, null);
536 		}
537 		return super.skinObjectDestroyed(skinObject, params);
538 	}
539 
540 	// @see org.gudy.azureus2.ui.swt.debug.ObfusticateImage#obfusticatedImage(org.eclipse.swt.graphics.Image, org.eclipse.swt.graphics.Point)
obfusticatedImage(Image image)541 	public Image obfusticatedImage(Image image) {
542 		if (view instanceof ObfusticateImage) {
543 			ObfusticateImage oi = (ObfusticateImage) view;
544 			return oi.obfusticatedImage(image);
545 		}
546 		return image;
547 	}
548 }
549