added first version of codetemplates (needs to fix some bugs)
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / preferences / CodeTemplateBlock.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplateBlock.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/preferences/CodeTemplateBlock.java
new file mode 100644 (file)
index 0000000..a1e4f67
--- /dev/null
@@ -0,0 +1,514 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.ui.preferences;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
+import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
+import net.sourceforge.phpdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
+import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ITreeListAdapter;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
+import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.TreeListDialogField;
+import net.sourceforge.phpdt.ui.PreferenceConstants;
+import net.sourceforge.phpdt.ui.text.JavaTextTools;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
+import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ */
+public class CodeTemplateBlock {
+
+  private class CodeTemplateAdapter implements ITreeListAdapter, IDialogFieldListener {
+
+    private final Object[] NO_CHILDREN = new Object[0];
+
+    public void customButtonPressed(TreeListDialogField field, int index) {
+      doButtonPressed(index, field.getSelectedElements());
+    }
+
+    public void selectionChanged(TreeListDialogField field) {
+      List selected = field.getSelectedElements();
+      field.enableButton(IDX_EDIT, canEdit(selected));
+      field.enableButton(IDX_EXPORT, !selected.isEmpty());
+
+      updateSourceViewerInput(selected);
+    }
+
+    public void doubleClicked(TreeListDialogField field) {
+      List selected = field.getSelectedElements();
+      if (canEdit(selected)) {
+        doButtonPressed(IDX_EDIT, selected);
+      }
+    }
+
+    public Object[] getChildren(TreeListDialogField field, Object element) {
+      if (element == COMMENT_NODE || element == CODE_NODE) {
+        return getTemplateOfCategory(element == COMMENT_NODE);
+      }
+      return NO_CHILDREN;
+    }
+
+    public Object getParent(TreeListDialogField field, Object element) {
+      if (element instanceof TemplatePersistenceData) {
+        TemplatePersistenceData data = (TemplatePersistenceData) element;
+        if (data.getTemplate().getName().endsWith(CodeTemplateContextType.COMMENT_SUFFIX)) {
+          return COMMENT_NODE;
+        }
+        return CODE_NODE;
+      }
+      return null;
+    }
+
+    public boolean hasChildren(TreeListDialogField field, Object element) {
+      return (element == COMMENT_NODE || element == CODE_NODE);
+    }
+
+    public void dialogFieldChanged(DialogField field) {
+    }
+
+    public void keyPressed(TreeListDialogField field, KeyEvent event) {
+    }
+
+  }
+
+  private static class CodeTemplateLabelProvider extends LabelProvider {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+     */
+    public Image getImage(Object element) {
+      return null;
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+     */
+    public String getText(Object element) {
+      if (element == COMMENT_NODE || element == CODE_NODE) {
+        return (String) element;
+      }
+      TemplatePersistenceData data = (TemplatePersistenceData) element;
+      Template template = data.getTemplate();
+      String name = template.getName();
+      if (CodeTemplateContextType.CATCHBLOCK.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.catchblock.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.METHODSTUB.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.methodstub.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.CONSTRUCTORSTUB.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.constructorstub.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.GETTERSTUB.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.getterstub.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.SETTERSTUB.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.setterstub.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.NEWTYPE.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.newtype.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.TYPECOMMENT.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.typecomment.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.FIELDCOMMENT.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.fieldcomment.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.METHODCOMMENT.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.methodcomment.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.OVERRIDECOMMENT.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.overridecomment.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.CONSTRUCTORCOMMENT.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.constructorcomment.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.GETTERCOMMENT.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.gettercomment.label"); //$NON-NLS-1$
+      } else if (CodeTemplateContextType.SETTERCOMMENT.equals(name)) {
+        return PreferencesMessages.getString("CodeTemplateBlock.settercomment.label"); //$NON-NLS-1$
+      }
+      return template.getDescription();
+    }
+
+  }
+
+  private final static int IDX_EDIT = 0;
+
+  private final static int IDX_IMPORT = 2;
+
+  private final static int IDX_EXPORT = 3;
+
+  private final static int IDX_EXPORTALL = 4;
+
+  protected final static Object COMMENT_NODE = PreferencesMessages.getString("CodeTemplateBlock.templates.comment.node"); //$NON-NLS-1$
+
+  protected final static Object CODE_NODE = PreferencesMessages.getString("CodeTemplateBlock.templates.code.node"); //$NON-NLS-1$
+
+  private static final String PREF_JAVADOC_STUBS = PreferenceConstants.CODEGEN_ADD_COMMENTS;
+
+  private TreeListDialogField fCodeTemplateTree;
+
+  private SelectionButtonDialogField fCreateJavaDocComments;
+
+  protected TemplateStore fTemplates;
+
+  private PixelConverter fPixelConverter;
+
+  private SourceViewer fPatternViewer;
+
+  private Control fSWTWidget;
+
+  private TemplateVariableProcessor fTemplateProcessor;
+
+  public CodeTemplateBlock() {
+
+    fTemplates = PHPeclipsePlugin.getDefault().getCodeTemplateStore();
+    fTemplateProcessor = new TemplateVariableProcessor();
+
+    CodeTemplateAdapter adapter = new CodeTemplateAdapter();
+
+    String[] buttonLabels = new String[] {
+    /* IDX_EDIT */PreferencesMessages.getString("CodeTemplateBlock.templates.edit.button"), //$NON-NLS-1$
+        /* */null,
+        /* IDX_IMPORT */PreferencesMessages.getString("CodeTemplateBlock.templates.import.button"), //$NON-NLS-1$
+        /* IDX_EXPORT */PreferencesMessages.getString("CodeTemplateBlock.templates.export.button"), //$NON-NLS-1$
+        /* IDX_EXPORTALL */PreferencesMessages.getString("CodeTemplateBlock.templates.exportall.button") //$NON-NLS-1$
+
+    };
+    fCodeTemplateTree = new TreeListDialogField(adapter, buttonLabels, new CodeTemplateLabelProvider());
+    fCodeTemplateTree.setDialogFieldListener(adapter);
+    fCodeTemplateTree.setLabelText(PreferencesMessages.getString("CodeTemplateBlock.templates.label")); //$NON-NLS-1$
+
+    fCodeTemplateTree.enableButton(IDX_EXPORT, false);
+    fCodeTemplateTree.enableButton(IDX_EDIT, false);
+
+    fCodeTemplateTree.addElement(COMMENT_NODE);
+    fCodeTemplateTree.addElement(CODE_NODE);
+
+    fCreateJavaDocComments = new SelectionButtonDialogField(SWT.CHECK | SWT.WRAP);
+    fCreateJavaDocComments.setLabelText(PreferencesMessages.getString("CodeTemplateBlock.createcomment.label")); //$NON-NLS-1$
+    fCreateJavaDocComments.setSelection(PreferenceConstants.getPreferenceStore().getBoolean(PREF_JAVADOC_STUBS));
+
+    fCodeTemplateTree.selectFirstElement();
+  }
+
+  protected Control createContents(Composite parent) {
+    fPixelConverter = new PixelConverter(parent);
+    fSWTWidget = parent;
+
+    Composite composite = new Composite(parent, SWT.NONE);
+    GridLayout layout = new GridLayout();
+    layout.marginHeight = 0;
+    layout.marginWidth = 0;
+    layout.numColumns = 2;
+    composite.setLayout(layout);
+
+    fCodeTemplateTree.doFillIntoGrid(composite, 3);
+    LayoutUtil.setHorizontalSpan(fCodeTemplateTree.getLabelControl(null), 2);
+    LayoutUtil.setHorizontalGrabbing(fCodeTemplateTree.getTreeControl(null));
+
+    fPatternViewer = createViewer(composite, 2);
+
+    fCreateJavaDocComments.doFillIntoGrid(composite, 2);
+
+    DialogField label = new DialogField();
+    label.setLabelText(PreferencesMessages.getString("CodeTemplateBlock.createcomment.description")); //$NON-NLS-1$
+    label.doFillIntoGrid(composite, 2);
+
+    return composite;
+
+  }
+
+  private Shell getShell() {
+    if (fSWTWidget != null) {
+      return fSWTWidget.getShell();
+    }
+    return PHPeclipsePlugin.getActiveWorkbenchShell();
+  }
+
+  private SourceViewer createViewer(Composite parent, int nColumns) {
+    Label label = new Label(parent, SWT.NONE);
+    label.setText(PreferencesMessages.getString("CodeTemplateBlock.preview")); //$NON-NLS-1$
+    GridData data = new GridData();
+    data.horizontalSpan = nColumns;
+    label.setLayoutData(data);
+
+    IDocument document = new Document();
+    JavaTextTools tools = PHPeclipsePlugin.getDefault().getJavaTextTools();
+    tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING);
+    IPreferenceStore store = PHPeclipsePlugin.getDefault().getCombinedPreferenceStore();
+    SourceViewer viewer = new JavaSourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
+    TemplateEditorSourceViewerConfiguration configuration = new TemplateEditorSourceViewerConfiguration(tools.getColorManager(),
+        store, null, fTemplateProcessor);
+    viewer.configure(configuration);
+    viewer.setEditable(false);
+    viewer.setDocument(document);
+
+    Font font = JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
+    viewer.getTextWidget().setFont(font);
+    new JavaSourcePreviewerUpdater(viewer, configuration, store);
+
+    Control control = viewer.getControl();
+    data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
+    data.horizontalSpan = nColumns;
+    data.heightHint = fPixelConverter.convertHeightInCharsToPixels(5);
+    control.setLayoutData(data);
+
+    return viewer;
+  }
+
+  protected TemplatePersistenceData[] getTemplateOfCategory(boolean isComment) {
+    ArrayList res = new ArrayList();
+    TemplatePersistenceData[] templates = fTemplates.getTemplateData(false);
+    for (int i = 0; i < templates.length; i++) {
+      TemplatePersistenceData curr = templates[i];
+      if (isComment == curr.getTemplate().getName().endsWith(CodeTemplateContextType.COMMENT_SUFFIX)) {
+        res.add(curr);
+      }
+    }
+    return (TemplatePersistenceData[]) res.toArray(new TemplatePersistenceData[res.size()]);
+  }
+
+  protected static boolean canEdit(List selected) {
+    return selected.size() == 1 && (selected.get(0) instanceof TemplatePersistenceData);
+  }
+
+  protected void updateSourceViewerInput(List selection) {
+    if (fPatternViewer == null || fPatternViewer.getTextWidget().isDisposed()) {
+      return;
+    }
+    if (selection.size() == 1 && selection.get(0) instanceof TemplatePersistenceData) {
+      TemplatePersistenceData data = (TemplatePersistenceData) selection.get(0);
+      Template template = data.getTemplate();
+      TemplateContextType type = PHPeclipsePlugin.getDefault().getCodeTemplateContextRegistry().getContextType(
+          template.getContextTypeId());
+      fTemplateProcessor.setContextType(type);
+      fPatternViewer.getDocument().set(template.getPattern());
+    } else {
+      fPatternViewer.getDocument().set(""); //$NON-NLS-1$
+    }
+  }
+
+  protected void doButtonPressed(int buttonIndex, List selected) {
+    if (buttonIndex == IDX_EDIT) {
+      edit((TemplatePersistenceData) selected.get(0));
+    } else if (buttonIndex == IDX_EXPORT) {
+      export(selected);
+    } else if (buttonIndex == IDX_EXPORTALL) {
+      exportAll();
+    } else if (buttonIndex == IDX_IMPORT) {
+      import_();
+    }
+  }
+
+  private void edit(TemplatePersistenceData data) {
+    Template newTemplate = new Template(data.getTemplate());
+    EditTemplateDialog dialog = new EditTemplateDialog(getShell(), newTemplate, true, false, PHPeclipsePlugin.getDefault()
+        .getCodeTemplateContextRegistry());
+    if (dialog.open() == Window.OK) {
+      // changed
+      data.setTemplate(newTemplate);
+      fCodeTemplateTree.refresh(data);
+      fCodeTemplateTree.selectElements(new StructuredSelection(data));
+    }
+  }
+
+  private void import_() {
+    FileDialog dialog = new FileDialog(getShell());
+    dialog.setText(PreferencesMessages.getString("CodeTemplateBlock.import.title")); //$NON-NLS-1$
+    dialog.setFilterExtensions(new String[] { PreferencesMessages.getString("CodeTemplateBlock.import.extension") }); //$NON-NLS-1$
+    String path = dialog.open();
+
+    if (path == null)
+      return;
+
+    try {
+      TemplateReaderWriter reader = new TemplateReaderWriter();
+      File file = new File(path);
+      if (file.exists()) {
+        InputStream input = new BufferedInputStream(new FileInputStream(file));
+        TemplatePersistenceData[] datas = reader.read(input, null);
+        for (int i = 0; i < datas.length; i++) {
+          updateTemplate(datas[i]);
+        }
+      }
+
+      fCodeTemplateTree.refresh();
+      updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
+
+    } catch (FileNotFoundException e) {
+      openReadErrorDialog(e);
+    } catch (IOException e) {
+      openReadErrorDialog(e);
+    }
+
+  }
+
+  private void updateTemplate(TemplatePersistenceData data) {
+    TemplatePersistenceData[] datas = fTemplates.getTemplateData(true);
+    for (int i = 0; i < datas.length; i++) {
+      String id = datas[i].getId();
+      if (id != null && id.equals(data.getId())) {
+        datas[i].setTemplate(data.getTemplate());
+        break;
+      }
+    }
+  }
+
+  private void exportAll() {
+    export(fTemplates.getTemplateData(false));
+  }
+
+  private void export(List selected) {
+    List datas = new ArrayList();
+    for (int i = 0; i < selected.size(); i++) {
+      Object curr = selected.get(i);
+      if (curr instanceof TemplatePersistenceData) {
+        datas.add(curr);
+      } else {
+        TemplatePersistenceData[] cat = getTemplateOfCategory(curr == COMMENT_NODE);
+        datas.addAll(Arrays.asList(cat));
+      }
+    }
+    export((TemplatePersistenceData[]) datas.toArray(new TemplatePersistenceData[datas.size()]));
+  }
+
+  private void export(TemplatePersistenceData[] templates) {
+    FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
+    dialog.setText(PreferencesMessages.getFormattedString("CodeTemplateBlock.export.title", String.valueOf(templates.length))); //$NON-NLS-1$
+    dialog.setFilterExtensions(new String[] { PreferencesMessages.getString("CodeTemplateBlock.export.extension") }); //$NON-NLS-1$
+    dialog.setFileName(PreferencesMessages.getString("CodeTemplateBlock.export.filename")); //$NON-NLS-1$
+    String path = dialog.open();
+
+    if (path == null)
+      return;
+
+    File file = new File(path);
+
+    if (file.isHidden()) {
+      String title = PreferencesMessages.getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$ 
+      String message = PreferencesMessages.getFormattedString("CodeTemplateBlock.export.error.hidden", file.getAbsolutePath()); //$NON-NLS-1$
+      MessageDialog.openError(getShell(), title, message);
+      return;
+    }
+
+    if (file.exists() && !file.canWrite()) {
+      String title = PreferencesMessages.getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
+      String message = PreferencesMessages.getFormattedString("CodeTemplateBlock.export.error.canNotWrite", file.getAbsolutePath()); //$NON-NLS-1$
+      MessageDialog.openError(getShell(), title, message);
+      return;
+    }
+
+    if (!file.exists() || confirmOverwrite(file)) {
+      try {
+        OutputStream output = new BufferedOutputStream(new FileOutputStream(file));
+        TemplateReaderWriter writer = new TemplateReaderWriter();
+        writer.save(templates, output);
+      } catch (IOException e) {
+        openWriteErrorDialog(e);
+      }
+    }
+
+  }
+
+  private boolean confirmOverwrite(File file) {
+    return MessageDialog.openQuestion(getShell(), PreferencesMessages.getString("CodeTemplateBlock.export.exists.title"), //$NON-NLS-1$
+        PreferencesMessages.getFormattedString("CodeTemplateBlock.export.exists.message", file.getAbsolutePath())); //$NON-NLS-1$
+  }
+
+  public void performDefaults() {
+    IPreferenceStore prefs = PHPeclipsePlugin.getDefault().getPreferenceStore();
+    fCreateJavaDocComments.setSelection(prefs.getDefaultBoolean(PREF_JAVADOC_STUBS));
+
+    fTemplates.restoreDefaults();
+
+    // refresh
+    fCodeTemplateTree.refresh();
+    updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
+  }
+
+  public boolean performOk(boolean enabled) {
+    IPreferenceStore prefs = PreferenceConstants.getPreferenceStore();
+    prefs.setValue(PREF_JAVADOC_STUBS, fCreateJavaDocComments.isSelected());
+    PHPeclipsePlugin.getDefault().savePluginPreferences();
+
+    try {
+      fTemplates.save();
+    } catch (IOException e) {
+      PHPeclipsePlugin.log(e);
+      openWriteErrorDialog(e);
+    }
+    return true;
+  }
+
+  public void performCancel() {
+    try {
+      fTemplates.load();
+    } catch (IOException e) {
+      openReadErrorDialog(e);
+    }
+  }
+
+  private void openReadErrorDialog(Exception e) {
+    String title = PreferencesMessages.getString("CodeTemplateBlock.error.read.title"); //$NON-NLS-1$
+
+    String message = e.getLocalizedMessage();
+    if (message != null)
+      message = PreferencesMessages.getFormattedString("CodeTemplateBlock.error.parse.message", message); //$NON-NLS-1$
+    else
+      message = PreferencesMessages.getString("CodeTemplateBlock.error.read.message"); //$NON-NLS-1$
+    MessageDialog.openError(getShell(), title, message);
+  }
+
+  private void openWriteErrorDialog(Exception e) {
+    String title = PreferencesMessages.getString("CodeTemplateBlock.error.write.title"); //$NON-NLS-1$
+    String message = PreferencesMessages.getString("CodeTemplateBlock.error.write.message"); //$NON-NLS-1$
+    MessageDialog.openError(getShell(), title, message);
+  }
+
+}
\ No newline at end of file