blob: 308e622b2d1da278e89b4f299c765dd60ca6aa63 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.dialogs;
import com.ibm.icu.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.IPreferenceConstants;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPage;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
import org.eclipse.ui.internal.registry.PerspectiveRegistry;
import org.eclipse.ui.internal.util.Descriptors;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.internal.util.Util;
/**
* The Workbench / Perspectives preference page.
*/
public class PerspectivesPreferencePage extends PreferencePage implements
IWorkbenchPreferencePage {
private IWorkbench workbench;
private PerspectiveRegistry perspectiveRegistry;
private ArrayList perspectives;
private String defaultPerspectiveId;
private ArrayList perspToDelete = new ArrayList();
private ArrayList perspToRevert = new ArrayList();
private Table perspectivesTable;
private Button revertButton;
private Button deleteButton;
private Button setDefaultButton;
// widgets for open perspective mode;
private Button openSameWindowButton;
private Button openNewWindowButton;
private int openPerspMode;
// widgets for open view mode
private int openViewMode;
private Button openEmbedButton;
private Button openFastButton;
// labels
private final String OVM_TITLE = WorkbenchMessages.OpenViewMode_title;
private final String OVM_EMBED = WorkbenchMessages.OpenViewMode_embed;
private final String OVM_FAST = WorkbenchMessages.OpenViewMode_fast;
private final String OPM_TITLE = WorkbenchMessages.OpenPerspectiveMode_optionsTitle;
private final String OPM_SAME_WINDOW = WorkbenchMessages.OpenPerspectiveMode_sameWindow;
private final String OPM_NEW_WINDOW = WorkbenchMessages.OpenPerspectiveMode_newWindow;
/**
* <code>Comparator</code> to compare two perspective descriptors
*/
private Comparator comparator = new Comparator() {
private Collator collator = Collator.getInstance();
public int compare(Object ob1, Object ob2) {
IPerspectiveDescriptor d1 = (IPerspectiveDescriptor) ob1;
IPerspectiveDescriptor d2 = (IPerspectiveDescriptor) ob2;
return collator.compare(d1.getLabel(), d2.getLabel());
}
};
/**
* Creates the page's UI content.
*/
protected Control createContents(Composite parent) {
// @issue if the product subclasses this page, then it should provide
// the help content
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
IWorkbenchHelpContextIds.PERSPECTIVES_PREFERENCE_PAGE);
Composite composite = createComposite(parent);
createOpenPerspButtonGroup(composite);
createOpenViewButtonGroup(composite);
createCustomizePerspective(composite);
return composite;
}
/**
* Creates the composite which will contain all the preference controls for
* this page.
*
* @param parent
* the parent composite
* @return the composite for this page
*/
protected Composite createComposite(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridData data = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(data);
composite.setFont(parent.getFont());
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.verticalSpacing = 10;
composite.setLayout(layout);
return composite;
}
/**
* Create a composite that contains buttons for selecting the open
* perspective mode.
*
* @param composite
* the parent composite
*/
protected void createOpenPerspButtonGroup(Composite composite) {
Font font = composite.getFont();
Group buttonComposite = new Group(composite, SWT.LEFT);
buttonComposite.setText(OPM_TITLE);
buttonComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
buttonComposite.setFont(composite.getFont());
GridLayout layout = new GridLayout();
layout.numColumns = 2;
buttonComposite.setLayout(layout);
openSameWindowButton = new Button(buttonComposite, SWT.RADIO);
openSameWindowButton.setText(OPM_SAME_WINDOW);
openSameWindowButton
.setSelection(IPreferenceConstants.OPM_ACTIVE_PAGE == openPerspMode);
openSameWindowButton.setFont(font);
openSameWindowButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
openPerspMode = IPreferenceConstants.OPM_ACTIVE_PAGE;
}
});
openNewWindowButton = new Button(buttonComposite, SWT.RADIO);
openNewWindowButton.setText(OPM_NEW_WINDOW);
openNewWindowButton
.setSelection(IPreferenceConstants.OPM_NEW_WINDOW == openPerspMode);
openNewWindowButton.setFont(font);
openNewWindowButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
openPerspMode = IPreferenceConstants.OPM_NEW_WINDOW;
}
});
}
/**
* Creates a composite that contains buttons for selecting open view mode.
*
* @param composite
* the parent composite
*/
protected void createOpenViewButtonGroup(Composite composite) {
Font font = composite.getFont();
Group buttonComposite = new Group(composite, SWT.LEFT);
buttonComposite.setText(OVM_TITLE);
buttonComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
buttonComposite.setFont(composite.getFont());
GridLayout layout = new GridLayout();
layout.numColumns = 2;
buttonComposite.setLayout(layout);
openEmbedButton = new Button(buttonComposite, SWT.RADIO);
openEmbedButton.setText(OVM_EMBED);
openEmbedButton
.setSelection(openViewMode == IPreferenceConstants.OVM_EMBED);
openEmbedButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
openViewMode = IPreferenceConstants.OVM_EMBED;
}
});
openEmbedButton.setFont(font);
// Open view as float no longer supported
if (openViewMode == IPreferenceConstants.OVM_FLOAT) {
openViewMode = IPreferenceConstants.OVM_FAST;
}
openFastButton = new Button(buttonComposite, SWT.RADIO);
openFastButton.setText(OVM_FAST);
openFastButton
.setSelection(openViewMode == IPreferenceConstants.OVM_FAST);
openFastButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
openViewMode = IPreferenceConstants.OVM_FAST;
}
});
openFastButton.setFont(font);
}
/**
* Create a table of 3 buttons to enable the user to manage customized
* perspectives.
*
* @param parent
* the parent for the button parent
* @return Composite that the buttons are created in.
*/
protected Composite createCustomizePerspective(Composite parent) {
Font font = parent.getFont();
// define container & its gridding
Composite perspectivesComponent = new Composite(parent, SWT.NONE);
perspectivesComponent.setLayoutData(new GridData(GridData.FILL_BOTH));
perspectivesComponent.setFont(parent.getFont());
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
perspectivesComponent.setLayout(layout);
// Add the label
Label label = new Label(perspectivesComponent, SWT.LEFT);
label.setText(WorkbenchMessages.PerspectivesPreference_available);
GridData data = new GridData();
data.horizontalSpan = 2;
label.setLayoutData(data);
label.setFont(font);
// Add perspectivesTable.
perspectivesTable = new Table(perspectivesComponent, SWT.H_SCROLL | SWT.V_SCROLL
| SWT.BORDER);
perspectivesTable.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateButtons();
}
});
perspectivesTable.setFont(font);
data = new GridData(GridData.FILL_BOTH);
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
perspectivesTable.setLayoutData(data);
// Populate the perspectivesTable
IPerspectiveDescriptor[] persps = perspectiveRegistry.getPerspectives();
perspectives = new ArrayList(persps.length);
for (int i = 0; i < persps.length; i++) {
perspectives.add(i, persps[i]);
}
Collections.sort(perspectives, comparator);
defaultPerspectiveId = perspectiveRegistry.getDefaultPerspective();
updatePerspectivesTable();
// Create vertical button bar.
Composite buttonBar = (Composite) createVerticalButtonBar(perspectivesComponent);
data = new GridData(GridData.FILL_VERTICAL);
buttonBar.setLayoutData(data);
//Add note label
String NOTE_LABEL = WorkbenchMessages.Preference_note;
String REVERT_NOTE = WorkbenchMessages.RevertPerspective_note;
Composite noteComposite = createNoteComposite(font, parent,
NOTE_LABEL, REVERT_NOTE);
GridData noteData = new GridData();
noteData.horizontalSpan = 2;
noteComposite.setLayoutData(noteData);
return perspectivesComponent;
}
/**
* Creates a new vertical button with the given id.
* <p>
* The default implementation of this framework method creates a standard
* push button, registers for selection events including button presses and
* help requests, and registers default buttons with its shell. The button
* id is stored as the buttons client data.
* </p>
*
* @param parent
* the parent composite
* @param label
* the label from the button
* @param defaultButton
* <code>true</code> if the button is to be the default button,
* and <code>false</code> otherwise
* @return Button The created button.
*/
protected Button createVerticalButton(Composite parent, String label,
boolean defaultButton) {
Button button = new Button(parent, SWT.PUSH);
button.setText(label);
GridData data = setButtonLayoutData(button);
data.horizontalAlignment = GridData.FILL;
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
verticalButtonPressed(event.widget);
}
});
button.setToolTipText(label);
if (defaultButton) {
Shell shell = parent.getShell();
if (shell != null) {
shell.setDefaultButton(button);
}
}
button.setFont(parent.getFont());
return button;
}
/**
* Creates and returns the vertical button bar.
*
* @param parent
* the parent composite to contain the button bar
* @return the button bar control
*/
protected Control createVerticalButtonBar(Composite parent) {
// Create composite.
Composite composite = new Composite(parent, SWT.NULL);
// create a layout with spacing and margins appropriate for the font
// size.
GridLayout layout = new GridLayout();
layout.numColumns = 1;
layout.marginWidth = 5;
layout.marginHeight = 0;
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
composite.setLayout(layout);
composite.setFont(parent.getFont());
// Add the buttons to the button bar.
setDefaultButton = createVerticalButton(composite, WorkbenchMessages.PerspectivesPreference_MakeDefault, false);
setDefaultButton.setToolTipText(WorkbenchMessages.PerspectivesPreference_MakeDefaultTip);
revertButton = createVerticalButton(composite, WorkbenchMessages.PerspectivesPreference_Reset, false);
revertButton.setToolTipText(WorkbenchMessages.PerspectivesPreference_ResetTip);
deleteButton = createVerticalButton(composite, WorkbenchMessages.PerspectivesPreference_Delete, false);
deleteButton.setToolTipText(WorkbenchMessages.PerspectivesPreference_DeleteTip);
updateButtons();
return composite;
}
/**
* @see IWorkbenchPreferencePage
*/
public void init(IWorkbench aWorkbench) {
this.workbench = aWorkbench;
this.perspectiveRegistry = (PerspectiveRegistry) workbench
.getPerspectiveRegistry();
IPreferenceStore store = WorkbenchPlugin.getDefault()
.getPreferenceStore();
setPreferenceStore(store);
openViewMode = store.getInt(IPreferenceConstants.OPEN_VIEW_MODE);
openPerspMode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE);
}
/**
* The default button has been pressed.
*/
protected void performDefaults() {
//Project perspective preferences
IPreferenceStore store = WorkbenchPlugin.getDefault()
.getPreferenceStore();
openViewMode = store.getDefaultInt(IPreferenceConstants.OPEN_VIEW_MODE);
// Open view as float no longer supported
if (openViewMode == IPreferenceConstants.OVM_FLOAT) {
openViewMode = IPreferenceConstants.OVM_FAST;
}
openEmbedButton
.setSelection(openViewMode == IPreferenceConstants.OVM_EMBED);
openFastButton
.setSelection(openViewMode == IPreferenceConstants.OVM_FAST);
openPerspMode = store
.getDefaultInt(IPreferenceConstants.OPEN_PERSP_MODE);
openSameWindowButton
.setSelection(IPreferenceConstants.OPM_ACTIVE_PAGE == openPerspMode);
openNewWindowButton
.setSelection(IPreferenceConstants.OPM_NEW_WINDOW == openPerspMode);
String currentDefault = perspectiveRegistry.getDefaultPerspective();
int index = indexOf(currentDefault);
if (index >= 0){
defaultPerspectiveId = currentDefault;
updatePerspectivesTable();
perspectivesTable.setSelection(index);
}
String newDefault = PrefUtil.getAPIPreferenceStore().getDefaultString(
IWorkbenchPreferenceConstants.DEFAULT_PERSPECTIVE_ID);
IPerspectiveDescriptor desc = null;
if (newDefault != null) {
desc = workbench.getPerspectiveRegistry().findPerspectiveWithId(newDefault);
}
if (desc == null) {
newDefault = workbench.getPerspectiveRegistry().getDefaultPerspective();
}
defaultPerspectiveId = newDefault;
updatePerspectivesTable();
}
/**
* Look up the index of the perpective with the given if.
* @param perspectiveId or <code>null</code>
* @return int -1 if it cannot be found
*/
private int indexOf(String perspectiveId) {
if (perspectiveId == null) {
return -1;
}
PerspectiveDescriptor[] descriptors =
new PerspectiveDescriptor[perspectives.size()];
perspectives.toArray(descriptors);
for (int i = 0; i < descriptors.length; i++) {
PerspectiveDescriptor descriptor = descriptors[i];
if(descriptor.getId().equals(perspectiveId)) {
return i;
}
}
return -1;
}
/**
* Deletes the perspectives selected by the user if there is no opened
* instance of that perspective.
*
* @return boolean <code>true</code> if all of the perspectives could be
* deleted.
*/
private boolean findOpenInstance(IPerspectiveDescriptor desc) {
IWorkbenchWindow windows[] = workbench.getWorkbenchWindows();
//find all active perspectives currently
for (int i = 0; i < windows.length; i++) {
IWorkbenchPage pages[] = windows[i].getPages();
for (int j = 0; j < pages.length; j++) {
WorkbenchPage page = (WorkbenchPage) pages[j];
if (page.findPerspective(desc) != null) {
if (!MessageDialog
.openQuestion(
getShell(),
WorkbenchMessages.PerspectivesPreference_perspectiveopen_title,
NLS.bind(WorkbenchMessages.PerspectivesPreference_perspectiveopen_message, desc.getLabel()))) {
return true;
}
}
}
}
return false;
}
/**
* Apply the user's changes if any
*/
public boolean performOk() {
// Set the default perspective
if (!Util.equals(defaultPerspectiveId, perspectiveRegistry.getDefaultPerspective())) {
perspectiveRegistry.setDefaultPerspective(defaultPerspectiveId);
}
//Delete the perspective
if(perspectives.size()<perspectiveRegistry.getPerspectives().length) {
IWorkbenchWindow windows[] = workbench.getWorkbenchWindows();
// close any perspectives that are about to be deleted
for (int i = 0; i < windows.length; i++) {
IWorkbenchPage pages[] = windows[i].getPages();
for (int j = 0; j < pages.length; j++) {
WorkbenchPage page = (WorkbenchPage) pages[j];
for (int k = 0; k < perspToDelete.size(); k++) {
IPerspectiveDescriptor desc = (IPerspectiveDescriptor) perspToDelete.get(k);
if (page.findPerspective(desc) != null) {
page.closePerspective(desc, true, true);
}
}
}
}
perspectiveRegistry.deletePerspectives(perspToDelete);
}
// Revert the perspectives
perspectiveRegistry.revertPerspectives(perspToRevert);
IPreferenceStore store = getPreferenceStore();
// store the open view mode setting
store.setValue(IPreferenceConstants.OPEN_VIEW_MODE, openViewMode);
// store the open perspective mode setting
store.setValue(IPreferenceConstants.OPEN_PERSP_MODE, openPerspMode);
// save both the API prefs and the internal prefs
// the API prefs are modified by
// PerspectiveRegistry.setDefaultPerspective
PrefUtil.savePrefs();
return true;
}
/**
* Update the button enablement state.
*/
protected void updateButtons() {
// Get selection.
int index = perspectivesTable.getSelectionIndex();
// Map it to the perspective descriptor
PerspectiveDescriptor desc = null;
if (index > -1) {
desc = (PerspectiveDescriptor) perspectives.get(index);
}
// Do enable.
if (desc != null) {
revertButton.setEnabled(desc.isPredefined()
&& desc.hasCustomDefinition()
&& !perspToRevert.contains(desc));
deleteButton.setEnabled(!desc.isPredefined());
setDefaultButton.setEnabled(true);
} else {
revertButton.setEnabled(false);
deleteButton.setEnabled(false);
setDefaultButton.setEnabled(false);
}
}
/**
* Update the perspectivesTable.
*/
protected void updatePerspectivesTable() {
// Populate the table with the items
perspectivesTable.removeAll();
for (int i = 0; i < perspectives.size(); i++) {
PerspectiveDescriptor persp = (PerspectiveDescriptor) perspectives.get(i);
newPerspectivesTableItem(persp, i, false);
}
}
/**
* Create a new tableItem using given perspective, and set image for the new item.
*/
protected TableItem newPerspectivesTableItem(IPerspectiveDescriptor persp,
int index, boolean selected) {
ImageDescriptor image = persp.getImageDescriptor();
TableItem item = new TableItem(perspectivesTable, SWT.NULL, index);
if (image != null) {
Descriptors.setImage(item, image);
}
String label=persp.getLabel();
if (persp.getId().equals(defaultPerspectiveId)){
label = NLS.bind(WorkbenchMessages.PerspectivesPreference_defaultLabel, label );
}
item.setText(label);
item.setData(persp);
if (selected) {
perspectivesTable.setSelection(index);
}
return item;
}
/**
* Notifies that this page's button with the given id has been pressed.
*
* @param button
* the button that was pressed
*/
protected void verticalButtonPressed(Widget button) {
// Get selection.
int index = perspectivesTable.getSelectionIndex();
// Map it to the perspective descriptor
PerspectiveDescriptor desc = null;
if (index > -1) {
desc = (PerspectiveDescriptor) perspectives.get(index);
} else {
return;
}
// Take action.
if (button == revertButton) {
if (desc.isPredefined() && !perspToRevert.contains(desc)) {
perspToRevert.add(desc);
}
} else if (button == deleteButton) {
if (!desc.isPredefined() && !perspToDelete.contains(desc)) {
if(!findOpenInstance(desc)){
perspToDelete.add(desc);
perspToRevert.remove(desc);
perspectives.remove(desc);
updatePerspectivesTable();
}
}
} else if (button == setDefaultButton) {
defaultPerspectiveId = desc.getId();
updatePerspectivesTable();
perspectivesTable.setSelection(index);
}
updateButtons();
}
}