001: /*******************************************************************************
002: * Copyright (c) 2003, 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.plugin;
011:
012: import java.util.ArrayList;
013:
014: import org.eclipse.jface.viewers.ISelection;
015: import org.eclipse.jface.viewers.IStructuredSelection;
016: import org.eclipse.osgi.util.NLS;
017: import org.eclipse.pde.core.IModelChangedEvent;
018: import org.eclipse.pde.core.plugin.IPluginAttribute;
019: import org.eclipse.pde.core.plugin.IPluginElement;
020: import org.eclipse.pde.core.plugin.IPluginModelBase;
021: import org.eclipse.pde.internal.core.ischema.IMetaAttribute;
022: import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
023: import org.eclipse.pde.internal.core.ischema.ISchemaElement;
024: import org.eclipse.pde.internal.core.ischema.ISchemaRestriction;
025: import org.eclipse.pde.internal.core.ischema.ISchemaSimpleType;
026: import org.eclipse.pde.internal.ui.PDEUIMessages;
027: import org.eclipse.pde.internal.ui.editor.FormLayoutFactory;
028: import org.eclipse.pde.internal.ui.editor.PDEFormPage;
029: import org.eclipse.pde.internal.ui.editor.PDESection;
030: import org.eclipse.pde.internal.ui.editor.plugin.rows.BooleanAttributeRow;
031: import org.eclipse.pde.internal.ui.editor.plugin.rows.ChoiceAttributeRow;
032: import org.eclipse.pde.internal.ui.editor.plugin.rows.ClassAttributeRow;
033: import org.eclipse.pde.internal.ui.editor.plugin.rows.ExtensionAttributeRow;
034: import org.eclipse.pde.internal.ui.editor.plugin.rows.ResourceAttributeRow;
035: import org.eclipse.pde.internal.ui.editor.plugin.rows.TextAttributeRow;
036: import org.eclipse.pde.internal.ui.editor.plugin.rows.TranslatableAttributeRow;
037: import org.eclipse.swt.layout.GridData;
038: import org.eclipse.swt.layout.GridLayout;
039: import org.eclipse.swt.widgets.Composite;
040: import org.eclipse.ui.forms.IFormPart;
041: import org.eclipse.ui.forms.widgets.ExpandableComposite;
042: import org.eclipse.ui.forms.widgets.FormToolkit;
043: import org.eclipse.ui.forms.widgets.Section;
044: import org.eclipse.ui.forms.widgets.SharedScrolledComposite;
045:
046: public class ExtensionElementDetails extends
047: AbstractPluginElementDetails {
048: private IPluginElement input;
049: private ISchemaElement schemaElement;
050: private ArrayList rows;
051: private Section section;
052:
053: /**
054: * @param masterSection
055: * @param schemaElement
056: */
057: public ExtensionElementDetails(PDESection masterSection,
058: ISchemaElement schemaElement) {
059: super (masterSection);
060: this .schemaElement = schemaElement;
061: rows = new ArrayList();
062: }
063:
064: public String getContextId() {
065: return PluginInputContext.CONTEXT_ID;
066: }
067:
068: public void fireSaveNeeded() {
069: markDirty();
070: getPage().getPDEEditor().fireSaveNeeded(getContextId(), false);
071: }
072:
073: public PDEFormPage getPage() {
074: return (PDEFormPage) getManagedForm().getContainer();
075: }
076:
077: public boolean isEditable() {
078: return getPage().getPDEEditor().getAggregateModel()
079: .isEditable();
080: }
081:
082: /*
083: * (non-Javadoc)
084: *
085: * @see org.eclipse.ui.forms.IDetailsPage#createContents(org.eclipse.swt.widgets.Composite)
086: */
087: public void createContents(Composite parent) {
088: parent.setLayout(FormLayoutFactory.createDetailsGridLayout(
089: false, 1));
090: FormToolkit toolkit = getManagedForm().getToolkit();
091: section = toolkit.createSection(parent,
092: ExpandableComposite.TITLE_BAR | Section.DESCRIPTION);
093: section.clientVerticalSpacing = FormLayoutFactory.SECTION_HEADER_VERTICAL_SPACING;
094: section.setText(PDEUIMessages.ExtensionElementDetails_title);
095: section.setDescription(""); //$NON-NLS-1$
096: section.setLayout(FormLayoutFactory.createClearGridLayout(
097: false, 1));
098: section.setLayoutData(new GridData(GridData.FILL_BOTH
099: | GridData.VERTICAL_ALIGN_BEGINNING));
100:
101: // Align the master and details section headers (misalignment caused
102: // by section toolbar icons)
103: getPage().alignSectionHeaders(getMasterSection().getSection(),
104: section);
105:
106: Composite client = toolkit.createComposite(section);
107: int span = 2;
108: GridLayout glayout = FormLayoutFactory
109: .createSectionClientGridLayout(false, span);
110: client.setLayout(glayout);
111: client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
112:
113: if (schemaElement != null) {
114: ISchemaAttribute atts[] = schemaElement.getAttributes();
115: // Compute horizontal span
116: for (int i = 0; i < atts.length; i++) {
117: if (isEditable()
118: && (atts[i].getKind() == IMetaAttribute.JAVA || atts[i]
119: .getKind() == IMetaAttribute.RESOURCE)) {
120: span = 3;
121: break;
122: }
123: }
124: glayout.numColumns = span;
125: // Add required attributes first
126: for (int i = 0; i < atts.length; i++) {
127: if (atts[i].getUse() == ISchemaAttribute.REQUIRED)
128: rows.add(createAttributeRow(atts[i], client,
129: toolkit, span));
130: }
131: // Add the rest
132: for (int i = 0; i < atts.length; i++) {
133: if (atts[i].getUse() != ISchemaAttribute.REQUIRED)
134: rows.add(createAttributeRow(atts[i], client,
135: toolkit, span));
136: }
137: createSpacer(toolkit, client, span);
138: } else {
139: // no schema - delay until input is set
140: }
141: toolkit.paintBordersFor(client);
142: section.setClient(client);
143: // Dynamically add focus listeners to all the section client's
144: // children in order to track the last focus control
145: getPage().addLastFocusListeners(client);
146:
147: IPluginModelBase model = (IPluginModelBase) getPage()
148: .getModel();
149: model.addModelChangedListener(this );
150: markDetailsPart(section);
151: }
152:
153: private ExtensionAttributeRow createAttributeRow(
154: ISchemaAttribute att, Composite parent,
155: FormToolkit toolkit, int span) {
156: ExtensionAttributeRow row;
157: if (att.getKind() == IMetaAttribute.JAVA)
158: row = new ClassAttributeRow(this , att);
159: else if (att.getKind() == IMetaAttribute.RESOURCE)
160: row = new ResourceAttributeRow(this , att);
161: else if (att.isTranslatable())
162: row = new TranslatableAttributeRow(this , att);
163: else {
164: ISchemaSimpleType type = att.getType();
165: if (type.getName().equals("boolean")) //$NON-NLS-1$
166: row = new BooleanAttributeRow(this , att);
167: else {
168: ISchemaRestriction restriction = type.getRestriction();
169: if (restriction != null)
170: row = new ChoiceAttributeRow(this , att);
171: else
172: row = new TextAttributeRow(this , att);
173: }
174: }
175: row.createContents(parent, toolkit, span);
176: return row;
177: }
178:
179: private ExtensionAttributeRow createAttributeRow(
180: IPluginAttribute att, Composite parent,
181: FormToolkit toolkit, int span) {
182: ExtensionAttributeRow row;
183: row = new TextAttributeRow(this , att);
184: row.createContents(parent, toolkit, span);
185: return row;
186: }
187:
188: /*
189: * (non-Javadoc)
190: *
191: * @see org.eclipse.ui.forms.IDetailsPage#inputChanged(org.eclipse.jface.viewers.IStructuredSelection)
192: */
193: public void selectionChanged(IFormPart masterPart,
194: ISelection selection) {
195: IStructuredSelection ssel = (IStructuredSelection) selection;
196: if (ssel.size() == 1) {
197: input = (IPluginElement) ssel.getFirstElement();
198: } else
199: input = null;
200: update();
201: }
202:
203: public void modelChanged(IModelChangedEvent e) {
204: if (e.getChangeType() == IModelChangedEvent.CHANGE) {
205: Object obj = e.getChangedObjects()[0];
206: if (obj.equals(input)) {
207: // do smart update (update only the row whose property changed
208: String property = e.getChangedProperty();
209: if (property != null) {
210: for (int i = 0; i < rows.size(); i++) {
211: ExtensionAttributeRow row = (ExtensionAttributeRow) rows
212: .get(i);
213: ISchemaAttribute attribute = row.getAttribute();
214: if (attribute == null) {
215: continue;
216: }
217: String name = attribute.getName();
218: if (name == null) {
219: continue;
220: }
221: if (name.equals(property)) {
222: row.setInput(input);
223: }
224: }
225: } else
226: refresh();
227: }
228: }
229: }
230:
231: private void update() {
232: updateDescription();
233: if (schemaElement == null)
234: updateRows();
235: for (int i = 0; i < rows.size(); i++) {
236: ExtensionAttributeRow row = (ExtensionAttributeRow) rows
237: .get(i);
238: row.setInput(input);
239: }
240: }
241:
242: private void updateRows() {
243: if (input == null)
244: return;
245: IPluginAttribute[] atts = input.getAttributes();
246: FormToolkit toolkit = getManagedForm().getToolkit();
247: boolean rowsAdded = false;
248: for (int i = 0; i < atts.length; i++) {
249: if (!hasAttribute(atts[i].getName())) {
250: rows.add(createAttributeRow(atts[i],
251: (Composite) section.getClient(), toolkit, 2));
252: rowsAdded = true;
253: }
254: }
255: if (rowsAdded) {
256: ((Composite) section.getClient()).layout(true);
257: section.layout(true);
258: section.getParent().layout(true);
259: reflow();
260: }
261: }
262:
263: private void reflow() {
264: Composite parent = section.getParent();
265: while (parent != null) {
266: if (parent instanceof SharedScrolledComposite) {
267: ((SharedScrolledComposite) parent).reflow(true);
268: return;
269: }
270: parent = parent.getParent();
271: }
272: }
273:
274: private boolean hasAttribute(String attName) {
275: for (int i = 0; i < rows.size(); i++) {
276: ExtensionAttributeRow row = (ExtensionAttributeRow) rows
277: .get(i);
278: if (row.getName().equals(attName))
279: return true;
280: }
281: return false;
282: }
283:
284: private void updateDescription() {
285: if (input != null) {
286: if (0 == input.getAttributeCount()) {
287: section
288: .setDescription(PDEUIMessages.ExtensionElementDetails_descNoAttributes);
289: } else {
290: String iname = input.getName();
291: section.setDescription(NLS.bind(
292: PDEUIMessages.ExtensionElementDetails_setDesc,
293: iname));
294: }
295: } else {
296: // no extensions = no description
297: section.setDescription(""); //$NON-NLS-1$
298: }
299: section.layout();
300: }
301:
302: /*
303: * (non-Javadoc)
304: *
305: * @see org.eclipse.ui.forms.IDetailsPage#commit()
306: */
307: public void commit(boolean onSave) {
308: for (int i = 0; i < rows.size(); i++) {
309: ExtensionAttributeRow row = (ExtensionAttributeRow) rows
310: .get(i);
311: row.commit();
312: }
313: super .commit(onSave);
314: }
315:
316: /*
317: * (non-Javadoc)
318: *
319: * @see org.eclipse.ui.forms.IDetailsPage#setFocus()
320: */
321: public void setFocus() {
322: if (rows.size() > 0)
323: ((ExtensionAttributeRow) rows.get(0)).setFocus();
324: }
325:
326: /*
327: * (non-Javadoc)
328: *
329: * @see org.eclipse.ui.forms.IDetailsPage#dispose()
330: */
331: public void dispose() {
332: for (int i = 0; i < rows.size(); i++) {
333: ExtensionAttributeRow row = (ExtensionAttributeRow) rows
334: .get(i);
335: row.dispose();
336: }
337: IPluginModelBase model = (IPluginModelBase) getPage()
338: .getModel();
339: if (model != null)
340: model.removeModelChangedListener(this );
341: super .dispose();
342: }
343:
344: /*
345: * (non-Javadoc)
346: *
347: * @see org.eclipse.ui.forms.IDetailsPage#refresh()
348: */
349: public void refresh() {
350: update();
351: super.refresh();
352: }
353: }
|