From 2d9d50bb2e8be866cd257e738132f27f77b9379b Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Wed, 17 Sep 2003 02:18:16 +0000 Subject: [PATCH] First draft on BinaryParserBlock to add dynamic UI contribution for differen BinaryParserPage extension. --- core/org.eclipse.cdt.ui/ChangeLog | 9 + core/org.eclipse.cdt.ui/plugin.xml | 11 + .../ui/dialogs/AbstractBinaryParserPage.java | 156 ++++++++++++++ .../cdt/ui/dialogs/BinaryParserBlock.java | 35 +++- .../ui/dialogs/GNUElfBinaryParserPage.java | 197 ++++++++++++++++++ 5 files changed, 406 insertions(+), 2 deletions(-) create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractBinaryParserPage.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index 21e3f82df20..c57c6a0247b 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,12 @@ +2003-09-16 Alain Magloire + + Work to the new BinaryParserBlock to add dynamic UI + contribution for binary parsers that need the flexibility. + + * src/ore/eclipse/cdt/ui/dialogs/BinaryParserBlock.java + * src/ore/eclipse/cdt/ui/dialogs/AbstractBinaryParserPage.java + * src/ore/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java + 2003-09-16 David Inglis Removal of make builder ui components. diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 5896b4154c1..8441c68ab81 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -25,6 +25,8 @@ + + @@ -602,4 +604,13 @@ + + + + + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractBinaryParserPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractBinaryParserPage.java new file mode 100644 index 00000000000..24292decd36 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/AbstractBinaryParserPage.java @@ -0,0 +1,156 @@ +/*********************************************************************** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.ui.dialogs; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IPluginDescriptor; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +public abstract class AbstractBinaryParserPage extends AbstractCOptionPage { + + protected ICOptionPage fCurrentBinaryParserPage; + protected Map fParserPageMap = null; + + // Composite parent provided by the block. + protected Composite fCompositeParent; + + public AbstractBinaryParserPage() { + super(); + } + + public AbstractBinaryParserPage(String title) { + super(title); + } + + public AbstractBinaryParserPage(String title, ImageDescriptor image) { + super(title, image); + } + + protected Composite getCompositeParent() { + return fCompositeParent; + } + + protected void setCompositeParent(Composite parent) { + fCompositeParent = parent; + } + + /** + * Save the current Binary parser page. + */ + protected void setCurrentBinaryParserPage(ICOptionPage current) { + fCurrentBinaryParserPage = current; + } + + /** + * Get the current Binary parser page. + */ + protected ICOptionPage getCurrentBinaryParserPage() { + return fCurrentBinaryParserPage; + } + + /** + * Notification that the user changed the selection of the Binary Parser. + */ + protected void handleBinaryParserChanged() { + loadDynamicBinaryParserArea(); + } + + /** + * Show the contributed piece of UI that was registered for the Binary parser id. + */ + protected void loadDynamicBinaryParserArea() { + // Dispose of any current child widgets in the tab holder area + Control[] children = getCompositeParent().getChildren(); + for (int i = 0; i < children.length; i++) { + children[i].dispose(); + } + + // Retrieve the dynamic UI for the current parser + String parserID = getCurrentBinaryParserID(); + ICOptionPage page = getBinaryParserPage(parserID); + if (page != null) { + Composite parent = getCompositeParent(); + page.setContainer(getContainer()); + page.createControl(parent); + page.getControl().setVisible(true); + parent.layout(true); + setCurrentBinaryParserPage(page); + } + } + + public void setContainer(ICOptionContainer container) { + super.setContainer(container); + initializeParserPageMap(); + } + + public ICOptionPage getBinaryParserPage(String parserID) { + if (fParserPageMap == null) { + initializeParserPageMap(); + } + IConfigurationElement configElement = (IConfigurationElement) fParserPageMap.get(parserID); + ICOptionPage page = null; + if (configElement != null) { + try { + page = (ICOptionPage) configElement.createExecutableExtension("class"); //$NON-NLS-1$ + } catch (CoreException ce) { + //ce.printStackTrace(); + } + } + return page; + } + + protected void initializeParserPageMap() { + fParserPageMap = new HashMap(5); + + IPluginDescriptor descriptor = CUIPlugin.getDefault().getDescriptor(); + IExtensionPoint extensionPoint = descriptor.getExtensionPoint("BinaryParserPage"); //$NON-NLS-1$ + IConfigurationElement[] infos = extensionPoint.getConfigurationElements(); + for (int i = 0; i < infos.length; i++) { + String id = infos[i].getAttribute("parserID"); //$NON-NLS-1$ + fParserPageMap.put(id, infos[i]); + } + } + + abstract protected String getCurrentBinaryParserID(); + + abstract public void createControl(Composite parent); + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) + */ + public void performApply(IProgressMonitor monitor) throws CoreException { + ICOptionPage page = getCurrentBinaryParserPage(); + if (page != null) { + page.performApply(monitor); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults() + */ + public void performDefaults() { + ICOptionPage page = getCurrentBinaryParserPage(); + if (page != null) { + page.performDefaults(); + } + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/BinaryParserBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/BinaryParserBlock.java index f4e65ac8f76..4d5a17a0c42 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/BinaryParserBlock.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/BinaryParserBlock.java @@ -1,4 +1,3 @@ -package org.eclipse.cdt.ui.dialogs; /*********************************************************************** * Copyright (c) 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials @@ -9,6 +8,7 @@ package org.eclipse.cdt.ui.dialogs; * Contributors: * QNX Software Systems - Initial API and implementation ***********************************************************************/ +package org.eclipse.cdt.ui.dialogs; import java.util.HashMap; import java.util.Iterator; @@ -31,9 +31,10 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; -public class BinaryParserBlock extends AbstractCOptionPage { +public class BinaryParserBlock extends AbstractBinaryParserPage { private static final String PREFIX = "BinaryParserBlock"; // $NON-NLS-1$ private static final String LABEL = PREFIX + ".label"; // $NON-NLS-1$ @@ -67,6 +68,7 @@ public class BinaryParserBlock extends AbstractCOptionPage { comboBox.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { getContainer().updateContainer(); + handleBinaryParserChanged(); } }); Iterator items = idMap.keySet().iterator(); @@ -77,6 +79,23 @@ public class BinaryParserBlock extends AbstractCOptionPage { if (initial != null) { comboBox.setText(initial); } + + // Add the Parser UI contribution. + Group parserGroup = new Group(control, SWT.SHADOW_ETCHED_IN); + parserGroup.setText("Binary Parser Options"); + GridLayout tabHolderLayout = new GridLayout(); + tabHolderLayout.marginHeight = 0; + tabHolderLayout.marginWidth = 0; + tabHolderLayout.numColumns = 1; + parserGroup.setLayout(tabHolderLayout); + gd = new GridData(GridData.FILL_BOTH); + gd.horizontalSpan = 2; + parserGroup.setLayoutData(gd); + // Must set the composite parent to super class. + setCompositeParent(parserGroup); + // fire a change event, to quick start. + handleBinaryParserChanged(); + setControl(control); } @@ -99,6 +118,10 @@ public class BinaryParserBlock extends AbstractCOptionPage { } else { fPrefs.setDefault(CCorePlugin.PREF_BINARY_PARSER, (String) idMap.get(initial)); } + // Give a chance to the contributions to save. + // We have to do it last to make sure the parser id is save + // in .cdtproject + super.performApply(monitor); } public void setContainer(ICOptionContainer container) { @@ -147,7 +170,15 @@ public class BinaryParserBlock extends AbstractCOptionPage { initial = point.getExtension(id).getLabel(); } comboBox.setText(initial); + // Give a change to the UI contributors to react. + // But do it last after the comboBox is set. + super.performDefaults(); getContainer().updateContainer(); } + protected String getCurrentBinaryParserID() { + String selected = comboBox.getText(); + return (String) idMap.get(selected); + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java new file mode 100644 index 00000000000..5d229ec6d00 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/GNUElfBinaryParserPage.java @@ -0,0 +1,197 @@ +/*********************************************************************** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.ui.dialogs; + +import java.io.File; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; +import org.eclipse.cdt.core.ICExtensionReference; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.utils.ui.controls.ControlFactory; +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.IPluginDescriptor; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +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.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + */ +public class GNUElfBinaryParserPage extends AbstractCOptionPage { + + protected Text fAddr2LineCommandText; + protected Text fCPPFiltCommandText; + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor) + */ + public void performApply(IProgressMonitor monitor) throws CoreException { + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + monitor.beginTask("Saving Attributes", 1); + IProject proj = getContainer().getProject(); + if (proj != null) { + ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(proj); + String addr2line = fAddr2LineCommandText.getText().trim(); + String cppfilt = fCPPFiltCommandText.getText().trim(); + ICExtensionReference[] cext = cdesc.get(CCorePlugin.BINARY_PARSER_UNIQ_ID); + if (cext.length == 0) { + // The value was not save yet and we need to save it now + // to apply the changes. Search the extension for our own ID + IPluginDescriptor descriptor = CUIPlugin.getDefault().getDescriptor(); + IExtensionPoint point = descriptor.getExtensionPoint("BinaryParserPage"); //$NON-NLS-1$ + IConfigurationElement[] infos = point.getConfigurationElements(); + for (int i = 0; i < infos.length; i++) { + String id = infos[i].getAttribute("parserID"); //$NON-NLS-1$ + String clazz = infos[i].getAttribute("class"); //$NON-NLS-1$ + String ego = getClass().getName(); + if (clazz != null && clazz.equals(ego)) { + cdesc.remove(CCorePlugin.BINARY_PARSER_UNIQ_ID); + cdesc.create(CCorePlugin.BINARY_PARSER_UNIQ_ID, id); + } + } + // Try again. + cext = cdesc.get(CCorePlugin.BINARY_PARSER_UNIQ_ID); + } + if (cext.length > 0) { + String orig = cext[0].getExtensionData("addr2line"); + if (orig == null || !orig.equals(addr2line)) { + cext[0].setExtensionData("addr2line", addr2line); + } + orig = cext[0].getExtensionData("c++filt"); + if (orig == null || !orig.equals(cppfilt)) { + cext[0].setExtensionData("c++filt", cppfilt); + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults() + */ + public void performDefaults() { + String addr2line = null; + String cppfilt = null; + IProject proj = getContainer().getProject(); + if (proj != null) { + try { + ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(proj); + ICExtensionReference[] cext = cdesc.get(CCorePlugin.BINARY_PARSER_UNIQ_ID); + if (cext.length > 0) { + addr2line = cext[0].getExtensionData("addr2line"); + cppfilt = cext[0].getExtensionData("c++filt"); + } + } catch (CoreException e) { + } + } + fAddr2LineCommandText.setText((addr2line == null) ? "addr2line" : addr2line); + fCPPFiltCommandText.setText((cppfilt == null) ? "c++filt" : cppfilt); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Composite comp = ControlFactory.createCompositeEx(parent, 2, GridData.FILL_HORIZONTAL); + ((GridLayout) comp.getLayout()).makeColumnsEqualWidth = false; + + Label label = ControlFactory.createLabel(comp, "addr2line Command:"); + GridData gd = new GridData(); + gd.horizontalSpan = 2; + label.setLayoutData(gd); + + fAddr2LineCommandText = ControlFactory.createTextField(comp, SWT.SINGLE | SWT.BORDER); + fAddr2LineCommandText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent evt) { + //updateLaunchConfigurationDialog(); + } + }); + + Button button = ControlFactory.createPushButton(comp, "&Browse..."); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + handleAddr2LineButtonSelected(); + //updateLaunchConfigurationDialog(); + } + + private void handleAddr2LineButtonSelected() { + FileDialog dialog = new FileDialog(getShell(), SWT.NONE); + dialog.setText("addr2line Command"); + String command = fAddr2LineCommandText.getText().trim(); + int lastSeparatorIndex = command.lastIndexOf(File.separator); + if (lastSeparatorIndex != -1) { + dialog.setFilterPath(command.substring(0, lastSeparatorIndex)); + } + String res = dialog.open(); + if (res == null) { + return; + } + fAddr2LineCommandText.setText(res); + } + }); + + label = ControlFactory.createLabel(comp, "c++filt Command:"); + gd = new GridData(); + gd.horizontalSpan = 2; + label.setLayoutData(gd); + + fCPPFiltCommandText = ControlFactory.createTextField(comp, SWT.SINGLE | SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + fCPPFiltCommandText.setLayoutData(gd); + fCPPFiltCommandText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent evt) { + //updateLaunchConfigurationDialog(); + } + }); + button = ControlFactory.createPushButton(comp, "&Browse..."); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent evt) { + handleCPPFiltButtonSelected(); + //updateLaunchConfigurationDialog(); + } + + private void handleCPPFiltButtonSelected() { + FileDialog dialog = new FileDialog(getShell(), SWT.NONE); + dialog.setText("c++filt Command"); + String command = fCPPFiltCommandText.getText().trim(); + int lastSeparatorIndex = command.lastIndexOf(File.separator); + if (lastSeparatorIndex != -1) { + dialog.setFilterPath(command.substring(0, lastSeparatorIndex)); + } + String res = dialog.open(); + if (res == null) { + return; + } + fCPPFiltCommandText.setText(res); + } + }); + + setControl(comp); + performDefaults(); + } + +}