1 /* 2 * Created on 05-Sep-2005 3 * Created by Paul Gardner 4 * Copyright (C) Azureus Software, Inc, All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * 18 */ 19 20 package org.gudy.azureus2.ui.swt.pluginsimpl; 21 22 import java.io.File; 23 import java.io.IOException; 24 import java.io.InputStream; 25 import java.lang.ref.WeakReference; 26 import java.net.URL; 27 import java.util.*; 28 29 import org.eclipse.swt.SWT; 30 import org.eclipse.swt.graphics.Image; 31 import org.eclipse.swt.graphics.ImageData; 32 import org.eclipse.swt.graphics.Resource; 33 import org.eclipse.swt.widgets.Display; 34 import org.eclipse.swt.widgets.Shell; 35 36 import org.gudy.azureus2.core3.config.COConfigurationManager; 37 import org.gudy.azureus2.core3.download.DownloadManager; 38 import org.gudy.azureus2.core3.internat.MessageText; 39 import org.gudy.azureus2.core3.util.AERunnable; 40 import org.gudy.azureus2.core3.util.AETemporaryFileHandler; 41 import org.gudy.azureus2.core3.util.Debug; 42 import org.gudy.azureus2.plugins.PluginInterface; 43 import org.gudy.azureus2.plugins.download.Download; 44 import org.gudy.azureus2.plugins.torrent.Torrent; 45 import org.gudy.azureus2.plugins.ui.*; 46 import org.gudy.azureus2.plugins.ui.menus.MenuItem; 47 import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel; 48 import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel; 49 import org.gudy.azureus2.plugins.ui.tables.TableColumn; 50 import org.gudy.azureus2.plugins.ui.tables.TableColumnCreationListener; 51 import org.gudy.azureus2.plugins.ui.tables.TableContextMenuItem; 52 import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem; 53 import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarManager; 54 import org.gudy.azureus2.pluginsimpl.local.PluginInitializer; 55 import org.gudy.azureus2.pluginsimpl.local.download.DownloadImpl; 56 import org.gudy.azureus2.pluginsimpl.local.ui.UIManagerImpl; 57 import org.gudy.azureus2.pluginsimpl.local.ui.config.ConfigSectionRepository; 58 import org.gudy.azureus2.ui.common.util.MenuItemManager; 59 import org.gudy.azureus2.ui.swt.*; 60 import org.gudy.azureus2.ui.swt.components.shell.ShellFactory; 61 import org.gudy.azureus2.ui.swt.mainwindow.*; 62 import org.gudy.azureus2.ui.swt.minibar.AllTransfersBar; 63 import org.gudy.azureus2.ui.swt.minibar.DownloadBar; 64 import org.gudy.azureus2.ui.swt.plugins.*; 65 import org.gudy.azureus2.ui.swt.shells.MessageBoxShell; 66 import org.gudy.azureus2.ui.swt.views.table.utils.TableContextMenuManager; 67 import org.gudy.azureus2.ui.swt.views.utils.ManagerUtils; 68 69 import com.aelitis.azureus.ui.IUIIntializer; 70 import com.aelitis.azureus.ui.common.table.TableColumnCore; 71 import com.aelitis.azureus.ui.common.table.TableStructureEventDispatcher; 72 import com.aelitis.azureus.ui.common.table.impl.TableColumnImpl; 73 import com.aelitis.azureus.ui.common.table.impl.TableColumnManager; 74 import com.aelitis.azureus.ui.mdi.MultipleDocumentInterface; 75 import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT; 76 import com.aelitis.azureus.ui.swt.UIFunctionsSWT; 77 78 public class 79 UISWTInstanceImpl 80 implements UIInstanceFactory, UISWTInstance, UIManagerEventListener 81 { 82 private Map<BasicPluginConfigModel,BasicPluginConfigImpl> config_view_map = new WeakHashMap<BasicPluginConfigModel,BasicPluginConfigImpl>(); 83 84 // Map<ParentId, Map<ViewId, Listener>> 85 private Map<String,Map<String,UISWTViewEventListenerHolder>> views = new HashMap<String,Map<String,UISWTViewEventListenerHolder>>(); 86 87 private Map<PluginInterface,UIInstance> plugin_map = new WeakHashMap<PluginInterface,UIInstance>(); 88 89 private boolean bUIAttaching; 90 91 private final UIFunctionsSWT uiFunctions; 92 93 public static interface SWTViewListener { setViewAdded(String parent, String id, UISWTViewEventListener l)94 public void setViewAdded(String parent, String id, UISWTViewEventListener l); setViewRemoved(String parent, String id, UISWTViewEventListener l)95 public void setViewRemoved(String parent, String id, UISWTViewEventListener l); 96 } 97 98 private List<SWTViewListener> listSWTViewListeners = new ArrayList<SWTViewListener>(0); 99 UISWTInstanceImpl()100 public UISWTInstanceImpl() { 101 // Since this is a UI **SWT** Instance Implementor, it's assumed 102 // that the UI Functions are of UIFunctionsSWT 103 uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT(); 104 } 105 106 public int getUIType()107 getUIType() 108 { 109 return( UIT_SWT ); 110 } 111 init(IUIIntializer init)112 public void init(IUIIntializer init) { 113 UIManager ui_manager = PluginInitializer.getDefaultInterface().getUIManager(); 114 ui_manager.addUIEventListener(this); 115 116 bUIAttaching = true; 117 118 ((UIManagerImpl) ui_manager).attachUI(this, init); 119 120 bUIAttaching = false; 121 } 122 123 public UIInstance getInstance( PluginInterface plugin_interface )124 getInstance( 125 PluginInterface plugin_interface ) 126 { 127 UIInstance instance = plugin_map.get( plugin_interface ); 128 129 if ( instance == null ){ 130 131 instance = new instanceWrapper( plugin_interface, uiFunctions, this ); 132 133 plugin_map.put( plugin_interface, instance ); 134 } 135 136 return( instance ); 137 } 138 139 public boolean eventOccurred( final UIManagerEvent event )140 eventOccurred( 141 final UIManagerEvent event ) 142 { 143 boolean done = true; 144 145 final Object data = event.getData(); 146 147 switch( event.getType()){ 148 149 case UIManagerEvent.ET_SHOW_TEXT_MESSAGE: 150 { 151 Utils.execSWTThread( 152 new Runnable() 153 { 154 public void 155 run() 156 { 157 String[] params = (String[])data; 158 159 new TextViewerWindow( params[0], params[1], params[2] ); 160 } 161 }); 162 163 break; 164 } 165 case UIManagerEvent.ET_SHOW_MSG_BOX: 166 { 167 final int[] result = { UIManagerEvent.MT_NONE }; 168 169 Utils.execSWTThread( 170 new Runnable() 171 { 172 public void 173 run() 174 { 175 UIFunctionsManagerSWT.getUIFunctionsSWT().bringToFront(); 176 177 Object[] params = (Object[])data; 178 179 long _styles = ((Long)(params[2])).longValue(); 180 181 int styles = 0; 182 int def = 0; 183 184 if (( _styles & UIManagerEvent.MT_YES ) != 0 ){ 185 186 styles |= SWT.YES; 187 } 188 if (( _styles & UIManagerEvent.MT_YES_DEFAULT ) != 0 ){ 189 190 styles |= SWT.YES; 191 def = SWT.YES; 192 } 193 if (( _styles & UIManagerEvent.MT_NO ) != 0 ){ 194 195 styles |= SWT.NO; 196 } 197 if (( _styles & UIManagerEvent.MT_NO_DEFAULT ) != 0 ){ 198 199 styles |= SWT.NO; 200 def = SWT.NO; 201 } 202 if (( _styles & UIManagerEvent.MT_OK ) != 0 ){ 203 204 styles |= SWT.OK; 205 } 206 if (( _styles & UIManagerEvent.MT_OK_DEFAULT ) != 0 ){ 207 208 styles |= SWT.OK; 209 def = SWT.OK; 210 } 211 212 if (( _styles & UIManagerEvent.MT_CANCEL ) != 0 ){ 213 214 styles |= SWT.CANCEL; 215 } 216 217 218 MessageBoxShell mb = 219 new MessageBoxShell( 220 styles, 221 MessageText.getString((String)params[0]), 222 MessageText.getString((String)params[1])); 223 224 if ( def != 0 ){ 225 226 mb.setDefaultButtonUsingStyle( def ); 227 } 228 229 if ( params.length == 4 && params[3] instanceof Map ){ 230 231 Map<String,Object> options = (Map<String,Object>)params[3]; 232 233 String rememberID = (String)options.get( UIManager.MB_PARAM_REMEMBER_ID ); 234 Boolean rememberByDefault = (Boolean)options.get( UIManager.MB_PARAM_REMEMBER_BY_DEF ); 235 String rememberText = (String)options.get( UIManager.MB_PARAM_REMEMBER_RES ); 236 237 if ( rememberID != null && rememberByDefault != null && rememberText != null ){ 238 239 mb.setRemember( rememberID, rememberByDefault, rememberText ); 240 } 241 242 Number auto_close_ms = (Number)options.get( UIManager.MB_PARAM_AUTO_CLOSE_MS ); 243 244 if ( auto_close_ms != null ){ 245 246 mb.setAutoCloseInMS( auto_close_ms.intValue()); 247 } 248 }else if ( params.length >= 6 ){ 249 250 String rememberID = (String)params[3]; 251 Boolean rememberByDefault = (Boolean)params[4]; 252 String rememberText = (String)params[5]; 253 254 if ( rememberID != null && rememberByDefault != null && rememberText != null ){ 255 256 mb.setRemember( rememberID, rememberByDefault, rememberText ); 257 } 258 } 259 260 mb.open(null); 261 262 int _r = mb.waitUntilClosed(); 263 264 int r = 0; 265 266 if (( _r & SWT.YES ) != 0 ){ 267 268 r |= UIManagerEvent.MT_YES; 269 } 270 if (( _r & SWT.NO ) != 0 ){ 271 272 r |= UIManagerEvent.MT_NO; 273 } 274 if (( _r & SWT.OK ) != 0 ){ 275 276 r |= UIManagerEvent.MT_OK; 277 } 278 if (( _r & SWT.CANCEL ) != 0 ){ 279 280 r |= UIManagerEvent.MT_CANCEL; 281 } 282 283 result[0] = r; 284 } 285 }, false ); 286 287 event.setResult( new Long( result[0] )); 288 289 break; 290 } 291 case UIManagerEvent.ET_OPEN_TORRENT_VIA_FILE: 292 { 293 TorrentOpener.openTorrent(((File)data).toString()); 294 295 break; 296 } 297 case UIManagerEvent.ET_OPEN_TORRENT_VIA_TORRENT: 298 { 299 Torrent t = (Torrent)data; 300 301 try{ 302 File f = AETemporaryFileHandler.createTempFile(); 303 304 t.writeToFile( f ); 305 306 TorrentOpener.openTorrent( f.toString()); 307 308 }catch( Throwable e ){ 309 310 Debug.printStackTrace( e ); 311 } 312 313 break; 314 } 315 case UIManagerEvent.ET_OPEN_TORRENT_VIA_URL: 316 { 317 Display display = SWTThread.getInstance().getDisplay(); 318 319 display.syncExec(new AERunnable() { 320 public void runSupport() { 321 Object[] params = (Object[]) data; 322 323 URL target = (URL) params[0]; 324 URL referrer = (URL) params[1]; 325 boolean auto_download = ((Boolean) params[2]).booleanValue(); 326 Map<?, ?> request_properties = (Map<?, ?>)params[3]; 327 328 // programmatic request to add a torrent, make sure az is visible 329 330 if (auto_download) { 331 Shell shell = uiFunctions.getMainShell(); 332 if (shell != null) { 333 new FileDownloadWindow(shell, target.toString(), 334 referrer == null ? null : referrer.toString(), 335 request_properties ); 336 } 337 } else { 338 339 // TODO: handle referrer? 340 341 TorrentOpener.openTorrent(target.toString()); 342 } 343 } 344 }); 345 346 break; 347 } 348 case UIManagerEvent.ET_PLUGIN_VIEW_MODEL_CREATED: 349 { 350 if ( data instanceof BasicPluginViewModel ){ 351 BasicPluginViewModel model = (BasicPluginViewModel)data; 352 353 // property bundles can't handle spaces in keys 354 // 355 // If this behaviour changes, change the openView(model) 356 // method lower down. 357 String sViewID = model.getName().replaceAll(" ", "."); 358 BasicPluginViewImpl view = new BasicPluginViewImpl(model); 359 addView(UISWTInstance.VIEW_MAIN, sViewID, view); 360 } 361 362 break; 363 } 364 case UIManagerEvent.ET_PLUGIN_VIEW_MODEL_DESTROYED: 365 { 366 if ( data instanceof BasicPluginViewModel ){ 367 BasicPluginViewModel model = (BasicPluginViewModel)data; 368 // property bundles can't handle spaces in keys 369 // 370 // If this behaviour changes, change the openView(model) 371 // method lower down. 372 String sViewID = model.getName().replaceAll(" ", "."); 373 removeViews(UISWTInstance.VIEW_MAIN, sViewID); 374 } 375 376 break; 377 } 378 case UIManagerEvent.ET_PLUGIN_CONFIG_MODEL_CREATED: 379 { 380 if ( data instanceof BasicPluginConfigModel ){ 381 382 BasicPluginConfigModel model = (BasicPluginConfigModel)data; 383 384 BasicPluginConfigImpl view = new BasicPluginConfigImpl( new WeakReference<BasicPluginConfigModel>( model )); 385 386 config_view_map.put( model, view ); 387 388 ConfigSectionRepository.getInstance().addConfigSection(view, model.getPluginInterface()); 389 } 390 391 break; 392 } 393 case UIManagerEvent.ET_PLUGIN_CONFIG_MODEL_DESTROYED: 394 { 395 if ( data instanceof BasicPluginConfigModel ){ 396 397 BasicPluginConfigModel model = (BasicPluginConfigModel)data; 398 399 BasicPluginConfigImpl view = config_view_map.get( model ); 400 401 if ( view != null ){ 402 403 ConfigSectionRepository.getInstance().removeConfigSection(view); 404 405 } 406 } 407 408 break; 409 } 410 case UIManagerEvent.ET_COPY_TO_CLIPBOARD: 411 { 412 ClipboardCopy.copyToClipBoard((String)data); 413 414 break; 415 } 416 case UIManagerEvent.ET_OPEN_URL: 417 { 418 Utils.launch(((URL)data).toExternalForm()); 419 420 break; 421 } 422 case UIManagerEvent.ET_CREATE_TABLE_COLUMN:{ 423 424 if (data instanceof TableColumn) { 425 event.setResult(data); 426 } else { 427 String[] args = (String[]) data; 428 429 event.setResult(new TableColumnImpl(args[0], args[1])); 430 } 431 432 break; 433 } 434 case UIManagerEvent.ET_ADD_TABLE_COLUMN:{ 435 436 TableColumn _col = (TableColumn)data; 437 438 if ( _col instanceof TableColumnImpl ){ 439 440 TableColumnManager.getInstance().addColumns(new TableColumnCore[] { (TableColumnCore) _col }); 441 442 TableStructureEventDispatcher tsed = TableStructureEventDispatcher.getInstance(_col.getTableID()); 443 444 tsed.tableStructureChanged(true, _col.getForDataSourceType()); 445 446 }else{ 447 448 throw(new UIRuntimeException("TableManager.addColumn(..) can only add columns created by createColumn(..)")); 449 } 450 451 break; 452 } 453 case UIManagerEvent.ET_REGISTER_COLUMN:{ 454 455 Object[] params = (Object[])data; 456 457 TableColumnManager tcManager = TableColumnManager.getInstance(); 458 459 Class<?> dataSource = (Class<?>)params[0]; 460 String columnName = (String)params[1]; 461 462 tcManager.registerColumn(dataSource, columnName, (TableColumnCreationListener)params[2]); 463 464 String[] tables = tcManager.getTableIDs(); 465 466 for ( String tid: tables ){ 467 468 // we don't know which tables are affected at this point to refresh all. 469 // if this proves to be a performance issue then we would have to use the 470 // datasource to derive affected tables somehow 471 472 TableStructureEventDispatcher tsed = TableStructureEventDispatcher.getInstance( tid ); 473 474 tsed.tableStructureChanged(true, dataSource); 475 } 476 477 break; 478 } 479 case UIManagerEvent.ET_UNREGISTER_COLUMN:{ 480 481 Object[] params = (Object[])data; 482 483 TableColumnManager tcManager = TableColumnManager.getInstance(); 484 485 Class<?> dataSource = (Class<?>)params[0]; 486 String columnName = (String)params[1]; 487 488 tcManager.unregisterColumn(dataSource, columnName, (TableColumnCreationListener)params[2]); 489 490 String[] tables = tcManager.getTableIDs(); 491 492 for ( String tid: tables ){ 493 494 TableColumnCore col = tcManager.getTableColumnCore( tid, columnName ); 495 496 if ( col != null ){ 497 498 col.remove(); 499 } 500 } 501 502 break; 503 } 504 case UIManagerEvent.ET_ADD_TABLE_CONTEXT_MENU_ITEM:{ 505 TableContextMenuItem item = (TableContextMenuItem)data; 506 TableContextMenuManager.getInstance().addContextMenuItem(item); 507 break; 508 } 509 case UIManagerEvent.ET_ADD_MENU_ITEM: { 510 MenuItem item = (MenuItem)data; 511 MenuItemManager.getInstance().addMenuItem(item); 512 break; 513 } 514 case UIManagerEvent.ET_REMOVE_TABLE_CONTEXT_MENU_ITEM:{ 515 TableContextMenuItem item = (TableContextMenuItem)data; 516 TableContextMenuManager.getInstance().removeContextMenuItem(item); 517 break; 518 } 519 case UIManagerEvent.ET_REMOVE_MENU_ITEM: { 520 MenuItem item = (MenuItem)data; 521 MenuItemManager.getInstance().removeMenuItem(item); 522 break; 523 } 524 case UIManagerEvent.ET_SHOW_CONFIG_SECTION: { 525 event.setResult(new Boolean(false)); 526 527 if (!(data instanceof String)){ 528 break; 529 } 530 531 event.setResult(Boolean.TRUE); 532 533 uiFunctions.getMDI().showEntryByID( 534 MultipleDocumentInterface.SIDEBAR_SECTION_CONFIG, data); 535 536 break; 537 } 538 case UIManagerEvent.ET_FILE_OPEN: { 539 File file_to_use = (File)data; 540 Utils.launch(file_to_use.getAbsolutePath()); 541 break; 542 } 543 case UIManagerEvent.ET_FILE_SHOW: { 544 File file_to_use = (File)data; 545 final boolean use_open_containing_folder = COConfigurationManager.getBooleanParameter("MyTorrentsView.menu.show_parent_folder_enabled"); 546 ManagerUtils.open(file_to_use, use_open_containing_folder); 547 break; 548 } 549 case UIManagerEvent.ET_HIDE_ALL: { 550 boolean hide = (Boolean)data; 551 552 uiFunctions.setHideAll( hide ); 553 554 break; 555 } 556 default: 557 { 558 done = false; 559 560 break; 561 } 562 } 563 564 return( done ); 565 } 566 567 public Display getDisplay()568 getDisplay() 569 { 570 return SWTThread.getInstance().getDisplay(); 571 } 572 573 public Image loadImage( String resource )574 loadImage( 575 String resource ) 576 { 577 throw( new RuntimeException( "plugin specific instance required" )); 578 } 579 580 public UISWTGraphic createGraphic( Image img)581 createGraphic( 582 Image img) 583 { 584 return new UISWTGraphicImpl(img); 585 } 586 createShell(int style)587 public Shell createShell(int style) { 588 Shell shell = ShellFactory.createMainShell(style); 589 Utils.setShellIcon(shell); 590 return shell; 591 } 592 593 594 public void detach()595 detach() 596 597 throws UIException 598 { 599 throw( new UIException( "not supported" )); 600 } 601 602 603 /* (non-Javadoc) 604 * @see org.gudy.azureus2.ui.swt.plugins.UISWTInstance#addView(java.lang.String, java.lang.String, java.lang.Class, java.lang.Object) 605 */ addView(String sParentID, String sViewID, Class<? extends UISWTViewEventListener> cla, Object datasource)606 public void addView(String sParentID, String sViewID, 607 Class<? extends UISWTViewEventListener> cla, Object datasource) { 608 addView(null, sParentID, sViewID, cla, datasource); 609 } 610 addView(PluginInterface pi, String sParentID, String sViewID, Class<? extends UISWTViewEventListener> cla, Object datasource)611 public void addView(PluginInterface pi, String sParentID, String sViewID, 612 Class<? extends UISWTViewEventListener> cla, Object datasource) { 613 614 UISWTViewEventListenerHolder _l = new UISWTViewEventListenerHolder(sViewID, 615 cla, datasource, pi); 616 addView( sParentID, sViewID, _l ); 617 } 618 619 /* (non-Javadoc) 620 * @see org.gudy.azureus2.ui.swt.plugins.UISWTInstance#addView(java.lang.String, java.lang.String, org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener) 621 */ addView(String sParentID, String sViewID, final UISWTViewEventListener l)622 public void addView(String sParentID, String sViewID, 623 final UISWTViewEventListener l) { 624 UISWTViewEventListenerHolder _l = new UISWTViewEventListenerHolder(sViewID, l, null ); 625 addView( sParentID, sViewID, _l ); 626 } 627 addView( String sParentID, final String sViewID, final UISWTViewEventListenerHolder holder)628 public void addView( String sParentID, 629 final String sViewID, final UISWTViewEventListenerHolder holder) 630 { 631 if (sParentID == null) { 632 sParentID = UISWTInstance.VIEW_MAIN; 633 } 634 Map<String,UISWTViewEventListenerHolder> subViews = views.get(sParentID); 635 if (subViews == null) { 636 subViews = new LinkedHashMap<String,UISWTViewEventListenerHolder>(); 637 views.put(sParentID, subViews); 638 } 639 640 subViews.put(sViewID, holder ); 641 642 if (sParentID.equals(UISWTInstance.VIEW_MAIN)) { 643 Utils.execSWTThread(new AERunnable() { 644 public void runSupport() { 645 try { 646 uiFunctions.addPluginView(sViewID, holder ); 647 } catch (Throwable e) { 648 // SWT not available prolly 649 } 650 } 651 }); 652 } 653 654 SWTViewListener[] viewListeners = listSWTViewListeners.toArray(new SWTViewListener[0]); 655 for (SWTViewListener l : viewListeners) { 656 l.setViewAdded(sParentID, sViewID, holder); 657 } 658 } 659 addSWTViewListener(SWTViewListener l)660 public void addSWTViewListener(SWTViewListener l) { 661 listSWTViewListeners.add(l); 662 } 663 removeSWTViewListener(SWTViewListener l)664 public void removeSWTViewListener(SWTViewListener l) { 665 listSWTViewListeners.remove(l); 666 } 667 668 // TODO: Remove views from PeersView, etc removeViews(String sParentID, final String sViewID)669 public void removeViews(String sParentID, final String sViewID) { 670 Map<String,UISWTViewEventListenerHolder> subViews = views.get(sParentID); 671 if (subViews == null) 672 return; 673 674 if (sParentID.equals(UISWTInstance.VIEW_MAIN)) { 675 Utils.execSWTThread(new AERunnable() { 676 public void runSupport() { 677 try { 678 if (uiFunctions != null) { 679 uiFunctions.removePluginView(sViewID); 680 } 681 } catch (Throwable e) { 682 // SWT not available prolly 683 } 684 } 685 }); 686 } 687 688 SWTViewListener[] viewListeners = listSWTViewListeners.toArray(new SWTViewListener[0]); 689 for (UISWTViewEventListener holder : subViews.values()) { 690 for (SWTViewListener l : viewListeners) { 691 l.setViewRemoved(sParentID, sViewID, holder); 692 } 693 } 694 695 subViews.remove(sViewID); 696 } 697 openView(final String sParentID, final String sViewID, final Object dataSource)698 public boolean openView(final String sParentID, final String sViewID, 699 final Object dataSource) { 700 return openView(sParentID, sViewID, dataSource, true); 701 } 702 openView(final String sParentID, final String sViewID, final Object dataSource, final boolean setfocus)703 public boolean openView(final String sParentID, final String sViewID, 704 final Object dataSource, final boolean setfocus) { 705 Map<String,UISWTViewEventListenerHolder> subViews = views.get(sParentID); 706 if (subViews == null) { 707 return false; 708 } 709 710 final UISWTViewEventListenerHolder l = subViews.get(sViewID); 711 if (l == null) { 712 return false; 713 } 714 715 Utils.execSWTThread(new AERunnable() { 716 public void runSupport() { 717 if (uiFunctions != null) { 718 uiFunctions.openPluginView( 719 sParentID, sViewID, l, dataSource, 720 setfocus && !bUIAttaching); 721 } 722 } 723 }); 724 725 return true; 726 } 727 openMainView(final String sViewID, UISWTViewEventListener l, Object dataSource)728 public void openMainView(final String sViewID, 729 UISWTViewEventListener l, Object dataSource) { 730 openMainView(null,sViewID, l, dataSource, true); 731 } 732 openMainView(PluginInterface pi, String sViewID, UISWTViewEventListener l, Object dataSource)733 public void openMainView(PluginInterface pi, String sViewID, 734 UISWTViewEventListener l, Object dataSource) { 735 openMainView( pi, sViewID, l, dataSource, true); 736 } 737 openMainView(final String sViewID, final UISWTViewEventListener l, final Object dataSource, final boolean setfocus)738 public void openMainView(final String sViewID, 739 final UISWTViewEventListener l, final Object dataSource, 740 final boolean setfocus) { 741 openMainView( null, sViewID, l, dataSource, setfocus ); 742 } openMainView(final PluginInterface pi, final String sViewID, final UISWTViewEventListener _l, final Object dataSource, final boolean setfocus)743 public void openMainView(final PluginInterface pi, final String sViewID, 744 final UISWTViewEventListener _l, final Object dataSource, 745 final boolean setfocus) { 746 Utils.execSWTThread(new AERunnable() { 747 public void runSupport() { 748 if (uiFunctions != null) { 749 UISWTViewEventListenerHolder l = new UISWTViewEventListenerHolder(sViewID, _l, pi ); 750 751 uiFunctions.openPluginView(UISWTInstance.VIEW_MAIN, sViewID, l, dataSource, setfocus && !bUIAttaching); 752 } 753 } 754 }); 755 } 756 getOpenViews(String sParentID)757 public UISWTView[] getOpenViews(String sParentID) { 758 if (sParentID.equals(UISWTInstance.VIEW_MAIN)) { 759 try { 760 if (uiFunctions != null) { 761 return uiFunctions.getPluginViews(); 762 } 763 } catch (Throwable e) { 764 // SWT not available prolly 765 } 766 } 767 return new UISWTView[0]; 768 } 769 770 // @see org.gudy.azureus2.plugins.ui.UIInstance#promptUser(java.lang.String, java.lang.String, java.lang.String[], int) promptUser(String title, String text, String[] options, int defaultOption)771 public int promptUser(String title, String text, String[] options, 772 int defaultOption) { 773 774 MessageBoxShell mb = new MessageBoxShell(title, text, options, 775 defaultOption); 776 mb.open(null); 777 // bah, no way to change this to use the UserPrompterResultListener trigger 778 return mb.waitUntilClosed(); 779 } 780 showDownloadBar(Download download, final boolean display)781 public void showDownloadBar(Download download, final boolean display) { 782 if (!(download instanceof DownloadImpl)) {return;} 783 final DownloadManager dm = ((DownloadImpl)download).getDownload(); 784 if (dm == null) {return;} // Not expecting this, but just in case... 785 Utils.execSWTThread(new AERunnable() { 786 public void runSupport() { 787 if (display) { 788 DownloadBar.open(dm, getDisplay().getActiveShell()); 789 } 790 else { 791 DownloadBar.close(dm); 792 } 793 } 794 }, false); 795 } 796 showTransfersBar(final boolean display)797 public void showTransfersBar(final boolean display) { 798 Utils.execSWTThread(new AERunnable() { 799 public void runSupport() { 800 if (display) { 801 AllTransfersBar.open(getDisplay().getActiveShell()); 802 } 803 else { 804 AllTransfersBar.closeAllTransfersBar(); 805 } 806 } 807 }, false); 808 } 809 810 // Core Functions 811 // ============== 812 getViewListeners(String sParentID)813 public UISWTViewEventListenerHolder[] getViewListeners(String sParentID) { 814 Map<String, UISWTViewEventListenerHolder> map = views.get(sParentID); 815 if (map == null) { 816 return new UISWTViewEventListenerHolder[0]; 817 } 818 UISWTViewEventListenerHolder[] array = map.values().toArray(new UISWTViewEventListenerHolder[0]); 819 Arrays.sort(array, new Comparator<UISWTViewEventListenerHolder>() { 820 public int compare(UISWTViewEventListenerHolder o1, 821 UISWTViewEventListenerHolder o2) { 822 if ((o1.getPluginInterface() == null) && (o2.getPluginInterface() == null)) { 823 return 0; 824 } 825 if ((o1.getPluginInterface() != null) && (o2.getPluginInterface() != null)) { 826 return 0; 827 } 828 return o1.getPluginInterface() == null ? -1 : 1; 829 } 830 }); 831 return array; 832 } 833 834 // @see org.gudy.azureus2.plugins.ui.UIInstance#getInputReceiver() getInputReceiver()835 public UIInputReceiver getInputReceiver() { 836 return new SimpleTextEntryWindow(); 837 } 838 839 // @see org.gudy.azureus2.plugins.ui.UIInstance#createMessage() createMessage()840 public UIMessage createMessage() { 841 return new UIMessageImpl(); 842 } 843 createStatusEntry()844 public UISWTStatusEntry createStatusEntry() { 845 final UISWTStatusEntryImpl entry = new UISWTStatusEntryImpl(); 846 UIFunctionsSWT functionsSWT = UIFunctionsManagerSWT.getUIFunctionsSWT(); 847 if (functionsSWT == null) { 848 Debug.outNoStack("No UIFunctionsSWT on createStatusEntry"); 849 return null; 850 } 851 852 IMainStatusBar mainStatusBar = functionsSWT.getMainStatusBar(); 853 if (mainStatusBar == null) { 854 Debug.outNoStack("No MainStatusBar on createStatusEntry"); 855 return null; 856 } 857 mainStatusBar.createStatusEntry(entry); 858 859 return entry; 860 } 861 openView(BasicPluginViewModel model)862 public boolean openView(BasicPluginViewModel model) { 863 return openView(VIEW_MAIN, model.getName().replaceAll(" ", "."), null); 864 } 865 openConfig(final BasicPluginConfigModel model)866 public void openConfig(final BasicPluginConfigModel model) { 867 Utils.execSWTThread(new Runnable() { 868 public void run() { 869 uiFunctions.getMDI().loadEntryByID( 870 MultipleDocumentInterface.SIDEBAR_SECTION_CONFIG, true, false, 871 model.getSection()); 872 } 873 }); 874 } 875 getToolBarManager()876 public UIToolBarManager getToolBarManager() { 877 throw( new RuntimeException( "plugin specific instance required" )); 878 } 879 880 protected static class 881 instanceWrapper 882 implements UISWTInstance, UIToolBarManager 883 { 884 private WeakReference<PluginInterface> pi_ref; 885 private UIFunctionsSWT ui_functions; 886 private UISWTInstanceImpl delegate; 887 888 private UIToolBarManagerCore toolBarManager; 889 private List<UIToolBarItem> listItems = new ArrayList<UIToolBarItem>(); 890 private List<Resource> listDisposeOnUnload = new ArrayList<Resource>(); 891 892 protected instanceWrapper( PluginInterface _pi, UIFunctionsSWT _ui_functions, UISWTInstanceImpl _delegate )893 instanceWrapper( 894 PluginInterface _pi, 895 UIFunctionsSWT _ui_functions, 896 UISWTInstanceImpl _delegate ) 897 { 898 pi_ref = new WeakReference<PluginInterface>(_pi ); 899 ui_functions = _ui_functions; 900 delegate = _delegate; 901 } 902 getToolBarItem(String id)903 public UIToolBarItem getToolBarItem(String id) { 904 return toolBarManager.getToolBarItem(id); 905 } 906 getAllToolBarItems()907 public UIToolBarItem[] getAllToolBarItems() { 908 return toolBarManager.getAllToolBarItems(); 909 } 910 911 public UIToolBarItem createToolBarItem( String id )912 createToolBarItem( 913 String id ) 914 { 915 UIToolBarItem addToolBarItem = toolBarManager.createToolBarItem( id ); 916 917 synchronized( this ){ 918 919 listItems.add( addToolBarItem ); 920 } 921 922 return addToolBarItem; 923 } 924 addToolBarItem(UIToolBarItem item)925 public void addToolBarItem(UIToolBarItem item) { 926 toolBarManager.addToolBarItem(item); 927 } 928 removeToolBarItem(String id)929 public void removeToolBarItem(String id) { 930 toolBarManager.removeToolBarItem(id); 931 } 932 933 public void detach()934 detach() 935 936 throws UIException 937 { 938 delegate.detach(); 939 } 940 941 public int getUIType()942 getUIType() 943 { 944 return( delegate.getUIType()); 945 } 946 947 public Display getDisplay()948 getDisplay() 949 { 950 return( delegate.getDisplay()); 951 } 952 953 public Image loadImage( String resource )954 loadImage( 955 String resource ) 956 { 957 PluginInterface pi = pi_ref.get(); 958 959 if ( pi == null ){ 960 961 return( null ); 962 } 963 964 InputStream is = pi.getPluginClassLoader().getResourceAsStream( resource); 965 966 if ( is != null ){ 967 968 ImageData imageData = new ImageData(is); 969 970 try { 971 is.close(); 972 } catch (IOException e) { 973 Debug.out(e); 974 } 975 976 Display display = getDisplay(); 977 978 Image image = new Image(display, imageData); 979 980 image = Utils.adjustPXForDPI( display, image ); 981 982 listDisposeOnUnload.add(image); 983 984 return image; 985 } 986 987 return null; 988 } 989 990 public UISWTGraphic createGraphic( Image img )991 createGraphic( 992 Image img ) 993 { 994 return( delegate.createGraphic( img )); 995 } 996 997 public void addView(String sParentID, String sViewID, UISWTViewEventListener l)998 addView(String sParentID, String sViewID, UISWTViewEventListener l) 999 { 1000 PluginInterface pi = pi_ref.get(); 1001 1002 delegate.addView( sParentID, sViewID, new UISWTViewEventListenerHolder(sViewID, l, pi) ); 1003 } 1004 addView(String sParentID, String sViewID, Class<? extends UISWTViewEventListener> cla, Object datasource)1005 public void addView(String sParentID, String sViewID, 1006 Class<? extends UISWTViewEventListener> cla, Object datasource) { 1007 PluginInterface pi = pi_ref.get(); 1008 1009 delegate.addView(sParentID, sViewID, new UISWTViewEventListenerHolder(sViewID, 1010 cla, datasource, pi)); 1011 } 1012 1013 public void openMainView(String sViewID, UISWTViewEventListener l,Object dataSource)1014 openMainView(String sViewID, UISWTViewEventListener l,Object dataSource) 1015 { 1016 PluginInterface pi = pi_ref.get(); 1017 1018 delegate.openMainView( pi, sViewID, l, dataSource ); 1019 } 1020 1021 public void openMainView(String sViewID, UISWTViewEventListener l,Object dataSource, boolean setfocus)1022 openMainView(String sViewID, UISWTViewEventListener l,Object dataSource, boolean setfocus) 1023 { 1024 PluginInterface pi = pi_ref.get(); 1025 1026 delegate.openMainView( pi, sViewID, l, dataSource, setfocus ); 1027 } 1028 1029 1030 public void removeViews(String sParentID, String sViewID)1031 removeViews(String sParentID, String sViewID) 1032 { 1033 delegate.removeViews(sParentID, sViewID ); 1034 } 1035 1036 1037 public UISWTView[] getOpenViews(String sParentID)1038 getOpenViews(String sParentID) 1039 { 1040 return( delegate.getOpenViews(sParentID)); 1041 } 1042 promptUser(String title, String text, String[] options, int defaultOption)1043 public int promptUser(String title, String text, String[] options, 1044 int defaultOption) { 1045 return delegate.promptUser(title, text, options, defaultOption); 1046 } 1047 openView(String sParentID, String sViewID, Object dataSource)1048 public boolean openView(String sParentID, String sViewID, Object dataSource) { 1049 return delegate.openView(sParentID, sViewID, dataSource); 1050 } 1051 openView(String sParentID, String sViewID, Object dataSource, boolean setfocus)1052 public boolean openView(String sParentID, String sViewID, Object dataSource, boolean setfocus) { 1053 return delegate.openView(sParentID, sViewID, dataSource, setfocus); 1054 } 1055 getViewListeners(String sParentId)1056 public UISWTViewEventListenerWrapper[] getViewListeners(String sParentId) { 1057 return delegate.getViewListeners(sParentId); 1058 } getInputReceiver()1059 public UIInputReceiver getInputReceiver() { 1060 return delegate.getInputReceiver(); 1061 } 1062 createMessage()1063 public UIMessage createMessage() { 1064 return delegate.createMessage(); 1065 } 1066 showDownloadBar(Download download, boolean display)1067 public void showDownloadBar(Download download, boolean display) { 1068 delegate.showDownloadBar(download, display); 1069 } 1070 showTransfersBar(boolean display)1071 public void showTransfersBar(boolean display) { 1072 delegate.showTransfersBar(display); 1073 } 1074 createStatusEntry()1075 public UISWTStatusEntry createStatusEntry() { 1076 return delegate.createStatusEntry(); 1077 } 1078 openView(BasicPluginViewModel model)1079 public boolean openView(BasicPluginViewModel model) { 1080 return delegate.openView(model); 1081 } 1082 openConfig(BasicPluginConfigModel model)1083 public void openConfig(BasicPluginConfigModel model) { 1084 delegate.openConfig(model); 1085 } 1086 createShell(int style)1087 public Shell createShell(int style) { 1088 return delegate.createShell(style); 1089 } 1090 1091 public UIToolBarManager getToolBarManager()1092 getToolBarManager() 1093 { 1094 if ( toolBarManager == null ){ 1095 1096 UIToolBarManager tbm = ui_functions.getToolBarManager(); 1097 1098 if ( tbm instanceof UIToolBarManagerCore ){ 1099 1100 toolBarManager = (UIToolBarManagerCore)tbm; 1101 1102 }else{ 1103 1104 return( null ); 1105 } 1106 } 1107 1108 return( this ); 1109 } 1110 1111 public void unload( PluginInterface pi )1112 unload( 1113 PluginInterface pi ) 1114 { 1115 if ( toolBarManager != null ){ 1116 1117 synchronized( this ){ 1118 1119 for (UIToolBarItem item : listItems) { 1120 1121 toolBarManager.removeToolBarItem(item.getID()); 1122 } 1123 1124 listItems.clear(); 1125 } 1126 } 1127 1128 Utils.disposeSWTObjects(listDisposeOnUnload); 1129 1130 listDisposeOnUnload.clear(); 1131 } 1132 } 1133 1134 public void unload( PluginInterface pi )1135 unload( 1136 PluginInterface pi ) 1137 { 1138 throw( new RuntimeException( "plugin specific instance required" )); 1139 } 1140 } 1141