package com.yoursway.ide.rcp.internal;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPageListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartConstants;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PerspectiveAdapter;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
import org.eclipse.ui.internal.ide.AboutInfo;
import org.eclipse.ui.internal.ide.EditorAreaDropAdapter;
import org.eclipse.ui.internal.ide.WorkbenchActionBuilder;
import org.eclipse.ui.internal.ide.dialogs.WelcomeEditorInput;
import org.eclipse.ui.part.EditorInputTransfer;
import org.eclipse.ui.part.MarkerTransfer;
import org.eclipse.ui.part.ResourceTransfer;
import org.eclipse.ui.statushandlers.StatusManager;
import org.eclipse.update.configurator.ConfiguratorUtils;
import org.eclipse.update.configurator.IPlatformConfiguration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
/**
* Window-level advisor for the IDE.
*/
public class IDEWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
private static final String WELCOME_EDITOR_ID = "org.eclipse.ui.internal.ide.dialogs.WelcomeEditor"; //$NON-NLS-1$
private IDEWorkbenchAdvisor wbAdvisor;
private boolean editorsAndIntrosOpened = false;
private IEditorPart lastActiveEditor = null;
private IPerspectiveDescriptor lastPerspective = null;
private IWorkbenchPage lastActivePage;
private String lastEditorTitle = ""; //$NON-NLS-1$
private IPropertyListener editorPropertyListener = new IPropertyListener() {
public void propertyChanged(Object source, int propId) {
if (propId == IWorkbenchPartConstants.PROP_TITLE) {
if (lastActiveEditor != null) {
String newTitle = lastActiveEditor.getTitle();
if (!lastEditorTitle.equals(newTitle)) {
recomputeTitle();
}
}
}
}
};
private IAdaptable lastInput;
/**
* Crates a new IDE workbench window advisor.
*
* @param wbAdvisor
* the workbench advisor
* @param configurer
* the window configurer
*/
public IDEWorkbenchWindowAdvisor(IDEWorkbenchAdvisor wbAdvisor, IWorkbenchWindowConfigurer configurer) {
super(configurer);
this.wbAdvisor = wbAdvisor;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.application.WorkbenchWindowAdvisor#createActionBarAdvisor(org.eclipse.ui.application.IActionBarConfigurer)
*/
public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) {
return new WorkbenchActionBuilder(configurer);
}
/**
* Returns the workbench.
*
* @return the workbench
*/
private IWorkbench getWorkbench() {
return getWindowConfigurer().getWorkbenchConfigurer().getWorkbench();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowShellClose
*/
public boolean preWindowShellClose() {
if (getWorkbench().getWorkbenchWindowCount() > 1) {
return true;
}
// the user has asked to close the last window, while will cause the
// workbench to close in due course - prompt the user for confirmation
IPreferenceStore store = Activator.getDefault().getPreferenceStore();
boolean promptOnExit = store.getBoolean(IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW);
if (promptOnExit) {
String message;
String productName = null;
IProduct product = Platform.getProduct();
if (product != null) {
productName = product.getName();
}
if (productName == null) {
message = "Exit application?";
} else {
message = NLS.bind("Exit {0}?", productName);
}
MessageDialogWithToggle dlg = MessageDialogWithToggle.openOkCancelConfirm(getWindowConfigurer()
.getWindow().getShell(), "Confirm Exit", message, "&Always exit without prompt", false,
null, null);
if (dlg.getReturnCode() != IDialogConstants.OK_ID) {
return false;
}
if (dlg.getToggleState()) {
store.setValue(IDEInternalPreferences.EXIT_PROMPT_ON_CLOSE_LAST_WINDOW, false);
Activator.getDefault().savePluginPreferences();
}
}
return true;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.application.WorkbenchAdvisor#preWindowOpen
*/
public void preWindowOpen() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
// show the shortcut bar and progress indicator, which are hidden by
// default
configurer.setShowPerspectiveBar(true);
configurer.setShowFastViewBars(true);
configurer.setShowProgressIndicator(true);
// add the drag and drop support for the editor area
configurer.addEditorAreaTransfer(EditorInputTransfer.getInstance());
configurer.addEditorAreaTransfer(ResourceTransfer.getInstance());
configurer.addEditorAreaTransfer(FileTransfer.getInstance());
configurer.addEditorAreaTransfer(MarkerTransfer.getInstance());
configurer.configureEditorAreaDropListener(new EditorAreaDropAdapter(configurer.getWindow()));
hookTitleUpdateListeners(configurer);
}
/**
* Hooks the listeners needed on the window
*
* @param configurer
*/
private void hookTitleUpdateListeners(IWorkbenchWindowConfigurer configurer) {
// hook up the listeners to update the window title
configurer.getWindow().addPageListener(new IPageListener() {
public void pageActivated(IWorkbenchPage page) {
updateTitle();
}
public void pageClosed(IWorkbenchPage page) {
updateTitle();
}
public void pageOpened(IWorkbenchPage page) {
// do nothing
}
});
configurer.getWindow().addPerspectiveListener(new PerspectiveAdapter() {
public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
updateTitle();
}
public void perspectiveSavedAs(IWorkbenchPage page, IPerspectiveDescriptor oldPerspective,
IPerspectiveDescriptor newPerspective) {
updateTitle();
}
public void perspectiveDeactivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
updateTitle();
}
});
configurer.getWindow().getPartService().addPartListener(new IPartListener2() {
public void partActivated(IWorkbenchPartReference ref) {
if (ref instanceof IEditorReference) {
updateTitle();
}
}
public void partBroughtToTop(IWorkbenchPartReference ref) {
if (ref instanceof IEditorReference) {
updateTitle();
}
}
public void partClosed(IWorkbenchPartReference ref) {
updateTitle();
}
public void partDeactivated(IWorkbenchPartReference ref) {
// do nothing
}
public void partOpened(IWorkbenchPartReference ref) {
// do nothing
}
public void partHidden(IWorkbenchPartReference ref) {
// do nothing
}
public void partVisible(IWorkbenchPartReference ref) {
// do nothing
}
public void partInputChanged(IWorkbenchPartReference ref) {
// do nothing
}
});
}
private String computeTitle() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
IWorkbenchPage currentPage = configurer.getWindow().getActivePage();
IEditorPart activeEditor = null;
if (currentPage != null) {
activeEditor = currentPage.getActiveEditor();
}
String title = null;
IProduct product = Platform.getProduct();
if (product != null) {
title = product.getName();
}
if (title == null) {
title = ""; //$NON-NLS-1$
}
if (currentPage != null) {
if (activeEditor != null) {
lastEditorTitle = activeEditor.getTitleToolTip();
title = NLS.bind("{0} - {1}", lastEditorTitle, title);
}
IPerspectiveDescriptor persp = currentPage.getPerspective();
String label = ""; //$NON-NLS-1$
if (persp != null) {
label = persp.getLabel();
}
IAdaptable input = currentPage.getInput();
if (input != null && !input.equals(wbAdvisor.getDefaultPageInput())) {
label = currentPage.getLabel();
}
if (label != null && !label.equals("")) { //$NON-NLS-1$
title = NLS.bind("{0} - {1}", label, title);
}
}
String workspaceLocation = wbAdvisor.getWorkspaceLocation();
if (workspaceLocation != null) {
title = NLS.bind("{0} - {1}", title, workspaceLocation);
}
return title;
}
private void recomputeTitle() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
String oldTitle = configurer.getTitle();
String newTitle = computeTitle();
if (!newTitle.equals(oldTitle)) {
configurer.setTitle(newTitle);
}
}
/**
* Updates the window title. Format will be: [pageInput -]
* [currentPerspective -] [editorInput -] [workspaceLocation -] productName
*/
private void updateTitle() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
IWorkbenchWindow window = configurer.getWindow();
IEditorPart activeEditor = null;
IWorkbenchPage currentPage = window.getActivePage();
IPerspectiveDescriptor persp = null;
IAdaptable input = null;
if (currentPage != null) {
activeEditor = currentPage.getActiveEditor();
persp = currentPage.getPerspective();
input = currentPage.getInput();
}
// Nothing to do if the editor hasn't changed
if (activeEditor == lastActiveEditor && currentPage == lastActivePage && persp == lastPerspective
&& input == lastInput) {
return;
}
if (lastActiveEditor != null) {
lastActiveEditor.removePropertyListener(editorPropertyListener);
}
lastActiveEditor = activeEditor;
lastActivePage = currentPage;
lastPerspective = persp;
lastInput = input;
if (activeEditor != null) {
activeEditor.addPropertyListener(editorPropertyListener);
}
recomputeTitle();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.application.WorkbenchAdvisor#postWindowRestore
*/
public void postWindowRestore() throws WorkbenchException {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
IWorkbenchWindow window = configurer.getWindow();
int index = getWorkbench().getWorkbenchWindowCount() - 1;
AboutInfo[] welcomePerspectiveInfos = wbAdvisor.getWelcomePerspectiveInfos();
if (index >= 0 && welcomePerspectiveInfos != null && index < welcomePerspectiveInfos.length) {
// find a page that exist in the window
IWorkbenchPage page = window.getActivePage();
if (page == null) {
IWorkbenchPage[] pages = window.getPages();
if (pages != null && pages.length > 0) {
page = pages[0];
}
}
// if the window does not contain a page, create one
String perspectiveId = welcomePerspectiveInfos[index].getWelcomePerspectiveId();
if (page == null) {
IAdaptable root = wbAdvisor.getDefaultPageInput();
page = window.openPage(perspectiveId, root);
} else {
IPerspectiveRegistry reg = getWorkbench().getPerspectiveRegistry();
IPerspectiveDescriptor desc = reg.findPerspectiveWithId(perspectiveId);
if (desc != null) {
page.setPerspective(desc);
}
}
// set the active page and open the welcome editor
window.setActivePage(page);
page.openEditor(new WelcomeEditorInput(welcomePerspectiveInfos[index]), WELCOME_EDITOR_ID, true);
}
}
/**
* Tries to open the intro, if one exists and otherwise will open the legacy
* Welcome pages.
*
* @see org.eclipse.ui.application.WorkbenchWindowAdvisor#openIntro()
*/
public void openIntro() {
if (editorsAndIntrosOpened) {
return;
}
editorsAndIntrosOpened = true;
// don't try to open the welcome editors if there is an intro
if (wbAdvisor.hasIntro()) {
super.openIntro();
} else {
openWelcomeEditors(getWindowConfigurer().getWindow());
// save any preferences changes caused by the above actions
Activator.getDefault().savePluginPreferences();
}
}
/*
* Open the welcome editor for the primary feature and for any newly
* installed features.
*/
private void openWelcomeEditors(IWorkbenchWindow window) {
if (Activator.getDefault().getPreferenceStore().getBoolean(IDEInternalPreferences.WELCOME_DIALOG)) {
// show the welcome page for the product the first time the
// workbench opens
IProduct product = Platform.getProduct();
if (product == null) {
return;
}
AboutInfo productInfo = new AboutInfo(product);
URL url = productInfo.getWelcomePageURL();
if (url == null) {
return;
}
Activator.getDefault().getPreferenceStore()
.setValue(IDEInternalPreferences.WELCOME_DIALOG, false);
openWelcomeEditor(window, new WelcomeEditorInput(productInfo), null);
} else {
// Show the welcome page for any newly installed features
List welcomeFeatures = new ArrayList();
for (Iterator it = wbAdvisor.getNewlyAddedBundleGroups().entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String versionedId = (String) entry.getKey();
String featureId = versionedId.substring(0, versionedId.indexOf(':'));
AboutInfo info = (AboutInfo) entry.getValue();
if (info != null && info.getWelcomePageURL() != null) {
welcomeFeatures.add(info);
// activate the feature plug-in so it can run some install
// code
IPlatformConfiguration platformConfiguration = ConfiguratorUtils
.getCurrentPlatformConfiguration();
IPlatformConfiguration.IFeatureEntry feature = platformConfiguration
.findConfiguredFeatureEntry(featureId);
if (feature != null) {
String pi = feature.getFeaturePluginIdentifier();
if (pi != null) {
// Start the bundle if there is one
Bundle bundle = Platform.getBundle(pi);
if (bundle != null) {
try {
bundle.start(Bundle.START_TRANSIENT);
} catch (BundleException exception) {
StatusManager.getManager().handle(
new Status(IStatus.ERROR, Activator.PLUGIN_ID,
"Failed to load feature", exception));//$NON-NLS-1$
}
}
}
}
}
}
int wCount = getWorkbench().getWorkbenchWindowCount();
for (int i = 0; i < welcomeFeatures.size(); i++) {
AboutInfo newInfo = (AboutInfo) welcomeFeatures.get(i);
String id = newInfo.getWelcomePerspectiveId();
// Other editors were already opened in postWindowRestore(..)
if (id == null || i >= wCount) {
openWelcomeEditor(window, new WelcomeEditorInput(newInfo), id);
}
}
}
}
/**
* Open a welcome editor for the given input
*/
private void openWelcomeEditor(IWorkbenchWindow window, WelcomeEditorInput input, String perspectiveId) {
if (getWorkbench().getWorkbenchWindowCount() == 0) {
// Something is wrong, there should be at least
// one workbench window open by now.
return;
}
IWorkbenchWindow win = window;
if (perspectiveId != null) {
try {
win = getWorkbench().openWorkbenchWindow(perspectiveId, wbAdvisor.getDefaultPageInput());
if (win == null) {
win = window;
}
} catch (WorkbenchException e) {
Activator.log("Error opening window with welcome perspective.", e.getStatus()); //$NON-NLS-1$
return;
}
}
if (win == null) {
win = getWorkbench().getWorkbenchWindows()[0];
}
IWorkbenchPage page = win.getActivePage();
String id = perspectiveId;
if (id == null) {
id = getWorkbench().getPerspectiveRegistry().getDefaultPerspective();
}
if (page == null) {
try {
page = win.openPage(id, wbAdvisor.getDefaultPageInput());
} catch (WorkbenchException e) {
ErrorDialog.openError(win.getShell(), "Problems Opening Page", e.getMessage(), e.getStatus());
}
}
if (page == null) {
return;
}
if (page.getPerspective() == null) {
try {
page = getWorkbench().showPerspective(id, win);
} catch (WorkbenchException e) {
ErrorDialog.openError(win.getShell(), "Problem", "Unable to open editor", e.getStatus());
return;
}
}
page.setEditorAreaVisible(true);
// see if we already have an editor
IEditorPart editor = page.findEditor(input);
if (editor != null) {
page.activate(editor);
return;
}
try {
page.openEditor(input, WELCOME_EDITOR_ID);
} catch (PartInitException e) {
ErrorDialog.openError(win.getShell(), "Problem", "Unable to open editor", e.getStatus());
}
return;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.application.WorkbenchAdvisor#createEmptyWindowContents(org.eclipse.ui.application.IWorkbenchWindowConfigurer,
* org.eclipse.swt.widgets.Composite)
*/
public Control createEmptyWindowContents(Composite parent) {
final IWorkbenchWindow window = getWindowConfigurer().getWindow();
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
Display display = composite.getDisplay();
Color bgCol = display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND);
composite.setBackground(bgCol);
Label label = new Label(composite, SWT.WRAP);
label.setForeground(display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));
label.setBackground(bgCol);
label.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT));
String msg = "No perspectives are open. To open a perspective, press this button:";
label.setText(msg);
ToolBarManager toolBarManager = new ToolBarManager();
// TODO: should obtain the open perspective action from ActionFactory
IAction openPerspectiveAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG.create(window);
toolBarManager.add(openPerspectiveAction);
ToolBar toolBar = toolBarManager.createControl(composite);
toolBar.setBackground(bgCol);
return composite;
}
}