/* * File : UISWTViewImpl.java * Created : Oct 14, 2005 * By : TuxPaper * * Copyright (C) 2005, 2006 Aelitis SAS, All rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details ( see the LICENSE file ). * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * AELITIS, SAS au capital de 46,603.30 euros, * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. */ package org.gudy.azureus2.ui.swt.pluginsimpl; import java.awt.Frame; import java.awt.Panel; import java.util.HashMap; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Layout; import org.gudy.azureus2.core3.internat.MessageText; import org.gudy.azureus2.core3.logging.LogEvent; import org.gudy.azureus2.core3.logging.LogIDs; import org.gudy.azureus2.core3.logging.Logger; import org.gudy.azureus2.core3.util.*; import org.gudy.azureus2.plugins.PluginInterface; import org.gudy.azureus2.plugins.ui.UIPluginViewToolBarListener; import org.gudy.azureus2.plugins.ui.UIRuntimeException; import org.gudy.azureus2.plugins.ui.toolbar.UIToolBarItem; import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils; import org.gudy.azureus2.ui.swt.Messages; import org.gudy.azureus2.ui.swt.Utils; import org.gudy.azureus2.ui.swt.debug.ObfusticateImage; import org.gudy.azureus2.ui.swt.plugins.*; import com.aelitis.azureus.ui.common.ToolBarEnabler; import com.aelitis.azureus.ui.common.ToolBarItem; import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT; import com.aelitis.azureus.ui.swt.UIFunctionsSWT; import com.aelitis.azureus.util.MapUtils; /** * This class creates an IView that triggers UISWTViewEventListener * appropriately * * @author TuxPaper * */ public class UISWTViewImpl implements UISWTViewCore, AEDiagnosticsEvidenceGenerator { public static final String CFG_PREFIX = "Views.plugins."; private PluginUISWTSkinObject skinObject; private Object dataSource = null; private boolean useCoreDataSource = false; private final UISWTViewEventListener eventListener; private Composite composite; private final String sViewID; private int iControlType = UISWTView.CONTROLTYPE_SWT; private boolean bFirstGetCompositeCall = true; //private final String sParentID; private String sTitle = null; private String lastFullTitleKey = null; private String lastFullTitle = ""; //private Boolean hasFocus = null; private UIPluginViewToolBarListener toolbarListener; private volatile Map<Object,Object> user_data; public UISWTViewImpl(String sParentID, String sViewID, UISWTViewEventListener eventListener, Object initialDatasource) throws Exception { //this.sParentID = sParentID; this.sViewID = sViewID; this.eventListener = eventListener; if (eventListener instanceof UISWTViewCoreEventListener) { useCoreDataSource = true; } AEDiagnostics.addEvidenceGenerator(this); if (initialDatasource != null) { triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, initialDatasource); } // we could pass the parentid as the data for the create call but unfortunately // there's a bunch of crap out there that assumes that data is the view object :( if (!eventListener.eventOccurred(new UISWTViewEventImpl(sParentID, this, UISWTViewEvent.TYPE_CREATE, this))) throw new UISWTViewEventCancelledException(); } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getEventListener() */ public UISWTViewEventListener getEventListener() { return eventListener; } // UISWTPluginView implementation // ============================== /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#getDataSource() */ public Object getDataSource() { return dataSource; } /* (non-Javadoc) * @see org.gudy.azureus2.plugins.ui.UIPluginView#getViewID() */ public String getViewID() { return sViewID; } /* (non-Javadoc) * @see org.gudy.azureus2.plugins.ui.UIPluginView#closeView() */ public void closeView() { try { UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT(); if (uiFunctions != null) { uiFunctions.closePluginView(this); } Composite c = getComposite(); if ( c != null && !c.isDisposed()){ Composite parent = c.getParent(); triggerEvent( UISWTViewEvent.TYPE_DESTROY, null ); if ( parent instanceof CTabFolder ){ for ( CTabItem item: ((CTabFolder)parent).getItems()){ if ( item.getControl() == c ){ item.dispose(); } } } } } catch (Throwable e) { Debug.out(e); } } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#setControlType(int) */ public void setControlType(int iControlType) { if (iControlType == CONTROLTYPE_AWT || iControlType == CONTROLTYPE_SWT || iControlType == CONTROLTYPE_SKINOBJECT) this.iControlType = iControlType; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#getControlType() */ public int getControlType() { return iControlType; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#triggerEvent(int, java.lang.Object) */ public void triggerEvent(int eventType, Object data) { // prevent double fire of focus gained/lost /* erm, this code doesn't do anything atm as nothing is setting hasFocus, removing for the moment if (eventType == UISWTViewEvent.TYPE_FOCUSGAINED && hasFocus != null && hasFocus) { return; } if (eventType == UISWTViewEvent.TYPE_FOCUSLOST && hasFocus != null && !hasFocus) { return; } */ if (eventType == UISWTViewEvent.TYPE_DATASOURCE_CHANGED) { Object newDataSource = PluginCoreUtils.convert(data, useCoreDataSource); if (dataSource == newDataSource) { return; } data = dataSource = newDataSource; } else if (eventType == UISWTViewEvent.TYPE_LANGUAGEUPDATE) { lastFullTitle = ""; Messages.updateLanguageForControl(getComposite()); } else if (eventType == UISWTViewEvent.TYPE_OBFUSCATE && (eventListener instanceof ObfusticateImage)) { if (data instanceof Map) { ((ObfusticateImage) eventListener).obfusticatedImage((Image) MapUtils.getMapObject( (Map) data, "image", null, Image.class)); } } try { eventListener.eventOccurred(new UISWTViewEventImpl(null,this, eventType, data)); } catch (Throwable t) { Debug.out("ViewID=" + sViewID + "; EventID=" + eventType + "; data=" + data, t); //throw (new UIRuntimeException("UISWTView.triggerEvent:: ViewID=" // + sViewID + "; EventID=" + eventType + "; data=" + data, t)); } if (eventType == UISWTViewEvent.TYPE_DESTROY) { Utils.disposeComposite(getComposite()); } } protected boolean triggerEventRaw(int eventType, Object data) { try { return eventListener.eventOccurred(new UISWTViewEventImpl(null,this, eventType, data)); } catch (Throwable t) { throw (new UIRuntimeException("UISWTView.triggerEvent:: ViewID=" + sViewID + "; EventID=" + eventType + "; data=" + data, t)); } } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#setTitle(java.lang.String) */ public void setTitle(String title) { if ( title.contains( "." ) && MessageText.keyExists(title)){ // it if appears to be a resource key then resolve it here title = MessageText.getString( title ); } sTitle = title; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.plugins.UISWTView#getPluginInterface() */ public PluginInterface getPluginInterface() { if (eventListener instanceof UISWTViewEventListenerHolder) { return (((UISWTViewEventListenerHolder) eventListener).getPluginInterface()); } return null; } // Core Functions /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getComposite() */ public Composite getComposite() { if (bFirstGetCompositeCall) { bFirstGetCompositeCall = false; } return composite; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getTitleID() */ public String getTitleID() { if (sTitle == null) { // still need this crappy check because some plugins still expect their // view id to be their name if (MessageText.keyExists(sViewID)) { return sViewID; } String id = CFG_PREFIX + sViewID + ".title"; if (MessageText.keyExists(id)) { return id; } return "!" + sViewID + "!"; } return "!" + sTitle + "!"; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getFullTitle() */ public String getFullTitle() { //System.out.println("getFullTitle " + sTitle + ";" + getTitleID() + ";" + lastFullTitle + ";" + lastFullTitleKey); if (sTitle != null) { return sTitle; } String key = getTitleID(); if (key == null) { return ""; } if (lastFullTitle.length() > 0 && key.equals(lastFullTitleKey)) { return lastFullTitle; } lastFullTitleKey = key; if (MessageText.keyExists(key) || key.startsWith("!") && key.endsWith("!")) { lastFullTitle = MessageText.getString(key); } else { lastFullTitle = key.replace('.', ' '); // support old plugins } return lastFullTitle; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#initialize(org.eclipse.swt.widgets.Composite) */ public void initialize(Composite parent) { if (iControlType == UISWTView.CONTROLTYPE_SWT) { GridData gridData; Layout parentLayout = parent.getLayout(); if (parentLayout instanceof FormLayout) { composite = parent; } else { composite = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(1, false); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); gridData = new GridData(GridData.FILL_BOTH); composite.setLayoutData(gridData); } triggerEvent(UISWTViewEvent.TYPE_INITIALIZE, composite); if (composite.getLayout() instanceof GridLayout) { // Force children to have GridData layoutdata. Control[] children = composite.getChildren(); for (int i = 0; i < children.length; i++) { Control control = children[i]; Object layoutData = control.getLayoutData(); if (layoutData == null || !(layoutData instanceof GridData)) { if (layoutData != null) Logger.log(new LogEvent(LogIDs.PLUGIN, LogEvent.LT_WARNING, "Plugin View '" + sViewID + "' tried to setLayoutData of " + control + " to a " + layoutData.getClass().getName())); if (children.length == 1) gridData = new GridData(SWT.FILL, SWT.FILL, true, true); else gridData = new GridData(); control.setLayoutData(gridData); } } } } else if (iControlType == UISWTView.CONTROLTYPE_AWT) { composite = new Composite(parent, SWT.EMBEDDED); FillLayout layout = new FillLayout(); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); GridData gridData = new GridData(GridData.FILL_BOTH); composite.setLayoutData(gridData); Frame f = SWT_AWT.new_Frame(composite); Panel pan = new Panel(); f.add(pan); triggerEvent(UISWTViewEvent.TYPE_INITIALIZE, pan); } else if (iControlType == UISWTViewCore.CONTROLTYPE_SKINOBJECT) { triggerEvent(UISWTViewEvent.TYPE_INITIALIZE, getSkinObject()); } } /** * @return */ public boolean requestClose() { return triggerEventRaw(UISWTViewEvent.TYPE_CLOSE, null); } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#useCoreDataSource() */ public boolean useCoreDataSource() { return useCoreDataSource; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#setUseCoreDataSource(boolean) */ public void setUseCoreDataSource(boolean useCoreDataSource) { if (this.useCoreDataSource == useCoreDataSource) { return; } this.useCoreDataSource = useCoreDataSource; triggerEvent(UISWTViewEvent.TYPE_DATASOURCE_CHANGED, dataSource); } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#getSkinObject() */ public PluginUISWTSkinObject getSkinObject() { return skinObject; } /* (non-Javadoc) * @see org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore#setSkinObject(org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject, org.eclipse.swt.widgets.Composite) */ public void setSkinObject(PluginUISWTSkinObject skinObject, Composite c) { this.skinObject = skinObject; this.composite = c; } /* (non-Javadoc) * @see org.gudy.azureus2.core3.util.AEDiagnosticsEvidenceGenerator#generate(org.gudy.azureus2.core3.util.IndentWriter) */ public void generate(IndentWriter writer) { if (eventListener instanceof AEDiagnosticsEvidenceGenerator) { writer.println("View: " + sViewID + ": " + sTitle); try { writer.indent(); ((AEDiagnosticsEvidenceGenerator) eventListener).generate(writer); } catch (Exception e) { } finally { writer.exdent(); } } else { writer.println("View (no generator): " + sViewID + ": " + sTitle); } } public boolean toolBarItemActivated(ToolBarItem item, long activationType, Object datasource) { if (toolbarListener != null) { return toolbarListener.toolBarItemActivated(item, activationType, datasource); } if (eventListener instanceof UIPluginViewToolBarListener) { return ((UIPluginViewToolBarListener) eventListener).toolBarItemActivated(item, activationType, datasource); } else if (eventListener instanceof ToolBarEnabler) { return ((ToolBarEnabler) eventListener).toolBarItemActivated(item.getID()); } return false; } public void refreshToolBarItems(Map<String, Long> list) { if (eventListener instanceof UIPluginViewToolBarListener) { ((UIPluginViewToolBarListener) eventListener).refreshToolBarItems(list); } else if (eventListener instanceof ToolBarEnabler) { Map<String, Boolean> states = new HashMap<String, Boolean>(); for ( Map.Entry<String, Long> entry: list.entrySet()){ String id = entry.getKey(); states.put(id, (entry.getValue() & UIToolBarItem.STATE_ENABLED) > 0); } ((ToolBarEnabler) eventListener).refreshToolBar(states); for ( Map.Entry<String, Boolean> entry: states.entrySet()){ String id = entry.getKey(); Boolean visible = entry.getValue(); list.put(id, visible ? UIToolBarItem.STATE_ENABLED : 0); } } } public void setToolBarListener(UIPluginViewToolBarListener l) { toolbarListener = l; } public UIPluginViewToolBarListener getToolBarListener() { return toolbarListener; } public void setUserData( Object key, Object data ) { synchronized( this ){ if ( user_data == null ){ if ( data == null ){ return; } user_data = new HashMap<Object, Object>(); } if ( data == null ){ user_data.remove( key ); if ( user_data.isEmpty()){ user_data = null; } }else{ user_data.put( key, data ); } } } public Object getUserData( Object key ) { Map<Object,Object> temp = user_data; if ( temp == null ){ return( null ); }else{ return( temp.get( key )); } } }