/**
*
*/
package org.gudy.azureus2.ui.swt.pluginsimpl;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.AERunnable;
import org.gudy.azureus2.pluginsimpl.local.ui.menus.MenuContextImpl;
import org.gudy.azureus2.ui.common.util.MenuItemManager;
import org.gudy.azureus2.ui.swt.MenuBuildUtils;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.mainwindow.MainStatusBar;
import org.gudy.azureus2.ui.swt.mainwindow.MainStatusBar.CLabelPadding;
import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntry;
import org.gudy.azureus2.ui.swt.plugins.UISWTStatusEntryListener;
import com.aelitis.azureus.ui.swt.imageloader.ImageLoader;
import org.gudy.azureus2.plugins.ui.menus.MenuContext;
import org.gudy.azureus2.plugins.ui.menus.MenuItem;
/**
* @author Allan Crooks
*
*/
public class UISWTStatusEntryImpl implements UISWTStatusEntry, MainStatusBar.CLabelUpdater {
private AEMonitor this_mon = new AEMonitor("UISWTStatusEntryImpl@" + Integer.toHexString(this.hashCode()));
private UISWTStatusEntryListener listener = null;
private MenuContextImpl menu_context = MenuContextImpl.create("status_entry");
// Used by "update".
private boolean needs_update = false;
private boolean needs_layout = false;
private String text = null;
private String tooltip = null;
private boolean image_enabled = false;
private Image image = null;
private boolean is_visible = false;
private boolean needs_disposing = false;
private boolean is_destroyed = false;
private Menu menu;
private CopyOnWriteArrayList<String> imageIDstoDispose = new CopyOnWriteArrayList<String>();
private String imageID = null;
private void checkDestroyed() {
if (is_destroyed) {throw new RuntimeException("object is destroyed, cannot be reused");}
}
public MenuContext getMenuContext() {
return this.menu_context;
}
public boolean update(CLabelPadding label) {
if (needs_disposing && !label.isDisposed()) {
if (menu != null && !menu.isDisposed()) {
menu.dispose();
menu = null;
}
label.dispose();
if (imageID != null) {
imageIDstoDispose.add(imageID);
}
releaseOldImages();
return( true );
}
boolean do_layout = needs_layout;
needs_layout = false;
if (menu_context.is_dirty) {needs_update = true; menu_context.is_dirty = false;}
if (!needs_update) {return do_layout;}
// This is where we do a big update.
try {
this_mon.enter();
update0(label);
}
finally {
this_mon.exit();
}
return do_layout;
}
/**
*
*
* @since 4.0.0.5
*/
private void releaseOldImages() {
if (imageIDstoDispose.size() > 0) {
ImageLoader imageLoader = ImageLoader.getInstance();
for (Iterator iter = imageIDstoDispose.iterator(); iter.hasNext();) {
String id = (String) iter.next();
imageLoader.releaseImage(id);
iter.remove();
}
}
}
private void update0(final CLabelPadding label) {
label.setText(text);
label.setToolTipText(tooltip);
label.setImage(image_enabled ? image : null);
label.setVisible(this.is_visible);
releaseOldImages();
MenuItem[] items = MenuItemManager.getInstance().getAllAsArray(menu_context.context);
if (items.length > 0 & menu == null) {
menu = new Menu(label);
label.setMenu(menu);
MenuBuildUtils.addMaintenanceListenerForMenu(menu,
new MenuBuildUtils.MenuBuilder() {
public void buildMenu(Menu menu, MenuEvent menuEvent) {
MenuItem[] items = MenuItemManager.getInstance().getAllAsArray(menu_context.context);
MenuBuildUtils.addPluginMenuItems(label, items, menu, true, true,
MenuBuildUtils.BASIC_MENU_ITEM_CONTROLLER);
}
}
);
}
else if (menu != null && items.length == 0) {
label.setMenu(null);
if (!menu.isDisposed()) {menu.dispose();}
this.menu = null;
}
this.needs_update = false;
}
void onClick() {
UISWTStatusEntryListener listener0 = listener; // Avoid race conditions.
if (listener0 != null) {listener.entryClicked(this);}
}
public void destroy() {
try {
this_mon.enter();
this.is_visible = false;
this.listener = null;
this.image = null;
this.needs_disposing = true;
this.is_destroyed = true;
// Remove any existing menu items.
MenuItemManager.getInstance().removeAllMenuItems(this.menu_context.context);
}
finally {
this_mon.exit();
}
}
public void setImage(int image_id) {
// we can't release the old image here because the label is still using it
// Put it into a list until the label is updated with the new image, then
// release the old
if (imageID != null) {
imageIDstoDispose.add(imageID);
}
switch (image_id) {
case IMAGE_LED_GREEN:
imageID = "greenled";
break;
case IMAGE_LED_RED:
imageID = "redled";
break;
case IMAGE_LED_YELLOW:
imageID = "yellowled";
break;
default:
imageID = "grayled";
break;
}
ImageLoader imageLoader = ImageLoader.getInstance();
this.setImage(imageLoader.getImage(imageID));
}
public void setImage(Image image) {
checkDestroyed();
this_mon.enter();
if( image != this.image ){
needs_layout = true;
}
this.image = image;
this.needs_update = true;
this_mon.exit();
}
public void setImageEnabled(boolean enabled) {
checkDestroyed();
this_mon.enter();
if ( enabled != image_enabled ){
needs_layout = true;
}
this.image_enabled = enabled;
this.needs_update = true;
this_mon.exit();
}
public void setListener(UISWTStatusEntryListener listener) {
checkDestroyed();
this.listener = listener;
}
public void setText(String text) {
checkDestroyed();
this_mon.enter();
this.text = text;
this.needs_update = true;
this_mon.exit();
}
public void setTooltipText(String text) {
checkDestroyed();
this_mon.enter();
this.tooltip = text;
this.needs_update = true;
this_mon.exit();
}
public void setVisible(boolean visible) {
checkDestroyed();
this_mon.enter();
this.is_visible = visible;
this.needs_update = true;
this_mon.exit();
}
public void created(final MainStatusBar.CLabelPadding label) {
final Listener click_listener = new Listener() {
public void handleEvent(Event e) {
onClick();
}
};
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
label.addListener(SWT.MouseDoubleClick, click_listener);
}
}, true);
}
}