org.eclipse.cdt.ui.newui.BinaryParsTab.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.cdt.ui.newui.BinaryParsTab.java

Source

/*******************************************************************************
 * 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() {
            @Override
            public Object[] getElements(Object inputElement) {
                return (Object[]) inputElement;
            }

            @Override
            public void dispose() {
            }

            @Override
            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() {
            @Override
            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();
    }
}