package com.aelitis.azureus.ui.swt.mdi;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.*;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.config.ParameterListener;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.ui.swt.Utils;
import org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject;
import org.gudy.azureus2.ui.swt.plugins.UISWTViewEventListener;
import org.gudy.azureus2.ui.swt.views.IView;
import org.gudy.azureus2.ui.swt.views.IViewAlwaysInitialize;
import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.AzureusCoreFactory;
import com.aelitis.azureus.core.AzureusCoreRunningListener;
import com.aelitis.azureus.ui.UIFunctionsManager;
import com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo;
import com.aelitis.azureus.ui.mdi.MdiEntry;
import com.aelitis.azureus.ui.mdi.MdiEntryCreationListener;
import com.aelitis.azureus.ui.swt.skin.SWTSkinObject;
import com.aelitis.azureus.ui.swt.skin.SWTSkinObjectTabFolder;
import com.aelitis.azureus.ui.swt.utils.ColorCache;
public class TabbedMDI
extends BaseMDI
implements AEDiagnosticsEvidenceGenerator
{
private CTabFolder tabFolder;
public TabbedMDI() {
super();
AEDiagnostics.addEvidenceGenerator(this);
}
public Object skinObjectCreated(SWTSkinObject skinObject, Object params) {
super.skinObjectCreated(skinObject, params);
creatMDI();
// building plugin views needs UISWTInstance, which needs core.
AzureusCoreFactory.addCoreRunningListener(new AzureusCoreRunningListener() {
public void azureusCoreRunning(AzureusCore core) {
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
setupPluginViews();
}
});
}
});
try {
loadCloseables();
} catch (Throwable t) {
Debug.out(t);
}
try {
UIFunctionsManager.getUIFunctions().getUIUpdater().addUpdater(this);
} catch (Exception e) {
Debug.out(e);
}
return null;
}
private void creatMDI() {
if (soMain instanceof SWTSkinObjectTabFolder) {
tabFolder = ((SWTSkinObjectTabFolder) soMain).getTabFolder();
} else {
tabFolder = new CTabFolder((Composite) soMain.getControl(), SWT.TOP
| SWT.BORDER | SWT.CLOSE);
}
COConfigurationManager.addAndFireParameterListener("GUI_SWT_bFancyTab",
new ParameterListener() {
public void parameterChanged(String parameterName) {
Utils.execSWTThread(new AERunnable() {
public void runSupport() {
boolean simple = !COConfigurationManager.getBooleanParameter("GUI_SWT_bFancyTab");
tabFolder.setSimple(simple);
}
});
}
});
Display display = tabFolder.getDisplay();
float[] hsb = tabFolder.getBackground().getRGB().getHSB();
hsb[2] *= (Constants.isOSX) ? 0.9 : 0.97;
tabFolder.setBackground(ColorCache.getColor(display, hsb));
hsb = tabFolder.getForeground().getRGB().getHSB();
hsb[2] *= (Constants.isOSX) ? 1.1 : 0.03;
tabFolder.setForeground(ColorCache.getColor(display, hsb));
tabFolder.setSelectionBackground(new Color[] {
display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
display.getSystemColor(SWT.COLOR_LIST_BACKGROUND),
display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)
}, new int[] {
10,
90
}, true);
tabFolder.setSelectionForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
tabFolder.setSimple(!COConfigurationManager.getBooleanParameter("GUI_SWT_bFancyTab"));
tabFolder.setMinimumCharacters(25);
tabFolder.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
TabbedEntry entry = (TabbedEntry) event.item.getData("TabbedEntry");
showEntry(entry);
}
});
tabFolder.getDisplay().addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event event) {
if ( tabFolder.isDisposed()){
return;
}
// Another window has control, skip filter
Control focus_control = tabFolder.getDisplay().getFocusControl();
if (focus_control != null
&& focus_control.getShell() != tabFolder.getShell()) {
return;
}
int key = event.character;
if ((event.stateMask & SWT.MOD1) != 0 && event.character <= 26
&& event.character > 0)
key += 'a' - 1;
// ESC or CTRL+F4 closes current Tab
if (key == SWT.ESC
|| (event.keyCode == SWT.F4 && event.stateMask == SWT.CTRL)) {
MdiEntry entry = getCurrentEntry();
if (entry != null) {
entry.close(false);
}
event.doit = false;
} else if (event.keyCode == SWT.F6
|| (event.character == SWT.TAB && (event.stateMask & SWT.CTRL) != 0)) {
// F6 or Ctrl-Tab selects next Tab
// On Windows the tab key will not reach this filter, as it is
// processed by the traversal TRAVERSE_TAB_NEXT. It's unknown
// what other OSes do, so the code is here in case we get TAB
if ((event.stateMask & SWT.SHIFT) == 0) {
event.doit = false;
selectNextTab(true);
// Shift+F6 or Ctrl+Shift+Tab selects previous Tab
} else if (event.stateMask == SWT.SHIFT) {
selectNextTab(false);
event.doit = false;
}
}
}
});
tabFolder.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
saveCloseables();
}
});
}
private void selectNextTab(boolean selectNext) {
if (tabFolder == null || tabFolder.isDisposed()) {
return;
}
final int nextOrPrevious = selectNext ? 1 : -1;
int index = tabFolder.getSelectionIndex() + nextOrPrevious;
if (index == 0 && selectNext || index == -2 || tabFolder.getItemCount() < 2) {
return;
}
if (index == tabFolder.getItemCount()) {
index = 0;
} else if (index < 0) {
index = tabFolder.getItemCount() - 1;
}
// instead of .setSelection, use showEntry which will ensure view de/activations
CTabItem item = tabFolder.getItem(index);
MdiEntry entry = (MdiEntry) item.getData("TabbedEntry");
if (entry != null) {
showEntry(entry);
}
}
public boolean showEntryByID(String id) {
return loadEntryByID(id, true);
}
// @see com.aelitis.azureus.ui.mdi.MultipleDocumentInterface#loadEntryByID(java.lang.String, boolean)
public boolean loadEntryByID(String id, boolean activate) {
return loadEntryByID(id, activate, false);
}
public boolean loadEntryByID(String id, boolean activate, boolean onlyLoadOnce) {
MdiEntry entry = mapIdToEntry.get(id);
if (entry != null) {
if (activate) {
showEntry(entry);
}
return true;
}
boolean loadedOnce = COConfigurationManager.getBooleanParameter("tab.once." + id, false);
if (loadedOnce && onlyLoadOnce) {
return false;
}
MdiEntryCreationListener mdiEntryCreationListener = mapIdToCreationListener.get(id);
if (mdiEntryCreationListener != null) {
entry = mdiEntryCreationListener.createMDiEntry(id);
if (entry != null) {
if (onlyLoadOnce) {
COConfigurationManager.setParameter("tab.once." + id, true);
}
if (activate) {
showEntry(entry);
}
return true;
}
}
return false;
}
public void showEntry(final MdiEntry newEntry) {
if (newEntry == null) {
return;
}
MdiEntry oldEntry = currentEntry;
if (newEntry == oldEntry) {
triggerSelectionListener(newEntry, newEntry);
return;
}
if (oldEntry != null) {
oldEntry.hide();
}
currentEntry = (MdiEntrySWT) newEntry; // assumed MdiEntrySWT
if (newEntry != null) {
((BaseMdiEntry) newEntry).show();
}
triggerSelectionListener(newEntry, oldEntry);
}
public void updateUI() {
MdiEntry currentEntry = getCurrentEntry();
if (currentEntry != null) {
currentEntry.updateUI();
}
}
public MdiEntry createEntryFromSkinRef(String parentID, String id,
String configID, String title, ViewTitleInfo titleInfo, Object params,
boolean closeable, int index) {
MdiEntry oldEntry = getEntry(id);
if (oldEntry != null) {
return oldEntry;
}
TabbedEntry entry = new TabbedEntry(this, skin, id);
entry.setTitle(title);
entry.setSkinRef(configID, params);
setupNewEntry(entry, id, index);
return entry;
}
// @see com.aelitis.azureus.ui.swt.mdi.BaseMDI#createEntryFromSkinRef(java.lang.String, java.lang.String, java.lang.String, java.lang.String, com.aelitis.azureus.ui.common.viewtitleinfo.ViewTitleInfo, java.lang.Object, boolean, java.lang.String)
public MdiEntry createEntryFromSkinRef(String parentID, String id,
String configID, String title, ViewTitleInfo titleInfo, Object params,
boolean closeable, String preferedAfterID) {
// afterid not fully supported yet
return createEntryFromSkinRef(parentID, id, configID, title, titleInfo,
params, closeable, "".equals(preferedAfterID) ? 0 : -1);
}
public MdiEntry createEntryFromEventListener(String parentID,
UISWTViewEventListener l, String id, boolean closeable, Object datasource) {
MdiEntry oldEntry = getEntry(id);
if (oldEntry != null) {
return oldEntry;
}
TabbedEntry entry = new TabbedEntry(this, skin, id);
entry.setDatasource(datasource);
entry.setEventListener(l);
setupNewEntry(entry, id, -1);
return entry;
}
public MdiEntry createEntryFromIViewClass(String parent, String id,
String title, Class<?> iviewClass, Class<?>[] iviewClassArgs,
Object[] iviewClassVals, Object datasource, ViewTitleInfo titleInfo,
boolean closeable) {
MdiEntry oldEntry = getEntry(id);
if (oldEntry != null) {
return oldEntry;
}
TabbedEntry entry = new TabbedEntry(this, skin, id);
entry.setTitle(title);
entry.setIViewClass(iviewClass, iviewClassArgs, iviewClassVals);
entry.setDatasource(datasource);
entry.setViewTitleInfo(titleInfo);
entry.setCloseable(closeable);
setupNewEntry(entry, id, -1);
if (IViewAlwaysInitialize.class.isAssignableFrom(iviewClass)) {
entry.build();
}
return entry;
}
public MdiEntry createEntryFromIView(String parentID, IView iview, String id,
Object datasource, boolean closeable, boolean show, boolean expand) {
if (id == null) {
id = iview.getClass().getName();
int i = id.lastIndexOf('.');
if (i > 0) {
id = id.substring(i + 1);
}
}
MdiEntry oldEntry = getEntry(id);
if (oldEntry != null) {
if (show) {
showEntry(oldEntry);
}
return oldEntry;
}
TabbedEntry entry = new TabbedEntry(this, skin, id);
entry.setIView(iview);
entry.setDatasource(datasource);
setupNewEntry(entry, id, -1);
if (iview instanceof IViewAlwaysInitialize) {
entry.build();
}
if (show) {
showEntry(entry);
}
return entry;
}
private void setupNewEntry(final TabbedEntry entry, final String id,
final int index) {
synchronized (mapIdToEntry) {
mapIdToEntry.put(id, entry);
}
Utils.execSWTThreadLater(0, new AERunnable() {
public void runSupport() {
swt_setupNewEntry(entry, id, index);
}
});
}
private void swt_setupNewEntry(TabbedEntry entry, String id, int index) {
if (index < 0 || index >= tabFolder.getItemCount()) {
index = tabFolder.getItemCount();
}
CTabItem cTabItem = new CTabItem(tabFolder, SWT.CLOSE, index);
cTabItem.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (tabFolder.getItemCount() == 0) {
currentEntry = null;
}
}
});
cTabItem.setData("TabbedEntry", entry);
entry.setSwtItem(cTabItem);
}
public String getUpdateUIName() {
String name = "MDI";
MdiEntry entry = getCurrentEntry();
if (entry != null) {
name += "-" + entry.getId();
}
return name;
}
public void generate(IndentWriter writer) {
MdiEntrySWT[] entries = getEntriesSWT();
for (MdiEntrySWT entry : entries) {
if (entry == null) {
continue;
}
IView view = entry.getIView();
if (view != null) {
writer.println(view.getFullTitle());
try {
writer.indent();
view.generateDiagnostics(writer);
} catch (Exception e) {
} finally {
writer.exdent();
}
}
}
}
// @see com.aelitis.azureus.ui.swt.mdi.MultipleDocumentInterfaceSWT#getEntryFromSkinObject(org.gudy.azureus2.ui.swt.plugins.PluginUISWTSkinObject)
public MdiEntrySWT getEntryFromSkinObject(PluginUISWTSkinObject pluginSkinObject) {
if (pluginSkinObject instanceof SWTSkinObject) {
Control control = ((SWTSkinObject) pluginSkinObject).getControl();
while (control != null && !control.isDisposed()) {
Object entry = control.getData("BaseMDIEntry");
if (entry instanceof BaseMdiEntry) {
BaseMdiEntry mdiEntry = (BaseMdiEntry) entry;
return mdiEntry;
}
control = control.getParent();
}
}
return null;
}
public MdiEntry createHeader(String id, String title, String preferredAfterID) {
return null;
}
}