/******************************************************************************* * Copyright (c) 2007, 2010 Intel 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: * Intel Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.ui.newui; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.layout.PixelConverter; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; 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.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.ui.PlatformUI; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICMultiResourceDescription; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.ICTargetPlatformSetting; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.dialogs.ICOptionPage; import org.eclipse.cdt.utils.ui.controls.TabFolderLayout; import org.eclipse.cdt.internal.ui.ICHelpContextIds; import org.eclipse.cdt.internal.ui.newui.Messages; /** * @noextend This class is not intended to be subclassed by clients. */ public class BinaryParsTab extends AbstractCPropertyTab { /* Settings from binary parser pages are NOT saved by prior CDT version. * So existing binary parsers _always_ use default values. * Moreover, obsolete interface is used while attempting to save. * * We have to affect both parsers and pages * to teach them to save data really. * * It will be done in next versions. Currently pages are disabled. */ private static final int DEFAULT_HEIGHT = 160; private static final String ATTR_FILTER = "filter"; //$NON-NLS-1$ private static final String ATTR_NAME = "name"; //$NON-NLS-1$ private static final String ATTR_NAME_VISIBILITY = "visibility"; //$NON-NLS-1$ private static final String ATTR_VALUE = "value"; //$NON-NLS-1$ private static final String ATTR_VALUE_PRIVATE = "private"; //$NON-NLS-1$ protected Map<String, BinaryParserConfiguration> configMap; protected Map<String, BinaryParserPageConfiguration> fParserPageMap = null; protected Table table; protected CheckboxTableViewer tv; protected Composite parserGroup; protected SashForm sashForm; private ICTargetPlatformSetting tps; protected class BinaryParserConfiguration { IExtension fExtension; public BinaryParserConfiguration(IExtension extension) { fExtension = extension; } public String getID() { return fExtension.getUniqueIdentifier();} public String getName() { return fExtension.getLabel(); } @Override public String toString() { return fExtension.getUniqueIdentifier(); } @Override public boolean equals(Object obj) { if (obj instanceof BinaryParserConfiguration) { return this.getID().equals(((BinaryParserConfiguration) obj).getID()); } return super.equals(obj); } } protected class BinaryParserPageConfiguration { ICOptionPage dynamicPage; IConfigurationElement fElement; public BinaryParserPageConfiguration(IConfigurationElement element) { fElement = element; } public ICOptionPage getPage() throws CoreException { if (dynamicPage == null) { dynamicPage = (ICOptionPage) fElement.createExecutableExtension("class"); //$NON-NLS-1$ } return dynamicPage; } } protected String getParserId() { return CCorePlugin.BINARY_PARSER_SIMPLE_ID; } @Override public void createControls(Composite parent) { super.createControls(parent); PlatformUI.getWorkbench().getHelpSystem().setHelp(usercomp, ICHelpContextIds.BINARY_PARSER_PAGE); usercomp.setLayout(new GridLayout(1, false)); sashForm = new SashForm(usercomp, SWT.NONE); sashForm.setBackground(sashForm.getDisplay().getSystemColor(SWT.COLOR_GRAY)); sashForm.setOrientation(SWT.VERTICAL); sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); GridLayout layout = new GridLayout(2, false); layout.marginHeight = 5; sashForm.setLayout(layout); Composite c1 = new Composite(sashForm, SWT.NONE); c1.setLayout(new GridLayout(2, false)); setupLabel(c1, Messages.BinaryParsTab_0, 2, GridData.FILL_HORIZONTAL); table = new Table(c1, SWT.BORDER | SWT.CHECK | SWT.SINGLE); table.setLayoutData(new GridData(GridData.FILL_BOTH)); table.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { handleBinaryParserChanged(); updateButtons(); }}); tv = new CheckboxTableViewer(table); tv.setContentProvider(new IStructuredContentProvider() { public Object[] getElements(Object inputElement) { return (Object[])inputElement; } public void dispose() {} public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} }); tv.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { String txt = (element != null) ? element.toString() : EMPTY_STR; if (element instanceof BinaryParserConfiguration) txt = ((BinaryParserConfiguration)element).getName(); return txt; } }); tv.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(CheckStateChangedEvent e) { saveChecked(); }}); // get "standard" buttons on my own place Composite c = new Composite(c1, SWT.NONE); c.setLayoutData(new GridData(GridData.END)); initButtons(c, new String[] {MOVEUP_STR, MOVEDOWN_STR}); parserGroup = new Composite(sashForm, SWT.NULL); GridData gd = new GridData(); parserGroup.setLayout(new TabFolderLayout()); PixelConverter converter = new PixelConverter(parent); gd.heightHint = converter.convertHorizontalDLUsToPixels(DEFAULT_HEIGHT); gd.horizontalAlignment = GridData.FILL; gd.grabExcessHorizontalSpace = true; gd.grabExcessVerticalSpace = true; gd.horizontalSpan = 2; parserGroup.setLayoutData(gd); sashForm.setWeights(new int[] {100, 100}); initializeParserList(); initializeParserPageMap(); handleBinaryParserChanged(); } @Override public void setVisible(boolean _visible) { super.setVisible(_visible); page.enableConfigSelection(!_visible); } @Override public void updateData(ICResourceDescription cfgd) { String[] ids = null; if (page.isForPrefs()) { // prefs if (cfgd != null && cfgd.getConfiguration() != null) { tps = cfgd.getConfiguration().getTargetPlatformSetting(); if (tps != null) ids = tps.getBinaryParserIds(); } if (ids == null) ids = new String[0]; // no selection } else { // project ICConfigurationDescription[] cfgs = page.getCfgsEditable(); ids = CoreModelUtil.getBinaryParserIds(cfgs); } Object[] data = new Object[configMap.size()]; HashMap<String, BinaryParserConfiguration> clone = new HashMap<String, BinaryParserConfiguration>(configMap); // add checked elements int i; for (i=0; i<ids.length; i++) { data[i] = clone.get(ids[i]); clone.remove(ids[i]); } // add remaining parsers (unchecked) Iterator<String> it = clone.keySet().iterator(); // i = 0; while (it.hasNext()) { String s = it.next(); data[i++] = clone.get(s); } tv.setInput(data); tv.setAllChecked(false); // set check marks for (i=0; i<ids.length; i++) { if (configMap.containsKey(ids[i])) { tv.setChecked(configMap.get(ids[i]), true); } } updateButtons(); } private void initializeParserList() { IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, CCorePlugin.BINARY_PARSER_SIMPLE_ID); if (point != null) { IExtension[] exts = point.getExtensions(); configMap = new HashMap<String, BinaryParserConfiguration>(exts.length); for (IExtension ext : exts) { if (isExtensionVisible(ext)) { configMap.put(ext.getUniqueIdentifier(), new BinaryParserConfiguration(ext)); } } } } private void initializeParserPageMap() { fParserPageMap = new HashMap<String, BinaryParserPageConfiguration>(5); IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(CUIPlugin.PLUGIN_ID, "BinaryParserPage"); //$NON-NLS-1$ IConfigurationElement[] infos = extensionPoint.getConfigurationElements(); for (IConfigurationElement info : infos) { if (info.getName().equals("parserPage")) { //$NON-NLS-1$ String id = info.getAttribute("parserID"); //$NON-NLS-1$ fParserPageMap.put(id, new BinaryParserPageConfiguration(info)); } } } private boolean isExtensionVisible(IExtension ext) { IConfigurationElement[] elements = ext.getConfigurationElements(); for (IConfigurationElement element : elements) { IConfigurationElement[] children = element.getChildren(ATTR_FILTER); for (IConfigurationElement element2 : children) { String name = element2.getAttribute(ATTR_NAME); if (name != null && name.equals(ATTR_NAME_VISIBILITY)) { String value = element2.getAttribute(ATTR_VALUE); if (value != null && value.equals(ATTR_VALUE_PRIVATE)) { return false; } } } return true; } return false; // invalid extension definition (must have at least cextension elements) } @Override public void updateButtons() { int cnt = table.getItemCount(); int pos = table.getSelectionIndex(); buttonSetEnabled(0, pos > 0); buttonSetEnabled(1, pos != -1 && pos < (cnt - 1)); } protected void handleBinaryParserChanged() { String[] enabled = getBinaryParserIDs(); ICOptionPage dynamicPage; for (String element : enabled) { // create all enabled pages dynamicPage = getBinaryParserPage(element); if (dynamicPage != null) { if (dynamicPage.getControl() == null) { dynamicPage.setContainer(page); dynamicPage.createControl(parserGroup); } dynamicPage.setVisible(false); } } // Retrieve the dynamic UI for the current parser String parserID = getCurrentBinaryParserID(); dynamicPage = getBinaryParserPage(parserID); if (dynamicPage != null) { dynamicPage.setVisible(true); } } protected String[] getBinaryParserIDs() { return configMap.keySet().toArray(new String[configMap.keySet().size()]); } protected ICOptionPage getBinaryParserPage(String parserID) { BinaryParserPageConfiguration configElement = fParserPageMap.get(parserID); if (configElement != null) { try { return configElement.getPage(); } catch (CoreException e) {} } return null; } protected String getCurrentBinaryParserID() { int x = table.getSelectionIndex(); if (x < 0) return null; return ((BinaryParserConfiguration)table.getItem(x).getData()).getID(); } @Override protected void performApply(ICResourceDescription src, ICResourceDescription dst) { if (page.isMultiCfg()) { src = ((ICResourceDescription[])((ICMultiResourceDescription)src).getItems())[0]; dst = ((ICResourceDescription[])((ICMultiResourceDescription)dst).getItems())[0]; } ICTargetPlatformSetting tps1 = src.getConfiguration().getTargetPlatformSetting(); ICTargetPlatformSetting tps2 = dst.getConfiguration().getTargetPlatformSetting(); if (tps1 != null && tps2 != null) { tps2.setBinaryParserIds(tps1.getBinaryParserIds()); } } @Override protected void performDefaults() { if (page.isForProject()) CoreModelUtil.setBinaryParserIds(page.getCfgsEditable(), null); else if (tps != null) tps.setBinaryParserIds(null); informPages(false); updateData(getResDesc()); } private void informPages(boolean apply) { IProgressMonitor mon = new NullProgressMonitor(); Iterator<BinaryParserPageConfiguration> it = fParserPageMap.values().iterator(); while (it.hasNext()) { try { ICOptionPage dynamicPage = (it.next()).getPage(); if (dynamicPage.isValid() && dynamicPage.getControl() != null) { if (apply) dynamicPage.performApply(mon); else dynamicPage.performDefaults(); } } catch (CoreException e) {} } } @Override public void buttonPressed(int i) { switch (i) { case 0: moveItem(true); break; case 1: moveItem(false); break; default: break; } } // Move item up / down private void moveItem(boolean up) { int n = table.getSelectionIndex(); if (n < 0 || (up && n == 0) || (!up && n+1 == table.getItemCount())) return; Object d = tv.getElementAt(n); boolean checked = tv.getChecked(d); tv.remove(d); n = up ? n - 1 : n + 1; tv.insert(d, n); tv.setChecked(d, checked); table.setSelection(n); saveChecked(); updateButtons(); } private void saveChecked() { Object[] objs = tv.getCheckedElements(); String[] ids = null; if (objs != null) { ids = new String[objs.length]; for (int i=0; i<objs.length; i++) { ids[i] = ((BinaryParserConfiguration)objs[i]).getID(); } } if (page.isForPrefs()) { if (tps != null) tps.setBinaryParserIds(ids); } else { CoreModelUtil.setBinaryParserIds(page.getCfgsEditable(), ids); } } // This page can be displayed for project only @Override public boolean canBeVisible() { return page.isForProject() || page.isForPrefs(); } }