blob: 4e987adbe98d1247b27ea3d4fe2d3a13e92be623 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2006 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 java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.IPreferenceNode;
import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.PreferenceContentProvider;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.ui.activities.WorkbenchActivityHelper;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.ui.preferences.IWorkingCopyManager;
import org.eclipse.ui.preferences.WorkingCopyManager;
import org.osgi.service.prefs.BackingStoreException;
/**
* Baseclass for preference dialogs that will show two tabs of preferences -
* filtered and unfiltered.
*
* @since 3.0
*/
public abstract class FilteredPreferenceDialog extends PreferenceDialog implements IWorkbenchPreferenceContainer{
protected class PreferenceFilteredTree extends FilteredTree{
/**
* An (optional) additional filter on the TreeViewer.
*/
private ViewerFilter viewerFilter;
/**
* Initial title of dialog. This is only used if the additional filter provided
* by the addFilter(ViewerFilter) method is utilized.
*/
private String cachedTitle;
/**
* Constructor.
*
* @param parent parent Composite
* @param treeStyle SWT style bits for Tree
* @param filter the PatternFilter to use for the TreeViewer
*/
PreferenceFilteredTree(Composite parent, int treeStyle,
PatternFilter filter) {
super(parent, treeStyle, filter);
}
/**
* Add an additional, optional filter to the viewer.
* If the filter text is cleared, this filter will be
* removed from the TreeViewer.
*
* @param filter
*/
protected void addFilter(ViewerFilter filter) {
viewerFilter = filter;
getViewer().addFilter(filter);
setInitialText(WorkbenchMessages.FilteredTree_FilterMessage);
if(filterText != null){
setFilterText(WorkbenchMessages.FilteredTree_FilterMessage);
textChanged();
}
cachedTitle = getShell().getText();
getShell().setText(
NLS.bind(
WorkbenchMessages.FilteredTree_FilteredDialogTitle,
cachedTitle));
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.dialogs.FilteredTree#updateToolbar(boolean)
*/
protected void updateToolbar(boolean visible) {
if (filterToolBar != null) {
filterToolBar.getControl().setVisible(
viewerFilter != null || visible);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.dialogs.FilteredTree#clearText()
*/
protected void clearText() {
setFilterText(""); //$NON-NLS-1$
// remove the filter if text is cleared
if(viewerFilter != null){
getViewer().removeFilter(viewerFilter);
viewerFilter = null;
getShell().setText(cachedTitle);
}
textChanged();
}
}
protected PreferenceFilteredTree filteredTree;
private Object pageData;
IWorkingCopyManager workingCopyManager;
private Collection updateJobs = new ArrayList();
/**
* The preference page history.
*
* @since 3.1
*/
PreferencePageHistory history;
/**
* Creates a new preference dialog under the control of the given preference
* manager.
*
* @param parentShell
* the parent shell
* @param manager
* the preference manager
*/
public FilteredPreferenceDialog(Shell parentShell, PreferenceManager manager) {
super(parentShell, manager);
history = new PreferencePageHistory(this);
}
/**
* Differs from super implementation in that if the node is found but should
* be filtered based on a call to
* <code>WorkbenchActivityHelper.filterItem()</code> then
* <code>null</code> is returned.
*
* @see org.eclipse.jface.preference.PreferenceDialog#findNodeMatching(java.lang.String)
*/
protected IPreferenceNode findNodeMatching(String nodeId) {
IPreferenceNode node = super.findNodeMatching(nodeId);
if (WorkbenchActivityHelper.filterItem(node)) {
return null;
}
return node;
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferenceDialog#createTreeViewer(org.eclipse.swt.widgets.Composite)
*/
protected TreeViewer createTreeViewer(Composite parent) {
int styleBits = SWT.SINGLE | SWT.H_SCROLL;
filteredTree = new PreferenceFilteredTree(parent, styleBits,
new PreferencePatternFilter());
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.horizontalIndent = IDialogConstants.HORIZONTAL_MARGIN;
filteredTree.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_LIST_BACKGROUND));
TreeViewer tree = filteredTree.getViewer();
setContentAndLabelProviders(tree);
tree.setInput(getPreferenceManager());
//if the tree has only one or zero pages, make the combo area disable
if(hasAtMostOnePage(tree)){
Text filterText = filteredTree.getFilterControl();
if (filterText != null) {
filteredTree.getFilterControl().setEnabled(false);
}
}
tree.addFilter(new CapabilityFilter());
tree.addSelectionChangedListener(new ISelectionChangedListener() {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
*/
public void selectionChanged(SelectionChangedEvent event) {
handleTreeSelectionChanged(event);
}
});
super.addListeners(filteredTree.getViewer());
return filteredTree.getViewer();
}
/**
* Return whether or not there are less than two pages.
* @param tree
* @return <code>true</code> if there are less than two
* pages.
*/
private boolean hasAtMostOnePage(TreeViewer tree){
ITreeContentProvider contentProvider = (ITreeContentProvider ) tree.getContentProvider();
Object[] children= contentProvider.getElements(tree.getInput());
if(children.length <= 1){
if(children.length == 0) {
return true;
}
return !contentProvider.hasChildren(children[0]);
}
return false;
}
/**
* Set the content and label providers for the treeViewer
*
* @param treeViewer
*/
protected void setContentAndLabelProviders(TreeViewer treeViewer) {
treeViewer.setLabelProvider(new PreferenceBoldLabelProvider(filteredTree));
treeViewer.setContentProvider(new PreferenceContentProvider());
}
/**
* A selection has been made in the tree.
* @param event SelectionChangedEvent
*/
protected void handleTreeSelectionChanged(SelectionChangedEvent event) {
//Do nothing by default
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferenceDialog#createTreeAreaContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createTreeAreaContents(Composite parent) {
Composite leftArea = new Composite(parent, SWT.NONE);
leftArea.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
leftArea.setFont(parent.getFont());
GridLayout leftLayout = new GridLayout();
leftLayout.numColumns = 1;
leftLayout.marginHeight = 0;
leftLayout.marginTop = IDialogConstants.VERTICAL_MARGIN;
leftLayout.marginWidth = 0;
leftLayout.marginLeft = IDialogConstants.HORIZONTAL_MARGIN;
leftLayout.horizontalSpacing = 0;
leftLayout.verticalSpacing = 0;
leftArea.setLayout(leftLayout);
// Build the tree an put it into the composite.
TreeViewer viewer = createTreeViewer(leftArea);
setTreeViewer(viewer);
updateTreeFont(JFaceResources.getDialogFont());
GridData viewerData = new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL);
viewer.getControl().getParent().setLayoutData(viewerData);
layoutTreeAreaControl(leftArea);
return leftArea;
}
/**
* Show only the supplied ids.
*
* @param filteredIds
*/
public void showOnly(String[] filteredIds) {
filteredTree.addFilter(new PreferenceNodeFilter(filteredIds));
}
/**
* Set the data to be applied to a page after it is created.
* @param pageData Object
*/
public void setPageData(Object pageData) {
this.pageData = pageData;
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferenceDialog#createPage(org.eclipse.jface.preference.IPreferenceNode)
*/
protected void createPage(IPreferenceNode node) {
super.createPage(node);
if (this.pageData == null) {
return;
}
//Apply the data if it has been set.
IPreferencePage page = node.getPage();
if (page instanceof PreferencePage) {
((PreferencePage) page).applyData(this.pageData);
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferenceDialog#getCurrentPage()
*/
public IPreferencePage getCurrentPage() {
return super.getCurrentPage();
}
/* (non-Javadoc)
* @see org.eclipse.ui.preferences.IWorkbenchPreferenceContainer#openPage(java.lang.String, java.lang.Object)
*/
public boolean openPage(String pageId, Object data) {
setPageData(data);
setCurrentPageId(pageId);
IPreferencePage page = getCurrentPage();
if (page instanceof PreferencePage) {
((PreferencePage) page).applyData(data);
}
return true;
}
/**
* Selects the current page based on the given preference page identifier.
* If no node can be found, then nothing will change.
*
* @param preferencePageId
* The preference page identifier to select; should not be
* <code>null</code>.
*/
public final void setCurrentPageId(final String preferencePageId) {
final IPreferenceNode node = findNodeMatching(preferencePageId);
if (node != null) {
getTreeViewer().setSelection(new StructuredSelection(node));
showPage(node);
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.preferences.IWorkbenchPreferenceContainer#getWorkingCopyManager()
*/
public IWorkingCopyManager getWorkingCopyManager() {
if(workingCopyManager == null){
workingCopyManager = new WorkingCopyManager();
}
return workingCopyManager;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#okPressed()
*/
protected void okPressed() {
super.okPressed();
if(getReturnCode() == FAILED) {
return;
}
if (workingCopyManager != null) {
try {
workingCopyManager.applyChanges();
} catch (BackingStoreException e) {
String msg = e.getMessage();
if (msg == null) {
msg = WorkbenchMessages.FilteredPreferenceDialog_PreferenceSaveFailed;
}
IStatus errorStatus = new Status(IStatus.ERROR,
WorkbenchPlugin.PI_WORKBENCH, IStatus.ERROR, msg, e);
ErrorDialog
.openError(
getShell(),
WorkbenchMessages.PreferencesExportDialog_ErrorDialogTitle,
WorkbenchMessages.FilteredPreferenceDialog_PreferenceSaveFailed,
errorStatus);
}
}
// Run the update jobs
Iterator updateIterator = updateJobs.iterator();
while (updateIterator.hasNext()) {
((Job) updateIterator.next()).schedule();
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.preferences.IWorkbenchPreferenceContainer#registerUpdateJob(org.eclipse.core.runtime.jobs.Job)
*/
public void registerUpdateJob(Job job){
updateJobs.add(job);
}
/**
* Get the toolbar for the container
*
* @return Control
*/
Control getContainerToolBar(Composite composite) {
ToolBar historyBar = new ToolBar(composite, SWT.HORIZONTAL | SWT.FLAT);
ToolBarManager historyManager = new ToolBarManager(historyBar);
history.createHistoryControls(historyBar, historyManager);
historyManager.update(false);
return historyBar;
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferenceDialog#showPage(org.eclipse.jface.preference.IPreferenceNode)
*/
protected boolean showPage(IPreferenceNode node) {
final boolean success = super.showPage(node);
if (success) {
history.addHistoryEntry(new PreferenceHistoryEntry(node.getId(), node.getLabelText(),
null));
}
return success;
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#close()
*/
public boolean close() {
history.dispose();
return super.close();
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferenceDialog#createTitleArea(org.eclipse.swt.widgets.Composite)
*/
protected Composite createTitleArea(Composite parent) {
GridLayout parentLayout = (GridLayout) parent.getLayout();
parentLayout.numColumns = 2;
parentLayout.marginHeight = 0;
parentLayout.marginTop = IDialogConstants.VERTICAL_MARGIN;
parent.setLayout(parentLayout);
Composite titleComposite = super.createTitleArea(parent);
Composite toolbarArea=new Composite(parent, SWT.NONE);
GridLayout toolbarLayout = new GridLayout();
toolbarLayout.marginHeight = 0;
toolbarLayout.verticalSpacing = 0;
toolbarArea.setLayout(toolbarLayout);
toolbarArea.setLayoutData(new GridData(SWT.END, SWT.FILL, false, true));
Control topBar = getContainerToolBar(toolbarArea);
topBar.setLayoutData(new GridData(SWT.END, SWT.FILL, false, true));
return titleComposite;
}
protected void selectSavedItem() {
getTreeViewer().setInput(getPreferenceManager());
super.selectSavedItem();
if(getTreeViewer().getTree().getItemCount() > 1) {
//unfortunately super will force focus to the list but we want the type ahead combo to get it.
Text filterText = filteredTree.getFilterControl();
if (filterText != null) {
filterText.setFocus();
}
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.preference.PreferenceDialog#updateTreeFont(org.eclipse.swt.graphics.Font)
*/
protected void updateTreeFont(Font dialogFont) {
applyDialogFont(filteredTree);
}
}