1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.preferences;
13 import java.io.BufferedInputStream;
14 import java.io.BufferedOutputStream;
16 import java.io.FileInputStream;
17 import java.io.FileNotFoundException;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
26 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
27 import net.sourceforge.phpdt.internal.ui.text.IPHPPartitions;
28 import net.sourceforge.phpdt.internal.ui.text.template.preferences.TemplateVariableProcessor;
29 import net.sourceforge.phpdt.internal.ui.util.PixelConverter;
30 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.DialogField;
31 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
32 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.ITreeListAdapter;
33 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.LayoutUtil;
34 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
35 import net.sourceforge.phpdt.internal.ui.wizards.dialogfields.TreeListDialogField;
36 import net.sourceforge.phpdt.ui.PreferenceConstants;
37 import net.sourceforge.phpdt.ui.text.JavaTextTools;
38 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
39 import net.sourceforge.phpeclipse.phpeditor.JavaSourceViewer;
41 import org.eclipse.jface.dialogs.MessageDialog;
42 import org.eclipse.jface.preference.IPreferenceStore;
43 import org.eclipse.jface.resource.JFaceResources;
44 import org.eclipse.jface.text.Document;
45 import org.eclipse.jface.text.IDocument;
46 import org.eclipse.jface.text.source.SourceViewer;
47 import org.eclipse.jface.text.templates.Template;
48 import org.eclipse.jface.text.templates.TemplateContextType;
49 import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
50 import org.eclipse.jface.text.templates.persistence.TemplateReaderWriter;
51 import org.eclipse.jface.text.templates.persistence.TemplateStore;
52 import org.eclipse.jface.viewers.LabelProvider;
53 import org.eclipse.jface.viewers.StructuredSelection;
54 import org.eclipse.jface.window.Window;
55 import org.eclipse.swt.SWT;
56 import org.eclipse.swt.events.KeyEvent;
57 import org.eclipse.swt.graphics.Font;
58 import org.eclipse.swt.graphics.Image;
59 import org.eclipse.swt.layout.GridData;
60 import org.eclipse.swt.layout.GridLayout;
61 import org.eclipse.swt.widgets.Composite;
62 import org.eclipse.swt.widgets.Control;
63 import org.eclipse.swt.widgets.FileDialog;
64 import org.eclipse.swt.widgets.Label;
65 import org.eclipse.swt.widgets.Shell;
69 public class CodeTemplateBlock {
71 private class CodeTemplateAdapter implements ITreeListAdapter, IDialogFieldListener {
73 private final Object[] NO_CHILDREN = new Object[0];
75 public void customButtonPressed(TreeListDialogField field, int index) {
76 doButtonPressed(index, field.getSelectedElements());
79 public void selectionChanged(TreeListDialogField field) {
80 List selected = field.getSelectedElements();
81 field.enableButton(IDX_EDIT, canEdit(selected));
82 field.enableButton(IDX_EXPORT, !selected.isEmpty());
84 updateSourceViewerInput(selected);
87 public void doubleClicked(TreeListDialogField field) {
88 List selected = field.getSelectedElements();
89 if (canEdit(selected)) {
90 doButtonPressed(IDX_EDIT, selected);
94 public Object[] getChildren(TreeListDialogField field, Object element) {
95 if (element == COMMENT_NODE || element == CODE_NODE) {
96 return getTemplateOfCategory(element == COMMENT_NODE);
101 public Object getParent(TreeListDialogField field, Object element) {
102 if (element instanceof TemplatePersistenceData) {
103 TemplatePersistenceData data = (TemplatePersistenceData) element;
104 if (data.getTemplate().getName().endsWith(CodeTemplateContextType.COMMENT_SUFFIX)) {
112 public boolean hasChildren(TreeListDialogField field, Object element) {
113 return (element == COMMENT_NODE || element == CODE_NODE);
116 public void dialogFieldChanged(DialogField field) {
119 public void keyPressed(TreeListDialogField field, KeyEvent event) {
124 private static class CodeTemplateLabelProvider extends LabelProvider {
129 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
131 public Image getImage(Object element) {
139 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
141 public String getText(Object element) {
142 if (element == COMMENT_NODE || element == CODE_NODE) {
143 return (String) element;
145 TemplatePersistenceData data = (TemplatePersistenceData) element;
146 Template template = data.getTemplate();
147 String name = template.getName();
148 if (CodeTemplateContextType.CATCHBLOCK.equals(name)) {
149 return PreferencesMessages.getString("CodeTemplateBlock.catchblock.label"); //$NON-NLS-1$
150 } else if (CodeTemplateContextType.METHODSTUB.equals(name)) {
151 return PreferencesMessages.getString("CodeTemplateBlock.methodstub.label"); //$NON-NLS-1$
152 } else if (CodeTemplateContextType.CONSTRUCTORSTUB.equals(name)) {
153 return PreferencesMessages.getString("CodeTemplateBlock.constructorstub.label"); //$NON-NLS-1$
154 } else if (CodeTemplateContextType.GETTERSTUB.equals(name)) {
155 return PreferencesMessages.getString("CodeTemplateBlock.getterstub.label"); //$NON-NLS-1$
156 } else if (CodeTemplateContextType.SETTERSTUB.equals(name)) {
157 return PreferencesMessages.getString("CodeTemplateBlock.setterstub.label"); //$NON-NLS-1$
158 } else if (CodeTemplateContextType.NEWTYPE.equals(name)) {
159 return PreferencesMessages.getString("CodeTemplateBlock.newtype.label"); //$NON-NLS-1$
160 } else if (CodeTemplateContextType.TYPECOMMENT.equals(name)) {
161 return PreferencesMessages.getString("CodeTemplateBlock.typecomment.label"); //$NON-NLS-1$
162 } else if (CodeTemplateContextType.FIELDCOMMENT.equals(name)) {
163 return PreferencesMessages.getString("CodeTemplateBlock.fieldcomment.label"); //$NON-NLS-1$
164 } else if (CodeTemplateContextType.METHODCOMMENT.equals(name)) {
165 return PreferencesMessages.getString("CodeTemplateBlock.methodcomment.label"); //$NON-NLS-1$
166 } else if (CodeTemplateContextType.OVERRIDECOMMENT.equals(name)) {
167 return PreferencesMessages.getString("CodeTemplateBlock.overridecomment.label"); //$NON-NLS-1$
168 } else if (CodeTemplateContextType.CONSTRUCTORCOMMENT.equals(name)) {
169 return PreferencesMessages.getString("CodeTemplateBlock.constructorcomment.label"); //$NON-NLS-1$
170 } else if (CodeTemplateContextType.GETTERCOMMENT.equals(name)) {
171 return PreferencesMessages.getString("CodeTemplateBlock.gettercomment.label"); //$NON-NLS-1$
172 } else if (CodeTemplateContextType.SETTERCOMMENT.equals(name)) {
173 return PreferencesMessages.getString("CodeTemplateBlock.settercomment.label"); //$NON-NLS-1$
175 return template.getDescription();
180 private final static int IDX_EDIT = 0;
182 private final static int IDX_IMPORT = 2;
184 private final static int IDX_EXPORT = 3;
186 private final static int IDX_EXPORTALL = 4;
188 protected final static Object COMMENT_NODE = PreferencesMessages.getString("CodeTemplateBlock.templates.comment.node"); //$NON-NLS-1$
190 protected final static Object CODE_NODE = PreferencesMessages.getString("CodeTemplateBlock.templates.code.node"); //$NON-NLS-1$
192 private static final String PREF_JAVADOC_STUBS = PreferenceConstants.CODEGEN_ADD_COMMENTS;
194 private TreeListDialogField fCodeTemplateTree;
196 private SelectionButtonDialogField fCreateJavaDocComments;
198 protected TemplateStore fTemplates;
200 private PixelConverter fPixelConverter;
202 private SourceViewer fPatternViewer;
204 private Control fSWTWidget;
206 private TemplateVariableProcessor fTemplateProcessor;
208 public CodeTemplateBlock() {
210 fTemplates = PHPeclipsePlugin.getDefault().getCodeTemplateStore();
211 fTemplateProcessor = new TemplateVariableProcessor();
213 CodeTemplateAdapter adapter = new CodeTemplateAdapter();
215 String[] buttonLabels = new String[] {
216 /* IDX_EDIT */PreferencesMessages.getString("CodeTemplateBlock.templates.edit.button"), //$NON-NLS-1$
218 /* IDX_IMPORT */PreferencesMessages.getString("CodeTemplateBlock.templates.import.button"), //$NON-NLS-1$
219 /* IDX_EXPORT */PreferencesMessages.getString("CodeTemplateBlock.templates.export.button"), //$NON-NLS-1$
220 /* IDX_EXPORTALL */PreferencesMessages.getString("CodeTemplateBlock.templates.exportall.button") //$NON-NLS-1$
223 fCodeTemplateTree = new TreeListDialogField(adapter, buttonLabels, new CodeTemplateLabelProvider());
224 fCodeTemplateTree.setDialogFieldListener(adapter);
225 fCodeTemplateTree.setLabelText(PreferencesMessages.getString("CodeTemplateBlock.templates.label")); //$NON-NLS-1$
227 fCodeTemplateTree.enableButton(IDX_EXPORT, false);
228 fCodeTemplateTree.enableButton(IDX_EDIT, false);
230 fCodeTemplateTree.addElement(COMMENT_NODE);
231 fCodeTemplateTree.addElement(CODE_NODE);
233 fCreateJavaDocComments = new SelectionButtonDialogField(SWT.CHECK | SWT.WRAP);
234 fCreateJavaDocComments.setLabelText(PreferencesMessages.getString("CodeTemplateBlock.createcomment.label")); //$NON-NLS-1$
235 fCreateJavaDocComments.setSelection(PreferenceConstants.getPreferenceStore().getBoolean(PREF_JAVADOC_STUBS));
237 fCodeTemplateTree.selectFirstElement();
240 protected Control createContents(Composite parent) {
241 fPixelConverter = new PixelConverter(parent);
244 Composite composite = new Composite(parent, SWT.NONE);
245 GridLayout layout = new GridLayout();
246 layout.marginHeight = 0;
247 layout.marginWidth = 0;
248 layout.numColumns = 2;
249 composite.setLayout(layout);
251 fCodeTemplateTree.doFillIntoGrid(composite, 3);
252 LayoutUtil.setHorizontalSpan(fCodeTemplateTree.getLabelControl(null), 2);
253 LayoutUtil.setHorizontalGrabbing(fCodeTemplateTree.getTreeControl(null));
255 fPatternViewer = createViewer(composite, 2);
257 fCreateJavaDocComments.doFillIntoGrid(composite, 2);
259 DialogField label = new DialogField();
260 label.setLabelText(PreferencesMessages.getString("CodeTemplateBlock.createcomment.description")); //$NON-NLS-1$
261 label.doFillIntoGrid(composite, 2);
267 private Shell getShell() {
268 if (fSWTWidget != null) {
269 return fSWTWidget.getShell();
271 return PHPeclipsePlugin.getActiveWorkbenchShell();
274 private SourceViewer createViewer(Composite parent, int nColumns) {
275 Label label = new Label(parent, SWT.NONE);
276 label.setText(PreferencesMessages.getString("CodeTemplateBlock.preview")); //$NON-NLS-1$
277 GridData data = new GridData();
278 data.horizontalSpan = nColumns;
279 label.setLayoutData(data);
281 IDocument document = new Document();
282 JavaTextTools tools = PHPeclipsePlugin.getDefault().getJavaTextTools();
283 tools.setupJavaDocumentPartitioner(document, IPHPPartitions.PHP_PARTITIONING);
284 IPreferenceStore store = PHPeclipsePlugin.getDefault().getCombinedPreferenceStore();
285 SourceViewer viewer = new JavaSourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL, store);
286 TemplateEditorSourceViewerConfiguration configuration = new TemplateEditorSourceViewerConfiguration(tools.getColorManager(),
287 store, null, fTemplateProcessor);
288 viewer.configure(configuration);
289 viewer.setEditable(false);
290 viewer.setDocument(document);
292 Font font = JFaceResources.getFont(PreferenceConstants.EDITOR_TEXT_FONT);
293 viewer.getTextWidget().setFont(font);
294 new JavaSourcePreviewerUpdater(viewer, configuration, store);
296 Control control = viewer.getControl();
297 data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
298 data.horizontalSpan = nColumns;
299 data.heightHint = fPixelConverter.convertHeightInCharsToPixels(5);
300 control.setLayoutData(data);
305 protected TemplatePersistenceData[] getTemplateOfCategory(boolean isComment) {
306 ArrayList res = new ArrayList();
307 TemplatePersistenceData[] templates = fTemplates.getTemplateData(false);
308 for (int i = 0; i < templates.length; i++) {
309 TemplatePersistenceData curr = templates[i];
310 if (isComment == curr.getTemplate().getName().endsWith(CodeTemplateContextType.COMMENT_SUFFIX)) {
314 return (TemplatePersistenceData[]) res.toArray(new TemplatePersistenceData[res.size()]);
317 protected static boolean canEdit(List selected) {
318 return selected.size() == 1 && (selected.get(0) instanceof TemplatePersistenceData);
321 protected void updateSourceViewerInput(List selection) {
322 if (fPatternViewer == null || fPatternViewer.getTextWidget().isDisposed()) {
325 if (selection.size() == 1 && selection.get(0) instanceof TemplatePersistenceData) {
326 TemplatePersistenceData data = (TemplatePersistenceData) selection.get(0);
327 Template template = data.getTemplate();
328 TemplateContextType type = PHPeclipsePlugin.getDefault().getCodeTemplateContextRegistry().getContextType(
329 template.getContextTypeId());
330 fTemplateProcessor.setContextType(type);
331 fPatternViewer.getDocument().set(template.getPattern());
333 fPatternViewer.getDocument().set(""); //$NON-NLS-1$
337 protected void doButtonPressed(int buttonIndex, List selected) {
338 if (buttonIndex == IDX_EDIT) {
339 edit((TemplatePersistenceData) selected.get(0));
340 } else if (buttonIndex == IDX_EXPORT) {
342 } else if (buttonIndex == IDX_EXPORTALL) {
344 } else if (buttonIndex == IDX_IMPORT) {
349 private void edit(TemplatePersistenceData data) {
350 Template newTemplate = new Template(data.getTemplate());
351 EditTemplateDialog dialog = new EditTemplateDialog(getShell(), newTemplate, true, false, PHPeclipsePlugin.getDefault()
352 .getCodeTemplateContextRegistry());
353 if (dialog.open() == Window.OK) {
355 data.setTemplate(newTemplate);
356 fCodeTemplateTree.refresh(data);
357 fCodeTemplateTree.selectElements(new StructuredSelection(data));
361 private void import_() {
362 FileDialog dialog = new FileDialog(getShell());
363 dialog.setText(PreferencesMessages.getString("CodeTemplateBlock.import.title")); //$NON-NLS-1$
364 dialog.setFilterExtensions(new String[] { PreferencesMessages.getString("CodeTemplateBlock.import.extension") }); //$NON-NLS-1$
365 String path = dialog.open();
371 TemplateReaderWriter reader = new TemplateReaderWriter();
372 File file = new File(path);
374 InputStream input = new BufferedInputStream(new FileInputStream(file));
375 TemplatePersistenceData[] datas = reader.read(input, null);
376 for (int i = 0; i < datas.length; i++) {
377 updateTemplate(datas[i]);
381 fCodeTemplateTree.refresh();
382 updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
384 } catch (FileNotFoundException e) {
385 openReadErrorDialog(e);
386 } catch (IOException e) {
387 openReadErrorDialog(e);
392 private void updateTemplate(TemplatePersistenceData data) {
393 TemplatePersistenceData[] datas = fTemplates.getTemplateData(true);
394 for (int i = 0; i < datas.length; i++) {
395 String id = datas[i].getId();
396 if (id != null && id.equals(data.getId())) {
397 datas[i].setTemplate(data.getTemplate());
403 private void exportAll() {
404 export(fTemplates.getTemplateData(false));
407 private void export(List selected) {
408 List datas = new ArrayList();
409 for (int i = 0; i < selected.size(); i++) {
410 Object curr = selected.get(i);
411 if (curr instanceof TemplatePersistenceData) {
414 TemplatePersistenceData[] cat = getTemplateOfCategory(curr == COMMENT_NODE);
415 datas.addAll(Arrays.asList(cat));
418 export((TemplatePersistenceData[]) datas.toArray(new TemplatePersistenceData[datas.size()]));
421 private void export(TemplatePersistenceData[] templates) {
422 FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
423 dialog.setText(PreferencesMessages.getFormattedString("CodeTemplateBlock.export.title", String.valueOf(templates.length))); //$NON-NLS-1$
424 dialog.setFilterExtensions(new String[] { PreferencesMessages.getString("CodeTemplateBlock.export.extension") }); //$NON-NLS-1$
425 dialog.setFileName(PreferencesMessages.getString("CodeTemplateBlock.export.filename")); //$NON-NLS-1$
426 String path = dialog.open();
431 File file = new File(path);
433 if (file.isHidden()) {
434 String title = PreferencesMessages.getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
435 String message = PreferencesMessages.getFormattedString("CodeTemplateBlock.export.error.hidden", file.getAbsolutePath()); //$NON-NLS-1$
436 MessageDialog.openError(getShell(), title, message);
440 if (file.exists() && !file.canWrite()) {
441 String title = PreferencesMessages.getString("CodeTemplateBlock.export.error.title"); //$NON-NLS-1$
442 String message = PreferencesMessages.getFormattedString("CodeTemplateBlock.export.error.canNotWrite", file.getAbsolutePath()); //$NON-NLS-1$
443 MessageDialog.openError(getShell(), title, message);
447 if (!file.exists() || confirmOverwrite(file)) {
449 OutputStream output = new BufferedOutputStream(new FileOutputStream(file));
450 TemplateReaderWriter writer = new TemplateReaderWriter();
451 writer.save(templates, output);
452 } catch (IOException e) {
453 openWriteErrorDialog(e);
459 private boolean confirmOverwrite(File file) {
460 return MessageDialog.openQuestion(getShell(), PreferencesMessages.getString("CodeTemplateBlock.export.exists.title"), //$NON-NLS-1$
461 PreferencesMessages.getFormattedString("CodeTemplateBlock.export.exists.message", file.getAbsolutePath())); //$NON-NLS-1$
464 public void performDefaults() {
465 IPreferenceStore prefs = PHPeclipsePlugin.getDefault().getPreferenceStore();
466 fCreateJavaDocComments.setSelection(prefs.getDefaultBoolean(PREF_JAVADOC_STUBS));
468 fTemplates.restoreDefaults();
471 fCodeTemplateTree.refresh();
472 updateSourceViewerInput(fCodeTemplateTree.getSelectedElements());
475 public boolean performOk(boolean enabled) {
476 IPreferenceStore prefs = PreferenceConstants.getPreferenceStore();
477 prefs.setValue(PREF_JAVADOC_STUBS, fCreateJavaDocComments.isSelected());
478 PHPeclipsePlugin.getDefault().savePluginPreferences();
482 } catch (IOException e) {
483 PHPeclipsePlugin.log(e);
484 openWriteErrorDialog(e);
489 public void performCancel() {
492 } catch (IOException e) {
493 openReadErrorDialog(e);
497 private void openReadErrorDialog(Exception e) {
498 String title = PreferencesMessages.getString("CodeTemplateBlock.error.read.title"); //$NON-NLS-1$
500 String message = e.getLocalizedMessage();
502 message = PreferencesMessages.getFormattedString("CodeTemplateBlock.error.parse.message", message); //$NON-NLS-1$
504 message = PreferencesMessages.getString("CodeTemplateBlock.error.read.message"); //$NON-NLS-1$
505 MessageDialog.openError(getShell(), title, message);
508 private void openWriteErrorDialog(Exception e) {
509 String title = PreferencesMessages.getString("CodeTemplateBlock.error.write.title"); //$NON-NLS-1$
510 String message = PreferencesMessages.getString("CodeTemplateBlock.error.write.message"); //$NON-NLS-1$
511 MessageDialog.openError(getShell(), title, message);