001: /*******************************************************************************
002: * Copyright (c) 2006, 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.commands;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.Iterator;
015: import java.util.Map;
016:
017: import org.eclipse.core.commands.AbstractParameterValueConverter;
018: import org.eclipse.core.commands.Command;
019: import org.eclipse.core.commands.IParameter;
020: import org.eclipse.core.commands.IParameterValues;
021: import org.eclipse.core.commands.ParameterType;
022: import org.eclipse.core.commands.ParameterValueConversionException;
023: import org.eclipse.core.commands.ParameterValuesException;
024: import org.eclipse.core.commands.Parameterization;
025: import org.eclipse.core.commands.ParameterizedCommand;
026: import org.eclipse.core.commands.common.CommandException;
027: import org.eclipse.core.commands.common.NotDefinedException;
028: import org.eclipse.core.expressions.IEvaluationContext;
029: import org.eclipse.jface.dialogs.IMessageProvider;
030: import org.eclipse.jface.dialogs.MessageDialog;
031: import org.eclipse.osgi.util.NLS;
032: import org.eclipse.pde.internal.ui.PDEPluginImages;
033: import org.eclipse.pde.internal.ui.PDEUIMessages;
034: import org.eclipse.swt.SWT;
035: import org.eclipse.swt.dnd.Clipboard;
036: import org.eclipse.swt.dnd.DND;
037: import org.eclipse.swt.dnd.TextTransfer;
038: import org.eclipse.swt.dnd.Transfer;
039: import org.eclipse.swt.events.DisposeEvent;
040: import org.eclipse.swt.events.DisposeListener;
041: import org.eclipse.swt.events.ModifyEvent;
042: import org.eclipse.swt.events.ModifyListener;
043: import org.eclipse.swt.events.SelectionAdapter;
044: import org.eclipse.swt.events.SelectionEvent;
045: import org.eclipse.swt.graphics.Image;
046: import org.eclipse.swt.layout.GridData;
047: import org.eclipse.swt.layout.GridLayout;
048: import org.eclipse.swt.widgets.Button;
049: import org.eclipse.swt.widgets.Combo;
050: import org.eclipse.swt.widgets.Composite;
051: import org.eclipse.swt.widgets.Label;
052: import org.eclipse.swt.widgets.Text;
053: import org.eclipse.ui.PlatformUI;
054: import org.eclipse.ui.forms.events.HyperlinkAdapter;
055: import org.eclipse.ui.forms.events.HyperlinkEvent;
056: import org.eclipse.ui.forms.widgets.ExpandableComposite;
057: import org.eclipse.ui.forms.widgets.FormToolkit;
058: import org.eclipse.ui.forms.widgets.ImageHyperlink;
059: import org.eclipse.ui.forms.widgets.Section;
060: import org.eclipse.ui.handlers.IHandlerService;
061: import org.eclipse.ui.internal.handlers.HandlerService;
062:
063: public class CommandDetails {
064:
065: private final HashMap fParameterToValue = new HashMap();
066: private final ArrayList fObjectParamList = new ArrayList();
067: private final ArrayList fValueParamList = new ArrayList();
068: private final ArrayList fTextParamList = new ArrayList();
069:
070: private CommandComposerPart fCCP;
071: private FormToolkit fToolkit;
072: private Command fSelectedCommand;
073: private ParameterizedCommand fPreSel;
074:
075: private Text fComIDT;
076: private Text fComPrev;
077: private Button fSurroundCopyText;
078: private Combo fFilterCombo;
079: private Composite fParamComposite;
080: private Composite fParamParent;
081: private Label fParamLabel;
082: private ImageHyperlink fCopyLink;
083: private ImageHyperlink fExecLink;
084:
085: public CommandDetails(CommandComposerPart cv, Composite parent) {
086: fCCP = cv;
087: fToolkit = cv.getToolkit();
088: createCommandDetails(parent);
089: }
090:
091: private void createCommandDetails(Composite parent) {
092: Composite c = fCCP.createComposite(parent, GridData.FILL_BOTH,
093: 1, true, 5);
094:
095: Section section = fToolkit.createSection(c,
096: ExpandableComposite.TITLE_BAR);
097: section.setText(PDEUIMessages.CommandDetails_groupName);
098: section.setLayoutData(new GridData(GridData.FILL_BOTH));
099:
100: Composite comp = fCCP.createComposite(section);
101:
102: createBasicInfo(comp);
103:
104: if (fCCP.getFilterType() == CommandComposerPart.F_FILTER_NOT_SET)
105: createPreviewLabelComp(comp);
106: createParameters(comp);
107:
108: section.setClient(comp);
109:
110: createLinks(c);
111: }
112:
113: private void createBasicInfo(Composite parent) {
114: Composite comp = fCCP.createComposite(parent,
115: GridData.FILL_HORIZONTAL, 2, false, 0);
116: fToolkit.createLabel(comp, PDEUIMessages.CommandDetails_id);
117: fComIDT = fToolkit.createText(comp,
118: PDEUIMessages.CommandDetails_noComSelected, SWT.BORDER);
119: fComIDT.setEditable(false);
120: fComIDT.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
121: }
122:
123: private void createParameters(Composite parent) {
124: Composite comp = fCCP.createComposite(parent,
125: GridData.FILL_HORIZONTAL, 1, false, 0);
126:
127: fParamLabel = fToolkit.createLabel(comp,
128: PDEUIMessages.CommandDetails_noParameters);
129: fParamLabel
130: .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
131:
132: fParamParent = parent;
133: createBlankParamComp();
134: }
135:
136: private void createLinks(Composite parent) {
137: Composite comp = fCCP.createComposite(parent,
138: GridData.FILL_HORIZONTAL
139: | GridData.HORIZONTAL_ALIGN_END, 1, false, 0);
140:
141: fExecLink = fToolkit.createImageHyperlink(comp, SWT.NONE);
142: final Image execImage = PDEPluginImages.DESC_RUN_EXC
143: .createImage();
144: fExecLink.setImage(execImage);
145: fExecLink.setText(PDEUIMessages.CommandDetails_executeText);
146: fExecLink.setToolTipText(PDEUIMessages.CommandDetails_execute);
147: fExecLink.addHyperlinkListener(new ExecCommand());
148: fExecLink.setLayoutData(new GridData(
149: GridData.HORIZONTAL_ALIGN_END));
150: fExecLink.setVisible(false);
151: fExecLink.addDisposeListener(new DisposeListener() {
152: public void widgetDisposed(DisposeEvent e) {
153: execImage.dispose();
154: }
155: });
156:
157: fCopyLink = fToolkit.createImageHyperlink(comp, SWT.NONE);
158: final Image clipImage = PDEPluginImages.DESC_CLIPBOARD
159: .createImage();
160: fCopyLink.setImage(clipImage);
161: fCopyLink.setText(PDEUIMessages.CommandDetails_copyToClipboard);
162: fCopyLink
163: .setToolTipText(PDEUIMessages.CommandDetails_copytooltip);
164: fCopyLink.addHyperlinkListener(new CopyToClipboard());
165: fCopyLink.setLayoutData(new GridData(
166: GridData.HORIZONTAL_ALIGN_END));
167: fCopyLink.setVisible(false);
168: fCopyLink.addDisposeListener(new DisposeListener() {
169: public void widgetDisposed(DisposeEvent e) {
170: clipImage.dispose();
171: }
172: });
173: }
174:
175: private void createPreviewLabelComp(Composite parent) {
176: Composite preLabelComp = fCCP.createComposite(parent,
177: GridData.FILL_HORIZONTAL, 3, false, 0);
178: fToolkit.createLabel(preLabelComp,
179: PDEUIMessages.CommandDetails_preview, SWT.NONE)
180: .setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
181:
182: fSurroundCopyText = fToolkit.createButton(preLabelComp,
183: PDEUIMessages.CommandDetails_includeMarkup, SWT.CHECK);
184: fSurroundCopyText
185: .setToolTipText(PDEUIMessages.CommandDetails_markupTooltip);
186: fSurroundCopyText.addSelectionListener(new SelectionAdapter() {
187: public void widgetSelected(SelectionEvent e) {
188: updatePreviewText();
189: }
190: });
191:
192: fFilterCombo = new Combo(preLabelComp, SWT.READ_ONLY
193: | SWT.DROP_DOWN);
194: CommandCopyFilter[] filters = CommandCopyFilter.getFilters();
195: for (int i = 0; i < filters.length; i++)
196: fFilterCombo.add(filters[i].getLabelText());
197: fFilterCombo.select(CommandCopyFilter
198: .indexOf(CommandCopyFilter.NONE));
199: fFilterCombo.addSelectionListener(new SelectionAdapter() {
200: public void widgetSelected(SelectionEvent e) {
201: updatePreviewText();
202: }
203: });
204: fToolkit.adapt(fFilterCombo, true, true);
205:
206: fComPrev = fToolkit.createText(parent,
207: "", SWT.MULTI | SWT.V_SCROLL | SWT.BORDER | SWT.WRAP); //$NON-NLS-1$
208: GridData gd = new GridData(GridData.FILL_HORIZONTAL);
209: gd.heightHint = 60;
210: fComPrev.setLayoutData(gd);
211: fComPrev.setEditable(false);
212: }
213:
214: protected ParameterizedCommand buildParameterizedCommand() {
215:
216: ArrayList list = new ArrayList();
217: for (Iterator i = fParameterToValue.keySet().iterator(); i
218: .hasNext();) {
219: IParameter parameter = (IParameter) i.next();
220: String value = (String) fParameterToValue.get(parameter);
221: list.add(new Parameterization(parameter, value));
222: }
223: Parameterization[] parameterizations = (Parameterization[]) list
224: .toArray(new Parameterization[list.size()]);
225:
226: ParameterizedCommand pCommand = new ParameterizedCommand(
227: fSelectedCommand, parameterizations);
228: return pCommand;
229: }
230:
231: private class ExecCommand extends HyperlinkAdapter {
232: public void linkActivated(HyperlinkEvent e) {
233: ParameterizedCommand pCommand = buildParameterizedCommand();
234: try {
235: Object obj = null;
236: IHandlerService service = getGlobalHandlerService();
237: IEvaluationContext context = fCCP.getSnapshotContext();
238: // TODO: MP: SimpleCS: Get rid of internal class use when context snapshots are made API
239: if ((service instanceof HandlerService)
240: && (context != null)) {
241: obj = ((HandlerService) service)
242: .executeCommandInContext(pCommand, null,
243: context);
244: } else {
245: // the default is just to execute within the global application
246: // context
247: obj = service.executeCommand(pCommand, null);
248: }
249: String resultString = null;
250: if (obj instanceof String) {
251: resultString = (String) obj;
252: } else {
253: ParameterType returnType = pCommand.getCommand()
254: .getReturnType();
255: if (returnType != null
256: && returnType.getValueConverter() != null)
257: resultString = returnType.getValueConverter()
258: .convertToString(obj);
259: }
260: if (resultString != null) {
261: MessageDialog.openInformation(fComIDT.getShell(),
262: PDEUIMessages.CommandDetails_commandResult,
263: resultString);
264: }
265: } catch (CommandException ex) {
266: MessageDialog.openError(fComIDT.getShell(),
267: PDEUIMessages.CommandDetails_execError, ex
268: .toString());
269: }
270: }
271: }
272:
273: private String getFilteredCommand() {
274: ParameterizedCommand pCommand = buildParameterizedCommand();
275: String serializedCommand = pCommand.serialize();
276: String markupLabel;
277: try {
278: markupLabel = fSelectedCommand.getName();
279: } catch (NotDefinedException ex) {
280: markupLabel = null;
281: }
282: int index;
283: boolean surroundWithMarkup = false;
284: if (fCCP.getFilterType() == CommandComposerPart.F_FILTER_NOT_SET) {
285: surroundWithMarkup = fSurroundCopyText.getSelection();
286: index = fFilterCombo.getSelectionIndex();
287: } else {
288: index = fCCP.getFilterType();
289: }
290: CommandCopyFilter ccf = CommandCopyFilter.getFilter(index);
291: return ccf.filter(serializedCommand, surroundWithMarkup,
292: markupLabel);
293: }
294:
295: private class CopyToClipboard extends HyperlinkAdapter {
296: public void linkActivated(HyperlinkEvent e) {
297: String filteredCommand = getFilteredCommand();
298:
299: Object[] data = new Object[] { filteredCommand, /* htmlBuffer.toString() */};
300: Transfer[] transfers = new Transfer[] { TextTransfer
301: .getInstance(),/* HTMLTransfer.getInstance() */};
302:
303: Clipboard clipboard = new Clipboard(null);
304: clipboard.setContents(data, transfers, DND.CLIPBOARD);
305: clipboard.dispose();
306: }
307: }
308:
309: private class ValuesParameterControl extends SelectionAdapter
310: implements ModifyListener {
311: private final IParameter fParameter;
312: private final Map fValues;
313: private final Combo fValuesCombo;
314: private final Button fClearButton;
315:
316: public ValuesParameterControl(IParameter parameter, Map values,
317: Combo valuesCombo, Button clearButton) {
318: fParameter = parameter;
319: fValues = values;
320:
321: fValuesCombo = valuesCombo;
322: fValuesCombo.addModifyListener(this );
323: if (fPreSel != null && fValues != null) {
324: Object obj = fPreSel.getParameterMap().get(
325: parameter.getId());
326: if (obj != null) {
327: for (Iterator i = fValues.keySet().iterator(); i
328: .hasNext();) {
329: Object next = i.next();
330: if (obj.equals(fValues.get(next))) {
331: fValuesCombo.setText(next.toString());
332: break;
333: }
334: }
335: }
336: }
337:
338: fClearButton = clearButton;
339: fClearButton.addSelectionListener(this );
340: }
341:
342: // clear button pressed
343: public void widgetSelected(SelectionEvent e) {
344: fValuesCombo.deselectAll();
345: fParameterToValue.remove(fParameter);
346: }
347:
348: // values combo changed
349: public void modifyText(ModifyEvent e) {
350: String key = fValuesCombo.getText();
351: String value = (String) fValues.get(key);
352: if (value == null)
353: fParameterToValue.remove(fParameter);
354: else
355: fParameterToValue.put(fParameter, value);
356: updatePreviewText();
357: }
358:
359: protected void dispose() {
360: if (!fValuesCombo.isDisposed())
361: fValuesCombo.removeModifyListener(this );
362: if (!fClearButton.isDisposed())
363: fClearButton.removeSelectionListener(this );
364: }
365: }
366:
367: private class ObjectParameterControl implements ModifyListener {
368: private final IParameter fParameter;
369: private final AbstractParameterValueConverter fValueConverter;
370: private final Text fParameterText;
371:
372: public ObjectParameterControl(IParameter parameter,
373: AbstractParameterValueConverter valueConverter,
374: Text parameterText, Object selectedObject) {
375: fParameter = parameter;
376: fValueConverter = valueConverter;
377:
378: fParameterText = parameterText;
379: fParameterText.addModifyListener(this );
380:
381: if (selectedObject != null)
382: setParameterText(selectedObject);
383:
384: if (fPreSel != null) {
385: Object obj = fPreSel.getParameterMap().get(
386: parameter.getId());
387: if (obj != null)
388: fParameterText.setText(obj.toString());
389: }
390: }
391:
392: public void modifyText(ModifyEvent e) {
393: String text = fParameterText.getText();
394: if ((text == null) || (text.trim().equals(""))) //$NON-NLS-1$
395: fParameterToValue.remove(fParameter);
396: else
397: fParameterToValue.put(fParameter, text);
398: updatePreviewText();
399: validate();
400: }
401:
402: private void setParameterText(Object selectedObject) {
403: try {
404: String converted = fValueConverter
405: .convertToString(selectedObject);
406: if (converted != null)
407: fParameterText.setText(converted);
408: } catch (ParameterValueConversionException ex) {
409: //
410: }
411: }
412:
413: protected void dispose() {
414: if (!fParameterText.isDisposed())
415: fParameterText.removeModifyListener(this );
416: }
417:
418: private void validate() {
419: String text = fParameterText.getText();
420: String error = null;
421: if (text.length() > 0) {
422: try {
423: fValueConverter.convertToObject(text);
424: } catch (ParameterValueConversionException e1) {
425: error = e1.getMessage();
426: }
427: }
428: if (error == null)
429: fCCP.setMessage(null, IMessageProvider.NONE);
430: else
431: fCCP.setMessage(NLS.bind(
432: PDEUIMessages.CommandDetails_paramValueMessage,
433: fParameter.getName(), error),
434: IMessageProvider.WARNING);
435: }
436: }
437:
438: private class TextParameterControl implements ModifyListener {
439: private final IParameter fParameter;
440: private final Text fParameterText;
441:
442: public TextParameterControl(IParameter parameter,
443: Text parameterText) {
444: fParameter = parameter;
445: fParameterText = parameterText;
446: fParameterText.addModifyListener(this );
447:
448: if (fPreSel != null) {
449: Object obj = fPreSel.getParameterMap().get(
450: parameter.getId());
451: if (obj != null)
452: fParameterText.setText(obj.toString());
453: }
454: }
455:
456: public void modifyText(ModifyEvent e) {
457: String text = fParameterText.getText();
458: if ((text == null) || (text.trim().equals(""))) //$NON-NLS-1$
459: fParameterToValue.remove(fParameter);
460: else
461: fParameterToValue.put(fParameter, text);
462: updatePreviewText();
463: }
464:
465: public void dispose() {
466: if (!fParameterText.isDisposed())
467: fParameterText.removeModifyListener(this );
468: }
469: }
470:
471: protected void dispose() {
472: for (int i = 0; i < fObjectParamList.size(); i++)
473: ((ObjectParameterControl) fObjectParamList.get(i))
474: .dispose();
475: for (int i = 0; i < fValueParamList.size(); i++)
476: ((ValuesParameterControl) fValueParamList.get(i)).dispose();
477: for (int i = 0; i < fTextParamList.size(); i++)
478: ((TextParameterControl) fTextParamList.get(i)).dispose();
479: }
480:
481: private void populateParams(Command command, Object selectedObject)
482: throws NotDefinedException {
483:
484: createBlankParamComp();
485:
486: IParameter[] parameters = command.getParameters();
487: if (parameters == null || parameters.length == 0) {
488: fParamLabel
489: .setText(PDEUIMessages.CommandDetails_noParameters);
490: } else {
491: fParamLabel.setText(PDEUIMessages.CommandDetails_numParams);
492: Composite paramLine = fToolkit
493: .createComposite(fParamComposite);
494:
495: GridLayout paramLineLayout = new GridLayout();
496: paramLine.setLayoutData(new GridData(
497: GridData.FILL_HORIZONTAL));
498: paramLineLayout.numColumns = 3;
499: paramLineLayout.marginHeight = 0;
500: paramLine.setLayout(paramLineLayout);
501: for (int i = 0; i < parameters.length; i++) {
502: IParameter parameter = parameters[i];
503:
504: String nameText = parameter.getName();
505: if (!parameter.isOptional())
506: nameText += '*';
507: fToolkit.createLabel(paramLine, NLS.bind(
508: PDEUIMessages.CommandDetails_param, nameText));
509:
510: IParameterValues parameterValues = getParameterValues(parameter);
511: if (parameterValues != null) {
512: Combo parameterValuesCombo = new Combo(paramLine,
513: SWT.READ_ONLY | SWT.DROP_DOWN);
514: parameterValuesCombo.setLayoutData(new GridData(
515: GridData.FILL_HORIZONTAL));
516: fToolkit.adapt(parameterValuesCombo, true, true);
517:
518: Map values = parameterValues.getParameterValues();
519: for (Iterator keys = values.keySet().iterator(); keys
520: .hasNext();)
521: parameterValuesCombo.add((String) keys.next());
522:
523: Button clearButton = fToolkit.createButton(
524: paramLine,
525: PDEUIMessages.CommandDetails_clear,
526: SWT.PUSH);
527:
528: fValueParamList.add(new ValuesParameterControl(
529: parameter, values, parameterValuesCombo,
530: clearButton));
531:
532: continue;
533: }
534:
535: ParameterType parameterType = command
536: .getParameterType(parameter.getId());
537: if ((parameterType != null)
538: && (parameterType.getValueConverter() != null)) {
539: Text parameterText = fToolkit.createText(paramLine,
540: "", SWT.SINGLE | SWT.BORDER); //$NON-NLS-1$
541: GridData gd = new GridData(GridData.FILL_HORIZONTAL);
542: gd.horizontalSpan = 2;
543: parameterText.setLayoutData(gd);
544: fObjectParamList.add(new ObjectParameterControl(
545: parameter, parameterType
546: .getValueConverter(),
547: parameterText, selectedObject));
548:
549: continue;
550: }
551:
552: Text parameterText = fToolkit.createText(paramLine,
553: "", SWT.SINGLE | SWT.BORDER); //$NON-NLS-1$
554: GridData gd = new GridData(GridData.FILL_HORIZONTAL);
555: gd.horizontalSpan = 2;
556: parameterText.setLayoutData(gd);
557: fTextParamList.add(new TextParameterControl(parameter,
558: parameterText));
559: }
560: }
561: // only use preselected on the first details showing
562: fPreSel = null;
563: fParamParent.layout();
564: }
565:
566: private IParameterValues getParameterValues(IParameter parameter) {
567: try {
568: return parameter.getValues();
569: } catch (ParameterValuesException ex) {
570: return null;
571: }
572: }
573:
574: public void showDetailsFor(Object object) {
575: if (object instanceof ParameterizedCommand)
576: object = (fPreSel = (ParameterizedCommand) object)
577: .getCommand();
578:
579: if (!(object instanceof Command)) {
580: resetAllFields();
581: return;
582: }
583: fSelectedCommand = (Command) object;
584: fComIDT.setText(fSelectedCommand.getId());
585:
586: fParameterToValue.clear();
587: fObjectParamList.clear();
588: fValueParamList.clear();
589:
590: fExecLink.setVisible(fSelectedCommand.isEnabled());
591: fCopyLink.setVisible(true);
592: try {
593: populateParams(fSelectedCommand, object);
594: } catch (NotDefinedException e) {
595: createNoParamComp();
596: }
597: updatePreviewText();
598: }
599:
600: private void resetAllFields() {
601: fSelectedCommand = null;
602: fComIDT.setText(PDEUIMessages.CommandDetails_noComSelected);
603: fParamLabel.setText(PDEUIMessages.CommandDetails_noParameters);
604:
605: if (fComPrev != null)
606: fComPrev.setText(""); //$NON-NLS-1$
607:
608: fExecLink.setVisible(false);
609: fCopyLink.setVisible(false);
610:
611: fParameterToValue.clear();
612: fObjectParamList.clear();
613: fValueParamList.clear();
614:
615: createNoParamComp();
616: }
617:
618: private void createNoParamComp() {
619: createBlankParamComp();
620: fParamParent.layout();
621: }
622:
623: private void createBlankParamComp() {
624: if (fParamComposite != null)
625: fParamComposite.dispose();
626: fParamComposite = fCCP.createComposite(fParamParent,
627: GridData.FILL_BOTH, 1, true, 0);
628: }
629:
630: private void updatePreviewText() {
631: if (fComPrev != null)
632: fComPrev.setText(getFilteredCommand());
633: }
634:
635: protected Command getCommand() {
636: return fSelectedCommand;
637: }
638:
639: public String getCommandName() {
640: if (fSelectedCommand != null)
641: try {
642: return fSelectedCommand.getName();
643: } catch (NotDefinedException e) {
644: return fSelectedCommand.getId();
645: }
646: return null;
647: }
648:
649: public String getSerializedString() {
650: if (fSelectedCommand != null)
651: return getFilteredCommand();
652: return null;
653: }
654:
655: public HashMap getParameters() {
656: if (fSelectedCommand != null)
657: return fParameterToValue;
658:
659: return null;
660: }
661:
662: /**
663: * @return
664: */
665: private IHandlerService getGlobalHandlerService() {
666: return (IHandlerService) PlatformUI.getWorkbench().getService(
667: IHandlerService.class);
668: }
669: }
|