package com.aelitis.azureus.ui.swt.mdi;
import java.lang.reflect.Constructor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.util.AERunnable;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.mainwindow.SWTThread;
import org.gudy.azureus2.ui.swt.plugins.UISWTView;
import org.gudy.azureus2.ui.swt.pluginsimpl.UISWTViewCore;
import org.gudy.azureus2.ui.swt.views.IView;
import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
import com.aelitis.azureus.ui.mdi.MdiEntryVitalityImage;
import com.aelitis.azureus.ui.swt.skin.SWTSkin;
import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectContainer;
public class TabbedEntry
extends BaseMdiEntry implements DisposeListener
{
private CTabItem swtItem;
private SWTSkin skin;
private boolean showonSWTItemSet;
private boolean buildonSWTItemSet;
private static long uniqueNumber = 0;
public TabbedEntry(TabbedMDI mdi, SWTSkin skin, String id) {
super(mdi, id);
this.skin = skin;
}
/* (non-Javadoc)
* @note SideBarEntrySWT is neary identical to this one. Please keep them
* in sync until commonalities are placed in BaseMdiEntry
*/
public void build() {
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
swt_build();
TabbedEntry.super.build();
}
});
}
public boolean swt_build() {
if (swtItem == null) {
buildonSWTItemSet = true;
return true;
}
buildonSWTItemSet = false;
Control control = swtItem.getControl();
if (control == null) {
Composite parent = swtItem.getParent();
SWTSkinObject soParent = (SWTSkinObject) parent.getData("SkinObject");
String skinRef = getSkinRef();
if (skinRef != null) {
Shell shell = parent.getShell();
Cursor cursor = shell.getCursor();
try {
shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
// SWTSkinObjectContainer soContents = (SWTSkinObjectContainer) skin.createSkinObject(
// "MdiContents." + uniqueNumber++, "mdi.content.item",
// soParent, getSkinRefParams());
// skin.addSkinObject(soContents);
SWTSkinObject skinObject = skin.createSkinObject(id, skinRef,
soParent, getDatasourceCore());
control = skinObject.getControl();
control.setLayoutData(Utils.getFilledFormData());
control.getParent().layout(true);
// swtItem.setControl will set the control's visibility based on
// whether the control is selected. To ensure it doesn't set
// our control invisible, set selection now
CTabItem oldSelection = swtItem.getParent().getSelection();
swtItem.getParent().setSelection(swtItem);
swtItem.setControl(control);
if (oldSelection != null) {
swtItem.getParent().setSelection(oldSelection);
}
setSkinObject(skinObject, skinObject);
} finally {
shell.setCursor(cursor);
}
} else if (iview != null) {
try {
SWTSkinObjectContainer soContents = (SWTSkinObjectContainer) skin.createSkinObject(
"MdiIView." + uniqueNumber++, "mdi.content.item",
soParent);
skin.addSkinObject(soContents);
parent.setBackgroundMode(SWT.INHERIT_NONE);
Composite viewComposite = soContents.getComposite();
//viewComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
//viewComposite.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
boolean doGridLayout = true;
if (iview instanceof UISWTView) {
UISWTView swtView = (UISWTView) iview;
if (swtView.getControlType() == UISWTViewCore.CONTROLTYPE_SKINOBJECT) {
doGridLayout = false;
}
}
if (doGridLayout) {
GridLayout gridLayout = new GridLayout();
gridLayout.horizontalSpacing = gridLayout.verticalSpacing = gridLayout.marginHeight = gridLayout.marginWidth = 0;
viewComposite.setLayout(gridLayout);
viewComposite.setLayoutData(Utils.getFilledFormData());
}
if (iview instanceof UISWTViewCore) {
UISWTViewCore uiViewCore = (UISWTViewCore) iview;
uiViewCore.setSkinObject(soContents, soContents.getComposite());
}
iview.initialize(viewComposite);
setTitle(iview.getFullTitle());
Composite iviewComposite = iview.getComposite();
control = iviewComposite;
if (doGridLayout) {
Object existingLayoutData = iviewComposite.getLayoutData();
Object existingParentLayoutData = iviewComposite.getParent().getLayoutData();
if (existingLayoutData == null
|| !(existingLayoutData instanceof GridData)
&& (existingParentLayoutData instanceof GridLayout)) {
GridData gridData = new GridData(GridData.FILL_BOTH);
iviewComposite.setLayoutData(gridData);
}
}
//soContents is invisible, so of course iviwComposite is invisible
//We should do the one time layout on the first show..
//if (iviewComposite.isVisible()) {
// parent.layout(true, true);
//}
CTabItem oldSelection = swtItem.getParent().getSelection();
swtItem.getParent().setSelection(swtItem);
swtItem.setControl(soContents.getControl());
if (oldSelection != null) {
swtItem.getParent().setSelection(oldSelection);
}
setSkinObject(soContents, soContents);
} catch (Exception e) {
Debug.out("Error creating sidebar content area for " + id, e);
close(true);
}
} else if (iviewClass != null) {
try {
IView view = null;
if (iviewClassArgs == null) {
view = (IView) iviewClass.newInstance();
} else {
Constructor<?> constructor = iviewClass.getConstructor(iviewClassArgs);
view = (IView) constructor.newInstance(iviewClassVals);
}
if (view != null) {
setIView(view);
// now that we have an IView, go through show one more time
return swt_build();
}
close(true);
return false;
} catch (Exception e) {
Debug.out(e);
close(true);
}
}
if (control != null && !control.isDisposed()) {
control.setData("BaseMDIEntry", this);
control.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
close(true);
}
});
} else {
return false;
}
}
return true;
}
/* (non-Javadoc)
* @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#show()
*/
public void show() {
// ensure show order by user execThreadLater
// fixes case where two showEntries are called, the first from a non
// SWT thread, and the 2nd from a SWT thread. The first one will run last
// showing itself
Utils.execSWTThreadLater(0, new AERunnable() {
public void runSupport() {
swt_show();
}
});
}
private void swt_show() {
if (swtItem == null) {
showonSWTItemSet = true;
return;
}
showonSWTItemSet = false;
if (!swt_build()) {
return;
}
triggerOpenListeners();
if (swtItem.getParent().getSelection() != swtItem) {
swtItem.getParent().setSelection(swtItem);
}
super.show();
}
/**
* Tabs don't have Vitality Image support (yet)
*/
public MdiEntryVitalityImage addVitalityImage(String imageID) {
return null; // new SideBarVitalityImageSWT(this, imageID);
}
/* (non-Javadoc)
* @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#isCloseable()
*/
public boolean isCloseable() {
// override.. we don't support non-closeable
return true;
}
public void setSwtItem(CTabItem swtItem) {
this.swtItem = swtItem;
if (swtItem == null) {
setDisposed(true);
return;
}
setDisposed(false);
swtItem.addDisposeListener(this);
String title = getTitle();
if (title != null) {
swtItem.setText(escapeAccelerators(title));
} else if (iviewClass != null) {
swtItem.setText(iviewClass.getSimpleName());
}
if (buildonSWTItemSet) {
build();
}
if (showonSWTItemSet) {
show();
}
}
public Item getSwtItem() {
return swtItem;
}
/* (non-Javadoc)
* @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#setTitle(java.lang.String)
*/
public void setTitle(String title) {
super.setTitle(title);
if (swtItem != null) {
swtItem.setText(escapeAccelerators(title));
}
}
/* (non-Javadoc)
* @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#getVitalityImages()
*/
public MdiEntryVitalityImage[] getVitalityImages() {
return new MdiEntryVitalityImage[0];
}
/* (non-Javadoc)
* @see com.aelitis.azureus.ui.swt.mdi.BaseMdiEntry#close()
*/
public boolean close(boolean forceClose) {
// triggerCloseListener
if (!super.close(forceClose)) {
return false;
}
Utils.execSWTThread(new Runnable() {
public void run() {
if (swtItem != null && !swtItem.isDisposed()) {
swtItem.dispose();
swtItem = null;
} else if (iview != null) {
iview.delete();
iview = null;
triggerCloseListeners(!SWTThread.getInstance().isTerminated());
}
}
});
return true;
}
public void redraw() {
}
public void widgetDisposed(DisposeEvent e) {
setSwtItem(null);
triggerCloseListeners(!SWTThread.getInstance().isTerminated());
IView iview = getIView();
if (iview != null) {
setIView(null);
iview.delete();
}
SWTSkinObject so = getSkinObject();
if (so != null) {
setSkinObject(null, null);
so.getSkin().removeSkinObject(so);
}
// delay saving of removing of auto-open flag. If after the delay, we are
// still alive, it's assumed the user invoked the close, and we should
// remove the auto-open flag
Utils.execSWTThreadLater(0, new AERunnable() {
public void runSupport() {
// even though execThreadLater will not run on close of app because
// the display is disposed, do a double check of tree disposal just
// in case. We don't want to trigger close listeners or
// remove autoopen parameters if the user is closing the app (as
// opposed to closing the sidebar)
if (SWTThread.getInstance().isTerminated()) {
return;
}
try {
COConfigurationManager.removeParameter("SideBar.AutoOpen." + id);
} catch (Exception e2) {
Debug.out(e2);
}
mdi.removeItem(TabbedEntry.this);
mdi.setEntryAutoOpen(id, false);
}
});
}
private String escapeAccelerators(String str) {
if (str == null) {
return (str);
}
return str.replaceAll("&", "&&");
}
public void expandTo() {
}
public void viewTitleInfoRefresh(ViewTitleInfo titleInfoToRefresh) {
super.viewTitleInfoRefresh(titleInfoToRefresh);
if (titleInfoToRefresh == null || this.viewTitleInfo != titleInfoToRefresh) {
return;
}
if (isDisposed()) {
return;
}
String textIndicator = null;
try {
textIndicator = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_INDICATOR_TEXT);
} catch (Exception e) {
Debug.out(e);
}
if (textIndicator != null) {
setPullTitleFromIView(false);
}
String newText = (String) viewTitleInfo.getTitleInfoProperty(ViewTitleInfo.TITLE_TEXT);
if (newText != null) {
if (textIndicator != null) {
newText += " (" + textIndicator + ")";
}
setPullTitleFromIView(false);
setTitle(newText);
} else if (iview != null) {
newText = iview.getShortTitle();
if (textIndicator != null) {
newText += " (" + textIndicator + ")";
}
setTitle(newText);
}
}
// @see com.aelitis.azureus.ui.mdi.MdiEntry#isSelectable()
public boolean isSelectable() {
return true;
}
// @see com.aelitis.azureus.ui.mdi.MdiEntry#setSelectable(boolean)
public void setSelectable(boolean selectable) {
}
// @see com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT#addListener(com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener)
public void addListener(MdiSWTMenuHackListener l) {
// TODO Auto-generated method stub
}
// @see com.aelitis.azureus.ui.swt.mdi.MdiEntrySWT#removeListener(com.aelitis.azureus.ui.swt.mdi.MdiSWTMenuHackListener)
public void removeListener(MdiSWTMenuHackListener l) {
// TODO Auto-generated method stub
}
}