/*
* Created on 19-Apr-2004
* Created by Paul Gardner
* Copyright (C) 2004, 2005, 2006 Aelitis, 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, or (at your option) any later version.
* 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.
* 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.pluginsimpl.local.ui;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.pluginsimpl.local.deprecate.PluginDeprecation;
import org.gudy.azureus2.pluginsimpl.local.ui.SWT.SWTManagerImpl;
import org.gudy.azureus2.pluginsimpl.local.ui.model.BasicPluginConfigModelImpl;
import org.gudy.azureus2.pluginsimpl.local.ui.model.BasicPluginViewModelImpl;
import org.gudy.azureus2.pluginsimpl.local.ui.menus.MenuManagerImpl;
import org.gudy.azureus2.pluginsimpl.local.ui.tables.TableManagerImpl;
import org.gudy.azureus2.plugins.PluginConfig;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.PluginView;
import org.gudy.azureus2.plugins.logging.LoggerChannel;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.plugins.ui.*;
import org.gudy.azureus2.plugins.ui.menus.MenuManager;
import org.gudy.azureus2.plugins.ui.SWT.SWTManager;
import org.gudy.azureus2.plugins.ui.config.ConfigSection;
import org.gudy.azureus2.plugins.ui.model.BasicPluginConfigModel;
import org.gudy.azureus2.plugins.ui.model.BasicPluginViewModel;
import org.gudy.azureus2.plugins.ui.model.PluginConfigModel;
import org.gudy.azureus2.plugins.ui.model.PluginViewModel;
import org.gudy.azureus2.plugins.ui.tables.TableManager;
import com.aelitis.azureus.core.util.CopyOnWriteList;
import com.aelitis.azureus.ui.IUIIntializer;
/**
* @author parg
*
*/
public class
UIManagerImpl
implements UIManager
{
protected static AEMonitor class_mon = new AEMonitor( "UIManager:class" );
protected static boolean initialisation_complete;
protected static CopyOnWriteList<Object[]> ui_listeners = new CopyOnWriteList<Object[]>();
protected static CopyOnWriteList ui_event_listeners = new CopyOnWriteList();
protected static List<UIInstanceFactory> ui_factories = new ArrayList<UIInstanceFactory>();
protected static List<UIManagerEventAdapter> ui_event_history = new ArrayList<UIManagerEventAdapter>();
protected static List<BasicPluginConfigModel> configModels = new ArrayList<BasicPluginConfigModel>();
protected PluginInterface pi;
protected PluginConfig plugin_config;
protected String key_prefix;
protected TableManager table_manager;
protected MenuManager menu_manager;
public
UIManagerImpl(
PluginInterface _pi )
{
pi =_pi;
plugin_config = pi.getPluginconfig();
key_prefix = plugin_config.getPluginConfigKeyPrefix();
table_manager = new TableManagerImpl( this );
menu_manager = new MenuManagerImpl( this );
}
public PluginInterface
getPluginInterface()
{
return( pi );
}
public BasicPluginViewModel
getBasicPluginViewModel(
String name )
{
// grrr, RSSImport plugin directly uses this method
return( createBasicPluginViewModel( name ));
// throw( new RuntimeException( "Deprecated method - use createBasicPluginViewModel"));
}
public PluginView
createPluginView(
PluginViewModel model )
{
try{
return( SWTManagerImpl.getSingleton().createPluginView( model ));
}catch( Throwable e ){
e.printStackTrace();
return( null );
}
}
public BasicPluginViewModel
createBasicPluginViewModel(
String name )
{
final BasicPluginViewModel model = new BasicPluginViewModelImpl( this, name );
fireEvent( pi, UIManagerEvent.ET_PLUGIN_VIEW_MODEL_CREATED, model );
return( model );
}
public void
destroy(
final BasicPluginViewModel model )
{
fireEvent( pi, UIManagerEvent.ET_PLUGIN_VIEW_MODEL_DESTROYED, model );
}
public BasicPluginConfigModel
createBasicPluginConfigModel(
String section_name )
{
return( createBasicPluginConfigModel( ConfigSection.SECTION_PLUGINS, section_name ));
}
public BasicPluginConfigModel
createBasicPluginConfigModel(
String parent_section,
String section_name )
{
final BasicPluginConfigModel model = new BasicPluginConfigModelImpl( this, parent_section, section_name );
try{
class_mon.enter();
configModels.add(model);
}finally{
class_mon.exit();
}
fireEvent( pi, UIManagerEvent.ET_PLUGIN_CONFIG_MODEL_CREATED, model );
return( model );
}
public void
destroy(
final BasicPluginConfigModel model )
{
try{
class_mon.enter();
configModels.remove(model);
}finally{
class_mon.exit();
}
fireEvent( pi, UIManagerEvent.ET_PLUGIN_CONFIG_MODEL_DESTROYED, model );
}
public PluginConfigModel[]
getPluginConfigModels()
{
try{
class_mon.enter();
return (PluginConfigModel[]) configModels.toArray(new PluginConfigModel[0]);
}finally{
class_mon.exit();
}
}
public void
copyToClipBoard(
final String data )
throws UIException
{
boolean ok = fireEvent( pi, UIManagerEvent.ET_COPY_TO_CLIPBOARD, data );
if ( !ok ){
throw( new UIException("Failed to deliver request to UI" ));
}
}
public void
openURL(
final URL url )
throws UIException
{
boolean ok = fireEvent( pi, UIManagerEvent.ET_OPEN_URL, url );
if ( !ok ){
throw( new UIException("Failed to deliver request to UI" ));
}
}
public TableManager getTableManager() {
return( table_manager );
}
public MenuManager getMenuManager() {
return menu_manager;
}
public SWTManager getSWTManager() {
PluginDeprecation.call("getSWTManager", pi.getPluginID());
return SWTManagerImpl.getSingleton();
}
public static void
initialisationComplete()
{
List<Object[]> to_fire = new ArrayList<Object[]>();
try{
class_mon.enter();
initialisation_complete = true;
for (int j=0;j<ui_factories.size();j++){
UIInstanceFactory factory = (UIInstanceFactory)ui_factories.get(j);
Iterator<Object[]> it = ui_listeners.iterator();
while( it.hasNext()){
Object[] entry = it.next();
List<UIInstanceFactory> fired = (List<UIInstanceFactory>)entry[2];
if ( !fired.contains( factory )){
fired.add( factory );
to_fire.add( new Object[]{ entry[0], factory.getInstance((PluginInterface)entry[1])});
}
}
}
}finally{
class_mon.exit();
}
for ( Object[] entry: to_fire ){
try{
((UIManagerListener)entry[0]).UIAttached( (UIInstance)entry[1] );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
public void attachUI(UIInstanceFactory factory) throws UIException {
attachUI(factory, null);
}
public void
attachUI(
UIInstanceFactory factory,
IUIIntializer init )
{
List<Object[]> to_fire = new ArrayList<Object[]>();
try{
class_mon.enter();
ui_factories.add( factory );
if ( initialisation_complete ){
Iterator<Object[]> it = ui_listeners.iterator();
while( it.hasNext()){
Object[] entry = (Object[])it.next();
List<UIInstanceFactory> fired = (List<UIInstanceFactory>)entry[2];
fired.add( factory );
to_fire.add( new Object[]{ entry[0], entry[1], factory.getInstance((PluginInterface)entry[1])});
}
}
}finally{
class_mon.exit();
}
for ( Object[] entry: to_fire ){
PluginInterface pi = (PluginInterface)entry[1];
String name = pi.getPluginName();
if ( init != null ){
init.reportCurrentTask(MessageText.getString("splash.plugin.UIinit",new String[] {name}));
init.increaseProgress();
}
try{
((UIManagerListener)entry[0]).UIAttached( (UIInstance)entry[2]);
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
public void
detachUI(
UIInstanceFactory factory )
throws UIException
{
factory.detach();
List<Object[]> to_fire = new ArrayList<Object[]>();
try{
class_mon.enter();
ui_factories.remove( factory );
if ( initialisation_complete ){
Iterator<Object[]> it = ui_listeners.iterator();
while( it.hasNext()){
Object[] entry = (Object[])it.next();
List<UIInstanceFactory> fired = (List<UIInstanceFactory>)entry[2];
fired.remove( factory );
to_fire.add( new Object[]{ entry[0], factory.getInstance((PluginInterface)entry[1])});
}
}
}finally{
class_mon.exit();
}
for ( Object[] entry: to_fire ){
try{
((UIManagerListener)entry[0]).UIDetached((UIInstance)entry[1]);
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
public void
addUIListener(
UIManagerListener listener )
{
List<UIInstance> to_fire = new ArrayList<UIInstance>();
try{
class_mon.enter();
List<UIInstanceFactory> fired = new ArrayList<UIInstanceFactory>();
ui_listeners.add( new Object[]{ listener, pi, fired });
if ( initialisation_complete ){
for (int i=0;i<ui_factories.size();i++){
UIInstanceFactory factory = (UIInstanceFactory)ui_factories.get(i);
to_fire.add( factory.getInstance( pi ));
}
}
}finally{
class_mon.exit();
}
for ( UIInstance instance: to_fire ){
try{
listener.UIAttached( instance );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
public void
removeUIListener(
UIManagerListener listener )
{
try{
class_mon.enter();
Iterator it = ui_listeners.iterator();
while( it.hasNext()){
Object[] entry = (Object[])it.next();
if ( entry[0] == listener ){
it.remove();
}
}
}finally{
class_mon.exit();
}
}
public void
addUIEventListener(
UIManagerEventListener listener )
{
List ui_event_history_copy;
try{
class_mon.enter();
ui_event_listeners.add( listener );
ui_event_history_copy = new ArrayList( ui_event_history );
}finally{
class_mon.exit();
}
for (int i=0;i<ui_event_history_copy.size();i++){
try{
listener.eventOccurred((UIManagerEvent)ui_event_history_copy.get(i));
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
public void
removeUIEventListener(
UIManagerEventListener listener )
{
try{
class_mon.enter();
ui_event_listeners.remove( listener );
}finally{
class_mon.exit();
}
}
public boolean hasUIInstances() {return !ui_factories.isEmpty();}
public UIInstance[] getUIInstances() {
try {
class_mon.enter();
ArrayList result = new ArrayList(ui_factories.size());
for (int i=0;i<ui_factories.size();i++){
UIInstanceFactory instance = (UIInstanceFactory)ui_factories.get(i);
result.add(instance.getInstance(pi));
}
return (UIInstance[])result.toArray(new UIInstance[result.size()]);
}
finally {
class_mon.exit();
}
}
public static boolean
fireEvent(
PluginInterface pi,
int type,
Object data )
{
return( fireEvent( new UIManagerEventAdapter( pi, type, data )));
}
public static boolean
fireEvent(
UIManagerEventAdapter event )
{
boolean delivered = false;
Iterator event_it = ui_event_listeners.iterator();
while( event_it.hasNext()){
try{
if (((UIManagerEventListener)event_it.next()).eventOccurred( event )){
delivered = true;
break;
}
}catch( Throwable e ){
e.printStackTrace();
}
}
int type = event.getType();
// some events need to be replayed when new UIs attach
if ( type == UIManagerEvent.ET_PLUGIN_VIEW_MODEL_CREATED ||
type == UIManagerEvent.ET_PLUGIN_CONFIG_MODEL_CREATED ||
type == UIManagerEvent.ET_ADD_TABLE_CONTEXT_MENU_ITEM ||
type == UIManagerEvent.ET_ADD_MENU_ITEM ||
type == UIManagerEvent.ET_REMOVE_TABLE_CONTEXT_MENU_ITEM ||
type == UIManagerEvent.ET_REMOVE_MENU_ITEM) {
delivered = true;
try{
class_mon.enter();
ui_event_history.add( event );
}finally{
class_mon.exit();
}
}else if ( type == UIManagerEvent.ET_PLUGIN_VIEW_MODEL_DESTROYED ||
type == UIManagerEvent.ET_PLUGIN_CONFIG_MODEL_DESTROYED ){
// remove any corresponding history events for creation of these entities
delivered = true;
try{
class_mon.enter();
Iterator history_it = ui_event_history.iterator();
while( history_it.hasNext()){
UIManagerEvent e = (UIManagerEvent)history_it.next();
int e_type = e.getType();
if ( e_type == UIManagerEvent.ET_PLUGIN_VIEW_MODEL_CREATED ||
e_type == UIManagerEvent.ET_PLUGIN_CONFIG_MODEL_CREATED ){
if ( e.getData() == event.getData()){
history_it.remove();
break;
}
}
}
}finally{
class_mon.exit();
}
}
return( delivered );
}
public void
showTextMessage(
final String title_resource,
final String message_resource,
final String contents )
{
fireEvent( pi, UIManagerEvent.ET_SHOW_TEXT_MESSAGE, new String[]{ title_resource, message_resource, contents });
}
public long
showMessageBox(
String title_resource,
String message_resource,
long message_map )
{
UIManagerEventAdapter event =
new UIManagerEventAdapter(
pi,
UIManagerEvent.ET_SHOW_MSG_BOX,
new Object[]{ title_resource, message_resource, new Long( message_map ) });
if (!fireEvent( event )){
return( UIManagerEvent.MT_NONE );
}
return(((Long)event.getResult()).longValue());
}
public void
openTorrent(
Torrent torrent)
{
fireEvent( pi, UIManagerEvent.ET_OPEN_TORRENT_VIA_TORRENT, torrent );
}
public void openFile(File file) {fireEvent(pi,UIManagerEvent.ET_FILE_OPEN, file);}
public void showFile(File file) {fireEvent(pi,UIManagerEvent.ET_FILE_SHOW, file);}
public boolean showConfigSection(String sectionID) {
UIManagerEventAdapter event = new UIManagerEventAdapter(
pi, UIManagerEvent.ET_SHOW_CONFIG_SECTION, sectionID);
if (!fireEvent(event))
return false;
if (event.getResult() instanceof Boolean)
return false;
return ((Boolean)event.getResult()).booleanValue();
}
public UIInputReceiver getInputReceiver() {
UIInstance[] instances = this.getUIInstances();
UIInputReceiver r = null;
for (int i=0; i<instances.length; i++) {
r = instances[i].getInputReceiver();
if (r != null) {return r;}
}
return null;
}
public UIMessage createMessage() {
UIInstance[] instances = this.getUIInstances();
UIMessage r = null;
for (int i=0; i<instances.length; i++) {
r = instances[i].createMessage();
if (r != null) {return r;}
}
return null;
}
public BasicPluginViewModel createLoggingViewModel(
LoggerChannel channel, boolean use_plugin_name
) {
String log_view_name = (use_plugin_name) ? pi.getPluginName() : channel.getName();
BasicPluginViewModel model = createBasicPluginViewModel(log_view_name);
model.getActivity().setVisible(false);
model.getProgress().setVisible(false);
model.getStatus().setVisible(false);
model.attachLoggerChannel(channel);
return model;
}
public static void
unload(
PluginInterface pi )
{
try{
class_mon.enter();
Iterator it = ui_listeners.iterator();
while( it.hasNext()){
Object[] entry = (Object[])it.next();
if ( pi == (PluginInterface)entry[1] ){
it.remove();
}
}
Iterator<UIManagerEventAdapter> ev_it = ui_event_history.iterator();
while( ev_it.hasNext()){
UIManagerEventAdapter event = ev_it.next();
if ( event.getPluginInterface() == pi ){
ev_it.remove();
}
}
}finally{
class_mon.exit();
}
}
}