1 /* 2 * Created on 30 juin 2003 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 ( see the LICENSE file ). 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 org.gudy.azureus2.ui.swt.views; 22 23 import java.io.File; 24 import java.net.URL; 25 import java.util.*; 26 import java.util.List; 27 import java.util.regex.Pattern; 28 29 import org.eclipse.swt.SWT; 30 import org.eclipse.swt.dnd.*; 31 import org.eclipse.swt.events.*; 32 import org.eclipse.swt.graphics.*; 33 import org.eclipse.swt.layout.GridData; 34 import org.eclipse.swt.layout.GridLayout; 35 import org.eclipse.swt.layout.RowData; 36 import org.eclipse.swt.layout.RowLayout; 37 import org.eclipse.swt.widgets.*; 38 import org.gudy.azureus2.core3.category.Category; 39 import org.gudy.azureus2.core3.category.CategoryManager; 40 import org.gudy.azureus2.core3.config.COConfigurationManager; 41 import org.gudy.azureus2.core3.config.ParameterListener; 42 import org.gudy.azureus2.core3.disk.DiskManagerFileInfo; 43 import org.gudy.azureus2.core3.disk.DiskManagerFileInfoSet; 44 import org.gudy.azureus2.core3.download.DownloadManager; 45 import org.gudy.azureus2.core3.download.DownloadManagerListener; 46 import org.gudy.azureus2.core3.download.DownloadManagerState; 47 import org.gudy.azureus2.core3.download.DownloadManagerStats; 48 import org.gudy.azureus2.core3.global.GlobalManager; 49 import org.gudy.azureus2.core3.global.GlobalManagerEvent; 50 import org.gudy.azureus2.core3.global.GlobalManagerEventListener; 51 import org.gudy.azureus2.core3.global.GlobalManagerListener; 52 import org.gudy.azureus2.core3.internat.MessageText; 53 import org.gudy.azureus2.core3.logging.LogEvent; 54 import org.gudy.azureus2.core3.logging.LogIDs; 55 import org.gudy.azureus2.core3.logging.Logger; 56 import org.gudy.azureus2.core3.torrent.TOTorrent; 57 import org.gudy.azureus2.core3.torrent.TOTorrentAnnounceURLSet; 58 import org.gudy.azureus2.core3.torrent.TOTorrentException; 59 import org.gudy.azureus2.core3.util.*; 60 import org.gudy.azureus2.plugins.PluginInterface; 61 import org.gudy.azureus2.plugins.PluginManager; 62 import org.gudy.azureus2.plugins.download.Download; 63 import org.gudy.azureus2.plugins.download.DownloadTypeComplete; 64 import org.gudy.azureus2.plugins.download.DownloadTypeIncomplete; 65 import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener; 66 import org.gudy.azureus2.plugins.ui.tables.TableManager; 67 import org.gudy.azureus2.plugins.ui.tables.TableRow; 68 import org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener; 69 import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarActivationListener; 70 import org.gudy.azureus2.ui.swt.*; 71 import org.gudy.azureus2.ui.swt.URLTransfer; 72 import org.gudy.azureus2.ui.swt.components.CompositeMinSize; 73 import org.gudy.azureus2.ui.swt.help.HealthHelpWindow; 74 import org.gudy.azureus2.ui.swt.mainwindow.TorrentOpener; 75 import org.gudy.azureus2.ui.swt.minibar.DownloadBar; 76 import org.gudy.azureus2.ui.swt.plugins.UISWTInstance; 77 import org.gudy.azureus2.ui.swt.plugins.UISWTViewEvent; 78 import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore; 79 import org.gudy.azureus2.ui.swt.views.piece.PieceInfoView; 80 import org.gudy.azureus2.ui.swt.views.table.TableViewSWT; 81 import org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener; 82 import org.gudy.azureus2.ui.swt.views.table.TableViewSWTPanelCreator; 83 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewFactory; 84 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewSWT_TabsCommon; 85 import org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab; 86 import org.gudy.azureus2.ui.swt.views.table.painted.TableRowPainted; 87 import org.gudy.azureus2.ui.swt.views.utils.CategoryUIUtils; 88 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils; 89 import org.gudy.azureus2.ui.swt.views.utils.TagUIUtils; 90 91 import com.aelitis.azureus.core.AzureusCore; 92 import com.aelitis.azureus.core.AzureusCoreFactory; 93 import com.aelitis.azureus.core.tag.*; 94 import com.aelitis.azureus.core.util.RegExUtil; 95 import com.aelitis.azureus.ui.UIFunctions; 96 import com.aelitis.azureus.ui.UIFunctionsManager; 97 import com.aelitis.azureus.ui.common.ToolBarItem; 98 import com.aelitis.azureus.ui.common.table.*; 99 import com.aelitis.azureus.ui.common.table.impl.TableViewImpl; 100 import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface; 101 import com.aelitis.azureus.ui.selectedcontent.ISelectedContent; 102 import com.aelitis.azureus.ui.selectedcontent.SelectedContent; 103 import com.aelitis.azureus.ui.selectedcontent.SelectedContentManager; 104 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT; 105 import com.aelitis.azureus.ui.swt.UIFunctionsSWT; 106 import com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT; 107 108 /** Displays a list of torrents in a table view. 109 * 110 * @author Olivier 111 * @author TuxPaper 112 * 2004/Apr/18: Use TableRowImpl instead of PeerRow 113 * 2004/Apr/20: Remove need for tableItemToObject 114 * 2004/Apr/21: extends TableView instead of IAbstractView 115 * 2005/Oct/01: Column moving in SWT >= 3.1 116 */ 117 public class MyTorrentsView 118 extends TableViewTab<DownloadManager> 119 implements GlobalManagerListener, 120 ParameterListener, 121 DownloadManagerListener, 122 TagTypeListener, 123 TagListener, 124 KeyListener, 125 TableLifeCycleListener, 126 TableViewSWTPanelCreator, 127 TableSelectionListener, 128 TableViewSWTMenuFillListener, 129 TableRefreshListener, 130 TableViewFilterCheck.TableViewFilterCheckEx<DownloadManager>, 131 TableRowRefreshListener, 132 TableCountChangeListener, 133 TableExpansionChangeListener, 134 UIPluginViewToolBarListener 135 { 136 private static final LogIDs LOGID = LogIDs.GUI; 137 138 public static volatile Set<String> preferred_tracker_names; 139 public static volatile boolean eta_absolute; 140 public static volatile boolean progress_eta_absolute; 141 142 static{ COConfigurationManager.addAndFireParameterListeners( new String[]{ R, R, R, }, new ParameterListener() { public void parameterChanged( String name ) { String prefs = COConfigurationManager.getStringParameter( R, null ); Set<String> new_vals = new HashSet<String>(); if ( prefs != null ){ String[] bits = prefs.split( R ); for ( String s: bits ){ s = s.trim(); if ( s.length() > 0 ){ new_vals.add( s ); } } } preferred_tracker_names = new_vals; eta_absolute = COConfigurationManager.getBooleanParameter( R, false ); progress_eta_absolute = COConfigurationManager.getBooleanParameter( R, false ); } })143 COConfigurationManager.addAndFireParameterListeners( 144 new String[]{ 145 "mtv.trackername.pref.hosts", 146 "mtv.eta.show_absolute", 147 "mtv.progress_eta.show_absolute", 148 }, 149 new ParameterListener() 150 { 151 public void 152 parameterChanged( 153 String name ) 154 { 155 String prefs = COConfigurationManager.getStringParameter( "mtv.trackername.pref.hosts", null ); 156 157 Set<String> new_vals = new HashSet<String>(); 158 159 if ( prefs != null ){ 160 161 String[] bits = prefs.split( ";" ); 162 163 for ( String s: bits ){ 164 165 s = s.trim(); 166 167 if ( s.length() > 0 ){ 168 169 new_vals.add( s ); 170 } 171 } 172 } 173 174 preferred_tracker_names = new_vals; 175 176 eta_absolute = COConfigurationManager.getBooleanParameter( "mtv.eta.show_absolute", false ); 177 progress_eta_absolute = COConfigurationManager.getBooleanParameter( "mtv.progress_eta.show_absolute", false ); 178 } 179 }); 180 } 181 182 private AzureusCore azureus_core; 183 184 private GlobalManager globalManager; 185 186 // keep this listener separate class as there is confusion within the globalmanager 187 // if the same instance is registered as both a GlobalManagerListener and a GlobalManagerEventListener 188 // yes, I know 189 190 private GlobalManagerEventListener gm_event_listener = 191 new GlobalManagerEventListener() 192 { 193 public void 194 eventOccurred( 195 GlobalManagerEvent event ) 196 { 197 if ( event.getEventType() == GlobalManagerEvent.ET_REQUEST_ATTENTION ){ 198 199 DownloadManager dm = event.getDownload(); 200 201 if ( isOurDownloadManager( dm )){ 202 203 TableRowCore row = tv.getRow( dm ); 204 205 if ( row != null ){ 206 207 TableRowCore[] existing = tv.getSelectedRows(); 208 209 if ( existing != null ){ 210 211 for ( TableRowCore e: existing ){ 212 213 if ( e != row ){ 214 215 e.setSelected( false ); 216 } 217 } 218 } 219 220 if ( !row.isSelected()){ 221 222 row.setSelected( true ); 223 } 224 225 } 226 } 227 } 228 } 229 }; 230 231 private boolean supportsTabs; 232 private Composite cTablePanel; 233 private Font fontButton = null; 234 protected Composite cCategoriesAndTags; 235 private DragSource dragSource = null; 236 private DropTarget dropTarget = null; 237 protected Text txtFilter = null; 238 private Menu tableHeaderMenu = null; 239 private TimerEventPeriodic txtFilterUpdateEvent; 240 241 242 private Tag[] currentTags; 243 private List<Tag> allTags; 244 245 // table item index, where the drag has started 246 private int drag_drop_line_start = -1; 247 private TableRowCore[] drag_drop_rows = null; 248 249 private boolean bDNDalwaysIncomplete; 250 private TableViewSWT<DownloadManager> tv; 251 private Composite cTableParentPanel; 252 protected boolean viewActive; 253 private TableSelectionListener defaultSelectedListener; 254 255 private Composite filterParent; 256 257 protected boolean neverShowCatOrTagButtons; 258 259 private boolean rebuildListOnFocusGain = false; 260 261 private Menu oldMenu; 262 263 private boolean isCompletedOnly; 264 265 private Class<?> forDataSourceType; 266 267 private SelectionListener buttonSelectionListener; 268 269 private Listener buttonHoverListener; 270 271 private DropTargetListener buttonDropTargetListener; 272 273 protected boolean isEmptyListOnNullDS; 274 MyTorrentsView( boolean supportsTabs )275 public MyTorrentsView( boolean supportsTabs ) { 276 super("MyTorrentsView"); 277 this.supportsTabs = supportsTabs; 278 } 279 MyTorrentsView(String propertiesPrefix, boolean supportsTabs)280 public MyTorrentsView(String propertiesPrefix, boolean supportsTabs) { 281 super(propertiesPrefix); 282 this.supportsTabs = supportsTabs; 283 } 284 285 /** 286 * Initialize 287 * 288 * @param _azureus_core 289 * @param isSeedingView 290 * @param basicItems 291 * @param cCats 292 */ 293 public MyTorrentsView( AzureusCore _azureus_core, String tableID, boolean isSeedingView, TableColumnCore[] basicItems, Text txtFilter, Composite cCatsAndTags, boolean supportsTabs )294 MyTorrentsView( 295 AzureusCore _azureus_core, 296 String tableID, 297 boolean isSeedingView, 298 TableColumnCore[] basicItems, 299 Text txtFilter, 300 Composite cCatsAndTags, 301 boolean supportsTabs ) 302 { 303 super("MyTorrentsView"); 304 this.txtFilter = txtFilter; 305 this.cCategoriesAndTags = cCatsAndTags; 306 this.supportsTabs = supportsTabs; 307 init(_azureus_core, tableID, isSeedingView 308 ? DownloadTypeComplete.class : DownloadTypeIncomplete.class, basicItems); 309 } 310 311 // @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#initYourTableView() initYourTableView()312 public TableViewSWT<DownloadManager> initYourTableView() { 313 return tv; 314 } 315 316 // @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#tableViewTabInitComplete() tableViewTabInitComplete()317 public void tableViewTabInitComplete() { 318 if (COConfigurationManager.getBooleanParameter("Library.showFancyMenu", true)) { 319 Composite tableComposite = tv.getComposite(); 320 oldMenu = tableComposite.getMenu(); 321 Menu menu = new Menu(tableComposite); 322 tableComposite.setMenu(menu); 323 menu.addMenuListener(new MenuListener() { 324 325 public void menuShown(MenuEvent e) { 326 if (!showMyOwnMenu(e)) { 327 oldMenu.setVisible(true); 328 } 329 } 330 331 public void menuHidden(MenuEvent e) { 332 } 333 }); 334 } 335 super.tableViewTabInitComplete(); 336 } 337 showMyOwnMenu(MenuEvent e)338 protected boolean showMyOwnMenu(MenuEvent e) { 339 Display d = e.widget.getDisplay(); 340 if (d == null) 341 return false; 342 343 Object[] dataSources = tv.getSelectedDataSources(true); 344 final DownloadManager[] dms = getSelectedDownloads(); 345 346 boolean hasSelection = (dms.length > 0); 347 348 if (!hasSelection) { 349 return false; 350 } 351 Point pt = e.display.getCursorLocation(); 352 pt = tv.getTableComposite().toControl(pt.x, pt.y); 353 TableColumnCore column = tv.getTableColumnByOffset(pt.x); 354 355 boolean isSeedingView = Download.class.equals(forDataSourceType) || DownloadTypeComplete.class.equals(forDataSourceType); 356 new TorrentMenuFancy(tv, isSeedingView, getComposite().getShell(), dms, 357 tv.getTableID()).showMenu(column, oldMenu); 358 return true; 359 } 360 init(AzureusCore _azureus_core, String tableID, Class<?> forDataSourceType, TableColumnCore[] basicItems)361 public void init(AzureusCore _azureus_core, String tableID, 362 Class<?> forDataSourceType, TableColumnCore[] basicItems) { 363 364 this.forDataSourceType = forDataSourceType; 365 this.isCompletedOnly = forDataSourceType.equals(DownloadTypeComplete.class); 366 367 tv = createTableView(forDataSourceType, tableID, basicItems); 368 369 /* 370 * 'Big' table has taller row height 371 */ 372 if (getRowDefaultHeight() > 0) { 373 tv.setRowDefaultHeightPX(getRowDefaultHeight()); 374 } else { 375 tv.setRowDefaultHeightEM(1); 376 } 377 378 azureus_core = _azureus_core; 379 this.globalManager = azureus_core.getGlobalManager(); 380 381 382 if (currentTags == null) { 383 currentTags = new Tag[] { 384 CategoryManager.getCategory(Category.TYPE_ALL) 385 }; 386 } 387 tv.addLifeCycleListener(this); 388 tv.setMainPanelCreator(this); 389 tv.addSelectionListener(this, false); 390 tv.addMenuFillListener(this); 391 tv.addRefreshListener(this, false); 392 if (tv.canHaveSubItems()) { 393 tv.addRefreshListener(this); 394 tv.addCountChangeListener(this); 395 tv.addExpansionChangeListener(this); 396 } 397 398 tv.addTableDataSourceChangedListener(new TableDataSourceChangedListener() { 399 public void tableDataSourceChanged(Object newDataSource) { 400 if (newDataSource instanceof Tag[]) { 401 neverShowCatOrTagButtons = true; 402 setCurrentTags((Tag[]) newDataSource); 403 return; 404 } 405 406 if (newDataSource instanceof Object[]) { 407 Object[] datasources = ((Object[]) newDataSource); 408 Object firstDS = datasources.length > 0 ? datasources[0] : null; 409 if (firstDS instanceof Tag) { 410 Tag[] tags = new Tag[datasources.length]; 411 System.arraycopy(datasources, 0, tags, 0, datasources.length); 412 setCurrentTags(tags); 413 return; 414 } 415 } 416 417 if ( newDataSource instanceof Tag ){ 418 neverShowCatOrTagButtons = true; 419 setCurrentTags(new Tag[] { 420 (Tag) newDataSource 421 }); 422 } 423 424 if (newDataSource == null && isEmptyListOnNullDS) { 425 setCurrentTags(new Tag[] { }); 426 } 427 } 428 }, true); 429 430 if (txtFilter != null) { 431 filterParent = txtFilter.getParent(); 432 if (Constants.isWindows) { 433 // dirty hack because window's filter box is within a bubble of it's own 434 filterParent = filterParent.getParent(); 435 } 436 437 Menu menuFilterHeader = getHeaderMenu(txtFilter); 438 filterParent.setMenu( menuFilterHeader ); 439 Control[] children = filterParent.getChildren(); 440 for (Control control : children) { 441 if (control != txtFilter) { 442 control.setMenu(menuFilterHeader); 443 } 444 } 445 } 446 } 447 448 // @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewInitialized() tableViewInitialized()449 public void tableViewInitialized() { 450 tv.addKeyListener(this); 451 452 createTabs(); 453 454 if (txtFilter == null) { 455 tv.enableFilterCheck(null, this); 456 } 457 458 createDragDrop(); 459 460 Utils.getOffOfSWTThread(new AERunnable() { 461 462 public void runSupport() { 463 COConfigurationManager.addAndFireParameterListeners(new String[] { 464 "DND Always In Incomplete", 465 "User Mode", 466 "Library.ShowCatButtons", "Library.ShowTagButtons", "Library.ShowTagButtons.CompOnly", 467 }, MyTorrentsView.this); 468 469 470 if ( currentTags != null ){ 471 for (Tag tag : currentTags) { 472 tag.addTagListener(MyTorrentsView.this, false); 473 } 474 } 475 TagManager tagManager = TagManagerFactory.getTagManager(); 476 TagType ttManual = tagManager.getTagType(TagType.TT_DOWNLOAD_MANUAL); 477 TagType ttCat = tagManager.getTagType(TagType.TT_DOWNLOAD_CATEGORY); 478 ttManual.addTagTypeListener(MyTorrentsView.this, false); 479 ttCat.addTagTypeListener(MyTorrentsView.this, false); 480 481 globalManager.addListener(MyTorrentsView.this, false); 482 globalManager.addEventListener( gm_event_listener ); 483 DownloadManager[] dms = globalManager.getDownloadManagers().toArray(new DownloadManager[0]); 484 for (int i = 0; i < dms.length; i++) { 485 DownloadManager dm = dms[i]; 486 dm.addListener(MyTorrentsView.this); 487 if (!isOurDownloadManager(dm)) { 488 dms[i] = null; 489 } 490 } 491 tv.addDataSources(dms); 492 tv.processDataSourceQueue(); 493 } 494 }); 495 496 cTablePanel.layout(); 497 } 498 499 private Menu getHeaderMenu( Control control )500 getHeaderMenu( 501 Control control ) 502 { 503 if ( tableHeaderMenu != null ){ 504 505 return( tableHeaderMenu ); 506 } 507 508 tableHeaderMenu = new Menu(control.getShell(), SWT.POP_UP ); 509 510 // show uptime 511 512 final MenuItem menuItemShowUptime = new MenuItem(tableHeaderMenu, SWT.CHECK); 513 Messages.setLanguageText( menuItemShowUptime, "ConfigView.label.showuptime" ); 514 515 menuItemShowUptime.addSelectionListener(new SelectionAdapter() { 516 public void widgetSelected(SelectionEvent e) { 517 COConfigurationManager.setParameter( 518 "MyTorrentsView.showuptime", menuItemShowUptime.getSelection()); 519 } 520 }); 521 522 // selected download rates 523 524 final MenuItem menuItemShowRates = new MenuItem(tableHeaderMenu, SWT.CHECK); 525 Messages.setLanguageText( menuItemShowRates, "label.show.selected.rates" ); 526 527 menuItemShowRates.addSelectionListener(new SelectionAdapter() { 528 public void widgetSelected(SelectionEvent e) { 529 COConfigurationManager.setParameter( 530 "MyTorrentsView.showrates", menuItemShowRates.getSelection()); 531 } 532 }); 533 // show category buttons 534 535 final MenuItem menuItemShowCatBut = new MenuItem(tableHeaderMenu, SWT.CHECK); 536 Messages.setLanguageText( menuItemShowCatBut, "ConfigView.label.show.cat.but" ); 537 538 menuItemShowCatBut.addSelectionListener(new SelectionAdapter() { 539 public void widgetSelected(SelectionEvent e) { 540 COConfigurationManager.setParameter( 541 "Library.ShowCatButtons", menuItemShowCatBut.getSelection()); 542 } 543 }); 544 545 546 // show tag buttons 547 548 final MenuItem menuItemShowTagBut = new MenuItem(tableHeaderMenu, SWT.CHECK); 549 Messages.setLanguageText( menuItemShowTagBut, "ConfigView.label.show.tag.but" ); 550 551 menuItemShowTagBut.addSelectionListener(new SelectionAdapter() { 552 public void widgetSelected(SelectionEvent e) { 553 COConfigurationManager.setParameter( 554 "Library.ShowTagButtons", menuItemShowTagBut.getSelection()); 555 } 556 }); 557 558 new MenuItem( tableHeaderMenu, SWT.SEPARATOR ); 559 560 // enable simple views 561 562 String rr = MessageText.getString( "ConfigView.section.security.restart.title" ); 563 564 final MenuItem menuEnableSimple = new MenuItem(tableHeaderMenu, SWT.CHECK); 565 566 menuEnableSimple.setText( MessageText.getString( "ConfigView.section.style.EnableSimpleView" ) + " (" + rr + ")" ); 567 568 menuEnableSimple.addSelectionListener(new SelectionAdapter() { 569 public void widgetSelected(SelectionEvent e) { 570 COConfigurationManager.setParameter( 571 "Library.EnableSimpleView", menuEnableSimple.getSelection()); 572 } 573 }); 574 575 576 // hooks 577 578 tableHeaderMenu.addMenuListener(new MenuListener() { 579 public void menuShown(MenuEvent e) { 580 menuItemShowUptime.setSelection(COConfigurationManager.getBooleanParameter( "MyTorrentsView.showuptime" )); 581 menuItemShowRates.setSelection(COConfigurationManager.getBooleanParameter( "MyTorrentsView.showrates" )); 582 menuItemShowCatBut.setSelection(COConfigurationManager.getBooleanParameter( "Library.ShowCatButtons" )); 583 menuItemShowTagBut.setSelection(COConfigurationManager.getBooleanParameter( "Library.ShowTagButtons" )); 584 585 menuItemShowCatBut.setEnabled( !neverShowCatOrTagButtons ); 586 menuItemShowTagBut.setEnabled( !neverShowCatOrTagButtons ); 587 588 menuEnableSimple.setSelection(COConfigurationManager.getBooleanParameter( "Library.EnableSimpleView" )); 589 590 } 591 592 public void menuHidden(MenuEvent e) { 593 } 594 }); 595 596 return( tableHeaderMenu ); 597 } 598 599 // @see com.aelitis.azureus.ui.common.table.TableLifeCycleListener#tableViewDestroyed() tableViewDestroyed()600 public void tableViewDestroyed() { 601 tv.removeKeyListener(this); 602 603 Utils.execSWTThread(new AERunnable() { 604 public void runSupport() { 605 try { 606 Utils.disposeSWTObjects(new Object[] { 607 dragSource, 608 dropTarget, 609 fontButton, 610 tableHeaderMenu 611 }); 612 dragSource = null; 613 dropTarget = null; 614 fontButton = null; 615 tableHeaderMenu = null; 616 617 } catch (Exception e) { 618 Debug.out(e); 619 } 620 } 621 }); 622 Object[] dms = globalManager.getDownloadManagers().toArray(); 623 for (int i = 0; i < dms.length; i++) { 624 DownloadManager dm = (DownloadManager) dms[i]; 625 dm.removeListener(this); 626 } 627 628 if (currentTags != null) { 629 for (Tag tag : currentTags) { 630 tag.removeTagListener(this); 631 } 632 } 633 TagManager tagManager = TagManagerFactory.getTagManager(); 634 TagType ttManual = tagManager.getTagType(TagType.TT_DOWNLOAD_MANUAL); 635 TagType ttCat = tagManager.getTagType(TagType.TT_DOWNLOAD_CATEGORY); 636 ttManual.removeTagTypeListener(MyTorrentsView.this); 637 ttCat.removeTagTypeListener(MyTorrentsView.this); 638 639 globalManager.removeListener(this); 640 globalManager.removeEventListener( gm_event_listener ); 641 COConfigurationManager.removeParameterListener("DND Always In Incomplete", this); 642 COConfigurationManager.removeParameterListener("Library.ShowCatButtons", this); 643 COConfigurationManager.removeParameterListener("Library.ShowTagButtons", this); 644 COConfigurationManager.removeParameterListener("Library.ShowTagButtons.CompOnly", this); 645 } 646 647 648 // @see org.gudy.azureus2.ui.swt.views.table.TableViewSWTPanelCreator#createTableViewPanel(org.eclipse.swt.widgets.Composite) createTableViewPanel(Composite composite)649 public Composite createTableViewPanel(Composite composite) { 650 651 GridData gridData; 652 cTableParentPanel = new Composite(composite, SWT.NONE); 653 GridLayout layout = new GridLayout(); 654 layout.horizontalSpacing = 0; 655 layout.verticalSpacing = 0; 656 layout.marginHeight = 0; 657 layout.marginWidth = 0; 658 cTableParentPanel.setLayout(layout); 659 if (composite.getLayout() instanceof GridLayout) { 660 cTableParentPanel.setLayoutData(new GridData(GridData.FILL_BOTH)); 661 } 662 663 cTablePanel = new Composite(cTableParentPanel, SWT.NULL); 664 665 cTablePanel.addListener(SWT.Activate, new Listener() { 666 public void handleEvent(Event event) { 667 viewActive = true; 668 updateSelectedContent(); 669 //refreshIconBar(); 670 } 671 }); 672 cTablePanel.addListener(SWT.Deactivate, new Listener() { 673 public void handleEvent(Event event) { 674 viewActive = false; 675 // don't updateSelectedContent() because we may have switched 676 // to a button or a text field, and we still want out content to be 677 // selected 678 } 679 }); 680 681 gridData = new GridData(GridData.FILL_BOTH); 682 cTablePanel.setLayoutData(gridData); 683 684 layout = new GridLayout(1, false); 685 layout.marginHeight = 0; 686 layout.marginWidth = 0; 687 layout.verticalSpacing = 0; 688 layout.horizontalSpacing = 0; 689 cTablePanel.setLayout(layout); 690 691 cTablePanel.layout(); 692 return cTablePanel; 693 } 694 createTabs()695 private void createTabs() { 696 Utils.execSWTThread(new AERunnable() { 697 public void runSupport() { 698 swt_createTabs(); 699 } 700 }); 701 } 702 swt_createTabs()703 private void swt_createTabs() { 704 705 boolean catButtonsDisabled = neverShowCatOrTagButtons; 706 if ( !catButtonsDisabled){ 707 catButtonsDisabled = !COConfigurationManager.getBooleanParameter( "Library.ShowCatButtons" ); 708 } 709 710 List<Tag> tags_to_show = new ArrayList<Tag>(); 711 712 boolean tagButtonsDisabled = neverShowCatOrTagButtons; 713 if ( !tagButtonsDisabled){ 714 tagButtonsDisabled = !COConfigurationManager.getBooleanParameter( "Library.ShowTagButtons" ); 715 716 if ( !tagButtonsDisabled ){ 717 if ( !isCompletedOnly ){ 718 tagButtonsDisabled = COConfigurationManager.getBooleanParameter( "Library.ShowTagButtons.CompOnly" ); 719 } 720 } 721 } 722 723 if ( !tagButtonsDisabled ){ 724 ArrayList<Tag> tagsManual = new ArrayList<Tag>( 725 TagManagerFactory.getTagManager().getTagType( 726 TagType.TT_DOWNLOAD_MANUAL).getTags()); 727 for (Tag tag : tagsManual) { 728 if (tag.isVisible()) { 729 tags_to_show.add(tag); 730 } 731 } 732 } 733 734 if (!catButtonsDisabled) { 735 ArrayList<Tag> tagsCat = new ArrayList<Tag>( 736 TagManagerFactory.getTagManager().getTagType( 737 TagType.TT_DOWNLOAD_CATEGORY).getTags()); 738 for (Tag tag : tagsCat) { 739 if (tag.isVisible()) { 740 tags_to_show.add(tag); 741 } 742 } 743 744 } 745 746 tags_to_show = TagUIUtils.sortTags( tags_to_show ); 747 748 buildHeaderArea(); 749 if (cCategoriesAndTags != null && !cCategoriesAndTags.isDisposed()) { 750 Utils.disposeComposite(cCategoriesAndTags, false); 751 } 752 753 if (tags_to_show.size() > 0 ) { 754 buildCatAndTag(tags_to_show); 755 } else if (cTableParentPanel != null && !cTableParentPanel.isDisposed()) { 756 cTableParentPanel.layout(); 757 } 758 } 759 buildHeaderArea()760 private void buildHeaderArea() { 761 if (cCategoriesAndTags == null) { 762 cCategoriesAndTags = new CompositeMinSize(cTableParentPanel, SWT.NONE); 763 ((CompositeMinSize) cCategoriesAndTags).setMinSize(new Point(SWT.DEFAULT, 24)); 764 GridData gridData = new GridData(SWT.RIGHT, SWT.CENTER, true, false); 765 cCategoriesAndTags.setLayoutData(gridData); 766 cCategoriesAndTags.moveAbove(null); 767 768 if ( filterParent != null ){ 769 // inherit the background of the search filter - best that can be done to make things look ok 770 Color background = filterParent.getBackground(); 771 if ( background != null ){ 772 cCategoriesAndTags.setBackground( background ); 773 cTableParentPanel.setBackground( background ); 774 } 775 } 776 777 cCategoriesAndTags.setBackgroundMode(SWT.INHERIT_FORCE); 778 }else if ( cCategoriesAndTags.isDisposed()){ 779 return; 780 } 781 782 RowLayout rowLayout; 783 784 if (cCategoriesAndTags.getLayout() instanceof RowLayout){ 785 rowLayout = (RowLayout)cCategoriesAndTags.getLayout(); 786 }else{ 787 rowLayout = new RowLayout(); 788 cCategoriesAndTags.setLayout(rowLayout); 789 } 790 rowLayout.marginTop = 0; 791 rowLayout.marginBottom = 0; 792 rowLayout.marginLeft = Utils.adjustPXForDPI(3); 793 rowLayout.marginRight = Utils.adjustPXForDPI(3); 794 rowLayout.spacing = 0; 795 rowLayout.wrap = true; 796 797 798 Menu menu = getHeaderMenu(cTableParentPanel); 799 cTableParentPanel.setMenu( menu ); 800 801 if ( Constants.isOSX ){ 802 803 /* bug on OSX whereby the table is allowing menu-detect events to fire both on the table itself and the composite it 804 * sits on - this results in the header-area menu appearing after a menu appears for the table itself 805 * Doesn't happen on 10.6.8 but observed to happen on 10.9.4 806 */ 807 808 cTableParentPanel.addListener( 809 SWT.MenuDetect, 810 new Listener() { 811 812 public void 813 handleEvent( 814 Event event ) 815 { 816 Display display = cTableParentPanel.getDisplay(); 817 818 Point pp_rel = display.map( null, cTableParentPanel, event.x, event.y ); 819 820 Control hit = Utils.findChild(cTableParentPanel, pp_rel.x, pp_rel.y ); 821 822 event.doit = hit == cTableParentPanel; 823 } 824 }); 825 } 826 827 tv.enableFilterCheck(txtFilter, this); 828 } 829 830 /** 831 * 832 * 833 * @param categories 834 * @since 3.1.1.1 835 */ buildCatAndTag(List<Tag> tags)836 private void buildCatAndTag(List<Tag> tags) { 837 838 if (tags.size() == 0 || cCategoriesAndTags.isDisposed()){ 839 return; 840 } 841 842 int iFontPixelsHeight = Utils.adjustPXForDPI(10); 843 int iFontPointHeight = (iFontPixelsHeight * 72) / cCategoriesAndTags.getDisplay().getDPI().y; 844 845 Label spacer = null; 846 847 int max_rd_height = 0; 848 849 allTags = tags; 850 851 if (buttonSelectionListener == null) { 852 buttonSelectionListener = new SelectionAdapter() { 853 public void widgetSelected(SelectionEvent e) { 854 boolean add = (e.stateMask == SWT.MOD1); 855 856 Button curButton = (Button) e.widget; 857 boolean isEnabled = curButton.getSelection(); 858 859 Tag tag = (Tag) curButton.getData("Tag"); 860 861 if (!isEnabled) { 862 removeTagFromCurrent(tag); 863 } else { 864 if (add) { 865 Category catAll = CategoryManager.getCategory(Category.TYPE_ALL); 866 867 if (tag.equals(catAll)) { 868 setCurrentTags(new Tag[] { catAll }); 869 } else { 870 Tag[] newTags = new Tag[currentTags.length + 1]; 871 System.arraycopy(currentTags, 0, newTags, 0, currentTags.length); 872 newTags[currentTags.length] = tag; 873 874 newTags = (Tag[]) removeFromArray(newTags, catAll); 875 setCurrentTags(newTags); 876 } 877 } else { 878 setCurrentTags(new Tag[] { 879 (Tag) curButton.getData("Tag") 880 }); 881 } 882 } 883 884 Control[] controls = curButton.getParent().getChildren(); 885 for (int i = 0; i < controls.length; i++) { 886 if (!(controls[i] instanceof Button)) { 887 continue; 888 } 889 Button b = (Button) controls[i]; 890 Tag btag = (Tag) b.getData("Tag"); 891 b.setSelection(isCurrent(btag)); 892 } 893 } 894 }; 895 896 buttonHoverListener = new Listener() { 897 public void handleEvent(Event event) { 898 Button curButton = (Button) event.widget; 899 Tag tag = (Tag) curButton.getData("Tag"); 900 901 if (!(tag instanceof Category)) { 902 curButton.setToolTipText(TagUIUtils.getTagTooltip(tag, true)); 903 return; 904 } 905 906 Category category = (Category) tag; 907 908 List<DownloadManager> dms = category.getDownloadManagers( 909 globalManager.getDownloadManagers()); 910 911 long ttlActive = 0; 912 long ttlSize = 0; 913 long ttlRSpeed = 0; 914 long ttlSSpeed = 0; 915 int count = 0; 916 for (DownloadManager dm : dms) { 917 918 if (!category.hasTaggable(dm)) { 919 continue; 920 } 921 922 count++; 923 if (dm.getState() == DownloadManager.STATE_DOWNLOADING 924 || dm.getState() == DownloadManager.STATE_SEEDING) { 925 ttlActive++; 926 } 927 DownloadManagerStats stats = dm.getStats(); 928 ttlSize += stats.getSizeExcludingDND(); 929 ttlRSpeed += stats.getDataReceiveRate(); 930 ttlSSpeed += stats.getDataSendRate(); 931 } 932 933 String up_details = ""; 934 String down_details = ""; 935 936 if (category.getType() != Category.TYPE_ALL) { 937 938 String up_str = MessageText.getString( 939 "GeneralView.label.maxuploadspeed"); 940 String down_str = MessageText.getString( 941 "GeneralView.label.maxdownloadspeed"); 942 String unlimited_str = MessageText.getString( 943 "MyTorrentsView.menu.setSpeed.unlimited"); 944 945 int up_speed = category.getUploadSpeed(); 946 int down_speed = category.getDownloadSpeed(); 947 948 up_details = up_str + ": " + (up_speed == 0 ? unlimited_str 949 : DisplayFormatters.formatByteCountToKiBEtc(up_speed)); 950 down_details = down_str + ": " + (down_speed == 0 ? unlimited_str 951 : DisplayFormatters.formatByteCountToKiBEtc(down_speed)); 952 } 953 954 if (count == 0) { 955 curButton.setToolTipText( 956 down_details + "\n" + up_details + "\nTotal: 0"); 957 return; 958 } 959 960 curButton.setToolTipText((up_details.length() == 0 ? "" 961 : (down_details + "\n" + up_details + "\n")) + "Total: " + count 962 + "\n" + "Downloading/Seeding: " + ttlActive + "\n" + "\n" 963 + "Total Speed: " 964 + DisplayFormatters.formatByteCountToKiBEtcPerSec(ttlRSpeed) 965 + " / " 966 + DisplayFormatters.formatByteCountToKiBEtcPerSec(ttlSSpeed) 967 + "\n" + "Average Speed: " 968 + DisplayFormatters.formatByteCountToKiBEtcPerSec( 969 ttlRSpeed / (ttlActive == 0 ? 1 : ttlActive)) 970 + " / " 971 + DisplayFormatters.formatByteCountToKiBEtcPerSec( 972 ttlSSpeed / (ttlActive == 0 ? 1 : ttlActive)) 973 + "\n" + "Size: " 974 + DisplayFormatters.formatByteCountToKiBEtc(ttlSize)); 975 976 } 977 }; 978 979 buttonDropTargetListener = new DropTargetAdapter() { 980 public void dragOver(DropTargetEvent e) { 981 982 if (drag_drop_line_start >= 0) { 983 boolean doAdd = false; 984 985 Control curButton = ((DropTarget) e.widget).getControl(); 986 Tag tag = (Tag) curButton.getData("Tag"); 987 Object[] ds = tv.getSelectedDataSources().toArray(); 988 if (tag != null) { 989 for (Object obj : ds) { 990 991 if (obj instanceof DownloadManager) { 992 993 DownloadManager dm = (DownloadManager) obj; 994 995 if (!tag.hasTaggable(dm)) { 996 doAdd = true; 997 break; 998 } 999 } 1000 } 1001 } 1002 1003 e.detail = doAdd ? DND.DROP_COPY : DND.DROP_MOVE; 1004 1005 } else { 1006 e.detail = DND.DROP_NONE; 1007 } 1008 } 1009 1010 public void drop(DropTargetEvent e) { 1011 e.detail = DND.DROP_NONE; 1012 1013 if (drag_drop_line_start >= 0) { 1014 drag_drop_line_start = -1; 1015 drag_drop_rows = null; 1016 1017 Object[] ds = tv.getSelectedDataSources().toArray(); 1018 1019 Control curButton = ((DropTarget) e.widget).getControl(); 1020 1021 Tag tag = (Tag) curButton.getData("Tag"); 1022 1023 if (tag instanceof Category) { 1024 TorrentUtil.assignToCategory(ds, (Category) tag); 1025 return; 1026 } 1027 1028 boolean doAdd = false; 1029 for (Object obj : ds) { 1030 1031 if (obj instanceof DownloadManager) { 1032 1033 DownloadManager dm = (DownloadManager) obj; 1034 1035 if (!tag.hasTaggable(dm)) { 1036 doAdd = true; 1037 break; 1038 } 1039 } 1040 } 1041 1042 for (Object obj : ds) { 1043 1044 if (obj instanceof DownloadManager) { 1045 1046 DownloadManager dm = (DownloadManager) obj; 1047 1048 if (doAdd) { 1049 tag.addTaggable(dm); 1050 } else { 1051 tag.removeTaggable(dm); 1052 } 1053 } 1054 } 1055 } 1056 } 1057 }; 1058 } 1059 1060 for ( final Tag tag: tags ){ 1061 boolean isCat = (tag instanceof Category); 1062 1063 final Button button = new Button(cCategoriesAndTags, SWT.TOGGLE); 1064 1065 if (isCat) { 1066 if (spacer == null) { 1067 spacer = new Label(cCategoriesAndTags, SWT.NONE); 1068 RowData rd = new RowData(); 1069 rd.width = 8; 1070 spacer.setLayoutData(rd); 1071 spacer.moveAbove(null); 1072 } 1073 button.moveAbove(spacer); 1074 } 1075 1076 button.addKeyListener(this); 1077 if ( fontButton == null) { 1078 Font f = button.getFont(); 1079 FontData fd = f.getFontData()[0]; 1080 fd.setHeight(iFontPointHeight); 1081 fontButton = new Font(cCategoriesAndTags.getDisplay(), fd); 1082 } 1083 button.setText("|"); 1084 button.setFont(fontButton); 1085 button.pack(true); 1086 if (button.computeSize(100, SWT.DEFAULT).y > 0) { 1087 RowData rd = new RowData(); 1088 int rd_height = button.computeSize(100, SWT.DEFAULT).y - 2 + button.getBorderWidth() * 2; 1089 rd.height = rd_height; 1090 max_rd_height = Math.max( max_rd_height, rd_height ); 1091 button.setLayoutData(rd); 1092 } 1093 1094 String tag_name = tag.getTagName( true ); 1095 1096 button.setText(tag_name); 1097 1098 button.setData("Tag", tag); 1099 if (isCurrent(tag)) { 1100 button.setSelection(true); 1101 } 1102 1103 button.addSelectionListener(buttonSelectionListener); 1104 1105 1106 button.addListener(SWT.MouseHover, buttonHoverListener); 1107 1108 final DropTarget tabDropTarget = new DropTarget(button, 1109 DND.DROP_DEFAULT | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK); 1110 Transfer[] types = new Transfer[] { 1111 TextTransfer.getInstance() 1112 }; 1113 tabDropTarget.setTransfer(types); 1114 tabDropTarget.addDropListener(buttonDropTargetListener); 1115 1116 button.addDisposeListener(new DisposeListener() { 1117 public void widgetDisposed(DisposeEvent e) { 1118 if (!tabDropTarget.isDisposed()) { 1119 tabDropTarget.dispose(); 1120 } 1121 } 1122 }); 1123 1124 Menu menu = new Menu( button ); 1125 1126 button.setMenu( menu ); 1127 1128 if (isCat) { 1129 CategoryUIUtils.setupCategoryMenu(menu, (Category) tag); 1130 } else { 1131 TagUIUtils.createSideBarMenuItems(menu, tag); 1132 } 1133 } 1134 1135 if ( max_rd_height > 0 ){ 1136 RowLayout layout = (RowLayout)cCategoriesAndTags.getLayout(); 1137 int top_margin = ( 24 - max_rd_height + 1 )/2; 1138 if (top_margin > 0 ){ 1139 layout.marginTop = top_margin; 1140 } 1141 } 1142 1143 cCategoriesAndTags.getParent().layout(true, true); 1144 } 1145 isOurDownloadManager(DownloadManager dm)1146 public boolean isOurDownloadManager(DownloadManager dm) { 1147 if (!isInTags(dm, currentTags)) { 1148 return false; 1149 } 1150 1151 if (Download.class.equals(forDataSourceType)) { 1152 return true; 1153 } 1154 1155 boolean bCompleted = dm.isDownloadComplete(bDNDalwaysIncomplete); 1156 boolean bOurs = (bCompleted && isCompletedOnly) 1157 || (!bCompleted && !isCompletedOnly); 1158 1159 //System.out.println("ourDM? " + tv.getTableID() + "; " + dm.getDisplayName() 1160 // + "; Complete=" + bCompleted + ";Ours=" + bOurs + ";bc" 1161 // + dm.getStats().getDownloadCompleted(false) + ";" 1162 // + dm.getStats().getDownloadCompleted(true)); 1163 1164 return bOurs; 1165 } 1166 filterCheck(DownloadManager dm, String sLastSearch, boolean bRegexSearch)1167 public boolean filterCheck(DownloadManager dm, String sLastSearch, boolean bRegexSearch) { 1168 if ( dm == null ){ 1169 return( false ); 1170 } 1171 boolean bOurs; 1172 if (sLastSearch.length() > 0) { 1173 try { 1174 String comment = dm.getDownloadState().getUserComment(); 1175 if ( comment == null ){ 1176 comment = ""; 1177 } 1178 1179 String[][] name_mapping = { 1180 { 1181 "", 1182 dm.getDisplayName() 1183 }, 1184 { 1185 "t:", 1186 "", // defer (index = 1)this as costly dm.getTorrent().getAnnounceURL().getHost() 1187 }, 1188 { 1189 "st:", 1190 "" + dm.getState() 1191 }, 1192 { 1193 "c:", 1194 comment 1195 }, 1196 { 1197 "f:", 1198 "", //defer (index = 4) 1199 }, 1200 }; 1201 1202 Object o_name = name_mapping[0][1]; 1203 1204 String tmpSearch = sLastSearch; 1205 1206 for ( int i = 1; i < name_mapping.length; i++ ){ 1207 1208 if ( tmpSearch.startsWith(name_mapping[i][0])) { 1209 1210 tmpSearch = tmpSearch.substring(name_mapping[i][0].length()); 1211 1212 if ( i == 1 ){ 1213 1214 List<String> names = new ArrayList<String>(); 1215 1216 o_name = names; 1217 1218 TOTorrent t = dm.getTorrent(); 1219 1220 if ( t != null ){ 1221 1222 names.add( t.getAnnounceURL().getHost()); 1223 1224 TOTorrentAnnounceURLSet[] sets = t.getAnnounceURLGroup().getAnnounceURLSets(); 1225 1226 for ( TOTorrentAnnounceURLSet set: sets ){ 1227 1228 URL[] urls = set.getAnnounceURLs(); 1229 1230 for ( URL u: urls ){ 1231 1232 names.add( u.getHost()); 1233 } 1234 } 1235 1236 try{ 1237 byte[] hash = t.getHash(); 1238 1239 names.add( ByteFormatter.encodeString( hash )); 1240 names.add( Base32.encode( hash )); 1241 1242 }catch( Throwable e ){ 1243 1244 } 1245 } 1246 }else if ( i == 4 ){ 1247 1248 List<String> names = new ArrayList<String>(); 1249 1250 o_name = names; 1251 1252 DiskManagerFileInfoSet file_set = dm.getDiskManagerFileInfoSet(); 1253 1254 DiskManagerFileInfo[] files = file_set.getFiles(); 1255 1256 for ( DiskManagerFileInfo f: files ){ 1257 1258 File file = f.getFile(true); 1259 1260 String name = tmpSearch.contains( File.separator )?file.getAbsolutePath():file.getName(); 1261 1262 names.add( name ); 1263 } 1264 1265 }else{ 1266 o_name = name_mapping[i][1]; 1267 } 1268 } 1269 } 1270 1271 String s = bRegexSearch ? tmpSearch : "\\Q" 1272 + tmpSearch.replaceAll("[|;]", "\\\\E|\\\\Q") + "\\E"; 1273 1274 boolean match_result = true; 1275 1276 if ( bRegexSearch && s.startsWith( "!" )){ 1277 s = s.substring(1); 1278 1279 match_result = false; 1280 } 1281 1282 Pattern pattern = RegExUtil.getCachedPattern( "tv:search", s, Pattern.CASE_INSENSITIVE); 1283 1284 if ( o_name instanceof String ){ 1285 1286 bOurs = pattern.matcher((String)o_name).find() == match_result; 1287 1288 }else{ 1289 List<String> names = (List<String>)o_name; 1290 1291 // match_result: true -> at least one match; false -> any fail 1292 1293 bOurs = !match_result; 1294 1295 for ( String name: names ){ 1296 if ( pattern.matcher( name ).find()){ 1297 bOurs = match_result; 1298 break; 1299 } 1300 } 1301 } 1302 } catch (Exception e) { 1303 // Future: report PatternSyntaxException message to user. 1304 1305 bOurs = true; 1306 } 1307 }else{ 1308 1309 bOurs = true; 1310 } 1311 1312 return bOurs; 1313 } 1314 1315 // @see org.gudy.azureus2.ui.swt.views.table.TableViewFilterCheck#filterSet(java.lang.String) filterSet(final String filter)1316 public void filterSet(final String filter) { 1317 Utils.execSWTThread(new AERunnable() { 1318 1319 public void runSupport() { 1320 if (txtFilter != null) { 1321 Object x = filterParent.getData( "ViewUtils:ViewTitleExtraInfo" ); 1322 1323 if ( x instanceof ViewUtils.ViewTitleExtraInfo ){ 1324 1325 boolean enabled = filter.length() > 0; 1326 1327 if ( enabled ){ 1328 1329 if ( txtFilterUpdateEvent == null ){ 1330 1331 txtFilterUpdateEvent = 1332 SimpleTimer.addPeriodicEvent( 1333 "MTV:updater", 1334 1000, 1335 new TimerEventPerformer() 1336 { 1337 public void 1338 perform( 1339 TimerEvent event ) 1340 { 1341 Utils.execSWTThread( 1342 new AERunnable() 1343 { 1344 public void 1345 runSupport() 1346 { 1347 if ( txtFilterUpdateEvent != null ){ 1348 1349 if ( tv.isDisposed()){ 1350 1351 txtFilterUpdateEvent.cancel(); 1352 1353 txtFilterUpdateEvent = null; 1354 1355 }else{ 1356 1357 viewChanged( tv ); 1358 } 1359 } 1360 } 1361 }); 1362 } 1363 }); 1364 } 1365 }else{ 1366 1367 if ( txtFilterUpdateEvent != null ){ 1368 1369 txtFilterUpdateEvent.cancel(); 1370 1371 txtFilterUpdateEvent = null; 1372 } 1373 } 1374 1375 ((ViewUtils.ViewTitleExtraInfo)x).setEnabled( tv.getComposite(), enabled ); 1376 } 1377 } 1378 } 1379 }); 1380 } 1381 1382 public void viewChanged( final TableView<DownloadManager> view )1383 viewChanged( 1384 final TableView<DownloadManager> view ) 1385 { 1386 Utils.execSWTThread(new AERunnable() { 1387 public void runSupport() { 1388 swt_viewChanged(view); 1389 } 1390 }); 1391 } 1392 swt_viewChanged(final TableView<DownloadManager> view)1393 private void swt_viewChanged(final TableView<DownloadManager> view) { 1394 1395 if ( filterParent != null && !filterParent.isDisposed()){ 1396 Object x = filterParent.getData( "ViewUtils:ViewTitleExtraInfo" ); 1397 1398 if ( x instanceof ViewUtils.ViewTitleExtraInfo ){ 1399 1400 TableRowCore[] rows = view.getRows(); 1401 1402 int active = 0; 1403 1404 for ( TableRowCore row: rows ){ 1405 1406 DownloadManager dm = (DownloadManager)row.getDataSource( true ); 1407 1408 int state = dm.getState(); 1409 1410 if ( state == DownloadManager.STATE_DOWNLOADING || state == DownloadManager.STATE_SEEDING ){ 1411 1412 active++; 1413 } 1414 } 1415 1416 ((ViewUtils.ViewTitleExtraInfo)x).update( tv.getComposite(), rows.length, active ); 1417 } 1418 } 1419 } 1420 1421 // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#selected(com.aelitis.azureus.ui.common.table.TableRowCore[]) selected(TableRowCore[] rows)1422 public void selected(TableRowCore[] rows) { 1423 updateSelectedContent(); 1424 refreshTorrentMenu(); 1425 } 1426 1427 // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#deselected(com.aelitis.azureus.ui.common.table.TableRowCore[]) deselected(TableRowCore[] rows)1428 public void deselected(TableRowCore[] rows) { 1429 updateSelectedContent(); 1430 refreshTorrentMenu(); 1431 } 1432 1433 // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#focusChanged(com.aelitis.azureus.ui.common.table.TableRowCore) focusChanged(TableRowCore focus)1434 public void focusChanged(TableRowCore focus) { 1435 updateSelectedContent(); 1436 refreshTorrentMenu(); 1437 } 1438 1439 // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#mouseEnter(com.aelitis.azureus.ui.common.table.TableRowCore) mouseEnter(TableRowCore row)1440 public void mouseEnter(TableRowCore row) { 1441 } 1442 1443 // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#mouseExit(com.aelitis.azureus.ui.common.table.TableRowCore) mouseExit(TableRowCore row)1444 public void mouseExit(TableRowCore row) { 1445 } 1446 1447 private FrequencyLimitedDispatcher refresh_limiter = new FrequencyLimitedDispatcher( 1448 new AERunnable() { 1449 public void runSupport() { 1450 Utils.getOffOfSWTThread(new AERunnable() { 1451 public void runSupport() { 1452 updateSelectedContent(); 1453 } 1454 }); 1455 } 1456 }, 250 ); 1457 1458 { refresh_limiter.setSingleThreaded()1459 refresh_limiter.setSingleThreaded(); 1460 } 1461 1462 private void updateSelectedContentRateLimited()1463 updateSelectedContentRateLimited() 1464 { 1465 // we can get a lot of these in succession when lots of rows are selected and we, for example, right-click or stop the torrents etc 1466 1467 refresh_limiter.dispatch(); 1468 } 1469 updateSelectedContent()1470 public void updateSelectedContent() { 1471 updateSelectedContent( false ); 1472 } 1473 updateSelectedContent( boolean force )1474 public void updateSelectedContent( boolean force ) { 1475 if (cTablePanel == null || cTablePanel.isDisposed()) { 1476 return; 1477 } 1478 // if we're not active then ignore this update as we don't want invisible components 1479 // updating the toolbar with their invisible selection. Note that unfortunately the 1480 // call we get here when activating a view does't yet have focus 1481 1482 if ( !isTableFocus()){ 1483 if ( !force ){ 1484 return; 1485 } 1486 } 1487 Object[] dataSources = tv.getSelectedDataSources(true); 1488 List<SelectedContent> listSelected = new ArrayList<SelectedContent>(dataSources.length); 1489 for (Object ds : dataSources) { 1490 if (ds instanceof DownloadManager) { 1491 listSelected.add(new SelectedContent((DownloadManager) ds)); 1492 } else if (ds instanceof DiskManagerFileInfo) { 1493 DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds; 1494 listSelected.add(new SelectedContent(fileInfo.getDownloadManager(), fileInfo.getIndex())); 1495 } 1496 } 1497 SelectedContent[] content = listSelected.toArray(new SelectedContent[0]); 1498 SelectedContentManager.changeCurrentlySelectedContent(tv.getTableID(), content, tv); 1499 } 1500 refreshTorrentMenu()1501 private void refreshTorrentMenu() { 1502 UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions(); 1503 if (uiFunctions != null && uiFunctions instanceof UIFunctionsSWT) { 1504 ((UIFunctionsSWT)uiFunctions).refreshTorrentMenu(); 1505 } 1506 } 1507 getSelectedDownloads()1508 public DownloadManager[] getSelectedDownloads() { 1509 Object[] data_sources = tv.getSelectedDataSources().toArray(); 1510 List<DownloadManager> list = new ArrayList<DownloadManager>(); 1511 for (Object ds : data_sources) { 1512 if (ds instanceof DownloadManager) { 1513 list.add((DownloadManager) ds); 1514 } 1515 } 1516 return list.toArray(new DownloadManager[0]); 1517 } 1518 1519 // @see com.aelitis.azureus.ui.common.table.TableSelectionListener#defaultSelected(com.aelitis.azureus.ui.common.table.TableRowCore[]) defaultSelected(TableRowCore[] rows, int keyMask)1520 public void defaultSelected(TableRowCore[] rows, int keyMask) { 1521 if (defaultSelectedListener != null) { 1522 defaultSelectedListener.defaultSelected(rows, keyMask); 1523 return; 1524 } 1525 showSelectedDetails(); 1526 } 1527 showSelectedDetails()1528 private void showSelectedDetails() { 1529 Object[] dm_sources = tv.getSelectedDataSources().toArray(); 1530 UIFunctions uiFunctions = UIFunctionsManager.getUIFunctions(); 1531 for (int i = 0; i < dm_sources.length; i++) { 1532 if (!(dm_sources[i] instanceof DownloadManager)) { 1533 continue; 1534 } 1535 if (uiFunctions != null) { 1536 uiFunctions.getMDI().showEntryByID( 1537 MultipleDocumentInterface.SIDEBAR_SECTION_TORRENT_DETAILS, 1538 dm_sources[i]); 1539 } 1540 } 1541 } 1542 overrideDefaultSelected(TableSelectionListener defaultSelectedListener)1543 public void overrideDefaultSelected(TableSelectionListener defaultSelectedListener) { 1544 this.defaultSelectedListener = defaultSelectedListener; 1545 } 1546 1547 1548 1549 /* SubMenu for column specific tasks. 1550 */ 1551 // @see org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener#addThisColumnSubMenu(java.lang.String, org.eclipse.swt.widgets.Menu) addThisColumnSubMenu(String sColumnName, Menu menuThisColumn)1552 public void addThisColumnSubMenu(String sColumnName, Menu menuThisColumn) { 1553 if (sColumnName.equals("health")) { 1554 MenuItem item = new MenuItem(menuThisColumn, SWT.PUSH); 1555 Messages.setLanguageText(item, "MyTorrentsView.menu.health"); 1556 Utils.setMenuItemImage(item, "st_explain"); 1557 item.addListener(SWT.Selection, new Listener() { 1558 public void handleEvent(Event e) { 1559 HealthHelpWindow.show(Display.getDefault()); 1560 } 1561 }); 1562 1563 }else if (sColumnName.equals("trackername")) { 1564 MenuItem item = new MenuItem(menuThisColumn, SWT.PUSH); 1565 Messages.setLanguageText(item, "MyTorrentsView.menu.trackername.editprefs"); 1566 item.addListener(SWT.Selection, new Listener() { 1567 public void handleEvent(Event e) { 1568 SimpleTextEntryWindow entryWindow = new SimpleTextEntryWindow( 1569 "trackername.prefs.title", "trackername.prefs.message"); 1570 entryWindow.setPreenteredText( COConfigurationManager.getStringParameter( "mtv.trackername.pref.hosts", "" ), true ); 1571 entryWindow.selectPreenteredText( false ); 1572 entryWindow.prompt(); 1573 if (entryWindow.hasSubmittedInput()) { 1574 String text = entryWindow.getSubmittedInput(); 1575 1576 COConfigurationManager.setParameter( "mtv.trackername.pref.hosts", text.trim()); 1577 } 1578 } 1579 }); 1580 1581 }else if (sColumnName.equals("eta") || sColumnName.equals("smootheta")) { 1582 final MenuItem item = new MenuItem(menuThisColumn, SWT.CHECK ); 1583 Messages.setLanguageText(item, "MyTorrentsView.menu.eta.abs"); 1584 item.setSelection( eta_absolute ); 1585 1586 item.addListener(SWT.Selection, new Listener() { 1587 public void handleEvent(Event e) { 1588 eta_absolute = item.getSelection(); 1589 tv.columnInvalidate("eta"); 1590 tv.refreshTable(false); 1591 COConfigurationManager.setParameter( "mtv.eta.show_absolute", eta_absolute ); 1592 } 1593 }); 1594 }else if ( sColumnName.equals( "ProgressETA" )) { 1595 final MenuItem item = new MenuItem(menuThisColumn, SWT.CHECK ); 1596 Messages.setLanguageText(item, "MyTorrentsView.menu.eta.abs"); 1597 item.setSelection( progress_eta_absolute ); 1598 1599 item.addListener(SWT.Selection, new Listener() { 1600 public void handleEvent(Event e) { 1601 progress_eta_absolute = item.getSelection(); 1602 tv.columnInvalidate("ProgressETA"); 1603 tv.refreshTable(false); 1604 COConfigurationManager.setParameter( "mtv.progress_eta.show_absolute", progress_eta_absolute ); 1605 } 1606 }); 1607 } 1608 } 1609 1610 // @see org.gudy.azureus2.ui.swt.views.table.TableViewSWTMenuFillListener#fillMenu(java.lang.String, org.eclipse.swt.widgets.Menu) fillMenu(String sColumnName, final Menu menu)1611 public void fillMenu(String sColumnName, final Menu menu) { 1612 Object[] dataSources = tv.getSelectedDataSources(true); 1613 DownloadManager[] dms = getSelectedDownloads(); 1614 1615 if (dms.length == 0 && dataSources.length > 0) { 1616 List<DiskManagerFileInfo> listFileInfos = new ArrayList<DiskManagerFileInfo>(); 1617 DownloadManager firstFileDM = null; 1618 for (Object ds : dataSources) { 1619 if (ds instanceof DiskManagerFileInfo) { 1620 DiskManagerFileInfo info = (DiskManagerFileInfo) ds; 1621 // for now, FilesViewMenuUtil.fillmenu can only handle one DM 1622 if (firstFileDM != null && !firstFileDM.equals(info.getDownloadManager())) { 1623 break; 1624 } 1625 firstFileDM = info.getDownloadManager(); 1626 listFileInfos.add(info); 1627 } 1628 } 1629 if (listFileInfos.size() > 0) { 1630 FilesViewMenuUtil.fillMenu( 1631 tv, 1632 menu, 1633 new DownloadManager[]{ firstFileDM }, 1634 new DiskManagerFileInfo[][]{ listFileInfos.toArray(new DiskManagerFileInfo[0])}); 1635 return; 1636 } 1637 } 1638 1639 boolean hasSelection = (dms.length > 0); 1640 1641 if (hasSelection) { 1642 boolean isSeedingView = Download.class.equals(forDataSourceType) || DownloadTypeComplete.class.equals(forDataSourceType); 1643 TorrentUtil.fillTorrentMenu(menu, dms, azureus_core, cTablePanel, true, 1644 (isSeedingView) ? 2 : 1, tv); 1645 1646 // --- 1647 new MenuItem(menu, SWT.SEPARATOR); 1648 } 1649 } 1650 createDragDrop()1651 private void createDragDrop() { 1652 try { 1653 1654 Transfer[] types = new Transfer[] { TextTransfer.getInstance() }; 1655 1656 if (dragSource != null && !dragSource.isDisposed()) { 1657 dragSource.dispose(); 1658 } 1659 1660 if (dropTarget != null && !dropTarget.isDisposed()) { 1661 dropTarget.dispose(); 1662 } 1663 1664 dragSource = tv.createDragSource(DND.DROP_MOVE | DND.DROP_COPY); 1665 if (dragSource != null) { 1666 dragSource.setTransfer(types); 1667 dragSource.addDragListener(new DragSourceAdapter() { 1668 private String eventData; 1669 1670 public void dragStart(DragSourceEvent event) { 1671 TableRowCore[] rows = tv.getSelectedRows(); 1672 if (rows.length != 0) { 1673 event.doit = true; 1674 //System.out.println("DragStart"); 1675 drag_drop_line_start = rows[0].getIndex(); 1676 drag_drop_rows = rows; 1677 } else { 1678 event.doit = false; 1679 drag_drop_line_start = -1; 1680 drag_drop_rows = null; 1681 } 1682 1683 // Build eventData here because on OSX, selection gets cleared 1684 // by the time dragSetData occurs 1685 boolean onlyDMs = true; 1686 StringBuffer sb = new StringBuffer(); 1687 Object[] selectedDataSources = tv.getSelectedDataSources(true); 1688 for (Object ds : selectedDataSources) { 1689 if (ds instanceof DownloadManager) { 1690 DownloadManager dm = (DownloadManager) ds; 1691 TOTorrent torrent = dm.getTorrent(); 1692 if (torrent != null) { 1693 try { 1694 sb.append(torrent.getHashWrapper().toBase32String()); 1695 sb.append('\n'); 1696 } catch (TOTorrentException e) { 1697 } 1698 } 1699 } else if (ds instanceof DiskManagerFileInfo) { 1700 DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds; 1701 DownloadManager dm = fileInfo.getDownloadManager(); 1702 TOTorrent torrent = dm.getTorrent(); 1703 if (torrent != null) { 1704 try { 1705 sb.append(torrent.getHashWrapper().toBase32String()); 1706 sb.append(';'); 1707 sb.append(fileInfo.getIndex()); 1708 sb.append('\n'); 1709 onlyDMs = false; 1710 } catch (TOTorrentException e) { 1711 } 1712 } 1713 } 1714 } 1715 1716 eventData = (onlyDMs ? "DownloadManager\n" : "DiskManagerFileInfo\n") + sb.toString(); 1717 } 1718 1719 public void dragSetData(DragSourceEvent event) { 1720 // System.out.println("DragSetData"); 1721 event.data = eventData; 1722 } 1723 }); 1724 } 1725 1726 dropTarget = tv.createDropTarget(DND.DROP_DEFAULT | DND.DROP_MOVE 1727 | DND.DROP_COPY | DND.DROP_LINK | DND.DROP_TARGET_MOVE); 1728 if (dropTarget != null) { 1729 dropTarget.setTransfer(new Transfer[] { HTMLTransfer.getInstance(), 1730 URLTransfer.getInstance(), FileTransfer.getInstance(), 1731 TextTransfer.getInstance() }); 1732 1733 dropTarget.addDropListener(new DropTargetAdapter() { 1734 Point enterPoint = null; 1735 public void dropAccept(DropTargetEvent event) { 1736 event.currentDataType = URLTransfer.pickBestType(event.dataTypes, 1737 event.currentDataType); 1738 } 1739 1740 public void dragEnter(DropTargetEvent event) { 1741 // no event.data on dragOver, use drag_drop_line_start to determine 1742 // if ours 1743 if (drag_drop_line_start < 0) { 1744 if (event.detail != DND.DROP_COPY) { 1745 if ((event.operations & DND.DROP_LINK) > 0) 1746 event.detail = DND.DROP_LINK; 1747 else if ((event.operations & DND.DROP_COPY) > 0) 1748 event.detail = DND.DROP_COPY; 1749 } 1750 } else if (TextTransfer.getInstance().isSupportedType( 1751 event.currentDataType)) { 1752 event.detail = tv.getTableRowWithCursor() == null ? DND.DROP_NONE : DND.DROP_MOVE; 1753 event.feedback = DND.FEEDBACK_SCROLL; 1754 enterPoint = new Point(event.x, event.y); 1755 } 1756 } 1757 1758 // @see org.eclipse.swt.dnd.DropTargetAdapter#dragLeave(org.eclipse.swt.dnd.DropTargetEvent) 1759 public void dragLeave(DropTargetEvent event) { 1760 super.dragLeave(event); 1761 1762 tv.getComposite().redraw(); 1763 } 1764 1765 public void dragOver(DropTargetEvent event) { 1766 if (drag_drop_line_start >= 0) { 1767 if (drag_drop_rows.length > 0 1768 && !(drag_drop_rows[0].getDataSource(true) instanceof DownloadManager)) { 1769 event.detail = DND.DROP_NONE; 1770 return; 1771 } 1772 TableRowCore row = tv.getTableRowWithCursor(); 1773 if (row instanceof TableRowPainted) { 1774 boolean dragging_down = row.getIndex() > drag_drop_line_start; 1775 Rectangle bounds = ((TableRowPainted) row).getBounds(); 1776 tv.getComposite().redraw(); 1777 tv.getComposite().update(); 1778 GC gc = new GC(tv.getComposite()); 1779 gc.setLineWidth(2); 1780 int y_pos = bounds.y; 1781 if ( dragging_down ){ 1782 y_pos +=bounds.height; 1783 } 1784 gc.drawLine(bounds.x, y_pos, bounds.x + bounds.width, y_pos ); 1785 gc.dispose(); 1786 } 1787 event.detail = row == null ? DND.DROP_NONE : DND.DROP_MOVE; 1788 event.feedback = DND.FEEDBACK_SCROLL 1789 | ((enterPoint != null && enterPoint.y > event.y) 1790 ? DND.FEEDBACK_INSERT_BEFORE : DND.FEEDBACK_INSERT_AFTER); 1791 } 1792 } 1793 1794 public void drop(DropTargetEvent event) { 1795 if (!(event.data instanceof String)) { 1796 TorrentOpener.openDroppedTorrents(event, true); 1797 return; 1798 } 1799 String data = (String) event.data; 1800 if (data.startsWith("DiskManagerFileInfo\n")) { 1801 return; 1802 } 1803 if (!data.startsWith("DownloadManager\n")) { 1804 TorrentOpener.openDroppedTorrents(event, true); 1805 return; 1806 } 1807 1808 event.detail = DND.DROP_NONE; 1809 // Torrent file from shell dropped 1810 if (drag_drop_line_start >= 0) { // event.data == null 1811 event.detail = DND.DROP_NONE; 1812 TableRowCore row = tv.getRow(event); 1813 if (row == null) 1814 return; 1815 if (row.getParentRowCore() != null) { 1816 row = row.getParentRowCore(); 1817 } 1818 int drag_drop_line_end = row.getIndex(); 1819 if (drag_drop_line_end != drag_drop_line_start) { 1820 DownloadManager dm = (DownloadManager) row.getDataSource(true); 1821 moveRowsTo(drag_drop_rows, dm.getPosition()); 1822 event.detail = DND.DROP_MOVE; 1823 } 1824 drag_drop_line_start = -1; 1825 drag_drop_rows = null; 1826 } 1827 } 1828 }); 1829 } 1830 1831 } catch (Throwable t) { 1832 Logger.log(new LogEvent(LOGID, "failed to init drag-n-drop", t)); 1833 } 1834 } 1835 moveRowsTo(TableRowCore[] rows, int iNewPos)1836 private void moveRowsTo(TableRowCore[] rows, int iNewPos) { 1837 if (rows == null || rows.length == 0) { 1838 return; 1839 } 1840 1841 TableColumnCore sortColumn = tv.getSortColumn(); 1842 boolean isSortAscending = sortColumn == null ? true 1843 : sortColumn.isSortAscending(); 1844 1845 for (int i = 0; i < rows.length; i++) { 1846 TableRowCore row = rows[i]; 1847 Object ds = row.getDataSource(true); 1848 if (!(ds instanceof DownloadManager)) { 1849 continue; 1850 } 1851 DownloadManager dm = (DownloadManager) ds; 1852 int iOldPos = dm.getPosition(); 1853 globalManager.moveTo(dm, iNewPos); 1854 if (isSortAscending) { 1855 if (iOldPos > iNewPos) 1856 iNewPos++; 1857 } else { 1858 if (iOldPos < iNewPos) 1859 iNewPos--; 1860 } 1861 } 1862 1863 boolean bForceSort = sortColumn == null ? false : sortColumn.getName().equals("#"); 1864 tv.columnInvalidate("#"); 1865 tv.refreshTable(bForceSort); 1866 } 1867 1868 // @see com.aelitis.azureus.ui.common.table.TableRefreshListener#tableRefresh() tableRefresh()1869 public void tableRefresh() { 1870 if (tv.isDisposed()) 1871 return; 1872 1873 refreshTorrentMenu(); 1874 } 1875 1876 1877 // @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) keyPressed(KeyEvent e)1878 public void keyPressed(KeyEvent e) { 1879 viewActive = true; 1880 int key = e.character; 1881 if (key <= 26 && key > 0) 1882 key += 'a' - 1; 1883 1884 if (e.stateMask == (SWT.CTRL | SWT.SHIFT)) { 1885 // CTRL+SHIFT+S stop all Torrents 1886 if (key == 's') { 1887 ManagerUtils.asyncStopAll(); 1888 e.doit = false; 1889 return; 1890 } 1891 1892 // Can't capture Ctrl-PGUP/DOWN for moving up/down in chunks 1893 // (because those keys move through tabs), so use shift-ctrl-up/down 1894 if (e.keyCode == SWT.ARROW_DOWN) { 1895 moveSelectedTorrents(10); 1896 e.doit = false; 1897 return; 1898 } 1899 1900 if (e.keyCode == SWT.ARROW_UP) { 1901 moveSelectedTorrents(-10); 1902 e.doit = false; 1903 return; 1904 } 1905 } 1906 1907 if (e.stateMask == SWT.MOD1) { 1908 switch (key) { 1909 case 'a': // CTRL+A select all Torrents 1910 if (e.widget != txtFilter) { 1911 tv.selectAll(); 1912 e.doit = false; 1913 } 1914 break; 1915 case 'c': // CTRL+C 1916 if (e.widget != txtFilter) { 1917 tv.clipboardSelected(); 1918 e.doit = false; 1919 } 1920 break; 1921 case 'i': // CTRL+I Info/Details 1922 showSelectedDetails(); 1923 e.doit = false; 1924 break; 1925 } 1926 1927 if (!e.doit) 1928 return; 1929 } 1930 1931 if (e.stateMask == SWT.CTRL) { 1932 switch (e.keyCode) { 1933 case SWT.ARROW_UP: 1934 moveSelectedTorrentsUp(); 1935 e.doit = false; 1936 break; 1937 case SWT.ARROW_DOWN: 1938 moveSelectedTorrentsDown(); 1939 e.doit = false; 1940 break; 1941 case SWT.HOME: 1942 moveSelectedTorrentsTop(); 1943 e.doit = false; 1944 break; 1945 case SWT.END: 1946 moveSelectedTorrentsEnd(); 1947 e.doit = false; 1948 break; 1949 } 1950 if (!e.doit) 1951 return; 1952 1953 switch (key) { 1954 case 'r': // CTRL+R resume/start selected Torrents 1955 TorrentUtil.resumeTorrents(tv.getSelectedDataSources().toArray()); 1956 e.doit = false; 1957 break; 1958 case 's': // CTRL+S stop selected Torrents 1959 Utils.getOffOfSWTThread(new AERunnable() { 1960 public void runSupport() { 1961 TorrentUtil.stopDataSources(tv.getSelectedDataSources().toArray()); 1962 } 1963 }); 1964 e.doit = false; 1965 break; 1966 } 1967 1968 if (!e.doit) 1969 return; 1970 } 1971 1972 if (e.keyCode == SWT.F2 && (e.stateMask & SWT.MODIFIER_MASK) == 0) { 1973 FilesViewMenuUtil.rename(tv, tv.getSelectedDataSources(true), true, false); 1974 e.doit = false; 1975 return; 1976 } 1977 1978 1979 // DEL remove selected Torrents 1980 if (e.stateMask == 0 && e.keyCode == SWT.DEL && e.widget != txtFilter) { 1981 Utils.getOffOfSWTThread(new AERunnable() { 1982 public void runSupport() { 1983 TorrentUtil.removeDataSources(tv.getSelectedDataSources().toArray()); 1984 } 1985 }); 1986 e.doit = false; 1987 return; 1988 } 1989 1990 if (e.keyCode != SWT.BS) { 1991 if ((e.stateMask & (~SWT.SHIFT)) != 0 || e.character < 32) 1992 return; 1993 } 1994 } 1995 keyReleased(KeyEvent e)1996 public void keyReleased(KeyEvent e) { 1997 // ignore 1998 } 1999 2000 2001 2002 2003 moveSelectedTorrentsDown()2004 private void moveSelectedTorrentsDown() { 2005 // Don't use runForSelectDataSources to ensure the order we want 2006 DownloadManager[] dms = getSelectedDownloads(); 2007 Arrays.sort(dms, new Comparator<DownloadManager>() { 2008 public int compare(DownloadManager a, DownloadManager b) { 2009 return a.getPosition() - b.getPosition(); 2010 } 2011 }); 2012 for (int i = dms.length - 1; i >= 0; i--) { 2013 DownloadManager dm = dms[i]; 2014 if (dm.getGlobalManager().isMoveableDown(dm)) { 2015 dm.getGlobalManager().moveDown(dm); 2016 } 2017 } 2018 2019 boolean bForceSort = tv.getSortColumn().getName().equals("#"); 2020 tv.columnInvalidate("#"); 2021 tv.refreshTable(bForceSort); 2022 } 2023 moveSelectedTorrentsUp()2024 private void moveSelectedTorrentsUp() { 2025 // Don't use runForSelectDataSources to ensure the order we want 2026 DownloadManager[] dms = getSelectedDownloads(); 2027 Arrays.sort(dms, new Comparator<DownloadManager>() { 2028 public int compare(DownloadManager a, DownloadManager b) { 2029 return a.getPosition() - b.getPosition(); 2030 } 2031 }); 2032 for (int i = 0; i < dms.length; i++) { 2033 DownloadManager dm = dms[i]; 2034 if (dm.getGlobalManager().isMoveableUp(dm)) { 2035 dm.getGlobalManager().moveUp(dm); 2036 } 2037 } 2038 2039 boolean bForceSort = tv.getSortColumn().getName().equals("#"); 2040 tv.columnInvalidate("#"); 2041 tv.refreshTable(bForceSort); 2042 } 2043 moveSelectedTorrents(int by)2044 private void moveSelectedTorrents(int by) { 2045 // Don't use runForSelectDataSources to ensure the order we want 2046 DownloadManager[] dms = getSelectedDownloads(); 2047 if (dms.length <= 0) 2048 return; 2049 2050 int[] newPositions = new int[dms.length]; 2051 2052 if (by < 0) { 2053 Arrays.sort(dms, new Comparator<DownloadManager>() { 2054 public int compare(DownloadManager a, DownloadManager b) { 2055 return a.getPosition() - b.getPosition(); 2056 } 2057 }); 2058 } else { 2059 Arrays.sort(dms, new Comparator<DownloadManager>() { 2060 public int compare(DownloadManager a, DownloadManager b) { 2061 return b.getPosition() - a.getPosition(); 2062 } 2063 }); 2064 } 2065 2066 for (int i = 0; i < dms.length; i++) { 2067 DownloadManager dm = dms[i]; 2068 boolean complete = dm.isDownloadComplete(false); 2069 int count = globalManager.downloadManagerCount(complete); 2070 int pos = dm.getPosition() + by; 2071 if (pos < i + 1) 2072 pos = i + 1; 2073 else if (pos > count - i) 2074 pos = count - i; 2075 2076 newPositions[i] = pos; 2077 } 2078 2079 for (int i = 0; i < dms.length; i++) { 2080 DownloadManager dm = dms[i]; 2081 globalManager.moveTo(dm, newPositions[i]); 2082 } 2083 2084 boolean bForceSort = tv.getSortColumn().getName().equals("#"); 2085 tv.columnInvalidate("#"); 2086 tv.refreshTable(bForceSort); 2087 } 2088 moveSelectedTorrentsTop()2089 private void moveSelectedTorrentsTop() { 2090 moveSelectedTorrentsTopOrEnd(true); 2091 } 2092 moveSelectedTorrentsEnd()2093 private void moveSelectedTorrentsEnd() { 2094 moveSelectedTorrentsTopOrEnd(false); 2095 } 2096 moveSelectedTorrentsTopOrEnd(boolean moveToTop)2097 private void moveSelectedTorrentsTopOrEnd(boolean moveToTop) { 2098 DownloadManager[] dms = getSelectedDownloads(); 2099 if (dms.length == 0) 2100 return; 2101 2102 if(moveToTop) 2103 globalManager.moveTop(dms); 2104 else 2105 globalManager.moveEnd(dms); 2106 2107 boolean bForceSort = tv.getSortColumn().getName().equals("#"); 2108 if (bForceSort) { 2109 tv.columnInvalidate("#"); 2110 tv.refreshTable(bForceSort); 2111 } 2112 } 2113 2114 /** 2115 * @param parameterName the name of the parameter that has changed 2116 * @see org.gudy.azureus2.core3.config.ParameterListener#parameterChanged(java.lang.String) 2117 */ parameterChanged(String parameterName)2118 public void parameterChanged(String parameterName) { 2119 if (parameterName == null || parameterName.equals("DND Always In Incomplete")) { 2120 bDNDalwaysIncomplete = COConfigurationManager.getBooleanParameter("DND Always In Incomplete"); 2121 } 2122 2123 if (parameterName != null && 2124 ( parameterName.equals("Library.ShowCatButtons") || 2125 parameterName.equals("Library.ShowTagButtons" ) || 2126 parameterName.equals("Library.ShowTagButtons.CompOnly" ))){ 2127 2128 createTabs(); 2129 } 2130 } 2131 getActiveView()2132 private MdiEntrySWT getActiveView() { 2133 TableViewSWT_TabsCommon tabsCommon = tv.getTabsCommon(); 2134 if (tabsCommon != null) { 2135 return tabsCommon.getActiveSubView(); 2136 } 2137 return null; 2138 } 2139 refreshToolBarItems(Map<String, Long> list)2140 public void refreshToolBarItems(Map<String, Long> list) { 2141 ISelectedContent[] datasource = SelectedContentManager.getCurrentlySelectedContent(); 2142 2143 if (!isTableFocus()) { 2144 UISWTViewCore active_view = getActiveView(); 2145 if (active_view != null) { 2146 UIPluginViewToolBarListener l = active_view.getToolBarListener(); 2147 if (l != null) { 2148 Map<String, Long> activeViewList = new HashMap<String, Long>(); 2149 l.refreshToolBarItems(activeViewList); 2150 if (activeViewList.size() > 0) { 2151 list.putAll(activeViewList); 2152 return; 2153 } 2154 } 2155 } 2156 } 2157 } 2158 toolBarItemActivated(ToolBarItem item, long activationType, Object datasource)2159 public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) { 2160 boolean isTableSelected = false; 2161 if (tv instanceof TableViewImpl) { 2162 isTableSelected = ((TableViewImpl) tv).isTableSelected(); 2163 } 2164 if (!isTableSelected) { 2165 UISWTViewCore active_view = getActiveView(); 2166 if (active_view != null) { 2167 UIPluginViewToolBarListener l = active_view.getToolBarListener(); 2168 if (l != null && l.toolBarItemActivated(item, activationType, datasource)) { 2169 return true; 2170 } 2171 } 2172 return false; 2173 } 2174 2175 String itemKey = item.getID(); 2176 if (activationType == UIToolBarActivationListener.ACTIVATIONTYPE_HELD) { 2177 if(itemKey.equals("up")) { 2178 moveSelectedTorrentsTop(); 2179 return true; 2180 } 2181 if(itemKey.equals("down")){ 2182 moveSelectedTorrentsEnd(); 2183 return true; 2184 } 2185 return false; 2186 } 2187 2188 if (activationType != UIToolBarActivationListener.ACTIVATIONTYPE_NORMAL) { 2189 return false; 2190 } 2191 if(itemKey.equals("top")) { 2192 moveSelectedTorrentsTop(); 2193 return true; 2194 } 2195 if(itemKey.equals("bottom")){ 2196 moveSelectedTorrentsEnd(); 2197 return true; 2198 } 2199 if(itemKey.equals("up")) { 2200 moveSelectedTorrentsUp(); 2201 return true; 2202 } 2203 if(itemKey.equals("down")){ 2204 moveSelectedTorrentsDown(); 2205 return true; 2206 } 2207 if(itemKey.equals("run")){ 2208 TorrentUtil.runDataSources(tv.getSelectedDataSources().toArray()); 2209 return true; 2210 } 2211 if(itemKey.equals("start")){ 2212 TorrentUtil.queueDataSources(tv.getSelectedDataSources().toArray(), true); 2213 return true; 2214 } 2215 if(itemKey.equals("stop")){ 2216 TorrentUtil.stopDataSources(tv.getSelectedDataSources().toArray()); 2217 return true; 2218 } 2219 if (itemKey.equals("startstop")) { 2220 TorrentUtil.stopOrStartDataSources(tv.getSelectedDataSources().toArray()); 2221 return true; 2222 } 2223 if(itemKey.equals("remove")){ 2224 TorrentUtil.removeDataSources(tv.getSelectedDataSources().toArray()); 2225 return true; 2226 } 2227 return false; 2228 } 2229 2230 // DownloadManagerListener Functions stateChanged(DownloadManager manager, int state)2231 public void stateChanged(DownloadManager manager, int state) { 2232 final TableRowCore row = tv.getRow(manager); 2233 if (row != null) { 2234 Utils.getOffOfSWTThread(new AERunnable() { 2235 public void runSupport() { 2236 row.refresh(true); 2237 if (row.isSelected()) { 2238 updateSelectedContentRateLimited(); 2239 } 2240 } 2241 }); 2242 } 2243 } 2244 2245 // DownloadManagerListener positionChanged(DownloadManager download, int oldPosition, int newPosition)2246 public void positionChanged(DownloadManager download, int oldPosition, int newPosition) { 2247 if (isOurDownloadManager(download)) { 2248 Utils.execSWTThreadLater(0, new AERunnable() { 2249 public void runSupport() { 2250 updateSelectedContent(); 2251 } 2252 }); 2253 } 2254 } 2255 2256 // DownloadManagerListener filePriorityChanged(DownloadManager download, DiskManagerFileInfo file)2257 public void filePriorityChanged(DownloadManager download, 2258 DiskManagerFileInfo file) { 2259 } 2260 2261 // DownloadManagerListener completionChanged(DownloadManager manager, boolean bCompleted)2262 public void completionChanged(DownloadManager manager, boolean bCompleted) { 2263 // manager has moved lists 2264 2265 if (isOurDownloadManager(manager)) { 2266 tv.addDataSource(manager); 2267 } else { 2268 2269 tv.removeDataSource(manager); 2270 } 2271 } 2272 2273 // DownloadManagerListener downloadComplete(DownloadManager manager)2274 public void downloadComplete(DownloadManager manager) { 2275 } 2276 2277 2278 public void tagTypeChanged( TagType tag_type )2279 tagTypeChanged( 2280 TagType tag_type ) 2281 { 2282 } 2283 2284 public void tagAdded( Tag tag )2285 tagAdded( 2286 Tag tag ) 2287 { 2288 createTabs(); 2289 } 2290 2291 private Set<Tag> pending_tag_changes = new HashSet<Tag>(); 2292 2293 private boolean currentTagsAny = true; 2294 2295 public void tagChanged( Tag tag )2296 tagChanged( 2297 Tag tag ) 2298 { 2299 // we can get a lot of hits here, limit tab rebuilds somewhat 2300 2301 synchronized( pending_tag_changes ){ 2302 2303 pending_tag_changes.add( tag ); 2304 } 2305 2306 Utils.execSWTThread(new AERunnable() { 2307 @Override 2308 public void runSupport() { 2309 2310 if ( allTags != null ){ 2311 2312 boolean create_tabs = false; 2313 2314 synchronized( pending_tag_changes ){ 2315 2316 for ( Tag t: pending_tag_changes ){ 2317 2318 boolean should_be_visible = t.isVisible(); 2319 boolean is_visible = allTags.contains( t ); 2320 2321 if ( should_be_visible != is_visible ){ 2322 2323 create_tabs = true; 2324 2325 break; 2326 } 2327 } 2328 2329 pending_tag_changes.clear(); 2330 } 2331 2332 if ( create_tabs ){ 2333 2334 createTabs(); 2335 } 2336 } 2337 } 2338 }); 2339 } 2340 2341 public void tagRemoved( Tag tag )2342 tagRemoved( 2343 Tag tag ) 2344 { 2345 if (currentTags == null) { 2346 return; 2347 } 2348 2349 removeTagFromCurrent(tag); 2350 createTabs(); 2351 } 2352 2353 removeTagFromCurrent(Tag tag)2354 private void removeTagFromCurrent(Tag tag) { 2355 boolean found = false; 2356 for (int i = 0; i < currentTags.length; i++) { 2357 Tag curTag = currentTags[i]; 2358 if (curTag.equals(tag)) { 2359 Tag[] tags; 2360 if (currentTags.length == 1) { 2361 tags = new Tag[] { 2362 CategoryManager.getCategory(Category.TYPE_ALL) 2363 }; 2364 } else { 2365 tags = new Tag[currentTags.length - 1]; 2366 if (i > 0) { 2367 System.arraycopy(currentTags, 0, tags, 0, i); 2368 } 2369 if (tags.length - i > 0) { 2370 System.arraycopy(currentTags, i + 1, tags, 0, tags.length - i); 2371 } 2372 } 2373 2374 setCurrentTags(tags); 2375 found = true; 2376 break; 2377 } 2378 } 2379 2380 if (!found) { 2381 // always activate as deletion of this one might have 2382 // affected the current view 2383 setCurrentTags(currentTags); 2384 } 2385 } 2386 removeFromArray(Object[] array, Object o)2387 private Object[] removeFromArray(Object[] array, Object o) { 2388 for (int i = 0; i < array.length; i++) { 2389 Object cur = array[i]; 2390 if (cur.equals(o)) { 2391 Tag[] newArray = new Tag[array.length - 1]; 2392 if (i > 0) { 2393 System.arraycopy(array, 0, newArray, 0, i); 2394 } 2395 if (newArray.length - i > 0) { 2396 System.arraycopy(array, i + 1, newArray, 0, newArray.length - i); 2397 } 2398 2399 return newArray; 2400 } 2401 } 2402 2403 return array; 2404 } 2405 2406 // tags 2407 getCurrentTags()2408 protected Tag[] getCurrentTags() { 2409 return currentTags; 2410 } 2411 setCurrentTags(Tag[] tags)2412 protected void setCurrentTags(Tag[] tags) { 2413 if (currentTags != null) { 2414 for (Tag tag : currentTags) { 2415 tag.removeTagListener(this); 2416 } 2417 } 2418 2419 currentTags = tags; 2420 if (currentTags != null) { 2421 Set<Tag> to_remove = null; 2422 for (Tag tag : currentTags) { 2423 if ( tag.getTaggableTypes() != Taggable.TT_DOWNLOAD ){ 2424 // hmm, not a download related tag (e.g. peer-set), remove from the set. We can get this in the 2425 // TagsOverview 'torrents' sub-view when peer-sets are selected in the main tag table 2426 if ( to_remove == null ){ 2427 to_remove = new HashSet<Tag>(); 2428 } 2429 to_remove.add( tag ); 2430 }else{ 2431 tag.addTagListener(this, false); 2432 } 2433 } 2434 if ( to_remove != null ){ 2435 Tag[] updated_tags = new Tag[currentTags.length-to_remove.size()]; 2436 2437 int pos = 0; 2438 for (Tag tag : currentTags) { 2439 if ( !to_remove.contains( tag )){ 2440 updated_tags[pos++] = tag; 2441 } 2442 } 2443 currentTags = updated_tags; 2444 } 2445 } 2446 2447 tv.processDataSourceQueue(); 2448 Object[] managers = globalManager.getDownloadManagers().toArray(); 2449 List<DownloadManager> listRemoves = new ArrayList<DownloadManager>(); 2450 List<DownloadManager> listAdds = new ArrayList<DownloadManager>(); 2451 2452 for (int i = 0; i < managers.length; i++) { 2453 DownloadManager dm = (DownloadManager) managers[i]; 2454 2455 boolean bHave = tv.isUnfilteredDataSourceAdded(dm); 2456 if (!isOurDownloadManager(dm)) { 2457 if (bHave) { 2458 listRemoves.add(dm); 2459 } 2460 } else { 2461 if (!bHave) { 2462 listAdds.add(dm); 2463 } 2464 } 2465 } 2466 tv.removeDataSources(listRemoves.toArray(new DownloadManager[0])); 2467 tv.addDataSources(listAdds.toArray(new DownloadManager[0])); 2468 2469 tv.processDataSourceQueue(); 2470 //tv.refreshTable(false); 2471 } 2472 2473 private boolean isInTags( DownloadManager manager, Tag[] tags )2474 isInTags( 2475 DownloadManager manager, 2476 Tag[] tags ) 2477 { 2478 if ( tags == null ){ 2479 return true; 2480 } 2481 2482 if (currentTagsAny) { 2483 for (Tag tag : tags) { 2484 if (tag.hasTaggable(manager)) { 2485 return true; 2486 } 2487 } 2488 return false; 2489 } else { 2490 for (Tag tag : tags) { 2491 if (!tag.hasTaggable(manager)) { 2492 return false; 2493 } 2494 } 2495 return true; 2496 } 2497 } 2498 2499 public boolean isInCurrentTag( DownloadManager manager )2500 isInCurrentTag( 2501 DownloadManager manager ) 2502 { 2503 return( isInTags(manager, currentTags )); 2504 } 2505 2506 public void taggableAdded( Tag tag, Taggable tagged )2507 taggableAdded( 2508 Tag tag, 2509 Taggable tagged ) 2510 { 2511 DownloadManager manager = (DownloadManager)tagged; 2512 2513 if ( isOurDownloadManager(manager)){ 2514 2515 tv.addDataSource( manager ); 2516 } 2517 } 2518 2519 public void taggableSync( Tag tag )2520 taggableSync( 2521 Tag tag ) 2522 { 2523 // request to fully resync this tag 2524 2525 List<DownloadManager> dataSources = tv.getDataSources(); 2526 2527 for ( DownloadManager dm : dataSources ){ 2528 2529 if ( !isOurDownloadManager(dm)){ 2530 2531 tv.removeDataSource(dm); 2532 } 2533 } 2534 2535 for ( Taggable t: tag.getTagged()){ 2536 2537 DownloadManager manager = (DownloadManager)t; 2538 2539 if ( isOurDownloadManager( manager ) && !tv.dataSourceExists(manager)){ 2540 2541 tv.addDataSource(manager); 2542 } 2543 } 2544 } 2545 2546 public void taggableRemoved( Tag tag, Taggable tagged )2547 taggableRemoved( 2548 Tag tag, 2549 Taggable tagged ) 2550 { 2551 DownloadManager manager = (DownloadManager)tagged; 2552 2553 tv.removeDataSource( manager ); 2554 } 2555 2556 2557 2558 // globalmanagerlistener Functions 2559 // @see org.gudy.azureus2.core3.global.GlobalManagerListener#downloadManagerAdded(org.gudy.azureus2.core3.download.DownloadManager) downloadManagerAdded( DownloadManager dm )2560 public void downloadManagerAdded( DownloadManager dm ) { 2561 dm.addListener( this ); 2562 if (isOurDownloadManager(dm)) { 2563 tv.addDataSource(dm); 2564 } 2565 } 2566 2567 // @see org.gudy.azureus2.core3.global.GlobalManagerListener#downloadManagerRemoved(org.gudy.azureus2.core3.download.DownloadManager) downloadManagerRemoved( DownloadManager dm )2568 public void downloadManagerRemoved( DownloadManager dm ) { 2569 dm.removeListener( this ); 2570 DownloadBar.close(dm); 2571 tv.removeDataSource(dm); 2572 } 2573 destroyInitiated()2574 public void destroyInitiated() { } destroyed()2575 public void destroyed() { } seedingStatusChanged( boolean seeding_only_mode, boolean b )2576 public void seedingStatusChanged( boolean seeding_only_mode, boolean b ){} 2577 2578 // End of globalmanagerlistener Functions 2579 2580 2581 2582 // @see org.gudy.azureus2.ui.swt.views.table.impl.TableViewTab#updateLanguage() updateLanguage()2583 public void updateLanguage() { 2584 super.updateLanguage(); 2585 getComposite().layout(true, true); 2586 } 2587 isTableFocus()2588 public boolean isTableFocus() { 2589 return viewActive; 2590 //return tv.isTableFocus(); 2591 } 2592 obfusticatedImage(final Image image)2593 public Image obfusticatedImage(final Image image) { 2594 return tv.obfusticatedImage(image); 2595 } 2596 2597 /** 2598 * Creates and return an <code>TableViewSWT</code> 2599 * Subclasses my override to return a different TableViewSWT if needed 2600 * @param basicItems 2601 * @return 2602 */ 2603 2604 private static boolean registeredCoreSubViews = false; 2605 2606 protected TableViewSWT<DownloadManager> createTableView( Class<?> forDataSourceType, String tableID, TableColumnCore[] basicItems )2607 createTableView( 2608 Class<?> forDataSourceType, 2609 String tableID, 2610 TableColumnCore[] basicItems ) 2611 { 2612 int tableExtraStyle = COConfigurationManager.getIntParameter("MyTorrentsView.table.style"); 2613 TableViewSWT<DownloadManager> table = 2614 TableViewFactory.createTableViewSWT(forDataSourceType, tableID, 2615 getPropertiesPrefix(), basicItems, "#", tableExtraStyle | SWT.MULTI 2616 | SWT.FULL_SELECTION | SWT.VIRTUAL | SWT.CASCADE); 2617 2618 // config?? 2619 2620 boolean enable_tab_views = 2621 !Utils.isAZ2UI() && 2622 supportsTabs && 2623 COConfigurationManager.getBooleanParameter( "Library.ShowTabsInTorrentView" ); 2624 2625 List<String> restrictTo = new ArrayList<String>(); 2626 restrictTo.addAll(Arrays.asList( 2627 GeneralView.MSGID_PREFIX, 2628 TrackerView.MSGID_PREFIX, 2629 PeersView.MSGID_PREFIX, 2630 PeersGraphicView.MSGID_PREFIX, 2631 PiecesView.MSGID_PREFIX, 2632 DownloadActivityView.MSGID_PREFIX, 2633 PieceInfoView.MSGID_PREFIX, 2634 FilesView.MSGID_PREFIX, 2635 TaggingView.MSGID_PREFIX, 2636 PrivacyView.MSGID_PREFIX 2637 )); 2638 2639 // sub-tab hacks 2640 restrictTo.add( "azbuddy.ui.menu.chat" ); 2641 PluginManager pm = AzureusCoreFactory.getSingleton().getPluginManager(); 2642 PluginInterface pi = pm.getPluginInterfaceByID("aercm", true); 2643 2644 if (pi != null) { 2645 String pluginInfo = pi.getPluginconfig().getPluginStringParameter( 2646 "plugin.info", ""); 2647 if (pluginInfo.equals("e")) { 2648 restrictTo.add("rcm.subview.torrentdetails.name"); 2649 } 2650 } 2651 2652 if ( Logger.isEnabled()){ 2653 2654 restrictTo.add( LoggerView.MSGID_PREFIX ); 2655 } 2656 2657 table.setEnableTabViews(enable_tab_views, false, 2658 restrictTo.toArray(new String[0])); 2659 2660 UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT(); 2661 if (uiFunctions != null) { 2662 UISWTInstance pluginUI = uiFunctions.getUISWTInstance(); 2663 2664 registerPluginViews( pluginUI ); 2665 } 2666 2667 return( table ); 2668 } 2669 2670 public static void registerPluginViews( UISWTInstance pluginUI )2671 registerPluginViews( 2672 UISWTInstance pluginUI ) 2673 { 2674 if ( pluginUI != null && !registeredCoreSubViews ){ 2675 2676 String[] views_with_tabs = { 2677 TableManager.TABLE_MYTORRENTS_ALL_BIG, // all simple views 2678 TableManager.TABLE_MYTORRENTS_INCOMPLETE, // downloading view 2679 TableManager.TABLE_MYTORRENTS_INCOMPLETE_BIG, // downloading view 2680 TableManager.TABLE_MYTORRENTS_COMPLETE, // bottom part of split views (hack of course) 2681 }; 2682 2683 boolean hasTags = false; 2684 try { 2685 // gotta be a simpler way? 2686 hasTags = TagManagerFactory.getTagManager().getTagType(TagType.TT_DOWNLOAD_MANUAL).getTags().size() > 0; 2687 } catch (Throwable t) { 2688 } 2689 2690 for ( String id: views_with_tabs ){ 2691 2692 pluginUI.addView( id, GeneralView.MSGID_PREFIX, GeneralView.class, null); 2693 pluginUI.addView( id, TrackerView.MSGID_PREFIX, TrackerView.class, null); 2694 pluginUI.addView( id, PeersView.MSGID_PREFIX, PeersView.class, null); 2695 pluginUI.addView( id, PeersGraphicView.MSGID_PREFIX, PeersGraphicView.class, null); 2696 pluginUI.addView( id, PiecesView.MSGID_PREFIX, PiecesView.class, null); 2697 pluginUI.addView( id, PieceInfoView.MSGID_PREFIX, PieceInfoView.class, null); 2698 pluginUI.addView( id, DownloadActivityView.MSGID_PREFIX, DownloadActivityView.class, null); 2699 pluginUI.addView( id, FilesView.MSGID_PREFIX, FilesView.class, null); 2700 pluginUI.addView( id, TorrentInfoView.MSGID_PREFIX, TorrentInfoView.class, null); 2701 pluginUI.addView( id, TorrentOptionsView.MSGID_PREFIX, TorrentOptionsView.class, null); 2702 if (hasTags) { 2703 pluginUI.addView( id, TaggingView.MSGID_PREFIX, TaggingView.class, null); 2704 } 2705 pluginUI.addView( id, PrivacyView.MSGID_PREFIX, PrivacyView.class, null); 2706 2707 if (Logger.isEnabled()) { 2708 pluginUI.addView( id, LoggerView.MSGID_PREFIX, LoggerView.class, null); 2709 } 2710 } 2711 2712 registeredCoreSubViews = true; 2713 } 2714 } 2715 /** 2716 * Returns the default row height for the table 2717 * Subclasses my override to return a different height if needed; a height of -1 means use default 2718 * @return 2719 */ getRowDefaultHeight()2720 protected int getRowDefaultHeight(){ 2721 return -1; 2722 } 2723 2724 // @see org.gudy.azureus2.plugins.ui.tables.TableRowRefreshListener#rowRefresh(org.gudy.azureus2.plugins.ui.tables.TableRow) rowRefresh(TableRow row)2725 public void rowRefresh(TableRow row) { 2726 if (!(row instanceof TableRowCore)) { 2727 return; 2728 } 2729 2730 TableRowCore rowCore = (TableRowCore) row; 2731 Object ds = rowCore.getDataSource(true); 2732 if (!(ds instanceof DownloadManager)) { 2733 return; 2734 } 2735 2736 DownloadManager dm = (DownloadManager) ds; 2737 if (rowCore.getSubItemCount() == 0 && dm.getTorrent() != null 2738 && !dm.getTorrent().isSimpleTorrent() && rowCore.isVisible() 2739 && dm.getNumFileInfos() > 0) { 2740 DiskManagerFileInfoSet fileInfos = dm.getDiskManagerFileInfoSet(); 2741 if (fileInfos != null) { 2742 DiskManagerFileInfo[] files = fileInfos.getFiles(); 2743 boolean copied = false; 2744 int pos = 0; 2745 for (int i = 0; i < files.length; i++) { 2746 DiskManagerFileInfo fileInfo = files[i]; 2747 if (fileInfo.isSkipped() 2748 && (fileInfo.getStorageType() == DiskManagerFileInfo.ST_COMPACT || fileInfo.getStorageType() == DiskManagerFileInfo.ST_REORDER_COMPACT)) { 2749 continue; 2750 } 2751 if (pos != i) { 2752 if ( !copied ){ 2753 // we *MUSTN'T* modify the returned array!!!! 2754 2755 DiskManagerFileInfo[] oldFiles = files; 2756 files = new DiskManagerFileInfo[files.length]; 2757 System.arraycopy(oldFiles, 0, files, 0, files.length); 2758 2759 copied = true; 2760 } 2761 2762 files[pos] = files[i]; 2763 } 2764 pos++; 2765 } 2766 if (pos != files.length) { 2767 DiskManagerFileInfo[] oldFiles = files; 2768 files = new DiskManagerFileInfo[pos]; 2769 System.arraycopy(oldFiles, 0, files, 0, pos); 2770 } 2771 rowCore.setSubItems(files); 2772 } 2773 } 2774 } 2775 eventOccurred(UISWTViewEvent event)2776 public boolean eventOccurred(UISWTViewEvent event) { 2777 boolean b = super.eventOccurred(event); 2778 if (event.getType() == UISWTViewEvent.TYPE_FOCUSGAINED) { 2779 if (rebuildListOnFocusGain) { 2780 List<?> dms = globalManager.getDownloadManagers(); 2781 List<DownloadManager> listAdds = new ArrayList<DownloadManager>(); 2782 List<DownloadManager> listRemoves = new ArrayList<DownloadManager>(); 2783 for (Iterator<?> iter = dms.iterator(); iter.hasNext();) { 2784 DownloadManager dm = (DownloadManager) iter.next(); 2785 2786 if (!isOurDownloadManager(dm)) { 2787 listRemoves.add(dm); 2788 } else { 2789 listAdds.add(dm); 2790 } 2791 } 2792 tv.removeDataSources(listRemoves.toArray(new DownloadManager[0])); 2793 tv.addDataSources(listAdds.toArray(new DownloadManager[0])); 2794 } 2795 updateSelectedContent(true); 2796 } else if (event.getType() == UISWTViewEvent.TYPE_FOCUSLOST) { 2797 } 2798 return b; 2799 } 2800 setRebuildListOnFocusGain(boolean rebuildListOnFocusGain)2801 public void setRebuildListOnFocusGain(boolean rebuildListOnFocusGain) { 2802 this.rebuildListOnFocusGain = rebuildListOnFocusGain; 2803 } 2804 rowAdded(TableRowCore row)2805 public void rowAdded(TableRowCore row) { 2806 if (row.getParentRowCore() == null) { 2807 DownloadManager dm = (DownloadManager) row.getDataSource(true); 2808 if ( dm.getDownloadState().getBooleanAttribute( DownloadManagerState.AT_FILES_EXPANDED )){ 2809 row.setExpanded(true); 2810 } 2811 } 2812 //if (getRowDefaultHeight() > 0 && row.getParentRowCore() != null) { 2813 // row.setHeight(20); 2814 //} 2815 } 2816 rowRemoved(TableRowCore row)2817 public void rowRemoved(TableRowCore row) { 2818 } 2819 2820 public void rowExpanded( TableRowCore row )2821 rowExpanded( 2822 TableRowCore row ) 2823 { 2824 if ( row.getParentRowCore() == null ){ 2825 2826 DownloadManager dm = (DownloadManager) row.getDataSource(true); 2827 2828 dm.getDownloadState().setBooleanAttribute( DownloadManagerState.AT_FILES_EXPANDED, true ); 2829 } 2830 } 2831 2832 public void rowCollapsed( TableRowCore row )2833 rowCollapsed( 2834 TableRowCore row ) 2835 { 2836 if ( row.getParentRowCore() == null ){ 2837 2838 DownloadManager dm = (DownloadManager) row.getDataSource(true); 2839 2840 dm.getDownloadState().setBooleanAttribute( DownloadManagerState.AT_FILES_EXPANDED, false ); 2841 } 2842 } 2843 getForDataSourceType()2844 protected Class<?> getForDataSourceType() { 2845 return forDataSourceType; 2846 } 2847 isCurrent(Tag tag)2848 private boolean isCurrent(Tag tag) { 2849 if (currentTags != null) { 2850 for (Tag curTag : currentTags) { 2851 if (tag.equals(curTag)) { 2852 return true; 2853 } 2854 } 2855 } 2856 return false; 2857 } 2858 isCurrentTagsAny()2859 public boolean isCurrentTagsAny() { 2860 return currentTagsAny; 2861 } 2862 setCurrentTagsAny(boolean currentTagsAny)2863 public void setCurrentTagsAny(boolean currentTagsAny) { 2864 if (this.currentTagsAny == currentTagsAny) { 2865 return; 2866 } 2867 this.currentTagsAny = currentTagsAny; 2868 setCurrentTags(currentTags); 2869 } 2870 } 2871