0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.ui.texteditor.templates;
0011:
0012: import java.io.BufferedInputStream;
0013: import java.io.BufferedOutputStream;
0014: import java.io.File;
0015: import java.io.FileInputStream;
0016: import java.io.FileNotFoundException;
0017: import java.io.FileOutputStream;
0018: import java.io.IOException;
0019: import java.io.InputStream;
0020: import java.io.OutputStream;
0021: import java.util.ArrayList;
0022: import java.util.HashMap;
0023: import java.util.Iterator;
0024: import java.util.List;
0025: import java.util.Map;
0026:
0027: import com.ibm.icu.text.Collator;
0028:
0029: import org.eclipse.swt.SWT;
0030: import org.eclipse.swt.custom.StyledText;
0031: import org.eclipse.swt.custom.VerifyKeyListener;
0032: import org.eclipse.swt.events.FocusEvent;
0033: import org.eclipse.swt.events.FocusListener;
0034: import org.eclipse.swt.events.ModifyEvent;
0035: import org.eclipse.swt.events.ModifyListener;
0036: import org.eclipse.swt.events.SelectionEvent;
0037: import org.eclipse.swt.events.SelectionListener;
0038: import org.eclipse.swt.events.VerifyEvent;
0039: import org.eclipse.swt.graphics.GC;
0040: import org.eclipse.swt.graphics.Image;
0041: import org.eclipse.swt.layout.GridData;
0042: import org.eclipse.swt.layout.GridLayout;
0043: import org.eclipse.swt.widgets.Button;
0044: import org.eclipse.swt.widgets.Combo;
0045: import org.eclipse.swt.widgets.Composite;
0046: import org.eclipse.swt.widgets.Control;
0047: import org.eclipse.swt.widgets.Event;
0048: import org.eclipse.swt.widgets.FileDialog;
0049: import org.eclipse.swt.widgets.Label;
0050: import org.eclipse.swt.widgets.Listener;
0051: import org.eclipse.swt.widgets.Menu;
0052: import org.eclipse.swt.widgets.Shell;
0053: import org.eclipse.swt.widgets.Table;
0054: import org.eclipse.swt.widgets.TableColumn;
0055: import org.eclipse.swt.widgets.Text;
0056: import org.eclipse.swt.widgets.Widget;
0057:
0058: import org.eclipse.jface.action.Action;
0059: import org.eclipse.jface.action.GroupMarker;
0060: import org.eclipse.jface.action.IAction;
0061: import org.eclipse.jface.action.IMenuListener;
0062: import org.eclipse.jface.action.IMenuManager;
0063: import org.eclipse.jface.action.MenuManager;
0064: import org.eclipse.jface.action.Separator;
0065: import org.eclipse.jface.dialogs.Dialog;
0066: import org.eclipse.jface.dialogs.IDialogSettings;
0067: import org.eclipse.jface.dialogs.MessageDialog;
0068: import org.eclipse.jface.dialogs.StatusDialog;
0069: import org.eclipse.jface.preference.IPreferenceStore;
0070: import org.eclipse.jface.preference.PreferencePage;
0071: import org.eclipse.jface.resource.JFaceResources;
0072: import org.eclipse.jface.viewers.CheckStateChangedEvent;
0073: import org.eclipse.jface.viewers.CheckboxTableViewer;
0074: import org.eclipse.jface.viewers.ColumnPixelData;
0075: import org.eclipse.jface.viewers.ColumnWeightData;
0076: import org.eclipse.jface.viewers.DoubleClickEvent;
0077: import org.eclipse.jface.viewers.ICheckStateListener;
0078: import org.eclipse.jface.viewers.IDoubleClickListener;
0079: import org.eclipse.jface.viewers.ISelectionChangedListener;
0080: import org.eclipse.jface.viewers.IStructuredSelection;
0081: import org.eclipse.jface.viewers.ITableLabelProvider;
0082: import org.eclipse.jface.viewers.LabelProvider;
0083: import org.eclipse.jface.viewers.SelectionChangedEvent;
0084: import org.eclipse.jface.viewers.StructuredSelection;
0085: import org.eclipse.jface.viewers.TableViewer;
0086: import org.eclipse.jface.viewers.Viewer;
0087: import org.eclipse.jface.viewers.ViewerComparator;
0088: import org.eclipse.jface.window.Window;
0089:
0090: import org.eclipse.jface.text.Document;
0091: import org.eclipse.jface.text.IDocument;
0092: import org.eclipse.jface.text.ITextListener;
0093: import org.eclipse.jface.text.ITextOperationTarget;
0094: import org.eclipse.jface.text.ITextViewer;
0095: import org.eclipse.jface.text.TextEvent;
0096: import org.eclipse.jface.text.contentassist.ContentAssistant;
0097: import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
0098: import org.eclipse.jface.text.contentassist.IContentAssistant;
0099: import org.eclipse.jface.text.source.ISourceViewer;
0100: import org.eclipse.jface.text.source.SourceViewer;
0101: import org.eclipse.jface.text.source.SourceViewerConfiguration;
0102: import org.eclipse.jface.text.templates.ContextTypeRegistry;
0103: import org.eclipse.jface.text.templates.Template;
0104: import org.eclipse.jface.text.templates.TemplateContextType;
0105: import org.eclipse.jface.text.templates.TemplateException;
0106: import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
0107: import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
0108: import org.eclipse.jface.text.templates.persistence.TemplateStore;
0109:
0110: import org.eclipse.ui.IWorkbench;
0111: import org.eclipse.ui.IWorkbenchPreferencePage;
0112: import org.eclipse.ui.internal.texteditor.NLSUtility;
0113: import org.eclipse.ui.internal.texteditor.TextEditorPlugin;
0114: import org.eclipse.ui.texteditor.ITextEditorActionConstants;
0115: import org.eclipse.ui.texteditor.IUpdate;
0116:
0117: /**
0118: * A template preference page allows configuration of the templates for an
0119: * editor. It provides controls for adding, removing and changing templates as
0120: * well as enablement, default management and an optional formatter preference.
0121: * <p>
0122: * Subclasses need to provide a {@link TemplateStore} and a
0123: * {@link ContextTypeRegistry} and should set the preference store. They may
0124: * optionally override {@link #isShowFormatterSetting()}.
0125: * </p>
0126: *
0127: * @since 3.0
0128: */
0129: public abstract class TemplatePreferencePage extends PreferencePage
0130: implements IWorkbenchPreferencePage {
0131:
0132: /**
0133: * Dialog to edit a template. Clients will usually instantiate, but
0134: * may also extend.
0135: *
0136: * @since 3.3
0137: */
0138: protected static class EditTemplateDialog extends StatusDialog {
0139:
0140: private class TextViewerAction extends Action implements
0141: IUpdate {
0142:
0143: private int fOperationCode = -1;
0144: private ITextOperationTarget fOperationTarget;
0145:
0146: /**
0147: * Creates a new action.
0148: *
0149: * @param viewer the viewer
0150: * @param operationCode the opcode
0151: */
0152: public TextViewerAction(ITextViewer viewer,
0153: int operationCode) {
0154: fOperationCode = operationCode;
0155: fOperationTarget = viewer.getTextOperationTarget();
0156: update();
0157: }
0158:
0159: /**
0160: * Updates the enabled state of the action.
0161: * Fires a property change if the enabled state changes.
0162: *
0163: * @see Action#firePropertyChange(String, Object, Object)
0164: */
0165: public void update() {
0166:
0167: boolean wasEnabled = isEnabled();
0168: boolean isEnabled = (fOperationTarget != null && fOperationTarget
0169: .canDoOperation(fOperationCode));
0170: setEnabled(isEnabled);
0171:
0172: if (wasEnabled != isEnabled) {
0173: firePropertyChange(ENABLED,
0174: wasEnabled ? Boolean.TRUE : Boolean.FALSE,
0175: isEnabled ? Boolean.TRUE : Boolean.FALSE);
0176: }
0177: }
0178:
0179: /**
0180: * @see Action#run()
0181: */
0182: public void run() {
0183: if (fOperationCode != -1 && fOperationTarget != null) {
0184: fOperationTarget.doOperation(fOperationCode);
0185: }
0186: }
0187: }
0188:
0189: private final Template fOriginalTemplate;
0190:
0191: private Text fNameText;
0192: private Text fDescriptionText;
0193: private Combo fContextCombo;
0194: private SourceViewer fPatternEditor;
0195: private Button fInsertVariableButton;
0196: private Button fAutoInsertCheckbox;
0197: private boolean fIsNameModifiable;
0198:
0199: private StatusInfo fValidationStatus;
0200: private boolean fSuppressError = true; // #4354
0201: private Map fGlobalActions = new HashMap(10);
0202: private List fSelectionActions = new ArrayList(3);
0203: private String[][] fContextTypes;
0204:
0205: private ContextTypeRegistry fContextTypeRegistry;
0206:
0207: private final TemplateVariableProcessor fTemplateProcessor = new TemplateVariableProcessor();
0208:
0209: private Template fNewTemplate;
0210:
0211: /**
0212: * Creates a new dialog.
0213: *
0214: * @param parent the shell parent of the dialog
0215: * @param template the template to edit
0216: * @param edit whether this is a new template or an existing being edited
0217: * @param isNameModifiable whether the name of the template may be modified
0218: * @param registry the context type registry to use
0219: */
0220: public EditTemplateDialog(Shell parent, Template template,
0221: boolean edit, boolean isNameModifiable,
0222: ContextTypeRegistry registry) {
0223: super (parent);
0224:
0225: setShellStyle(getShellStyle() | SWT.MAX | SWT.RESIZE);
0226:
0227: String title = edit ? TextEditorTemplateMessages.EditTemplateDialog_title_edit
0228: : TextEditorTemplateMessages.EditTemplateDialog_title_new;
0229: setTitle(title);
0230:
0231: fOriginalTemplate = template;
0232: fIsNameModifiable = isNameModifiable;
0233:
0234: List contexts = new ArrayList();
0235: for (Iterator it = registry.contextTypes(); it.hasNext();) {
0236: TemplateContextType type = (TemplateContextType) it
0237: .next();
0238: contexts.add(new String[] { type.getId(),
0239: type.getName() });
0240: }
0241: fContextTypes = (String[][]) contexts
0242: .toArray(new String[contexts.size()][]);
0243:
0244: fValidationStatus = new StatusInfo();
0245:
0246: fContextTypeRegistry = registry;
0247:
0248: TemplateContextType type = fContextTypeRegistry
0249: .getContextType(template.getContextTypeId());
0250: fTemplateProcessor.setContextType(type);
0251: }
0252:
0253: /*
0254: * @see org.eclipse.ui.texteditor.templates.StatusDialog#create()
0255: */
0256: public void create() {
0257: super .create();
0258: // update initial OK button to be disabled for new templates
0259: boolean valid = fNameText == null
0260: || fNameText.getText().trim().length() != 0;
0261: if (!valid) {
0262: StatusInfo status = new StatusInfo();
0263: status
0264: .setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname);
0265: updateButtonsEnableState(status);
0266: }
0267: }
0268:
0269: /*
0270: * @see Dialog#createDialogArea(Composite)
0271: */
0272: protected Control createDialogArea(Composite ancestor) {
0273: Composite parent = new Composite(ancestor, SWT.NONE);
0274: GridLayout layout = new GridLayout();
0275: layout.numColumns = 2;
0276: parent.setLayout(layout);
0277: parent.setLayoutData(new GridData(GridData.FILL_BOTH));
0278:
0279: ModifyListener listener = new ModifyListener() {
0280: public void modifyText(ModifyEvent e) {
0281: doTextWidgetChanged(e.widget);
0282: }
0283: };
0284:
0285: if (fIsNameModifiable) {
0286: createLabel(
0287: parent,
0288: TextEditorTemplateMessages.EditTemplateDialog_name);
0289:
0290: Composite composite = new Composite(parent, SWT.NONE);
0291: composite.setLayoutData(new GridData(
0292: GridData.FILL_HORIZONTAL));
0293: layout = new GridLayout();
0294: layout.numColumns = 4;
0295: layout.marginWidth = 0;
0296: layout.marginHeight = 0;
0297: composite.setLayout(layout);
0298:
0299: fNameText = createText(composite);
0300: fNameText.addModifyListener(listener);
0301: fNameText.addFocusListener(new FocusListener() {
0302:
0303: public void focusGained(FocusEvent e) {
0304: }
0305:
0306: public void focusLost(FocusEvent e) {
0307: if (fSuppressError) {
0308: fSuppressError = false;
0309: updateButtons();
0310: }
0311: }
0312: });
0313:
0314: createLabel(
0315: composite,
0316: TextEditorTemplateMessages.EditTemplateDialog_context);
0317: fContextCombo = new Combo(composite, SWT.READ_ONLY);
0318:
0319: for (int i = 0; i < fContextTypes.length; i++) {
0320: fContextCombo.add(fContextTypes[i][1]);
0321: }
0322:
0323: fContextCombo.addModifyListener(listener);
0324:
0325: fAutoInsertCheckbox = createCheckbox(
0326: composite,
0327: TextEditorTemplateMessages.EditTemplateDialog_autoinsert);
0328: fAutoInsertCheckbox.setSelection(fOriginalTemplate
0329: .isAutoInsertable());
0330: }
0331:
0332: createLabel(
0333: parent,
0334: TextEditorTemplateMessages.EditTemplateDialog_description);
0335:
0336: int descFlags = fIsNameModifiable ? SWT.BORDER : SWT.BORDER
0337: | SWT.READ_ONLY;
0338: fDescriptionText = new Text(parent, descFlags);
0339: fDescriptionText.setLayoutData(new GridData(
0340: GridData.FILL_HORIZONTAL));
0341:
0342: fDescriptionText.addModifyListener(listener);
0343:
0344: Label patternLabel = createLabel(
0345: parent,
0346: TextEditorTemplateMessages.EditTemplateDialog_pattern);
0347: patternLabel.setLayoutData(new GridData(
0348: GridData.VERTICAL_ALIGN_BEGINNING));
0349: fPatternEditor = createEditor(parent, fOriginalTemplate
0350: .getPattern());
0351:
0352: Label filler = new Label(parent, SWT.NONE);
0353: filler.setLayoutData(new GridData());
0354:
0355: Composite composite = new Composite(parent, SWT.NONE);
0356: layout = new GridLayout();
0357: layout.marginWidth = 0;
0358: layout.marginHeight = 0;
0359: composite.setLayout(layout);
0360: composite.setLayoutData(new GridData());
0361:
0362: fInsertVariableButton = new Button(composite, SWT.NONE);
0363: fInsertVariableButton
0364: .setLayoutData(getButtonGridData(fInsertVariableButton));
0365: fInsertVariableButton
0366: .setText(TextEditorTemplateMessages.EditTemplateDialog_insert_variable);
0367: fInsertVariableButton
0368: .addSelectionListener(new SelectionListener() {
0369: public void widgetSelected(SelectionEvent e) {
0370: fPatternEditor.getTextWidget().setFocus();
0371: fPatternEditor
0372: .doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
0373: }
0374:
0375: public void widgetDefaultSelected(
0376: SelectionEvent e) {
0377: }
0378: });
0379:
0380: fDescriptionText
0381: .setText(fOriginalTemplate.getDescription());
0382: if (fIsNameModifiable) {
0383: fNameText.setText(fOriginalTemplate.getName());
0384: fNameText.addModifyListener(listener);
0385: fContextCombo.select(getIndex(fOriginalTemplate
0386: .getContextTypeId()));
0387: } else {
0388: fPatternEditor.getControl().setFocus();
0389: }
0390: initializeActions();
0391:
0392: applyDialogFont(parent);
0393: return composite;
0394: }
0395:
0396: private void doTextWidgetChanged(Widget w) {
0397: if (w == fNameText) {
0398: fSuppressError = false;
0399: updateButtons();
0400: } else if (w == fContextCombo) {
0401: String contextId = getContextId();
0402: fTemplateProcessor.setContextType(fContextTypeRegistry
0403: .getContextType(contextId));
0404: } else if (w == fDescriptionText) {
0405: // oh, nothing
0406: }
0407: }
0408:
0409: private String getContextId() {
0410: if (fContextCombo != null && !fContextCombo.isDisposed()) {
0411: String name = fContextCombo.getText();
0412: for (int i = 0; i < fContextTypes.length; i++) {
0413: if (name.equals(fContextTypes[i][1])) {
0414: return fContextTypes[i][0];
0415: }
0416: }
0417: }
0418:
0419: return fOriginalTemplate.getContextTypeId();
0420: }
0421:
0422: private void doSourceChanged(IDocument document) {
0423: String text = document.get();
0424: fValidationStatus.setOK();
0425: TemplateContextType contextType = fContextTypeRegistry
0426: .getContextType(getContextId());
0427: if (contextType != null) {
0428: try {
0429: contextType.validate(text);
0430: } catch (TemplateException e) {
0431: fValidationStatus.setError(e.getLocalizedMessage());
0432: }
0433: }
0434:
0435: updateUndoAction();
0436: updateButtons();
0437: }
0438:
0439: private static GridData getButtonGridData(Button button) {
0440: GridData data = new GridData(GridData.FILL_HORIZONTAL);
0441: // TODO get some button hints.
0442: // data.heightHint= SWTUtil.getButtonHeightHint(button);
0443:
0444: return data;
0445: }
0446:
0447: private static Label createLabel(Composite parent, String name) {
0448: Label label = new Label(parent, SWT.NULL);
0449: label.setText(name);
0450: label.setLayoutData(new GridData());
0451:
0452: return label;
0453: }
0454:
0455: private static Text createText(Composite parent) {
0456: Text text = new Text(parent, SWT.BORDER);
0457: text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
0458:
0459: return text;
0460: }
0461:
0462: private static Button createCheckbox(Composite parent,
0463: String name) {
0464: Button button = new Button(parent, SWT.CHECK);
0465: button.setText(name);
0466: button.setLayoutData(new GridData());
0467:
0468: return button;
0469: }
0470:
0471: private SourceViewer createEditor(Composite parent,
0472: String pattern) {
0473: SourceViewer viewer = createViewer(parent);
0474: viewer.setEditable(true);
0475:
0476: IDocument document = viewer.getDocument();
0477: if (document != null)
0478: document.set(pattern);
0479: else {
0480: document = new Document(pattern);
0481: viewer.setDocument(document);
0482: }
0483:
0484: int nLines = document.getNumberOfLines();
0485: if (nLines < 5) {
0486: nLines = 5;
0487: } else if (nLines > 12) {
0488: nLines = 12;
0489: }
0490:
0491: Control control = viewer.getControl();
0492: GridData data = new GridData(GridData.FILL_BOTH);
0493: data.widthHint = convertWidthInCharsToPixels(80);
0494: data.heightHint = convertHeightInCharsToPixels(nLines);
0495: control.setLayoutData(data);
0496:
0497: viewer.addTextListener(new ITextListener() {
0498: public void textChanged(TextEvent event) {
0499: if (event.getDocumentEvent() != null)
0500: doSourceChanged(event.getDocumentEvent()
0501: .getDocument());
0502: }
0503: });
0504:
0505: viewer
0506: .addSelectionChangedListener(new ISelectionChangedListener() {
0507: public void selectionChanged(
0508: SelectionChangedEvent event) {
0509: updateSelectionDependentActions();
0510: }
0511: });
0512:
0513: viewer.prependVerifyKeyListener(new VerifyKeyListener() {
0514: public void verifyKey(VerifyEvent event) {
0515: handleVerifyKeyPressed(event);
0516: }
0517: });
0518:
0519: return viewer;
0520: }
0521:
0522: /**
0523: * Creates the viewer to be used to display the pattern. Subclasses may override.
0524: *
0525: * @param parent the parent composite of the viewer
0526: * @return a configured <code>SourceViewer</code>
0527: */
0528: protected SourceViewer createViewer(Composite parent) {
0529: SourceViewer viewer = new SourceViewer(parent, null, null,
0530: false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
0531: SourceViewerConfiguration configuration = new SourceViewerConfiguration() {
0532: public IContentAssistant getContentAssistant(
0533: ISourceViewer sourceViewer) {
0534:
0535: ContentAssistant assistant = new ContentAssistant();
0536: assistant.enableAutoActivation(true);
0537: assistant.enableAutoInsert(true);
0538: assistant.setContentAssistProcessor(
0539: fTemplateProcessor,
0540: IDocument.DEFAULT_CONTENT_TYPE);
0541: return assistant;
0542: }
0543: };
0544: viewer.configure(configuration);
0545: return viewer;
0546: }
0547:
0548: private void handleVerifyKeyPressed(VerifyEvent event) {
0549: if (!event.doit)
0550: return;
0551:
0552: if (event.stateMask != SWT.MOD1)
0553: return;
0554:
0555: switch (event.character) {
0556: case ' ':
0557: fPatternEditor
0558: .doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS);
0559: event.doit = false;
0560: break;
0561:
0562: // CTRL-Z
0563: case 'z' - 'a' + 1:
0564: fPatternEditor.doOperation(ITextOperationTarget.UNDO);
0565: event.doit = false;
0566: break;
0567: }
0568: }
0569:
0570: private void initializeActions() {
0571: TextViewerAction action = new TextViewerAction(
0572: fPatternEditor, ITextOperationTarget.UNDO);
0573: action
0574: .setText(TextEditorTemplateMessages.EditTemplateDialog_undo);
0575: fGlobalActions.put(ITextEditorActionConstants.UNDO, action);
0576:
0577: action = new TextViewerAction(fPatternEditor,
0578: ITextOperationTarget.CUT);
0579: action
0580: .setText(TextEditorTemplateMessages.EditTemplateDialog_cut);
0581: fGlobalActions.put(ITextEditorActionConstants.CUT, action);
0582:
0583: action = new TextViewerAction(fPatternEditor,
0584: ITextOperationTarget.COPY);
0585: action
0586: .setText(TextEditorTemplateMessages.EditTemplateDialog_copy);
0587: fGlobalActions.put(ITextEditorActionConstants.COPY, action);
0588:
0589: action = new TextViewerAction(fPatternEditor,
0590: ITextOperationTarget.PASTE);
0591: action
0592: .setText(TextEditorTemplateMessages.EditTemplateDialog_paste);
0593: fGlobalActions
0594: .put(ITextEditorActionConstants.PASTE, action);
0595:
0596: action = new TextViewerAction(fPatternEditor,
0597: ITextOperationTarget.SELECT_ALL);
0598: action
0599: .setText(TextEditorTemplateMessages.EditTemplateDialog_select_all);
0600: fGlobalActions.put(ITextEditorActionConstants.SELECT_ALL,
0601: action);
0602:
0603: action = new TextViewerAction(fPatternEditor,
0604: ISourceViewer.CONTENTASSIST_PROPOSALS);
0605: action
0606: .setText(TextEditorTemplateMessages.EditTemplateDialog_content_assist);
0607: fGlobalActions.put("ContentAssistProposal", action); //$NON-NLS-1$
0608:
0609: fSelectionActions.add(ITextEditorActionConstants.CUT);
0610: fSelectionActions.add(ITextEditorActionConstants.COPY);
0611: fSelectionActions.add(ITextEditorActionConstants.PASTE);
0612:
0613: // create context menu
0614: MenuManager manager = new MenuManager(null, null);
0615: manager.setRemoveAllWhenShown(true);
0616: manager.addMenuListener(new IMenuListener() {
0617: public void menuAboutToShow(IMenuManager mgr) {
0618: fillContextMenu(mgr);
0619: }
0620: });
0621:
0622: StyledText text = fPatternEditor.getTextWidget();
0623: Menu menu = manager.createContextMenu(text);
0624: text.setMenu(menu);
0625: }
0626:
0627: private void fillContextMenu(IMenuManager menu) {
0628: menu.add(new GroupMarker(
0629: ITextEditorActionConstants.GROUP_UNDO));
0630: menu.appendToGroup(ITextEditorActionConstants.GROUP_UNDO,
0631: (IAction) fGlobalActions
0632: .get(ITextEditorActionConstants.UNDO));
0633:
0634: menu.add(new Separator(
0635: ITextEditorActionConstants.GROUP_EDIT));
0636: menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT,
0637: (IAction) fGlobalActions
0638: .get(ITextEditorActionConstants.CUT));
0639: menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT,
0640: (IAction) fGlobalActions
0641: .get(ITextEditorActionConstants.COPY));
0642: menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT,
0643: (IAction) fGlobalActions
0644: .get(ITextEditorActionConstants.PASTE));
0645: menu
0646: .appendToGroup(
0647: ITextEditorActionConstants.GROUP_EDIT,
0648: (IAction) fGlobalActions
0649: .get(ITextEditorActionConstants.SELECT_ALL));
0650:
0651: menu.add(new Separator("templates")); //$NON-NLS-1$
0652: menu
0653: .appendToGroup(
0654: "templates", (IAction) fGlobalActions.get("ContentAssistProposal")); //$NON-NLS-1$ //$NON-NLS-2$
0655: }
0656:
0657: private void updateSelectionDependentActions() {
0658: Iterator iterator = fSelectionActions.iterator();
0659: while (iterator.hasNext())
0660: updateAction((String) iterator.next());
0661: }
0662:
0663: private void updateUndoAction() {
0664: IAction action = (IAction) fGlobalActions
0665: .get(ITextEditorActionConstants.UNDO);
0666: if (action instanceof IUpdate)
0667: ((IUpdate) action).update();
0668: }
0669:
0670: private void updateAction(String actionId) {
0671: IAction action = (IAction) fGlobalActions.get(actionId);
0672: if (action instanceof IUpdate)
0673: ((IUpdate) action).update();
0674: }
0675:
0676: private int getIndex(String contextid) {
0677:
0678: if (contextid == null)
0679: return -1;
0680:
0681: for (int i = 0; i < fContextTypes.length; i++) {
0682: if (contextid.equals(fContextTypes[i][0])) {
0683: return i;
0684: }
0685: }
0686: return -1;
0687: }
0688:
0689: private void updateButtons() {
0690: StatusInfo status;
0691:
0692: boolean valid = fNameText == null
0693: || fNameText.getText().trim().length() != 0;
0694: if (!valid) {
0695: status = new StatusInfo();
0696: if (!fSuppressError) {
0697: status
0698: .setError(TextEditorTemplateMessages.EditTemplateDialog_error_noname);
0699: }
0700: } else {
0701: status = fValidationStatus;
0702: }
0703: updateStatus(status);
0704: }
0705:
0706: /*
0707: * @since 3.1
0708: */
0709: protected void okPressed() {
0710: String name = fNameText == null ? fOriginalTemplate
0711: .getName() : fNameText.getText();
0712: boolean isAutoInsertable = fAutoInsertCheckbox != null
0713: && fAutoInsertCheckbox.getSelection();
0714: fNewTemplate = new Template(name, fDescriptionText
0715: .getText(), getContextId(), fPatternEditor
0716: .getDocument().get(), isAutoInsertable);
0717: super .okPressed();
0718: }
0719:
0720: /**
0721: * Returns the created template.
0722: *
0723: * @return the created template
0724: * @since 3.1
0725: */
0726: public Template getTemplate() {
0727: return fNewTemplate;
0728: }
0729:
0730: /**
0731: * Returns the content assist processor that
0732: * suggests template variables.
0733: *
0734: * @return the processor to suggest variables
0735: * @since 3.3
0736: */
0737: protected IContentAssistProcessor getTemplateProcessor() {
0738: return fTemplateProcessor;
0739: }
0740:
0741: /*
0742: * @see org.eclipse.jface.dialogs.Dialog#getDialogBoundsSettings()
0743: * @since 3.2
0744: */
0745: protected IDialogSettings getDialogBoundsSettings() {
0746: String sectionName = getClass().getName() + "_dialogBounds"; //$NON-NLS-1$
0747: IDialogSettings settings = TextEditorPlugin.getDefault()
0748: .getDialogSettings();
0749: IDialogSettings section = settings.getSection(sectionName);
0750: if (section == null)
0751: section = settings.addNewSection(sectionName);
0752: return section;
0753: }
0754:
0755: }
0756:
0757: /**
0758: * Label provider for templates.
0759: */
0760: private class TemplateLabelProvider extends LabelProvider implements
0761: ITableLabelProvider {
0762:
0763: /*
0764: * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
0765: */
0766: public Image getColumnImage(Object element, int columnIndex) {
0767: return null;
0768: }
0769:
0770: /*
0771: * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
0772: */
0773: public String getColumnText(Object element, int columnIndex) {
0774: TemplatePersistenceData data = (TemplatePersistenceData) element;
0775: Template template = data.getTemplate();
0776:
0777: switch (columnIndex) {
0778: case 0:
0779: return template.getName();
0780: case 1:
0781: TemplateContextType type = fContextTypeRegistry
0782: .getContextType(template.getContextTypeId());
0783: if (type != null)
0784: return type.getName();
0785: return template.getContextTypeId();
0786: case 2:
0787: return template.getDescription();
0788: case 3:
0789: return template.isAutoInsertable() ? TextEditorTemplateMessages.TemplatePreferencePage_on
0790: : ""; //$NON-NLS-1$
0791: default:
0792: return ""; //$NON-NLS-1$
0793: }
0794: }
0795: }
0796:
0797: /** Qualified key for formatter preference. */
0798: private static final String DEFAULT_FORMATTER_PREFERENCE_KEY = "org.eclipse.ui.texteditor.templates.preferences.format_templates"; //$NON-NLS-1$
0799:
0800: /** The table presenting the templates. */
0801: private CheckboxTableViewer fTableViewer;
0802:
0803: /* buttons */
0804: private Button fAddButton;
0805: private Button fEditButton;
0806: private Button fImportButton;
0807: private Button fExportButton;
0808: private Button fRemoveButton;
0809: private Button fRestoreButton;
0810: private Button fRevertButton;
0811:
0812: /** The viewer displays the pattern of selected template. */
0813: private SourceViewer fPatternViewer;
0814: /** Format checkbox. This gets conditionally added. */
0815: private Button fFormatButton;
0816: /** The store for our templates. */
0817: private TemplateStore fTemplateStore;
0818: /** The context type registry. */
0819: private ContextTypeRegistry fContextTypeRegistry;
0820:
0821: /**
0822: * Creates a new template preference page.
0823: */
0824: protected TemplatePreferencePage() {
0825: super ();
0826:
0827: setDescription(TextEditorTemplateMessages.TemplatePreferencePage_message);
0828: }
0829:
0830: /**
0831: * Returns the template store.
0832: *
0833: * @return the template store
0834: */
0835: public TemplateStore getTemplateStore() {
0836: return fTemplateStore;
0837: }
0838:
0839: /**
0840: * Returns the context type registry.
0841: *
0842: * @return the context type registry
0843: */
0844: public ContextTypeRegistry getContextTypeRegistry() {
0845: return fContextTypeRegistry;
0846: }
0847:
0848: /**
0849: * Sets the template store.
0850: *
0851: * @param store the new template store
0852: */
0853: public void setTemplateStore(TemplateStore store) {
0854: fTemplateStore = store;
0855: }
0856:
0857: /**
0858: * Sets the context type registry.
0859: *
0860: * @param registry the new context type registry
0861: */
0862: public void setContextTypeRegistry(ContextTypeRegistry registry) {
0863: fContextTypeRegistry = registry;
0864: }
0865:
0866: /*
0867: * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
0868: */
0869: public void init(IWorkbench workbench) {
0870: }
0871:
0872: /*
0873: * @see PreferencePage#createContents(Composite)
0874: */
0875: protected Control createContents(Composite ancestor) {
0876: Composite parent = new Composite(ancestor, SWT.NONE);
0877: GridLayout layout = new GridLayout();
0878: layout.numColumns = 2;
0879: layout.marginHeight = 0;
0880: layout.marginWidth = 0;
0881: parent.setLayout(layout);
0882:
0883: Composite innerParent = new Composite(parent, SWT.NONE);
0884: GridLayout innerLayout = new GridLayout();
0885: innerLayout.numColumns = 2;
0886: innerLayout.marginHeight = 0;
0887: innerLayout.marginWidth = 0;
0888: innerParent.setLayout(innerLayout);
0889: GridData gd = new GridData(GridData.FILL_BOTH);
0890: gd.horizontalSpan = 2;
0891: innerParent.setLayoutData(gd);
0892:
0893: Composite tableComposite = new Composite(innerParent, SWT.NONE);
0894: GridData data = new GridData(GridData.FILL_BOTH);
0895: data.widthHint = 360;
0896: data.heightHint = convertHeightInCharsToPixels(10);
0897: tableComposite.setLayoutData(data);
0898:
0899: ColumnLayout columnLayout = new ColumnLayout();
0900: tableComposite.setLayout(columnLayout);
0901: Table table = new Table(tableComposite, SWT.CHECK | SWT.BORDER
0902: | SWT.MULTI | SWT.FULL_SELECTION | SWT.H_SCROLL
0903: | SWT.V_SCROLL);
0904:
0905: table.setHeaderVisible(true);
0906: table.setLinesVisible(true);
0907:
0908: GC gc = new GC(getShell());
0909: gc.setFont(JFaceResources.getDialogFont());
0910:
0911: TableColumn column1 = new TableColumn(table, SWT.NONE);
0912: column1
0913: .setText(TextEditorTemplateMessages.TemplatePreferencePage_column_name);
0914: int minWidth = computeMinimumColumnWidth(
0915: gc,
0916: TextEditorTemplateMessages.TemplatePreferencePage_column_name);
0917: columnLayout.addColumnData(new ColumnWeightData(2, minWidth,
0918: true));
0919:
0920: TableColumn column2 = new TableColumn(table, SWT.NONE);
0921: column2
0922: .setText(TextEditorTemplateMessages.TemplatePreferencePage_column_context);
0923: minWidth = computeMinimumColumnWidth(
0924: gc,
0925: TextEditorTemplateMessages.TemplatePreferencePage_column_context);
0926: columnLayout.addColumnData(new ColumnWeightData(1, minWidth,
0927: true));
0928:
0929: TableColumn column3 = new TableColumn(table, SWT.NONE);
0930: column3
0931: .setText(TextEditorTemplateMessages.TemplatePreferencePage_column_description);
0932: minWidth = computeMinimumColumnWidth(
0933: gc,
0934: TextEditorTemplateMessages.TemplatePreferencePage_column_description);
0935: columnLayout.addColumnData(new ColumnWeightData(3, minWidth,
0936: true));
0937:
0938: TableColumn column4 = new TableColumn(table, SWT.NONE);
0939: column4.setAlignment(SWT.CENTER);
0940: column4
0941: .setText(TextEditorTemplateMessages.TemplatePreferencePage_column_autoinsert);
0942: minWidth = computeMinimumColumnWidth(
0943: gc,
0944: TextEditorTemplateMessages.TemplatePreferencePage_column_autoinsert);
0945: minWidth = Math.max(minWidth, computeMinimumColumnWidth(gc,
0946: TextEditorTemplateMessages.TemplatePreferencePage_on));
0947: columnLayout.addColumnData(new ColumnPixelData(minWidth, false,
0948: false));
0949:
0950: gc.dispose();
0951:
0952: fTableViewer = new CheckboxTableViewer(table);
0953: fTableViewer.setLabelProvider(new TemplateLabelProvider());
0954: fTableViewer.setContentProvider(new TemplateContentProvider());
0955:
0956: fTableViewer.setComparator(new ViewerComparator() {
0957: public int compare(Viewer viewer, Object object1,
0958: Object object2) {
0959: if ((object1 instanceof TemplatePersistenceData)
0960: && (object2 instanceof TemplatePersistenceData)) {
0961: Template left = ((TemplatePersistenceData) object1)
0962: .getTemplate();
0963: Template right = ((TemplatePersistenceData) object2)
0964: .getTemplate();
0965: int result = Collator.getInstance().compare(
0966: left.getName(), right.getName());
0967: if (result != 0)
0968: return result;
0969: return Collator.getInstance().compare(
0970: left.getDescription(),
0971: right.getDescription());
0972: }
0973: return super .compare(viewer, object1, object2);
0974: }
0975:
0976: public boolean isSorterProperty(Object element,
0977: String property) {
0978: return true;
0979: }
0980: });
0981:
0982: fTableViewer.addDoubleClickListener(new IDoubleClickListener() {
0983: public void doubleClick(DoubleClickEvent e) {
0984: edit();
0985: }
0986: });
0987:
0988: fTableViewer
0989: .addSelectionChangedListener(new ISelectionChangedListener() {
0990: public void selectionChanged(SelectionChangedEvent e) {
0991: selectionChanged1();
0992: }
0993: });
0994:
0995: fTableViewer.addCheckStateListener(new ICheckStateListener() {
0996: public void checkStateChanged(CheckStateChangedEvent event) {
0997: TemplatePersistenceData d = (TemplatePersistenceData) event
0998: .getElement();
0999: d.setEnabled(event.getChecked());
1000: }
1001: });
1002:
1003: Composite buttons = new Composite(innerParent, SWT.NONE);
1004: buttons.setLayoutData(new GridData(
1005: GridData.VERTICAL_ALIGN_BEGINNING));
1006: layout = new GridLayout();
1007: layout.marginHeight = 0;
1008: layout.marginWidth = 0;
1009: buttons.setLayout(layout);
1010:
1011: fAddButton = new Button(buttons, SWT.PUSH);
1012: fAddButton
1013: .setText(TextEditorTemplateMessages.TemplatePreferencePage_new);
1014: fAddButton.setLayoutData(getButtonGridData(fAddButton));
1015: fAddButton.addListener(SWT.Selection, new Listener() {
1016: public void handleEvent(Event e) {
1017: add();
1018: }
1019: });
1020:
1021: fEditButton = new Button(buttons, SWT.PUSH);
1022: fEditButton
1023: .setText(TextEditorTemplateMessages.TemplatePreferencePage_edit);
1024: fEditButton.setLayoutData(getButtonGridData(fEditButton));
1025: fEditButton.addListener(SWT.Selection, new Listener() {
1026: public void handleEvent(Event e) {
1027: edit();
1028: }
1029: });
1030:
1031: fRemoveButton = new Button(buttons, SWT.PUSH);
1032: fRemoveButton
1033: .setText(TextEditorTemplateMessages.TemplatePreferencePage_remove);
1034: fRemoveButton.setLayoutData(getButtonGridData(fRemoveButton));
1035: fRemoveButton.addListener(SWT.Selection, new Listener() {
1036: public void handleEvent(Event e) {
1037: remove();
1038: }
1039: });
1040:
1041: createSeparator(buttons);
1042:
1043: fRestoreButton = new Button(buttons, SWT.PUSH);
1044: fRestoreButton
1045: .setText(TextEditorTemplateMessages.TemplatePreferencePage_restore);
1046: fRestoreButton.setLayoutData(getButtonGridData(fRestoreButton));
1047: fRestoreButton.addListener(SWT.Selection, new Listener() {
1048: public void handleEvent(Event e) {
1049: restoreDeleted();
1050: }
1051: });
1052:
1053: fRevertButton = new Button(buttons, SWT.PUSH);
1054: fRevertButton
1055: .setText(TextEditorTemplateMessages.TemplatePreferencePage_revert);
1056: fRevertButton.setLayoutData(getButtonGridData(fRevertButton));
1057: fRevertButton.addListener(SWT.Selection, new Listener() {
1058: public void handleEvent(Event e) {
1059: revert();
1060: }
1061: });
1062:
1063: createSeparator(buttons);
1064:
1065: fImportButton = new Button(buttons, SWT.PUSH);
1066: fImportButton
1067: .setText(TextEditorTemplateMessages.TemplatePreferencePage_import);
1068: fImportButton.setLayoutData(getButtonGridData(fImportButton));
1069: fImportButton.addListener(SWT.Selection, new Listener() {
1070: public void handleEvent(Event e) {
1071: import_();
1072: }
1073: });
1074:
1075: fExportButton = new Button(buttons, SWT.PUSH);
1076: fExportButton
1077: .setText(TextEditorTemplateMessages.TemplatePreferencePage_export);
1078: fExportButton.setLayoutData(getButtonGridData(fExportButton));
1079: fExportButton.addListener(SWT.Selection, new Listener() {
1080: public void handleEvent(Event e) {
1081: export();
1082: }
1083: });
1084:
1085: fPatternViewer = doCreateViewer(parent);
1086:
1087: if (isShowFormatterSetting()) {
1088: fFormatButton = new Button(parent, SWT.CHECK);
1089: fFormatButton
1090: .setText(TextEditorTemplateMessages.TemplatePreferencePage_use_code_formatter);
1091: GridData gd1 = new GridData();
1092: gd1.horizontalSpan = 2;
1093: fFormatButton.setLayoutData(gd1);
1094: fFormatButton.setSelection(getPreferenceStore().getBoolean(
1095: getFormatterPreferenceKey()));
1096: }
1097:
1098: fTableViewer.setInput(fTemplateStore);
1099: fTableViewer.setAllChecked(false);
1100: fTableViewer.setCheckedElements(getEnabledTemplates());
1101:
1102: updateButtons();
1103: Dialog.applyDialogFont(parent);
1104: innerParent.layout();
1105:
1106: return parent;
1107: }
1108:
1109: /*
1110: * @since 3.2
1111: */
1112: private int computeMinimumColumnWidth(GC gc, String string) {
1113: return gc.stringExtent(string).x + 10; // pad 10 to accommodate table header trimmings
1114: }
1115:
1116: /**
1117: * Creates a separator between buttons
1118: * @param parent
1119: * @return a separator
1120: */
1121: private Label createSeparator(Composite parent) {
1122: Label separator = new Label(parent, SWT.NONE);
1123: separator.setVisible(false);
1124: GridData gd = new GridData();
1125: gd.horizontalAlignment = GridData.FILL;
1126: gd.verticalAlignment = GridData.BEGINNING;
1127: gd.heightHint = 4;
1128: separator.setLayoutData(gd);
1129: return separator;
1130: }
1131:
1132: /**
1133: * Returns whether the formatter preference checkbox should be shown.
1134: *
1135: * @return <code>true</code> if the formatter preference checkbox should
1136: * be shown, <code>false</code> otherwise
1137: */
1138: protected boolean isShowFormatterSetting() {
1139: return true;
1140: }
1141:
1142: private TemplatePersistenceData[] getEnabledTemplates() {
1143: List enabled = new ArrayList();
1144: TemplatePersistenceData[] datas = fTemplateStore
1145: .getTemplateData(false);
1146: for (int i = 0; i < datas.length; i++) {
1147: if (datas[i].isEnabled())
1148: enabled.add(datas[i]);
1149: }
1150: return (TemplatePersistenceData[]) enabled
1151: .toArray(new TemplatePersistenceData[enabled.size()]);
1152: }
1153:
1154: private SourceViewer doCreateViewer(Composite parent) {
1155: Label label = new Label(parent, SWT.NONE);
1156: label
1157: .setText(TextEditorTemplateMessages.TemplatePreferencePage_preview);
1158: GridData data = new GridData();
1159: data.horizontalSpan = 2;
1160: label.setLayoutData(data);
1161:
1162: SourceViewer viewer = createViewer(parent);
1163: viewer.setEditable(false);
1164:
1165: Control control = viewer.getControl();
1166: data = new GridData(GridData.FILL_BOTH);
1167: data.horizontalSpan = 2;
1168: data.heightHint = convertHeightInCharsToPixels(5);
1169: control.setLayoutData(data);
1170:
1171: return viewer;
1172: }
1173:
1174: /**
1175: * Creates, configures and returns a source viewer to present the template
1176: * pattern on the preference page. Clients may override to provide a custom
1177: * source viewer featuring e.g. syntax coloring.
1178: *
1179: * @param parent the parent control
1180: * @return a configured source viewer
1181: */
1182: protected SourceViewer createViewer(Composite parent) {
1183: SourceViewer viewer = new SourceViewer(parent, null, null,
1184: false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
1185: SourceViewerConfiguration configuration = new SourceViewerConfiguration();
1186: viewer.configure(configuration);
1187: IDocument document = new Document();
1188: viewer.setDocument(document);
1189: return viewer;
1190: }
1191:
1192: private static GridData getButtonGridData(Button button) {
1193: GridData data = new GridData(GridData.FILL_HORIZONTAL);
1194: // TODO replace SWTUtil
1195: // data.widthHint= SWTUtil.getButtonWidthHint(button);
1196: // data.heightHint= SWTUtil.getButtonHeightHint(button);
1197:
1198: return data;
1199: }
1200:
1201: private void selectionChanged1() {
1202: updateViewerInput();
1203: updateButtons();
1204: }
1205:
1206: /**
1207: * Updates the pattern viewer.
1208: */
1209: protected void updateViewerInput() {
1210: IStructuredSelection selection = (IStructuredSelection) fTableViewer
1211: .getSelection();
1212:
1213: if (selection.size() == 1) {
1214: TemplatePersistenceData data = (TemplatePersistenceData) selection
1215: .getFirstElement();
1216: Template template = data.getTemplate();
1217: fPatternViewer.getDocument().set(template.getPattern());
1218: } else {
1219: fPatternViewer.getDocument().set(""); //$NON-NLS-1$
1220: }
1221: }
1222:
1223: /**
1224: * Updates the buttons.
1225: */
1226: protected void updateButtons() {
1227: IStructuredSelection selection = (IStructuredSelection) fTableViewer
1228: .getSelection();
1229: int selectionCount = selection.size();
1230: int itemCount = fTableViewer.getTable().getItemCount();
1231: boolean canRestore = fTemplateStore.getTemplateData(true).length != fTemplateStore
1232: .getTemplateData(false).length;
1233: boolean canRevert = false;
1234: for (Iterator it = selection.iterator(); it.hasNext();) {
1235: TemplatePersistenceData data = (TemplatePersistenceData) it
1236: .next();
1237: if (data.isModified()) {
1238: canRevert = true;
1239: break;
1240: }
1241: }
1242:
1243: fEditButton.setEnabled(selectionCount == 1);
1244: fExportButton.setEnabled(selectionCount > 0);
1245: fRemoveButton.setEnabled(selectionCount > 0
1246: && selectionCount <= itemCount);
1247: fRestoreButton.setEnabled(canRestore);
1248: fRevertButton.setEnabled(canRevert);
1249: }
1250:
1251: private void add() {
1252:
1253: Iterator it = fContextTypeRegistry.contextTypes();
1254: if (it.hasNext()) {
1255: Template template = new Template(
1256: "", "", ((TemplateContextType) it.next()).getId(), "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1257:
1258: Template newTemplate = editTemplate(template, false, true);
1259: if (newTemplate != null) {
1260: TemplatePersistenceData data = new TemplatePersistenceData(
1261: newTemplate, true);
1262: fTemplateStore.add(data);
1263: fTableViewer.refresh();
1264: fTableViewer.setChecked(data, true);
1265: fTableViewer
1266: .setSelection(new StructuredSelection(data));
1267: }
1268: }
1269: }
1270:
1271: /**
1272: * Creates the edit dialog. Subclasses may override this method to provide a
1273: * custom dialog.
1274: *
1275: * @param template the template being edited
1276: * @param edit whether the dialog should be editable
1277: * @param isNameModifiable whether the template name may be modified
1278: * @return an <code>EditTemplateDialog</code> which will be opened.
1279: * @deprecated not called any longer as of 3.1 - use {@link #editTemplate(Template, boolean, boolean)}
1280: */
1281: protected Dialog createTemplateEditDialog(Template template,
1282: boolean edit, boolean isNameModifiable) {
1283: return new EditTemplateDialog(getShell(), template, edit,
1284: isNameModifiable, fContextTypeRegistry);
1285: }
1286:
1287: /**
1288: * Creates the edit dialog. Subclasses may override this method to provide a
1289: * custom dialog.
1290: *
1291: * @param template the template being edited
1292: * @param edit whether the dialog should be editable
1293: * @param isNameModifiable whether the template name may be modified
1294: * @return the created or modified template, or <code>null</code> if the edition failed
1295: * @since 3.1
1296: */
1297: protected Template editTemplate(Template template, boolean edit,
1298: boolean isNameModifiable) {
1299: EditTemplateDialog dialog = new EditTemplateDialog(getShell(),
1300: template, edit, isNameModifiable, fContextTypeRegistry);
1301: if (dialog.open() == Window.OK) {
1302: return dialog.getTemplate();
1303: }
1304: return null;
1305: }
1306:
1307: private void edit() {
1308: IStructuredSelection selection = (IStructuredSelection) fTableViewer
1309: .getSelection();
1310:
1311: Object[] objects = selection.toArray();
1312: if ((objects == null) || (objects.length != 1))
1313: return;
1314:
1315: TemplatePersistenceData data = (TemplatePersistenceData) selection
1316: .getFirstElement();
1317: edit(data);
1318: }
1319:
1320: private void edit(TemplatePersistenceData data) {
1321: Template oldTemplate = data.getTemplate();
1322: Template newTemplate = editTemplate(new Template(oldTemplate),
1323: true, true);
1324: if (newTemplate != null) {
1325:
1326: if (!newTemplate.getName().equals(oldTemplate.getName())
1327: && MessageDialog
1328: .openQuestion(
1329: getShell(),
1330: TextEditorTemplateMessages.TemplatePreferencePage_question_create_new_title,
1331: TextEditorTemplateMessages.TemplatePreferencePage_question_create_new_message)) {
1332: data = new TemplatePersistenceData(newTemplate, true);
1333: fTemplateStore.add(data);
1334: fTableViewer.refresh();
1335: } else {
1336: data.setTemplate(newTemplate);
1337: fTableViewer.refresh(data);
1338: }
1339: selectionChanged1();
1340: fTableViewer.setChecked(data, data.isEnabled());
1341: fTableViewer.setSelection(new StructuredSelection(data));
1342: }
1343: }
1344:
1345: private void import_() {
1346: FileDialog dialog = new FileDialog(getShell());
1347: dialog
1348: .setText(TextEditorTemplateMessages.TemplatePreferencePage_import_title);
1349: dialog
1350: .setFilterExtensions(new String[] { TextEditorTemplateMessages.TemplatePreferencePage_import_extension });
1351: String path = dialog.open();
1352:
1353: if (path == null)
1354: return;
1355:
1356: try {
1357: TemplateReaderWriter reader = new TemplateReaderWriter();
1358: File file = new File(path);
1359: if (file.exists()) {
1360: InputStream input = new BufferedInputStream(
1361: new FileInputStream(file));
1362: try {
1363: TemplatePersistenceData[] datas = reader.read(
1364: input, null);
1365: for (int i = 0; i < datas.length; i++) {
1366: TemplatePersistenceData data = datas[i];
1367: fTemplateStore.add(data);
1368: }
1369: } finally {
1370: try {
1371: input.close();
1372: } catch (IOException x) {
1373: // ignore
1374: }
1375: }
1376: }
1377:
1378: fTableViewer.refresh();
1379: fTableViewer.setAllChecked(false);
1380: fTableViewer.setCheckedElements(getEnabledTemplates());
1381:
1382: } catch (FileNotFoundException e) {
1383: openReadErrorDialog();
1384: } catch (IOException e) {
1385: openReadErrorDialog();
1386: }
1387: }
1388:
1389: private void export() {
1390: IStructuredSelection selection = (IStructuredSelection) fTableViewer
1391: .getSelection();
1392: Object[] templates = selection.toArray();
1393:
1394: TemplatePersistenceData[] datas = new TemplatePersistenceData[templates.length];
1395: for (int i = 0; i != templates.length; i++)
1396: datas[i] = (TemplatePersistenceData) templates[i];
1397:
1398: export(datas);
1399: }
1400:
1401: private void export(TemplatePersistenceData[] templates) {
1402: FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
1403: dialog
1404: .setText(TextEditorTemplateMessages.TemplatePreferencePage_export_title);
1405: dialog
1406: .setFilterExtensions(new String[] { TextEditorTemplateMessages.TemplatePreferencePage_export_extension });
1407: dialog
1408: .setFileName(TextEditorTemplateMessages.TemplatePreferencePage_export_filename);
1409: String path = dialog.open();
1410:
1411: if (path == null)
1412: return;
1413:
1414: File file = new File(path);
1415:
1416: if (file.isHidden()) {
1417: String title = TextEditorTemplateMessages.TemplatePreferencePage_export_error_title;
1418: String message = NLSUtility
1419: .format(
1420: TextEditorTemplateMessages.TemplatePreferencePage_export_error_hidden,
1421: file.getAbsolutePath());
1422: MessageDialog.openError(getShell(), title, message);
1423: return;
1424: }
1425:
1426: if (file.exists() && !file.canWrite()) {
1427: String title = TextEditorTemplateMessages.TemplatePreferencePage_export_error_title;
1428: String message = NLSUtility
1429: .format(
1430: TextEditorTemplateMessages.TemplatePreferencePage_export_error_canNotWrite,
1431: file.getAbsolutePath());
1432: MessageDialog.openError(getShell(), title, message);
1433: return;
1434: }
1435:
1436: if (!file.exists() || confirmOverwrite(file)) {
1437: OutputStream output = null;
1438: try {
1439: output = new BufferedOutputStream(new FileOutputStream(
1440: file));
1441: TemplateReaderWriter writer = new TemplateReaderWriter();
1442: writer.save(templates, output);
1443: } catch (IOException e) {
1444: openWriteErrorDialog();
1445: } finally {
1446: if (output != null) {
1447: try {
1448: output.close();
1449: } catch (IOException e) {
1450: // ignore
1451: }
1452: }
1453: }
1454: }
1455: }
1456:
1457: private boolean confirmOverwrite(File file) {
1458: return MessageDialog
1459: .openQuestion(
1460: getShell(),
1461: TextEditorTemplateMessages.TemplatePreferencePage_export_exists_title,
1462: NLSUtility
1463: .format(
1464: TextEditorTemplateMessages.TemplatePreferencePage_export_exists_message,
1465: file.getAbsolutePath()));
1466: }
1467:
1468: private void remove() {
1469: IStructuredSelection selection = (IStructuredSelection) fTableViewer
1470: .getSelection();
1471:
1472: Iterator elements = selection.iterator();
1473: while (elements.hasNext()) {
1474: TemplatePersistenceData data = (TemplatePersistenceData) elements
1475: .next();
1476: fTemplateStore.delete(data);
1477: }
1478:
1479: fTableViewer.refresh();
1480: }
1481:
1482: private void restoreDeleted() {
1483: fTemplateStore.restoreDeleted();
1484: fTableViewer.refresh();
1485: fTableViewer.setCheckedElements(getEnabledTemplates());
1486: updateButtons();
1487: }
1488:
1489: private void revert() {
1490: IStructuredSelection selection = (IStructuredSelection) fTableViewer
1491: .getSelection();
1492:
1493: Iterator elements = selection.iterator();
1494: while (elements.hasNext()) {
1495: TemplatePersistenceData data = (TemplatePersistenceData) elements
1496: .next();
1497: data.revert();
1498: fTableViewer.setChecked(data, data.isEnabled());
1499: }
1500:
1501: selectionChanged1();
1502: fTableViewer.refresh();
1503: }
1504:
1505: /*
1506: * @see Control#setVisible(boolean)
1507: */
1508: public void setVisible(boolean visible) {
1509: super .setVisible(visible);
1510: if (visible)
1511: setTitle(TextEditorTemplateMessages.TemplatePreferencePage_title);
1512: }
1513:
1514: /*
1515: * @see PreferencePage#performDefaults()
1516: */
1517: protected void performDefaults() {
1518: if (isShowFormatterSetting()) {
1519: IPreferenceStore prefs = getPreferenceStore();
1520: fFormatButton.setSelection(prefs
1521: .getDefaultBoolean(getFormatterPreferenceKey()));
1522: }
1523:
1524: fTemplateStore.restoreDefaults();
1525:
1526: // refresh
1527: fTableViewer.refresh();
1528: fTableViewer.setAllChecked(false);
1529: fTableViewer.setCheckedElements(getEnabledTemplates());
1530: }
1531:
1532: /*
1533: * @see PreferencePage#performOk()
1534: */
1535: public boolean performOk() {
1536: if (isShowFormatterSetting()) {
1537: IPreferenceStore prefs = getPreferenceStore();
1538: prefs.setValue(getFormatterPreferenceKey(), fFormatButton
1539: .getSelection());
1540: }
1541:
1542: try {
1543: fTemplateStore.save();
1544: } catch (IOException e) {
1545: openWriteErrorDialog();
1546: }
1547:
1548: return super .performOk();
1549: }
1550:
1551: /**
1552: * Returns the key to use for the formatter preference.
1553: *
1554: * @return the formatter preference key
1555: */
1556: protected String getFormatterPreferenceKey() {
1557: return DEFAULT_FORMATTER_PREFERENCE_KEY;
1558: }
1559:
1560: /*
1561: * @see PreferencePage#performCancel()
1562: */
1563: public boolean performCancel() {
1564: try {
1565: fTemplateStore.load();
1566: } catch (IOException e) {
1567: openReadErrorDialog();
1568: return false;
1569: }
1570: return super .performCancel();
1571: }
1572:
1573: /*
1574: * @since 3.2
1575: */
1576: private void openReadErrorDialog() {
1577: String title = TextEditorTemplateMessages.TemplatePreferencePage_error_read_title;
1578: String message = TextEditorTemplateMessages.TemplatePreferencePage_error_read_message;
1579: MessageDialog.openError(getShell(), title, message);
1580: }
1581:
1582: /*
1583: * @since 3.2
1584: */
1585: private void openWriteErrorDialog() {
1586: String title = TextEditorTemplateMessages.TemplatePreferencePage_error_write_title;
1587: String message = TextEditorTemplateMessages.TemplatePreferencePage_error_write_message;
1588: MessageDialog.openError(getShell(), title, message);
1589: }
1590:
1591: protected SourceViewer getViewer() {
1592: return fPatternViewer;
1593: }
1594:
1595: protected TableViewer getTableViewer() {
1596: return fTableViewer;
1597: }
1598: }
|