/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* Sergey Prigogin, Google
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences.formatter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Observable;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CCorePreferenceConstants;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.preferences.PreferencesAccess;
/**
* Allows to choose the formatter in a combo box.
* If no formatter is contributed, nothing is shown.
*/
public class CustomCodeFormatterBlock extends Observable {
private HashMap<String, String> idMap = new HashMap<String, String>();
private IEclipsePreferences fPrefs;
private String fDefaultFormatterId;
private Combo fFormatterCombo;
private static final String ATTR_NAME = "name"; //$NON-NLS-1$
private static final String ATTR_ID = "id"; //$NON-NLS-1$
private static final String DEFAULT = FormatterMessages.CustomCodeFormatterBlock_default_formatter;
public CustomCodeFormatterBlock(IProject project, PreferencesAccess access) {
final IScopeContext scope;
final IEclipsePreferences defaults;
if (project != null) {
scope= access.getProjectScope(project);
defaults= access.getInstanceScope().getNode(CCorePlugin.PLUGIN_ID);
} else {
scope= access.getInstanceScope();
defaults= access.getDefaultScope().getNode(CCorePlugin.PLUGIN_ID);
}
fPrefs= scope.getNode(CCorePlugin.PLUGIN_ID);
fDefaultFormatterId= defaults.get(CCorePreferenceConstants.CODE_FORMATTER, null);
if (fDefaultFormatterId == null) {
// backward compatibility: use UI prefs
IEclipsePreferences instance= access.getInstanceScope().getNode(CUIPlugin.PLUGIN_ID);
fDefaultFormatterId= instance.get(CCorePreferenceConstants.CODE_FORMATTER, null);
if (fDefaultFormatterId != null) {
instance.remove(CCorePreferenceConstants.CODE_FORMATTER);
if (project != null) {
defaults.put(CCorePreferenceConstants.CODE_FORMATTER, fDefaultFormatterId);
}
}
}
initializeFormatters();
}
public void performOk() {
if (fFormatterCombo == null) {
return;
}
String text = fFormatterCombo.getText();
String formatterId = idMap.get(text);
if (formatterId != null && !formatterId.equals(fDefaultFormatterId)) {
fPrefs.put(CCorePreferenceConstants.CODE_FORMATTER, formatterId);
} else {
// simply reset to the default one.
performDefaults();
}
}
public void performDefaults() {
fPrefs.remove(CCorePreferenceConstants.CODE_FORMATTER);
if (fFormatterCombo == null) {
return;
}
fFormatterCombo.clearSelection();
fFormatterCombo.setText(DEFAULT);
Iterator<Map.Entry<String,String>> iterator = idMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String,String> entry = iterator.next();
String val = entry.getValue();
if (val != null && val.equals(fDefaultFormatterId)) {
fFormatterCombo.setText(entry.getKey());
}
}
handleFormatterChanged();
}
/**
* Get the currently selected formatter id.
*
* @return the selected formatter id or <code>null</code> if the default is selected.
*/
public String getFormatterId() {
if (fFormatterCombo == null) {
return fPrefs.get(CCorePreferenceConstants.CODE_FORMATTER, fDefaultFormatterId);
}
String formatterId= idMap.get(fFormatterCombo.getText());
return formatterId;
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
*/
public Control createContents(Composite parent) {
if (getNumberOfAvailableFormatters() == 0) {
return parent;
}
Composite composite = ControlFactory.createGroup(parent, FormatterMessages.CustomCodeFormatterBlock_formatter_name, 1);
((GridData)composite.getLayoutData()).horizontalSpan = 5;
PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, ICHelpContextIds.CODEFORMATTER_PREFERENCE_PAGE);
fFormatterCombo = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY);
fFormatterCombo.setFont(parent.getFont());
fFormatterCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
fFormatterCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleFormatterChanged();
}
});
Iterator<String> items = idMap.keySet().iterator();
while (items.hasNext()) {
fFormatterCombo.add(items.next());
}
final String noteTitle= FormatterMessages.CustomCodeFormatterBlock_formatter_note;
final String noteMessage= FormatterMessages.CustomCodeFormatterBlock_contributed_formatter_warning;
ControlFactory.createNoteComposite(JFaceResources.getDialogFont(), composite, noteTitle, noteMessage);
initDefault();
return composite;
}
private void handleFormatterChanged() {
setChanged();
String formatterId= getFormatterId();
notifyObservers(formatterId);
}
private void initDefault() {
boolean init = false;
String formatterID= fPrefs.get(CCorePreferenceConstants.CODE_FORMATTER, fDefaultFormatterId);
if (formatterID != null) {
Iterator<Map.Entry<String,String>> iterator = idMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
String val = entry.getValue();
if (val != null && val.equals(formatterID)) {
fFormatterCombo.setText(entry.getKey());
init = true;
}
}
}
if (!init) {
formatterID= null;
fFormatterCombo.setText(DEFAULT);
}
}
private void initializeFormatters() {
idMap = new HashMap<String, String>();
idMap.put(DEFAULT, CCorePreferenceConstants.DEFAULT_CODE_FORMATTER);
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, CCorePlugin.FORMATTER_EXTPOINT_ID);
if (point != null) {
IExtension[] exts = point.getExtensions();
for (IExtension ext : exts) {
IConfigurationElement[] elements = ext.getConfigurationElements();
for (int j = 0; j < elements.length; ++j) {
String name = elements[j].getAttribute(ATTR_NAME);
String id= elements[j].getAttribute(ATTR_ID);
idMap.put(name, id);
}
}
}
}
private final int getNumberOfAvailableFormatters() {
return idMap.size() - 1;
}
}