/******************************************************************************* * Copyright (c) 2004, 2008 TimeSys 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: * TimeSys Corporation - Initial implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.ui.preferences; import java.util.ArrayList; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.content.IContentTypeManager; import org.eclipse.core.runtime.content.IContentTypeSettings; import org.eclipse.core.runtime.content.IContentTypeManager.ContentTypeChangeEvent; import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.swt.SWT; 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.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.internal.core.model.CModelManager; import org.eclipse.cdt.internal.ui.ICHelpContextIds; /* * The preference page used for displaying/editing CDT file * type associations for a project */ public class CFileTypesPropertyPage extends PropertyPage { class FixCFileTypesPreferenceBlock extends CFileTypesPreferenceBlock { ArrayList<ContentTypeChangeEvent> list = new ArrayList<ContentTypeChangeEvent>(); public FixCFileTypesPreferenceBlock() { super(); } public FixCFileTypesPreferenceBlock(IProject input) { super(input); } private IContentTypeManager.ContentTypeChangeEvent newContentTypeChangeEvent(IContentType source, IScopeContext context) { return new IContentTypeManager.ContentTypeChangeEvent(source, context); } @Override public boolean performOk() { boolean changed = super.performOk(); if (changed) { int size = list.size(); if (size > 0) { IContentTypeManager.ContentTypeChangeEvent[] events = new IContentTypeManager.ContentTypeChangeEvent[size]; list.toArray(events); CModelManager.getDefault().contentTypeChanged(events); } } return changed; } /* (non-Javadoc) * @see org.eclipse.cdt.internal.ui.preferences.CFileTypesPreferenceBlock#addAssociation(org.eclipse.core.runtime.preferences.IScopeContext, org.eclipse.core.runtime.content.IContentType, java.lang.String, int) */ @Override protected void addAssociation(IScopeContext context, IContentType contentType, String spec, int type) { super.addAssociation(context, contentType, spec, type); // accumulate the events list.add(newContentTypeChangeEvent(contentType, context)); } /* (non-Javadoc) * @see org.eclipse.cdt.internal.ui.preferences.CFileTypesPreferenceBlock#removeAssociation(org.eclipse.core.runtime.preferences.IScopeContext, org.eclipse.core.runtime.content.IContentType, java.lang.String, int) */ @Override protected void removeAssociation(IScopeContext context, IContentType contentType, String spec, int type) { super.removeAssociation(context, contentType, spec, type); // accumulate the events list.add(newContentTypeChangeEvent(contentType, context)); } } protected Button fUseWorkspace; protected Button fUseProject; protected FixCFileTypesPreferenceBlock fPrefsBlock; public CFileTypesPropertyPage(){ super(); noDefaultAndApplyButton(); } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) */ @Override protected Control createContents(Composite parent) { Composite topPane = new Composite(parent, SWT.NONE); topPane.setLayout(new GridLayout()); topPane.setLayoutData(new GridData(GridData.FILL_BOTH)); // Workspace radio buttons Composite radioPane = new Composite(topPane, SWT.NONE); radioPane.setLayout(new GridLayout()); radioPane.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); fUseWorkspace = new Button(radioPane, SWT.RADIO); fUseWorkspace.setText(PreferencesMessages.CFileTypesPropertyPage_useWorkspaceSettings); fUseWorkspace.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { if (fUseWorkspace.getSelection()) { fPrefsBlock.setInput(null); fPrefsBlock.setEnabled(false); } } }); final IProject project = getProject(); boolean custom = CCorePlugin.usesProjectSpecificContentTypes(project); fUseProject = new Button(radioPane, SWT.RADIO); fUseProject.setText(PreferencesMessages.CFileTypesPropertyPage_useProjectSettings); fUseProject.addListener(SWT.Selection, new Listener() { public void handleEvent(Event e) { if (fUseProject.getSelection()) { fPrefsBlock.setInput(project); fPrefsBlock.setEnabled(true); } } }); Composite blockPane = new Composite(topPane, SWT.NONE); blockPane.setLayout(new GridLayout()); blockPane.setLayoutData(new GridData(GridData.FILL_BOTH)); if (custom) { fPrefsBlock = new FixCFileTypesPreferenceBlock(project); } else { fPrefsBlock = new FixCFileTypesPreferenceBlock(); } fPrefsBlock.createControl(blockPane); fUseWorkspace.setSelection(!custom); fUseProject.setSelection(custom); fPrefsBlock.setEnabled(custom); PlatformUI.getWorkbench().getHelpSystem().setHelp( topPane, ICHelpContextIds.FILE_TYPES_STD_PAGE ); return topPane; } /* (non-Javadoc) * @see org.eclipse.jface.preference.PreferencePage#performDefaults() */ @Override protected void performDefaults() { fUseWorkspace.setSelection(true); fUseProject.setSelection(false); fPrefsBlock.setInput(null); fPrefsBlock.setEnabled(false); super.performDefaults(); } /* (non-Javadoc) * @see org.eclipse.jface.preference.IPreferencePage#performOk() */ @Override public boolean performOk() { boolean useProjectContentTypes= fUseProject.getSelection(); IProject project = getProject(); if (CCorePlugin.usesProjectSpecificContentTypes(project) != useProjectContentTypes) { CCorePlugin.setUseProjectSpecificContentTypes(project, useProjectContentTypes); computeEvents(project); } if (useProjectContentTypes) { fPrefsBlock.performOk(); } return super.performOk(); } private IProject getProject(){ Object element = getElement(); IProject project = null; if (element instanceof IProject) { project = (IProject) element; } else if (element instanceof IAdaptable) { project= (IProject) ((IAdaptable)element).getAdapter(IProject.class); } return project; } public IContentType[] getRegistedContentTypes() { String [] ids = CoreModel.getRegistedContentTypeIds(); IContentTypeManager manager = Platform.getContentTypeManager(); IContentType [] ctypes = new IContentType[ids.length]; for (int i = 0; i < ids.length; i++) { ctypes[i] = manager.getContentType(ids[i]); } return ctypes; } /** * We are looking at the association from the project, if we have any * we should generate an event. * @param project */ void computeEvents(IProject project) { IScopeContext projectScope = new ProjectScope(project); IContentType[] ctypes = getRegistedContentTypes(); ArrayList<IContentType> list = new ArrayList<IContentType>(ctypes.length); for (IContentType ctype : ctypes) { try { IContentTypeSettings projectSettings = ctype.getSettings(projectScope); String[] projectSpecs = projectSettings.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); if (projectSpecs!= null && projectSpecs.length > 0) { list.add(ctype); } else { projectSpecs = projectSettings.getFileSpecs(IContentType.FILE_NAME_SPEC); if (projectSpecs != null && projectSpecs.length > 0) { list.add(ctype); } } } catch (CoreException e) { // ignore ? } } // fire the events if (list.size() > 0) { IContentTypeManager.ContentTypeChangeEvent[] events = new IContentTypeManager.ContentTypeChangeEvent[list.size()]; for (int i = 0; i < list.size(); ++i) { IContentType source = list.get(i); events[i] = new IContentTypeManager.ContentTypeChangeEvent(source, projectScope); } CModelManager.getDefault().contentTypeChanged(events); } } boolean isSpecsChanged(String[] newSpecs, String[] oldSpecs) { if (newSpecs.length != oldSpecs.length) { return true; } for (int i = 0; i < newSpecs.length; ++i) { String newSpec = newSpecs[i]; boolean found = false; for (int j = 0; j < oldSpecs.length; ++j) { String oldSpec = oldSpecs[j]; if (newSpec.equalsIgnoreCase(oldSpec)) { found = true; break; } } if (!found) { return true; } } return false; } }