/******************************************************************************* * Copyright (c) 2005, 2010 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 - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.ui.dialogs; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.ControlEnableState; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.ui.IPluginContribution; import org.eclipse.ui.activities.WorkbenchActivityHelper; import org.eclipse.ui.dialogs.PropertyPage; import com.ibm.icu.text.Collator; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionPreferences; import org.eclipse.cdt.core.settings.model.ICProjectDescriptionWorkspacePreferences; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.utils.ui.controls.ControlFactory; import org.eclipse.cdt.utils.ui.controls.TabFolderLayout; import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; import org.eclipse.cdt.internal.ui.preferences.IndexerPreferencePage; /** * This <code>IndexerBlock</code> is used in the <code>MakeProjectWizardOptionPage</code> and * the <code>NewManagedProjectOptionPage</code> to display the indexer options during the creation of * a new project. * * @noextend This class is not intended to be subclassed by clients. */ public class IndexerBlock extends AbstractCOptionPage { private static final String NODE_INDEXERUI = "indexerUI"; //$NON-NLS-1$ private static final String ATTRIB_CLASS = "class"; //$NON-NLS-1$ private static final String ATTRIB_NAME = "name"; //$NON-NLS-1$ private static final String ATTRIB_INDEXERID = "indexerID"; //$NON-NLS-1$ private static final String ATTRIB_ID = "id"; //$NON-NLS-1$ private static final String PREF_PAGE_ID = "org.eclipse.cdt.ui.preferences.IndexerPreferencePage"; //$NON-NLS-1$ private static final String INDEXER_LABEL = CUIPlugin.getResourceString("BaseIndexerBlock.label" ); //$NON-NLS-1$ private static final String INDEXER_DESCRIPTION = CUIPlugin.getResourceString("BaseIndexerBlock.desc"); //$NON-NLS-1$ private PreferenceScopeBlock fPrefScopeBlock; private Button fEnableIndexer; private Combo fIndexersComboBox; private HashMap<String, IndexerConfig> fIndexerConfigMap; private String fTheOneIndexerID; private Composite fIndexerPageComposite; private AbstractIndexerPage fCurrentPage; private Properties fCurrentProperties; private Composite fPreferenceContent; private Composite fParent; private Button fUseActiveBuildButton; private Button fUseFixedBuildConfig; private Combo fBuildConfigComboBox; private ControlEnableState fEnableState; private Group fBuildConfigGroup; private int fLastScope; public IndexerBlock(){ super(INDEXER_LABEL); setDescription(INDEXER_DESCRIPTION); initializeIndexerConfigMap(); } @Override public boolean isValid() { return super.isValid() && (fCurrentPage == null || fCurrentPage.isValid()); } @Override public String getErrorMessage() { String msg = super.getErrorMessage(); if (msg == null && fCurrentPage != null) { msg= fCurrentPage.getErrorMessage(); } return msg; } /** * Create a profile page only on request */ private static class IndexerConfig implements IPluginContribution { private static final String NULL = "null"; //$NON-NLS-1$ private AbstractIndexerPage fPage; private IConfigurationElement fElement; public IndexerConfig(NullIndexerBlock fixed) { fPage= fixed; } public IndexerConfig(IConfigurationElement element) { fElement= element; } public AbstractIndexerPage getPage() throws CoreException { if (fPage == null) { try { fPage= (AbstractIndexerPage) fElement.createExecutableExtension(ATTRIB_CLASS); } catch (Exception e) { CUIPlugin.log(e); } if (fPage == null) { fPage= new NullIndexerBlock(); } } return fPage; } public String getName() { if (fElement == null) return NULL; return fElement.getAttribute(ATTRIB_NAME); } public String getLocalId() { if (fElement == null) return NULL; return fElement.getAttribute(ATTRIB_ID); } public String getPluginId() { if (fElement == null) return NULL; return fElement.getContributor().getName(); } } @Override public void createControl(Composite parent) { fParent= parent; Composite composite = ControlFactory.createComposite(parent, 1); GridLayout layout= ((GridLayout)composite.getLayout()); layout.marginWidth= 0; GridData gd= (GridData) composite.getLayoutData(); gd.grabExcessHorizontalSpace= true; setControl(composite); if (getProject() != null || getContainer() instanceof ICOptionContainerExtension) { fPrefScopeBlock= new PreferenceScopeBlock(PREF_PAGE_ID) { @Override protected void onPreferenceScopeChange() { IndexerBlock.this.onPreferenceScopeChange(); } }; fPrefScopeBlock.createControl(composite); } fPreferenceContent= ControlFactory.createComposite(composite, 1); layout= (GridLayout)fPreferenceContent.getLayout(); layout.marginHeight= 0; layout.marginWidth= 0; gd= (GridData) fPreferenceContent.getLayoutData(); gd.horizontalIndent= 0; // add option to enable indexer final SelectionAdapter indexerChangeListener = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { onIndexerChange(); } }; fEnableIndexer= ControlFactory.createCheckBox(fPreferenceContent, CUIPlugin.getResourceString("IndexerBlock.enable")); //$NON-NLS-1$ fEnableIndexer.addSelectionListener(indexerChangeListener); // Add a group for indexer options. Group group= ControlFactory.createGroup(fPreferenceContent, DialogsMessages.IndexerBlock_indexerOptions, 1); gd= (GridData) group.getLayoutData(); gd.grabExcessHorizontalSpace= true; if (fIndexerConfigMap.size() > 2) { fIndexersComboBox = ControlFactory.createSelectCombo(group, "", ""); //$NON-NLS-1$ //$NON-NLS-2$ fIndexersComboBox.addSelectionListener(indexerChangeListener); } // add composite for pages fIndexerPageComposite= ControlFactory.createComposite(group, 1); fIndexerPageComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1)); fIndexerPageComposite.setLayout(new TabFolderLayout()); if (needBuildConfigOptions()) { fBuildConfigGroup= group= ControlFactory.createGroup(composite, DialogsMessages.IndexerStrategyBlock_buildConfigGroup, 1); gd= (GridData) group.getLayoutData(); gd.grabExcessHorizontalSpace= true; fUseActiveBuildButton= ControlFactory.createRadioButton(group, DialogsMessages.IndexerStrategyBlock_activeBuildConfig, null, null); fUseFixedBuildConfig= ControlFactory.createRadioButton(group, DialogsMessages.IndexerBlock_fixedBuildConfig, null, null); fBuildConfigComboBox= ControlFactory.createSelectCombo(group, "", ""); //$NON-NLS-1$ //$NON-NLS-2$ final SelectionAdapter listener = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { setUseActiveBuildConfig(fUseActiveBuildButton.getSelection()); } }; fUseActiveBuildButton.addSelectionListener(listener); fUseFixedBuildConfig.addSelectionListener(listener); } initializeScope(); initializeIndexerCombo(); initializeBuildConfigs(); onPreferenceScopeChange(); fParent.layout(true); } protected boolean needBuildConfigOptions() { if (fPrefScopeBlock == null || !(getContainer() instanceof PropertyPage)) { return false; } IProject prj= getProject(); if (prj != null) { if (IndexerPreferencePage.showBuildConfiguration()) { ICProjectDescriptionManager prjDescMgr= CCorePlugin.getDefault().getProjectDescriptionManager(); if (prjDescMgr.isNewStyleProject(prj)) return true; } } return false; } private void updateBuildConfigForScope(int scope) { if (fBuildConfigComboBox != null) { if (scope == IndexerPreferences.SCOPE_INSTANCE) { ICProjectDescriptionManager prjDescMgr= CCorePlugin.getDefault().getProjectDescriptionManager(); ICProjectDescriptionWorkspacePreferences prefs= prjDescMgr.getProjectDescriptionWorkspacePreferences(false); boolean useActive= prefs.getConfigurationRelations() == ICProjectDescriptionPreferences.CONFIGS_LINK_SETTINGS_AND_ACTIVE; fUseActiveBuildButton.setSelection(useActive); fUseFixedBuildConfig.setSelection(!useActive); } updateBuildConfigEnablement(scope); } } void updateBuildConfigEnablement(int scope) { if (fBuildConfigGroup == null) return; if (!fEnableIndexer.getSelection()) { ControlEnableState.disable(fBuildConfigGroup); } else { final boolean notDerived = scope != IndexerPreferences.SCOPE_INSTANCE; final boolean fixed = fUseFixedBuildConfig.getSelection(); // independent of scope fBuildConfigComboBox.setEnabled(fixed); fUseActiveBuildButton.setEnabled(notDerived); fUseFixedBuildConfig.setEnabled(notDerived); fBuildConfigGroup.setEnabled(notDerived || fixed); } } protected void setUseActiveBuildConfig(boolean useActive) { if (fBuildConfigComboBox != null) { if (useActive) { ICProjectDescriptionManager prjDescMgr= CCorePlugin.getDefault().getProjectDescriptionManager(); ICProjectDescription prefs= prjDescMgr.getProjectDescription(getProject(), false); selectBuildConfigInCombo(prefs.getActiveConfiguration().getName()); fBuildConfigComboBox.setEnabled(false); } else { // independent of the scope fBuildConfigComboBox.setEnabled(true); } fUseActiveBuildButton.setSelection(useActive); fUseFixedBuildConfig.setSelection(!useActive); } } private void enablePreferenceContent(boolean enable) { if (fEnableState != null) { fEnableState.restore(); } if (enable) { fEnableState= null; } else { fEnableState= ControlEnableState.disable(fPreferenceContent); } } private void initializeScope() { IProject proj= getProject(); if (fPrefScopeBlock == null) { return; } int scope= proj == null ? IndexerPreferences.SCOPE_INSTANCE : IndexerPreferences.getScope(proj); switch(scope) { case IndexerPreferences.SCOPE_PROJECT_PRIVATE: fPrefScopeBlock.setProjectLocalScope(); break; case IndexerPreferences.SCOPE_PROJECT_SHARED: fPrefScopeBlock.setProjectScope(); break; default: fPrefScopeBlock.setInstanceScope(); break; } } private void initializeIndexerCombo() { if (fIndexersComboBox != null) { String[] names= new String[fIndexerConfigMap.size()-1]; int j= 0; for (String id : fIndexerConfigMap.keySet()) { if (!IPDOMManager.ID_NO_INDEXER.equals(id)) { names[j++]= fIndexerConfigMap.get(id).getName(); } } final Comparator<Object> collator = Collator.getInstance(); Arrays.sort(names, collator); fIndexersComboBox.setItems(names); } else { fTheOneIndexerID= IPDOMManager.ID_NO_INDEXER; for (String id : fIndexerConfigMap.keySet()) { if (!IPDOMManager.ID_NO_INDEXER.equals(id)) { fTheOneIndexerID= id; break; } } } } private void initializeBuildConfigs() { if (fBuildConfigComboBox != null) { ICProjectDescriptionManager prjDescMgr= CCorePlugin.getDefault().getProjectDescriptionManager(); ICProjectDescription prefs= prjDescMgr.getProjectDescription(getProject(), false); setUseActiveBuildConfig(prefs.getConfigurationRelations() == ICProjectDescriptionPreferences.CONFIGS_LINK_SETTINGS_AND_ACTIVE); ICConfigurationDescription[] configs= prefs.getConfigurations(); String[] names= new String[configs.length]; for (int i = 0; i < configs.length; i++) { ICConfigurationDescription config = configs[i]; names[i]= config.getName(); } final Comparator<Object> collator = Collator.getInstance(); Arrays.sort(names, collator); fBuildConfigComboBox.setItems(names); selectBuildConfigInCombo(prefs.getDefaultSettingConfiguration().getName()); } } private void selectBuildConfigInCombo(String useName) { String[] names= fBuildConfigComboBox.getItems(); int selectedIndex = 0; for (int i = 0; i < names.length; i++){ if (names[i].equals(useName)) selectedIndex = i; } fBuildConfigComboBox.select(selectedIndex); } protected void onPreferenceScopeChange() { int scope= computeScope(); if (fCurrentProperties == null || scope == IndexerPreferences.SCOPE_INSTANCE || (fLastScope == IndexerPreferences.SCOPE_INSTANCE && scope == IndexerPreferences.SCOPE_PROJECT_SHARED)) { Properties props= IndexerPreferences.getProperties(getProject(), scope); String indexerId= props.getProperty(IndexerPreferences.KEY_INDEXER_ID); if (getIndexerName(indexerId) == null) { if (fCurrentProperties != null) { props= fCurrentProperties; } else { props= IndexerPreferences.getProperties(getProject(), IndexerPreferences.SCOPE_INSTANCE); } } fCurrentProperties= props; } else { fCurrentProperties.putAll(fCurrentPage.getProperties()); } updateForNewProperties(scope); updateBuildConfigForScope(scope); fLastScope= scope; } private void updateForNewProperties(int scope) { String indexerId= fCurrentProperties.getProperty(IndexerPreferences.KEY_INDEXER_ID); if (IPDOMManager.ID_NO_INDEXER.equals(indexerId)) { fEnableIndexer.setSelection(false); } else { fEnableIndexer.setSelection(true); if (fIndexersComboBox != null) { String indexerName = getIndexerName(indexerId); String[] indexerList = fIndexersComboBox.getItems(); int selectedIndex = 0; for (int i = 0; i < indexerList.length; i++){ if (indexerList[i].equals(indexerName)) selectedIndex = i; } fIndexersComboBox.select(selectedIndex); } } setPage(); if (fPrefScopeBlock != null) { enablePreferenceContent(scope != IndexerPreferences.SCOPE_INSTANCE); } } protected void onIndexerChange() { if (fCurrentPage != null) { Properties props= fCurrentPage.getProperties(); if (props != null) { fCurrentProperties.putAll(props); } } setPage(); updateBuildConfigEnablement(computeScope()); } private int computeScope() { if (fPrefScopeBlock != null) { if (fPrefScopeBlock.isProjectLocalScope()) { return IndexerPreferences.SCOPE_PROJECT_PRIVATE; } if (fPrefScopeBlock.isProjectScope()) { return IndexerPreferences.SCOPE_PROJECT_SHARED; } } return IndexerPreferences.SCOPE_INSTANCE; } private void setPage() { String indexerID= getSelectedIndexerID(); AbstractIndexerPage page = getIndexerPage(indexerID); if (page != null) { if (page.getControl() == null) { page.setContainer(getContainer()); page.createControl(fIndexerPageComposite); fIndexerPageComposite.layout(true); fParent.layout(true); } } if (fCurrentPage != null){ fCurrentPage.setVisible(false); } if (page != null) { page.setProperties(fCurrentProperties); page.setVisible(true); } fCurrentPage= page; } /** * Adds all the contributed Indexer Pages to a map */ private void initializeIndexerConfigMap() { fIndexerConfigMap = new HashMap<String, IndexerConfig>(5); IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CUIPlugin.getPluginId(), "IndexerPage"); //$NON-NLS-1$ IConfigurationElement[] infos = extensionPoint.getConfigurationElements(); for (final IConfigurationElement info : infos) { if (info.getName().equals(NODE_INDEXERUI)) { final String id = info.getAttribute(ATTRIB_INDEXERID); if (id != null) { IndexerConfig config= new IndexerConfig(info); if (config.getName() != null && !WorkbenchActivityHelper.filterItem(config)) { fIndexerConfigMap.put(id, config); } } } } fIndexerConfigMap.put(IPDOMManager.ID_NO_INDEXER, new IndexerConfig(new NullIndexerBlock())); } private String getIndexerName(String indexerID) { IndexerConfig configElement= fIndexerConfigMap.get(indexerID); if (configElement != null) { return configElement.getName(); } return null; } private AbstractIndexerPage getIndexerPage(String indexerID) { IndexerConfig configElement= fIndexerConfigMap.get(indexerID); if (configElement != null) { try { return configElement.getPage(); } catch (CoreException e) { CUIPlugin.log(e); } } return null; } @Override public void performApply(IProgressMonitor monitor) throws CoreException { int scope= computeScope(); IProject project= getProject(); String indexerID = getSelectedIndexerID(); if (indexerID == null) { return; } if (scope != IndexerPreferences.SCOPE_INSTANCE || project == null) { Properties props= new Properties(); props.setProperty(IndexerPreferences.KEY_INDEXER_ID, indexerID); if (fCurrentPage != null) { Properties p1= fCurrentPage.getProperties(); if (p1 != null) { props.putAll(p1); } } IndexerPreferences.setProperties(project, scope, props); } if (project != null) { IndexerPreferences.setScope(project, scope); } if (fBuildConfigComboBox != null) { boolean useActive= fUseActiveBuildButton.getSelection(); ICProjectDescriptionManager prjDescMgr= CCorePlugin.getDefault().getProjectDescriptionManager(); ICProjectDescription prefs= prjDescMgr.getProjectDescription(getProject(), true); if (scope == IndexerPreferences.SCOPE_INSTANCE) { prefs.useDefaultConfigurationRelations(); } else { prefs.setConfigurationRelations(useActive ? ICProjectDescriptionPreferences.CONFIGS_LINK_SETTINGS_AND_ACTIVE : ICProjectDescriptionPreferences.CONFIGS_INDEPENDENT); } if (!useActive) { final ICConfigurationDescription config= prefs.getConfigurationByName(fBuildConfigComboBox.getText()); if (config != null) { prefs.setDefaultSettingConfiguration(config); } } prjDescMgr.setProjectDescription(getProject(), prefs); } CCoreInternals.savePreferences(project, scope == IndexerPreferences.SCOPE_PROJECT_SHARED); } @Override public void performDefaults() { fCurrentProperties= null; if (fPrefScopeBlock != null) { fPrefScopeBlock.setInstanceScope(); onPreferenceScopeChange(); } else { fCurrentProperties= IndexerPreferences.getDefaultIndexerProperties(); updateForNewProperties(IndexerPreferences.SCOPE_INSTANCE); } } /** * @deprecated always returns false */ @Deprecated public boolean isIndexEnabled() { return false; } private String getSelectedIndexerID(){ if (fEnableIndexer.getSelection()) { if (fIndexersComboBox == null) return fTheOneIndexerID; final String indexerName = fIndexersComboBox.getText(); for (Map.Entry<String, IndexerConfig> entry : fIndexerConfigMap.entrySet()) { if (indexerName.equals(entry.getValue().getName())) { return entry.getKey(); } } return null; } return IPDOMManager.ID_NO_INDEXER; } public IProject getProject() { ICOptionContainer container = getContainer(); if (container != null){ if (container instanceof ICOptionContainerExtension) { try { return ((ICOptionContainerExtension) container).getProjectHandle(); } catch (Exception e) { return null; } } return container.getProject(); } return null; } }