001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.editor.product;
011:
012: import java.util.TreeSet;
013:
014: import org.eclipse.core.resources.IFile;
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.core.runtime.IConfigurationElement;
017: import org.eclipse.core.runtime.IExtension;
018: import org.eclipse.core.runtime.IProgressMonitor;
019: import org.eclipse.jface.dialogs.IDialogConstants;
020: import org.eclipse.jface.dialogs.MessageDialog;
021: import org.eclipse.jface.window.Window;
022: import org.eclipse.jface.wizard.WizardDialog;
023: import org.eclipse.pde.core.IBaseModel;
024: import org.eclipse.pde.core.IModelChangedEvent;
025: import org.eclipse.pde.core.plugin.IPluginModelBase;
026: import org.eclipse.pde.core.plugin.PluginRegistry;
027: import org.eclipse.pde.internal.core.PDECore;
028: import org.eclipse.pde.internal.core.TargetPlatformHelper;
029: import org.eclipse.pde.internal.core.ibundle.IBundle;
030: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
031: import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
032: import org.eclipse.pde.internal.core.iproduct.IIntroInfo;
033: import org.eclipse.pde.internal.core.iproduct.IProduct;
034: import org.eclipse.pde.internal.core.iproduct.IProductModel;
035: import org.eclipse.pde.internal.core.iproduct.IProductModelFactory;
036: import org.eclipse.pde.internal.core.iproduct.IProductPlugin;
037: import org.eclipse.pde.internal.core.text.bundle.RequireBundleHeader;
038: import org.eclipse.pde.internal.core.text.bundle.RequireBundleObject;
039: import org.eclipse.pde.internal.ui.PDEPlugin;
040: import org.eclipse.pde.internal.ui.PDEUIMessages;
041: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
042: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
043: import org.eclipse.pde.internal.ui.editor.PDESection;
044: import org.eclipse.pde.internal.ui.parts.ComboPart;
045: import org.eclipse.pde.internal.ui.util.ModelModification;
046: import org.eclipse.pde.internal.ui.util.PDEModelUtility;
047: import org.eclipse.pde.internal.ui.wizards.product.ProductIntroWizard;
048: import org.eclipse.swt.SWT;
049: import org.eclipse.swt.events.SelectionAdapter;
050: import org.eclipse.swt.events.SelectionEvent;
051: import org.eclipse.swt.layout.GridData;
052: import org.eclipse.swt.widgets.Button;
053: import org.eclipse.swt.widgets.Composite;
054: import org.eclipse.swt.widgets.Label;
055: import org.eclipse.ui.forms.IFormColors;
056: import org.eclipse.ui.forms.editor.IFormPage;
057: import org.eclipse.ui.forms.widgets.FormToolkit;
058: import org.eclipse.ui.forms.widgets.Section;
059: import org.osgi.framework.Constants;
060:
061: public class IntroSection extends PDESection {
062:
063: private ComboPart fIntroCombo;
064: private IFile fManifest;
065: private String[] fAvailableIntroIds;
066: private static final String INTRO_PLUGIN_ID = "org.eclipse.ui.intro"; //$NON-NLS-1$
067: private static final double NEW_INTRO_SUPPORT_VERSION = 3.1;
068:
069: public IntroSection(PDEFormPage page, Composite parent) {
070: super (page, parent, Section.DESCRIPTION);
071: createClient(getSection(), page.getEditor().getToolkit());
072: }
073:
074: public void createClient(Section section, FormToolkit toolkit) {
075:
076: section.setLayout(FormLayoutFactory.createClearGridLayout(
077: false, 1));
078: GridData data = new GridData(GridData.FILL_HORIZONTAL);
079: section.setLayoutData(data);
080:
081: section.setText(PDEUIMessages.IntroSection_sectionText);
082: section
083: .setDescription(PDEUIMessages.IntroSection_sectionDescription);
084:
085: boolean canCreateNew = TargetPlatformHelper.getTargetVersion() >= NEW_INTRO_SUPPORT_VERSION;
086:
087: Composite client = toolkit.createComposite(section);
088: client.setLayout(FormLayoutFactory
089: .createSectionClientGridLayout(false, canCreateNew ? 3
090: : 2));
091: client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
092:
093: Label label = toolkit.createLabel(client,
094: PDEUIMessages.IntroSection_introLabel, SWT.WRAP);
095: GridData td = new GridData();
096: td.horizontalSpan = canCreateNew ? 3 : 2;
097: label.setLayoutData(td);
098:
099: Label introLabel = toolkit.createLabel(client,
100: PDEUIMessages.IntroSection_introInput);
101: introLabel.setForeground(toolkit.getColors().getColor(
102: IFormColors.TITLE));
103:
104: fIntroCombo = new ComboPart();
105: fIntroCombo.createControl(client, toolkit, SWT.READ_ONLY);
106: td = new GridData(GridData.FILL_HORIZONTAL);
107: fIntroCombo.getControl().setLayoutData(td);
108: loadManifestAndIntroIds(false);
109: if (fAvailableIntroIds != null)
110: fIntroCombo.setItems(fAvailableIntroIds);
111: fIntroCombo.add(""); //$NON-NLS-1$
112: fIntroCombo.addSelectionListener(new SelectionAdapter() {
113: public void widgetSelected(SelectionEvent e) {
114: handleSelection();
115: }
116: });
117:
118: if (canCreateNew) {
119: Button button = toolkit.createButton(client,
120: PDEUIMessages.IntroSection_new, SWT.PUSH);
121: button.setEnabled(isEditable());
122: button.setLayoutData(new GridData(GridData.FILL));
123: button.addSelectionListener(new SelectionAdapter() {
124: public void widgetSelected(SelectionEvent e) {
125: handleNewIntro();
126: }
127: });
128: }
129:
130: fIntroCombo.getControl().setEnabled(isEditable());
131:
132: toolkit.paintBordersFor(client);
133: section.setClient(client);
134: // Register to be notified when the model changes
135: getModel().addModelChangedListener(this );
136: }
137:
138: private void handleSelection() {
139: if (!productDefined()) {
140: fIntroCombo.setText(""); //$NON-NLS-1$
141: return;
142: }
143: getIntroInfo().setId(fIntroCombo.getSelection());
144: addDependenciesAndPlugins();
145: }
146:
147: private void loadManifestAndIntroIds(boolean onlyLoadManifest) {
148: TreeSet result = new TreeSet();
149: String introId;
150: IExtension[] extensions = PDECore.getDefault()
151: .getExtensionsRegistry().findExtensions(
152: "org.eclipse.ui.intro"); //$NON-NLS-1$
153: for (int i = 0; i < extensions.length; i++) {
154: IConfigurationElement[] children = extensions[i]
155: .getConfigurationElements();
156: for (int j = 0; j < children.length; j++) {
157: if ("introProductBinding".equals(children[j].getName())) {//$NON-NLS-1$
158: String attribute = children[j]
159: .getAttribute("productId"); //$NON-NLS-1$
160: if (attribute != null
161: && attribute.equals(getProduct().getId())) {
162: if (fManifest == null) {
163: IPluginModelBase base = PluginRegistry
164: .findModel(extensions[i]
165: .getContributor().getName());
166: if (base == null)
167: continue;
168: fManifest = (IFile) base
169: .getUnderlyingResource();
170: }
171: if (onlyLoadManifest)
172: return;
173: introId = children[j].getAttribute("introId"); //$NON-NLS-1$
174: if (introId != null)
175: result.add(introId);
176: }
177: }
178: }
179: }
180: fAvailableIntroIds = (String[]) result
181: .toArray(new String[result.size()]);
182: }
183:
184: private void handleNewIntro() {
185: boolean needNewProduct = false;
186: if (!productDefined()) {
187: needNewProduct = true;
188: MessageDialog mdiag = new MessageDialog(
189: PDEPlugin.getActiveWorkbenchShell(),
190: PDEUIMessages.IntroSection_undefinedProductId,
191: null,
192: PDEUIMessages.IntroSection_undefinedProductIdMessage,
193: MessageDialog.QUESTION, new String[] {
194: IDialogConstants.YES_LABEL,
195: IDialogConstants.NO_LABEL }, 0);
196: if (mdiag.open() != Window.OK)
197: return;
198: }
199: ProductIntroWizard wizard = new ProductIntroWizard(
200: getProduct(), needNewProduct);
201: WizardDialog dialog = new WizardDialog(PDEPlugin
202: .getActiveWorkbenchShell(), wizard);
203: dialog.create();
204: if (dialog.open() == Window.OK) {
205: String id = wizard.getIntroId();
206: fIntroCombo.add(id, 0);
207: fIntroCombo.setText(id);
208: getIntroInfo().setId(id);
209: addDependenciesAndPlugins();
210: }
211: }
212:
213: public void refresh() {
214: String introId = getIntroInfo().getId();
215: if (introId == null) {
216: fIntroCombo.setText(""); //$NON-NLS-1$
217: } else {
218: fIntroCombo.setText(introId);
219: }
220: super .refresh();
221: }
222:
223: private IIntroInfo getIntroInfo() {
224: IIntroInfo info = getProduct().getIntroInfo();
225: if (info == null) {
226: info = getModel().getFactory().createIntroInfo();
227: getProduct().setIntroInfo(info);
228: }
229: return info;
230: }
231:
232: private IProduct getProduct() {
233: return getModel().getProduct();
234: }
235:
236: private IProductModel getModel() {
237: return (IProductModel) getPage().getPDEEditor()
238: .getAggregateModel();
239: }
240:
241: private boolean productDefined() {
242: String id = getProduct().getId();
243: return id != null && !id.equals(""); //$NON-NLS-1$
244: }
245:
246: private void addDependenciesAndPlugins() {
247: IProduct product = getProduct();
248: if (!product.useFeatures()) {
249: IProductModelFactory factory = product.getModel()
250: .getFactory();
251: IProductPlugin plugin = factory.createPlugin();
252: plugin.setId(INTRO_PLUGIN_ID);
253: product.addPlugins(new IProductPlugin[] { plugin });
254: boolean includeOptional = false;
255: IFormPage page = getPage().getEditor().findPage(
256: ConfigurationPage.PLUGIN_ID);
257: if (page != null)
258: includeOptional = ((ConfigurationPage) page)
259: .includeOptionalDependencies();
260: PluginSection.handleAddRequired(
261: new IProductPlugin[] { plugin }, includeOptional);
262: }
263: if (fManifest == null)
264: loadManifestAndIntroIds(true);
265: if (fManifest != null)
266: addRequiredBundle();
267: }
268:
269: private void addRequiredBundle() {
270: ModelModification mod = new ModelModification(fManifest) {
271: protected void modifyModel(IBaseModel model,
272: IProgressMonitor monitor) throws CoreException {
273: if (!(model instanceof IBundlePluginModelBase))
274: return;
275: IBundlePluginModelBase modelBase = (IBundlePluginModelBase) model;
276: IBundle bundle = modelBase.getBundleModel().getBundle();
277: IManifestHeader header = bundle
278: .getManifestHeader(Constants.REQUIRE_BUNDLE);
279: if (header instanceof RequireBundleHeader) {
280: RequireBundleObject[] requires = ((RequireBundleHeader) header)
281: .getRequiredBundles();
282: for (int i = 0; i < requires.length; i++)
283: if (requires[i].getId().equals(INTRO_PLUGIN_ID))
284: return;
285: ((RequireBundleHeader) header)
286: .addBundle(INTRO_PLUGIN_ID);
287: } else
288: bundle.setHeader(Constants.REQUIRE_BUNDLE,
289: INTRO_PLUGIN_ID);
290: }
291: };
292: PDEModelUtility.modifyModel(mod, null);
293: }
294:
295: /* (non-Javadoc)
296: * @see org.eclipse.pde.internal.ui.editor.PDESection#modelChanged(org.eclipse.pde.core.IModelChangedEvent)
297: */
298: public void modelChanged(IModelChangedEvent e) {
299: // No need to call super, handling world changed event here
300: if (e.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
301: handleModelEventWorldChanged(e);
302: }
303: }
304:
305: /**
306: * @param event
307: */
308: private void handleModelEventWorldChanged(IModelChangedEvent event) {
309: refresh();
310: }
311:
312: /* (non-Javadoc)
313: * @see org.eclipse.ui.forms.AbstractFormPart#dispose()
314: */
315: public void dispose() {
316: IProductModel model = getModel();
317: if (model != null) {
318: model.removeModelChangedListener(this);
319: }
320: super.dispose();
321: }
322:
323: }
|