--- /dev/null
+/*******************************************************************************
+ * 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